web-dev-qa-db-fra.com

Comment ajouter des feuilles de style uniquement aux pages avec un shortcode spécifique?

J'exécute une fonction sur les pages où le shortcode [make-me-a-map] est utilisé. Il met en javascript le code javascript sur la page et crée une carte. Cette partie fonctionne bien (woot!) Mais je ne parviens pas à ajouter les feuilles de style uniquement à ces pages de la même manière.

functions.php (Current)

add_shortcode("make-me-a-map", "create_new_map");
add_action("wp_head", "style_my_new_map");

function create_new_map () {
    global $new_map_called_for;
    $map_called_for = true;

    wp_register_script('make-a-new-map', get_template_directory_uri() . '/js/new-map.js', array('jquery'), '0.1', true);
    wp_enqueue_script('make-a-new-map');
    }

function style_my_new_map() {
    global $new_map_called_for;
    if ($new_map_called_for == true) {
        $tDir = get_template_directory_uri();

        // Echo stylesheets because wp_register_style & wp_enqueue_style don't work atm
        // And add_action('wp_enqueue_script', 'style_my_new_maps') with those functions would add style to all pages
        // Not just the ones with [make-me-a-map] shortcode
        echo "<link rel='stylesheet' href='", $tDir, "/css/new-map.css' />", PHP_EOL;

        // Echo Javascript straight to page (couldn't do it with wp_enqueue_script) to let js code know the template directory
        echo '<script type="text/javascript">var templateDir = "', get_template_directory_uri(), '";</script>', PHP_EOL;
        $map_called_for = false;
    }
}

Cela ne semble pas fonctionner malheureusement. Les styles sont ajoutés à toutes les pages.

Je n'ai pas utilisé wp_register_style & wp_enqueue_style car ce bogue ajoute toujours des balises <Link /> au pied de page à partir de ces fonctions.

J'aurais pu utiliser add_action("wp_enqueue_scripts", "style_my_new_map") au lieu de add_action('wp-head', "style_my_new_map") mais, autant que je sache et que j'ai vérifié, il n'y a pas de différence? Ajoute toujours les feuilles de style à toutes les pages.

Donc ma question est en fait en deux parties: :)

  1. Pourquoi le fichier functions.php actuel ne fonctionne-t-il pas et l'ajout de styles à toutes les pages? Je ne sais pas s'il s'agit de l'appel global ou de la déclaration if ...
  2. Quelle est la meilleure façon pour moi d’ajouter les feuilles de style à l’en-tête des pages sur lesquelles le shortcode ci-dessus est utilisé, en supposant que je ne connaisse pas les identifiants de page, etc.?

Merci d'avance! P

7
Padraic

2 questions donc 2 réponses :)

Pourquoi le fichier functions.php actuel ne fonctionne-t-il pas et l'ajout de styles à toutes les pages? Je ne suis pas sûr que ce soit l'appel global ou l'énoncé if ...

Cela ne fonctionne pas à cause de l'ordre dans lequel ces fonctions sont appelées. Votre rappel de shortcode est appelé pendant le rendu du contenu de la publication (très probablement l'appel de la fonction the_content).

wp_enqueue_scripts et wp_head sont tous deux appelés beaucoup plus tôt: wp_head quelque part dans votre fichier de thèmes header.php et wp_enqueue_scripts pendant l'appel wp_head.

Quelle est la meilleure façon pour moi d’ajouter les feuilles de style à l’en-tête des pages sur lesquelles le shortcode ci-dessus est utilisé, en supposant que je ne connaisse pas les identifiants de page, etc.?

Je ne pense pas qu'il existe un tel "meilleur" moyen. Ce n'est pas une bonne idée du tout. Les navigateurs cachent les fichiers CSS. Donc, si vous avez le même CSS sur toutes les pages, le navigateur ne l'obtiendra qu'une fois. S'il existe de nombreux fichiers CSS pour différentes pages, le navigateur devra tous les obtenir. Donc, je ne le ferais pas du tout, et inclure ces styles CSS dans un fichier css global.

Bien que si vous ne devez l'inclure que sur les pages qui utilisent ce shortcode, alors (2 solutions, le choix qui vous convient le mieux est le vôtre; je pense que la deuxième est plus jolie) ...

  1. Vous pouvez ajouter ces styles en tant que styles en ligne. Faites juste attention à ne pas les inclure plusieurs fois. Donc, affichez-les avec votre shortcode et assurez-vous qu'ils ne seront imprimés qu'une seule fois.
  2. Comme les publications sont déjà sélectionnées, lorsque wp_head/wp_enqueue_scripts est appelé, vous pouvez ajouter une fonction à ce hook, parcourir les publications sélectionnées, vérifier si elles contiennent votre code court et mettre en file d'attente votre CSS si nécessaire. (Bien sûr ça ne sera pas très efficace).
1
Krzysiek Dróżdż

Chargement dynamique de scripts et de styles à l'aide d'un shortcode

Avantages

  • Ne recherche pas dans tous les articles à chaque appel du shortcode.
  • Possibilité d'ajouter des styles et des scripts de manière dynamique uniquement lorsque le shortcode est sur la page.
  • N'utilise pas de regex car ils ont tendance à être plus lent que strstr() ou strpos(). Vous pouvez passer à regex si vous devez accepter les arguments.
  • Réduit les appels de fichiers

Explication du code

  1. Trouve les codes courts sur la page à l'aide du point d'ancrage save_post uniquement lorsque la publication n'est pas une révision et correspond au post_type spécifié.

  2. Enregistre les identifiants de publication trouvés en tant que tableau à l'aide de add_option() avec le chargement automatique défini sur yes, sauf si l'entrée est déjà présente. Ensuite, il utilisera update_option().

  3. Utilise hook wp_enqueue_scripts pour appeler notre fonction add_scripts_and_styles().

  4. Cette fonction appelle ensuite get_option() pour récupérer notre tableau d'identifiants de page. Si le $page_id actuel est dans le $option_id_array, il ajoute les scripts et les styles.

S'il vous plaît noter: J'ai converti le code de OOP classes d'espaces de noms afin que je puisse avoir manqué quelque chose. Faites-moi savoir dans les commentaires si je l'ai fait.

Exemple de code: recherche d'occurrences de code court

function find_shortcode_occurences($shortcode, $post_type = 'page')
{
    $found_ids = array();
    $args         = array(
        'post_type'   => $post_type,
        'post_status' => 'publish',
        'posts_per_page' => -1,
    );
    $query_result = new \WP_Query($args);
    foreach ($query_result->posts as $post) {
        if (false !== strpos($post->post_content, $shortcode)) {
            $found_ids[] = $post->ID;
        }
    }
    return $found_ids;
}

function save_option_shortcode_post_id_array( $post_id ) {
    if ( wp_is_post_revision( $post_id ) OR 'page' != get_post_type( $post_id )) {
        return;
    }
    $option_name = 'yourprefix-yourshortcode';
    $id_array = find_shortcode_occurences($option_name);
    $autoload = 'yes';
    if (false == add_option($option_name, $id_array, '', 'yes')) update_option($option_name, $id_array);
}

add_action('save_post', 'save_option_shortcode_id_array' );

Exemple de code: Shortcode inclure dynamiquement des scripts et des styles

function yourshortcode_add_scripts_and_styles() {
    $page_id = get_the_ID();
    $option_id_array = get_option('yourprefix-yourshortcode');
    if (in_array($page_id, $option_id_array)) {
        wp_enqueue_script( $handle, $src, $deps, $ver, $footer = true );
        wp_enqueue_style( $handle, $src , $deps);
    }
}

add_action('wp_enqueue_scripts', 'yourshortcode_add_scripts_and_styles');
9
CommandZ

Cela fonctionne pour moi:

function register_my_css () {
    wp_register_style('my-style', plugins_url('styles.css', __FILE__));
}

function register_my_scripts () {
    wp_register_script('my-script', plugins_url('scripts.js', __FILE__));
}

// only enqueue the scripts / styles when the short code is called
function do_my_shortcode () {
    wp_enqueue_style('my-style');
    wp_enqueue_script('my-script');

    // do short code stuff...
}

// register css
add_action('wp_enqueue_scripts', 'register_my_css');

// register javascript
add_action('wp_enqueue_scripts', 'register_my_scripts');

// register shortcode
add_shortcode('my-shortcode', 'do_my_shortcode');

Plus d'infos ici: http://mikejolley.com/2013/12/sensible-script-enqueuing-shortcodes/

2
benedict_w

Vous pouvez vous connecter à une action après l'exécution de la requête principale et déterminer si vous devez charger vos styles et scripts.

add_action('template_include', 'custom_template_include');
function custom_template_include($template) {
    if (is_single() || is_page()) {
          global $post;
          if (has_shortcode($post->post_content, 'your_short_code')) {
              add_action('wp_enqueue_scripts, 'custom_enqueue_scripts');
          }
    } 
}

function custom_enqueue_scripts() {
    //Enqueue your stuff here. 
}
1
Lucas Stark

Chargement dynamique de scripts et de styles à l'aide d'un shortcode

Ceci est un code étendu pour la solution fournie par Commandz ci-dessus.

J'ai trouvé que sa méthode était la meilleure et la plus pratique étant donné que l'option de base de données est disponible à presque tous les crochets.

Il est modifié pour rechercher les occurrences de shortcodes only pour le contenu de la publication actuelle, au lieu de parcourir toutes les publications - ce qui peut être plus lent lorsque le nombre de publications est important.

Il est modifié ici sur deux lignes après le passage d'une autre variable $ post_id de l'action save_post à la fonction find_shortcode_occurences ()

if( !empty($post_id) ) {
    $args['posts__in'] = $post_id; 
}

Code modifié pour les deux fonctions

function find_shortcode_occurences($shortcode, $post_id='', $post_type = 'page') {
    $found_ids = array();
    $args         = array(
        'post_type'   => $post_type,
        'post_status' => 'publish',
        'posts_per_page' => -1,
    );

    if( !empty($post_id) ) {
        $args['posts__in'] = $post_id; 
    }

    $query_result = new WP_Query($args);
    foreach ($query_result->posts as $post) {
        if (false !== strpos($post->post_content, $shortcode)) {
            $found_ids[] = $post->ID;
        }
    }
    return $found_ids;
}

add_action('save_post', 'save_option_for_sppro_pages' );
function save_option_for_sppro_pages( $post_id ) {
    if ( wp_is_post_revision( $post_id ) ) {
        return;
    }
    $option_name = 'database-option';
    $shortcode = 'shortcode-name';
    $id_array = find_shortcode_occurences($shortcode, $post_id);
    $autoload = 'yes';
    if (false == add_option($option_name, $id_array, '', 'yes')) {
        $current_value = get_option($option_name);
        $new_value = array_merge($current_value, $id_array);
        update_option($option_name, $id_array);
    }
}

De plus, une autre variable a été ajoutée afin que vous puissiez avoir des noms différents pour l'option de base de données et le nom du shortcode.

0
OmAk
add_action( 'wp_enqueue_scripts', 'enqueue_shortcode_styles', 1 );
function enqueue_shortcode_styles() {

    global $post;

    if ( isset($post->post_content) && is_singular(array( 'post','page' ) ) && ! has_shortcode( $post->post_content, '$tag' ) ) {

    wp_enqueue_style( 'shortcode-styles', get_stylesheet_directory_uri() . '/style.css' );

    }

}

Je voudrais utiliser has_shortcode pour vérifier le contenu de $ post et charger les scripts à l’aide de wp_enqueue_scripts, mais cela dépend de l’endroit où vos shortcodes sont intégrés.

Échangez la balise $ avec votre balise shortcode dans le code ci-dessus.

Ajoutez à votre fichier de fonctions de thèmes enfants et modifiez les conditions si nécessaire.

0
Dev

Une solution beaucoup plus simple qui a fonctionné pour moi a consisté à enregistrer le script en dehors de la fonction shortcode, puis à le mettre en file d'attente au sein de la fonction. Ensuite, il ne charge que le script sur les pages utilisant votre shortcode.

wp_register_script('make-a-new-map', get_template_directory_uri() . '/js/new-map.js', array('jquery'), '0.1', true);
wp_register_style('make-a-new-map-style', get_template_directory_uri() . '/css/new-map.css');

add_shortcode("make-me-a-map", "create_new_map");
add_action("wp_head", "style_my_new_map");

function create_new_map () {
   wp_enqueue_script('make-a-new-map');
   wp_enqueue_style('make-a-new-map-style');

   global $new_map_called_for;
   $map_called_for = true;
}

Vous trouverez une description de cette méthode ici: http://mikejolley.com/2013/12/sensible-script-enqueuing-shortcodes/

Notez que cela charge le CSS dans le pied de page, ce qui peut ne pas être souhaitable ou être valide pour le W3C. Dans mon cas, ce n'était pas un problème.

0
stellarcowboy

Vous pouvez simplement le faire comme ceci:

// shortcode hook
add_shortcode("make-me-a-map", "create_new_map");

// shortcode callback
function style_my_new_map() {
    global $new_map_called_for;
    if ($new_map_called_for == true) {
  wp_register_script('make-a-new-map', get_template_directory_uri() . '/js/new-map.js', array('jquery'), '0.1', true);
  wp_enqueue_script('make-a-new-map');

// the rest of your codes
    }
}

Cela fonctionne aussi pour les feuilles de style. Pour charger votre feuille de style à la dernière, puis ajoutez des numéros à votre hook de shortcode, comme ceci:

add_shortcode("make-me-a-map", "create_new_map", 9999);

Je l'ai testé et ça marche.

0
KeepMove