Завантаження сценаріїв лише за наявності певного короткого коду чи віджета


17

Мені потрібен був спосіб фільтрації вмісту сторінки / публікацій до її завантаження, щоб я міг додати сценарії до заголовка, якщо був присутній певний короткий код. Після довгих пошуків я натрапив на це на 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');

який абсолютно геніальний і робив саме те, що мені потрібно.

Тепер мені потрібно трохи продовжити його і зробити те ж саме для бічних панелей. Це може бути певний тип віджета, короткий код, фрагмент коду чи що-небудь інше, що допоможе визначити, коли сценарій потрібно завантажувати.

Проблема полягає в тому, що я не можу зрозуміти, як отримати доступ до вмісту бічних панелей перед завантаженням бічної панелі (у відповідної теми буде кілька бічних панелей)


Чи є сценарії в заголовку жорсткою вимогою до вашої ситуації? Сценарії в кінці сторінки простіше розібратися з умовою та рекомендованою практикою для виконання.
Рарст,

Я спробував це в wp_footer спочатку, що красиво позбавляє від необхідності попередньої фільтрації вмісту, але поки сценарії завантажувались добре, вони не спрацювали. Ці сценарії повинні бути в wp_head, щоб робити те, що їм потрібно.
Ешлі Г

Відповіді:


20

Ви можете використовувати функцію 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' );

Щоб завантажити скрипт на сторінку, на яку завантажено лише віджет, вам доведеться додати код ви_джета () у свій віджет. Наприклад, перегляньте віджет останніх коментарів за замовчуванням (wp-include / 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') );
    }

Чи можна це назвати ДО ПЕРЕД завантаження віджетів. Щоб було зрозуміло, це має відбуватися до завантаження сторінки. Мій зразок коду використовує the_posts для фільтрування вмісту на сторінці, але це не отримує бічні панелі / віджети.
Ешлі Г

Так, дивіться приклад, який я додав до своєї відповіді.
sorich87

Ваш приклад насправді не працює. Невже я пропускаю щось очевидне?
Ешлі Г

Насправді я був. wp_enqueue_script не працює, коли застосовується до wp_head, але wp_print_scripts робить. wp_enqueue_script працює, хоча якщо він застосовується до init, так: addgery ('init', 'check_widget');
Ешлі Г

Однак він завантажує сценарії на кожну сторінку сайту, навіть якщо віджет активний лише на одній бічній панелі. наприклад, якщо у мене є бічна панель для сторінок блогу та інша бічна панель для інших сторінок. Я додаю віджет пошуку на бічну панель блогу, і сценарії завантажуються, але він також завантажується на сторінки, у яких немає бічної панелі блогу. Мені потрібно мати змогу завантажити сценарій, лише якщо віджет присутній на цій сторінці.
Ешлі G

3

Просто хотів поділитися рішенням, над яким я працював, що дозволило мені бути трохи більш універсальним щодо моєї реалізації. Замість того, щоб перевірити функцію для різних шорткодів, я змінив її для пошуку єдиного короткого коду, який посилається на функцію сценарію / стилю, яку потрібно запустити. Це буде працювати як для інших методів в інших класах (наприклад, плагіни, які можуть не робити цього самостійно), так і для функцій в межах області. Просто введіть наведений нижче код у function.php та додайте наступний синтаксис на будь-яку сторінку / публікацію, де потрібно конкретні CSS та JS.

Синтаксис сторінки / публікації: [loadCSSandJS function = "(клас-> метод / назва функції)"]

Функції.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;
}

Це також дозволить вам додати на сторінку стільки, скільки потрібно. Майте на увазі, що для завантаження вам потрібен метод / функція.


1

Дякуємо, що поділилися цією порадою! Це мало мене боліло, бо спочатку це не працювало. Я думаю, що в коді є кілька помилок (можливо помилок), 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, і це призвело до того, що цикл завжди розривався при першій ітерації. Інша проблема була більш тонкою і важкою для виявлення. Код вище не працює, якщо короткий код - це найперше, що написано в дописі. Мені довелося скористатися ===оператором, щоб вирішити це.

У будь-якому випадку, велике спасибі за те, що поділився цією методикою, вона дуже допомогла.


1

У 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 та його можна знайти на нових сторінках документації для розробників .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.