Загрузка скриптов только при наличии определенного шорткода или виджета
-
-
Являются ли сценарии в заголовке жесткими требованиями для вашей ситуации?Со скриптами в конце страницы легче справиться условно и рекомендуется для выполнения.Are scripts in header hard requirement for your situation? Scripts at end of page are easier to deal with conditionally and recommended practice for performance.
- 0
- 2010-09-28
- Rarst
-
Сначала я попробовал это в wp_footer,что прекрасно устраняет необходимость предварительной фильтрации содержимого,но,хотя скрипты загружались нормально,они не работали.Эти скрипты должны быть в wp_head,чтобы делать то,что им нужно.I did try it in wp_footer first which nicely eliminates the need for prefiltering the content, but while the scripts loaded fine, they didn't work. These scripts have to be in wp_head to do what they need to.
- 0
- 2010-09-28
- Ashley G
-
4 ответ
- голосов
-
- 2010-09-28
Вы можете использовать функцию is_active_widget . Например:
function check_widget() { if( is_active_widget( '', '', 'search' ) ) { // check if search widget is used wp_enqueue_script('my-script'); } } add_action( 'init', 'check_widget' );
Чтобы загрузить скрипт только на страницу,где загружен виджет,вам нужно будет добавить кодis_active_widget () в свой класс виджета. Например,просмотрите виджет недавних комментариев по умолчанию (wp-includes/default-widgets.php,строка 602):
class WP_Widget_Recent_Comments extends WP_Widget { function WP_Widget_Recent_Comments() { $widget_ops = array('classname' => 'widget_recent_comments', 'description' => __( 'The most recent comments' ) ); $this->WP_Widget('recent-comments', __('Recent Comments'), $widget_ops); $this->alt_option_name = 'widget_recent_comments'; if ( is_active_widget(false, false, $this->id_base) ) add_action( 'wp_head', array(&$this, 'recent_comments_style') ); add_action( 'comment_post', array(&$this, 'flush_widget_cache') ); add_action( 'transition_comment_status', array(&$this, 'flush_widget_cache') ); }
You can use the function is_active_widget . E.g.:
function check_widget() { if( is_active_widget( '', '', 'search' ) ) { // check if search widget is used wp_enqueue_script('my-script'); } } add_action( 'init', 'check_widget' );
To load the script in the page where the widget is loaded only, you will have to add the is_active_widget() code, in you widget class. E.g., see the default recent comments widget (wp-includes/default-widgets.php, line 602):
class WP_Widget_Recent_Comments extends WP_Widget { function WP_Widget_Recent_Comments() { $widget_ops = array('classname' => 'widget_recent_comments', 'description' => __( 'The most recent comments' ) ); $this->WP_Widget('recent-comments', __('Recent Comments'), $widget_ops); $this->alt_option_name = 'widget_recent_comments'; if ( is_active_widget(false, false, $this->id_base) ) add_action( 'wp_head', array(&$this, 'recent_comments_style') ); add_action( 'comment_post', array(&$this, 'flush_widget_cache') ); add_action( 'transition_comment_status', array(&$this, 'flush_widget_cache') ); }
-
Можно ли это вызвать ДО загрузки виджетов.Чтобы было понятно,это должно произойти до того,как страница загрузится.Мой пример кода используетthe_posts для фильтрации содержимого на странице,но не получает боковые панели/виджеты.Can that be called BEFORE the widgets are loaded. To be clear this has to take place before the page even loads. My sample code uses the_posts to filter the content on the page, but that doesn't get the sidebars/widgets.
- 0
- 2010-09-28
- Ashley G
-
Да,посмотрите пример,который я добавил к своему ответу.Yes, see the example I added to my answer.
- 0
- 2010-09-28
- sorich87
-
Ваш пример на самом деле не работает.Я упускаю что-то очевидное?Your example doesn't actually work. Am I missing something obvious?
- 0
- 2010-09-29
- Ashley G
-
На самом деле я был.wp_enqueue_script,похоже,не работает при применении к wp_head,но wp_print_scripts работает.wp_enqueue_script действительно работает,если применить его кinit следующим образом: add_action ('init','check_widget');Actually I was. wp_enqueue_script doesn't seem to work when applied to wp_head, but wp_print_scripts does. wp_enqueue_script does work though if applied to init like so: add_action( 'init', 'check_widget' );
- 0
- 2010-09-29
- Ashley G
-
Однако он загружает скрипты на каждую страницу сайта,даже если виджет активен только на одной боковой панели.например,если у меня есть боковая панель для страниц блога и еще одна боковая панель для других страниц.Я добавляю виджет поиска на боковую панель блога,и скрипты загружаются,но он также загружается на страницы,у которых нет боковой панели блога.Мне нужно иметь возможность загружать скрипт,только если виджет присутствует на этой странице.However it loads the scripts on every page of the site, even if the widget is only active in one sidebar. for example if I have a sidebar for blog pages and a another sidebar for other pages. I add the search widget to the blog sidebar and the scripts does load, but it also loads on pages that don't have the blog sidebar. I need to be able to load the script only if the widget is present on that page.
- 0
- 2010-09-29
- Ashley G
-
Я отредактировал свой ответI edited my answer
- 0
- 2010-09-29
- sorich87
-
Ты мужчина!Ура!You are the man! Cheers!
- 0
- 2010-09-29
- Ashley G
-
Очень красивое решение :)Very nice solution :)
- 0
- 2011-12-25
- Anh Tran
-
Лучше использовать wp_enqueue_scripts вместо wp_head.отличный ответ,спасибо.Better to use wp_enqueue_scripts instead of wp_head. great answer, thank you.
- 0
- 2017-03-06
- wesamly
-
- 2012-09-25
Просто хотел поделиться решением,над которым я работал,которое позволило мне быть более универсальным в моей реализации. Вместо того,чтобы проверять различные шорткоды,я изменил его,чтобы найти единственный шорткод,который ссылается на функцию скрипта/стиля,которую нужно поставить в очередь. Это будет работать как для методов в других классах (таких как плагины,которые могут не делать этого сами),так и для функций в области видимости. Просто поместите приведенный ниже код вfunctions.php и добавьте следующий синтаксис на любую страницу/сообщение,где вам нужен определенный CSS & amp; JS.
Синтаксис страницы/сообщения: [loadCSSandJSfunction="(класс-> имя метода/функции)"]
кодfunctions.php:
function page_specific_CSSandJS( $posts ) { if ( empty( $posts ) ) return $posts; foreach ($posts as $post) { $returnValue = preg_match_all('#\[loadCSSandJS function="([A-z\-\>]+)"\]#i', $post->post_content, $types); foreach($types[1] as $type) { $items = explode("->",$type); if (count($items) == 2) { global $$items[0]; if( method_exists( $$items[0], $items[1] )) add_action( 'wp_enqueue_scripts', array(&$$items[0], $items[1]) ); } else if( !empty( $type ) && function_exists( $type )) add_action( 'wp_enqueue_scripts', $type ); } } return $posts; }
Это также позволит вам добавить на страницу столько,сколько хотите. Имейте в виду,что вам нужен метод/функция для загрузки.
Just wanted to share a solution I worked on which allowed me to be a bit more versatile with my implementation. Rather than having the function check for a variety of shortcodes, I modified it to seek out a single shortcode that references a script/style function that needs to be enqueued. This will work for both methods in other classes (such as plugins that may not do this themselves) and in-scope functions. Just drop the below code in functions.php and add the following syntax to any page/post where you want specific CSS & JS.
Page/Post Syntax: [loadCSSandJS function="(class->method/function name)"]
functions.php code:
function page_specific_CSSandJS( $posts ) { if ( empty( $posts ) ) return $posts; foreach ($posts as $post) { $returnValue = preg_match_all('#\[loadCSSandJS function="([A-z\-\>]+)"\]#i', $post->post_content, $types); foreach($types[1] as $type) { $items = explode("->",$type); if (count($items) == 2) { global $$items[0]; if( method_exists( $$items[0], $items[1] )) add_action( 'wp_enqueue_scripts', array(&$$items[0], $items[1]) ); } else if( !empty( $type ) && function_exists( $type )) add_action( 'wp_enqueue_scripts', $type ); } } return $posts; }
This will also allow you to add as many as you want on a page. Keep in mind that you do need a method/function to load.
-
- 2011-12-22
Спасибо,что поделились этим советом! У меня немного заболела голова,потому что сначала это не помогало. Я думаю,что в приведенном выше коде
has_my_shortcode
есть пара ошибок (возможно,опечаток),и я переписал функцию,как показано ниже:function has_my_shortcode( $posts ) { if ( empty($posts) ) return $posts; $shortcode_found = false; foreach ($posts as $post) { if ( !( stripos($post->post_content, '[my-shortcode') === false ) ) { $shortcode_found = true; break; } } if ( $shortcode_found ) { $this->add_scripts(); $this->add_styles(); } return $posts; }
Я думаю,что было две основных проблемы:
break
не входил в область действия оператораif,и из-за этого цикл всегда прерывался на первой итерации. Другая проблема была более тонкой и трудной для обнаружения. Приведенный выше код не работает,если шорткод - это первое,что написано в сообщении. Чтобы решить эту проблему,мне пришлось использовать оператор===
.В любом случае,большое спасибо за то,что поделились этой техникой,она очень помогла.
Thank you for sharing this tip! It gave me a little headache, because at first it wasn't working. I think there are a couple of mistakes (maybe typos) in the code above
has_my_shortcode
and I re-written the function as below:function has_my_shortcode( $posts ) { if ( empty($posts) ) return $posts; $shortcode_found = false; foreach ($posts as $post) { if ( !( stripos($post->post_content, '[my-shortcode') === false ) ) { $shortcode_found = true; break; } } if ( $shortcode_found ) { $this->add_scripts(); $this->add_styles(); } return $posts; }
I think there were two main issues: the
break
wasn't in the scope of the if statement, and that caused the loop to always break at the first iteration. The other problem was more subtle and difficult to discover. The code above doesn't work if the shortcode is the very first thing written in a post. I had to use the===
operator to solve this.Anyway, thank you so much for sharing this technique, it helped a lot.
-
- 2017-01-31
В Wordpress 4.7 есть другой способ добиться этого - в файле
functions.php
add_action( 'wp_enqueue_scripts', 'register_my_script'); function register_my_script(){ wp_register_script('my-shortcode-js',$src, $dependency, $version, $inFooter); }
сначала вы регистрируете свой скрипт ,который фактически не печатается на ваша страница,если вы не поставите ее в очередь,если ваш шорткод вызван,
add_filter( 'do_shortcode_tag','enqueue_my_script',10,3); function enqueue_my_script($output, $tag, $attr){ if('myShortcode' != $tag){ //make sure it is the right shortcode return $output; } if(!isset($attr['id'])){ //you can even check for specific attributes return $output; } wp_enqueue_script('my-shortcode-js'); //enqueue your script for printing return $output; }
do_shortcode_tag
был представлен в WP 4.7 и можно найти на страницах документации для новых разработчиков .with Wordpress 4.7 there is another way to achieve this in your
functions.php
file,add_action( 'wp_enqueue_scripts', 'register_my_script'); function register_my_script(){ wp_register_script('my-shortcode-js',$src, $dependency, $version, $inFooter); }
first you register your script, which doesn't actually get printed on your page unless your enqueue it if your shortcode is called,
add_filter( 'do_shortcode_tag','enqueue_my_script',10,3); function enqueue_my_script($output, $tag, $attr){ if('myShortcode' != $tag){ //make sure it is the right shortcode return $output; } if(!isset($attr['id'])){ //you can even check for specific attributes return $output; } wp_enqueue_script('my-shortcode-js'); //enqueue your script for printing return $output; }
the
do_shortcode_tag
was introduced in WP 4.7 and can be found in the new developers documentation pages.
Мне нужен был способ фильтрации содержимого страницы/сообщений до их загрузки,чтобы я мог добавлять сценарии в заголовок,если присутствует определенный шорткод. После долгих поисков я наткнулся на это на http://wpengineer.com
,который великолепен и сделал именно то,что мне нужно.
Теперь мне нужно немного расширить его и сделать то же самое для боковых панелей. Это может быть конкретный тип виджета,шорткод,фрагмент кода или что-то еще,что поможет определить,когда необходимо загрузить скрипт.
Проблема в том,что я не могу понять,как получить доступ к содержимому боковых панелей до загрузки боковой панели (у рассматриваемой темы будет несколько боковых панелей)