Chỉ tải tập lệnh nếu có một mã ngắn hoặc tiện ích cụ thể


17

Tôi cần một cách để lọc nội dung trang / bài viết trước khi nó được tải để tôi có thể thêm tập lệnh vào tiêu đề nếu có một mã ngắn cụ thể. Sau nhiều tìm kiếm, tôi đã tìm thấy cái này trên 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');

đó là hoàn toàn xuất sắc và đã làm chính xác những gì tôi cần.

Bây giờ tôi cần mở rộng thêm một chút và làm tương tự cho các thanh bên. Nó có thể bằng một loại widget cụ thể, shortcode, đoạn mã hoặc bất cứ thứ gì khác có thể hoạt động để xác định khi tập lệnh cần được tải.

Vấn đề là tôi không thể tìm ra cách truy cập nội dung thanh bên trước khi thanh bên được tải (chủ đề được đề cập sẽ có một số thanh bên)


Là các kịch bản trong tiêu đề cứng yêu cầu cho tình huống của bạn? Các tập lệnh ở cuối trang dễ dàng hơn để xử lý thực hành có điều kiện và được đề xuất cho hiệu suất.
Hết

Tôi đã thử nó trong wp_footer trước tiên để loại bỏ nhu cầu tiền lọc nội dung, nhưng trong khi các tập lệnh được tải tốt, chúng không hoạt động. Các tập lệnh này phải có trong wp_head để làm những gì chúng cần.
Ashley G

Câu trả lời:


20

Bạn có thể sử dụng hàm is_active_widget . Ví dụ:

function check_widget() {
    if( is_active_widget( '', '', 'search' ) ) { // check if search widget is used
        wp_enqueue_script('my-script');
    }
}

add_action( 'init', 'check_widget' );

Để tải tập lệnh trong trang chỉ tải tiện ích, bạn sẽ phải thêm mã is_active_widget () trong lớp tiện ích con. Ví dụ: xem tiện ích nhận xét gần đây mặc định (wp-gồm / default-widget.php, dòng 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') );
    }

Điều đó có thể được gọi TRƯỚC KHI các widget được tải. Để rõ ràng, điều này phải diễn ra trước khi trang tải. Mã mẫu của tôi sử dụng the_posts để lọc nội dung trên trang, nhưng điều đó không nhận được các thanh bên / widget.
Ashley G

Vâng, xem ví dụ tôi thêm vào câu trả lời của tôi.
sorich87

Ví dụ của bạn không thực sự hoạt động. Tôi có thiếu một cái gì đó rõ ràng?
Ashley G

Thật ra tôi đã như vậy. wp_enqueue_script dường như không hoạt động khi được áp dụng cho wp_head, nhưng wp_print_scripts thì có. wp_enqueue_script hoạt động mặc dù nếu được áp dụng cho init như vậy: add_action ('init', 'check_widget');
Ashley G

Tuy nhiên, nó tải các tập lệnh trên mỗi trang của trang web, ngay cả khi tiện ích chỉ hoạt động trong một thanh bên. ví dụ: nếu tôi có một thanh bên cho các trang blog và một thanh bên khác cho các trang khác. Tôi thêm tiện ích tìm kiếm vào thanh bên blog và các tập lệnh sẽ tải, nhưng nó cũng tải trên các trang không có thanh bên blog. Tôi cần có thể tải tập lệnh chỉ khi tiện ích có mặt trên trang đó.
Ashley G

3

Chỉ muốn chia sẻ một giải pháp mà tôi đã làm việc cho phép tôi linh hoạt hơn một chút với việc thực hiện. Thay vì kiểm tra chức năng cho nhiều loại mã ngắn, tôi đã sửa đổi nó để tìm ra một mã ngắn duy nhất tham chiếu chức năng tập lệnh / kiểu cần được xử lý. Điều này sẽ làm việc cho cả hai phương thức trong các lớp khác (chẳng hạn như các plugin có thể không tự làm điều này) và các hàm trong phạm vi. Chỉ cần thả đoạn mã dưới đây vào hàm.php và thêm cú pháp sau vào bất kỳ trang / bài đăng nào mà bạn muốn CSS & JS cụ thể.

Cú pháp trang / bài viết: [loadCSSandJS function = "(class-> phương thức / tên hàm)"]

mã hàm.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;
}

Điều này cũng sẽ cho phép bạn thêm bao nhiêu tùy ý trên một trang. Hãy nhớ rằng bạn cần một phương thức / hàm để tải.


1

Cảm ơn bạn đã chia sẻ mẹo này! Nó làm tôi hơi đau đầu, vì lúc đầu nó không hoạt động. Tôi nghĩ rằng có một vài lỗi (có thể là lỗi chính tả) trong đoạn mã trên has_my_shortcodevà tôi đã viết lại hàm như sau:

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;
    }

Tôi nghĩ có hai vấn đề chính: breakkhông nằm trong phạm vi của câu lệnh if và điều đó khiến cho vòng lặp luôn bị phá vỡ ở lần lặp đầu tiên. Vấn đề khác là tinh tế và khó khám phá hơn. Mã ở trên không hoạt động nếu shortcode là điều đầu tiên được viết trong một bài đăng. Tôi đã phải sử dụng các ===toán tử để giải quyết điều này.

Dù sao, cảm ơn bạn rất nhiều vì đã chia sẻ kỹ thuật này, nó đã giúp rất nhiều.


1

với Wordpress 4.7, có một cách khác để đạt được điều này trong functions.phptệp của bạn ,

add_action( 'wp_enqueue_scripts', 'register_my_script');
function register_my_script(){
  wp_register_script('my-shortcode-js',$src, $dependency, $version, $inFooter);
}

đầu tiên bạn đăng ký tập lệnh của mình , tập lệnh này không thực sự được in trên trang của bạn trừ khi bạn đăng ký nó nếu shortcode của bạn được gọi,

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;
}

những do_shortcode_tagđược giới thiệu trong WP 4.7 và có thể được tìm thấy trong các nhà phát triển tài liệu mới trang.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.