Загрузка скриптов только при наличии определенного шорткода или виджета
Мне нужен был способ фильтрации содержимого страницы/сообщений до его загрузки, чтобы я мог добавлять сценарии в заголовок, если присутствовал определенный шорткод. После долгих поисков я наткнулся на это на http://wpengineer.com
function has_my_shortcode($posts) {
if ( empty($posts) )
return $posts;
$found = false;
foreach ($posts as $post) {
if ( stripos($post->post_content, '[my_shortcode') )
$found = true;
break;
}
if ($found){
$urljs = get_bloginfo( 'template_directory' ).IMP_JS;
wp_register_script('my_script', $urljs.'myscript.js' );
wp_print_scripts('my_script');
}
return $posts;
}
add_action('the_posts', 'has_my_shortcode');
Что абсолютно блестяще и сделало именно то, что мне было нужно.
Теперь мне нужно немного расширить его и сделать то же самое для боковых панелей. Это может быть определенный тип виджета, шорткод, фрагмент кода или что-либо еще, что могло бы работайте над определением того, когда необходимо загрузить скрипт.
Проблема в том, что я не могу понять, как получить доступ к содержимому боковых панелей до загрузки боковой панели (в рассматриваемой теме будет несколько боковых панелей)
4 answers
Вы можете использовать функцию 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') );
}
Просто хотел поделиться решением, над которым я работал, которое позволило мне быть немного более универсальным в своей реализации. Вместо того, чтобы проверять функцию на наличие различных коротких кодов, я изменил ее, чтобы найти один короткий код, который ссылается на функцию сценария/стиля, которую необходимо поставить в очередь. Это будет работать как для методов в других классах (таких как плагины, которые могут не делать этого сами), так и для функций в области действия. Просто введите приведенный ниже код в functions.php и добавьте следующее синтаксис для любой страницы/публикации, где вам нужны конкретные CSS и JS.
Синтаксис страницы/сообщения: [Функция LOADCSSANDJS="(класс->имя метода/функции)"]
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;
}
Это также позволит вам добавлять на страницу столько, сколько вы хотите. Имейте в виду, что вам действительно нужен метод/функция для загрузки.
С 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 и его можно найти на страницах новой документации для разработчиков.
Спасибо, что поделились этим советом!
Это вызвало у меня небольшую головную боль, потому что сначала это не работало. Я думаю, что в приведенном выше коде есть пара ошибок (возможно, опечаток) 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, и это приводило к тому, что цикл всегда прерывался на первой итерации. Другая проблема была более тонкой и трудной для обнаружения. Приведенный выше код не работает, если шорткод - это самое первое, что пишется в посте. Мне пришлось использовать оператор ===
, чтобы решить эту проблему.
В любом случае, большое вам спасибо за то, что поделились этой техникой, она очень помогла.