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: :)
global
ou de la déclaration if
...Merci d'avance! P
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) ...
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).strstr()
ou strpos()
. Vous pouvez passer à regex si vous devez accepter les arguments.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é.
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()
.
Utilise hook wp_enqueue_scripts
pour appeler notre fonction add_scripts_and_styles()
.
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.
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' );
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');
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/
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.
}
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;
}
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.
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.
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.
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.