web-dev-qa-db-fra.com

Comment détecter si une fonction a été passée sur une page afin que les scripts/styles puissent être chargés de manière conditionnelle

Je construis un petit plugin de galerie et j'aimerais charger uniquement les scripts/styles sur la page SI la galerie a été chargée via la balise template. La balise de modèle peut prendre un paramètre de publication lorsqu'elle est utilisée pour appeler la galerie d'une publication où que vous soyez dans le thème.

Je sais comment faire cela sur des pages singulières (je peux simplement rechercher la méta_key et la faire correspondre à la publication actuellement visionnée), mais détecter si une galerie est présente sur la page d'accueil (ou toute autre page) s'avère plus difficile.

Supposons donc que la balise template ressemble à ceci:

if ( function_exists( 'my_gallery' ) )
    echo my_gallery( '100' ); // gallery of image from post 100 will be shown

Et la fonction de la galerie ressemble à ceci (simplifié):

function my_gallery( $post_id = '' ) {
    // whole bunch of stuff in here which is returned
}

Les scripts et les styles de la galerie ressemblent à ceci (simplifié):

function my_gallery_scripts() {

   wp_register_script( 'my-gallery-js', MY_GALLERY_URL . 'js/my-gallery.js', array( 'jquery' ), '1.0', true );
   wp_register_style( 'my-gallery-css', MY_GALLERY_URL . 'css/my-gallery.css', '', '1.0', 'screen' );

    // need to load these conditionally, but how?
    wp_enqueue_style( 'my-gallery-js' );
    wp_enqueue_script( 'my-gallery-css' );

}
add_action( 'wp_enqueue_scripts', 'my_gallery_scripts' );

J'ai essayé d'utiliser set_query_var dans my_gallery() comme ceci pour définir une variable globale dans $ wp_query.

 function my_gallery( $post_id = '' ) {

    set_query_var( 'has_gallery', true );

    // whole bunch of stuff in here which is returned
}    

Le problème est que je ne peux pas utiliser get_query_var dans l'action wp_enqueue_scripts.

Ce qui suit serait donc idéal pour moi, je crois, charger has_gallery dans l’objet $ wp_query qui m’est disponible à chaque page (sauf que cela ne fonctionne pas).

 function my_gallery_scripts() {

   wp_register_script( 'my-gallery-js', MY_GALLERY_URL . 'js/my-gallery.js', array( 'jquery' ), '1.0', true );
   wp_register_style( 'my-gallery-css', MY_GALLERY_URL . 'css/my-gallery.css', '', '1.0', 'screen' );

    // does not work
    $has_gallery = get_query_var( 'has_gallery' );

    if ( $has_gallery ) {
        wp_enqueue_style( 'my-gallery-js' );
        wp_enqueue_script( 'my-gallery-css' );
    }
}
add_action( 'wp_enqueue_scripts', 'my_gallery_scripts' );

Existe-t-il un autre moyen de définir une option globale similaire à set_query_var mais fonctionnera dans mon scénario? J'aimerais évidemment éviter l'utilisation d'une variable globale. J'ai aussi essayé de mettre une constante en vain.

2
Andrew

Pour les scripts, ce n'est pas une mince affaire - il suffit de mettre en file d'attente dans la fonction my_gallery() et ils seront affichés dans le pied de page (puisque l'en-tête est déjà passé).

Cependant, les feuilles de style représentent un défi, elles ne sont censées fonctionner que dans la section head et la mise en file d'attente pour le pied de page n'est pas prise en charge.

Essentiellement, vous devez savoir si la fonction a été appelée avant. Cela n'a pas de solution simple pour les conditions données.

J'essaierais probablement de charger la feuille de style à partir du code JS pour y parvenir sous la forme que vous décrivez.

1
Rarst

Le meilleur moyen que je puisse imaginer (et avec le meilleur terme, je veux dire "travail", pas "rapide"), est de vérifier le contenu de la publication à la recherche de l'existence de ce shortcode. L'utilisation de la fonction Regex principale facilite grandement les choses.

Étape 1: Inscrivez-vous

/**
 * Register the needed assets
 */
add_action( 'wp_enqueue_scripts', 'wpse_105537_register_assets', 0 );
function wpse_105537_register_assests()
{
    wp_register_script(
        'wpse_105537_script',
        // ETC.
    );
    wp_register_style(
        'wpse_105537_style',
        // ETC.
    );
}

Étape 2: En file d'attente

/**
 * Enqueue the needed assets if the shortcode is present anywhere
 */
add_action( 'wp_enqueue_scripts', 'wpse_105537_register_assets' );
function wpse_105537_enqueue_assets()
{
    if ( ! wpse_105537_check_content() )
        return;

    wp_enqueue_script( 'wpse_105537_script' );
    wp_enqueue_style( 'wpse_105537_style' );
}

Helper: Rechercher le shortcode dans le contenu de l'article

Cette fonction d'assistance est abandonnée après le premier match.

/**
 * Check if any of the posts has the shortcode in its post_content
 * @return bool
 */
function wpse_105537_check_content()
{
    global $wp_query;

    foreach ( $GLOBALS['wp_query']->posts as $post )
    {
        $pattern = get_shortcode_regex();
        if (
            preg_match_all( '/'. $pattern .'/s', $post->post_content, $matches )
            AND array_key_exists( 2, $matches )
            AND in_array( 'gallery', $matches[2] )
        )
            return true;
    }

    return false;
}
1
kaiser

Je sais comment faire cela sur des pages singulières (je peux simplement rechercher la méta_key et la faire correspondre à la publication actuellement visionnée), mais détecter si une galerie est présente sur la page d'accueil (ou toute autre page) s'avère plus difficile.

Donc, s'il y a une clé méta, ce serait encore plus simple: il suffit de l'attraper tôt. Les deux premières fonctions peuvent être tirées de l’autre réponse. Juste le chèque lui-même serait remplacé par la fonction suivante:

/**
 * Check if any of the posts has the needed gallery meta data attached
 * @return bool
 */
function wpse_105537_check_meta()
{
    global $wp_query;

    foreach ( $GLOBALS['wp_query']->posts as $post )
    {
        if ( '' !== get_post_meta( $post->ID, 'your_meta_key', true ) )
            return true;
    }

    return false;
}
0
kaiser