Memuat skrip hanya jika ada kode pendek atau widget tertentu

17

Saya membutuhkan cara untuk memfilter konten halaman / posting sebelum dimuat sehingga saya dapat menambahkan skrip ke header jika ada kode pendek tertentu. Setelah banyak mencari saya menemukan ini di 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');

yang benar-benar brilian dan melakukan apa yang saya butuhkan.

Sekarang saya perlu memperpanjang sedikit lebih jauh dan melakukan hal yang sama untuk sidebar. Itu bisa dengan jenis widget tertentu, kode pendek, cuplikan kode atau apa pun yang akan berfungsi untuk mengidentifikasi kapan skrip perlu dimuat.

Masalahnya adalah saya tidak tahu cara mengakses konten sidebars sebelum sidebar dimuat (tema yang dimaksud akan memiliki beberapa sidebars)

Ashley G
sumber
Apakah skrip di header persyaratan sulit untuk situasi Anda? Script di akhir halaman lebih mudah untuk ditangani dengan praktik dan direkomendasikan untuk kinerja.
Jarang
Saya memang mencobanya di wp_footer pertama yang dengan baik menghilangkan kebutuhan untuk memfilter konten, tetapi sementara skrip dimuat dengan baik, mereka tidak berfungsi. Script ini harus dalam wp_head untuk melakukan apa yang mereka butuhkan.
Ashley G

Jawaban:

20

Anda dapat menggunakan fungsi is_active_widget . Misalnya:

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

add_action( 'init', 'check_widget' );

Untuk memuat skrip di halaman yang hanya memuat widget, Anda harus menambahkan kode is_active_widget (), di dalam kelas widget Anda. Misalnya, lihat widget komentar terbaru default (wp-include / default-widgets.php, baris 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') );
    }
sorich87
sumber
Bisakah itu disebut SEBELUM widget dimuat. Agar jelas ini harus terjadi sebelum halaman bahkan memuat. Kode sampel saya menggunakan the_posts untuk memfilter konten pada halaman, tetapi itu tidak mendapatkan sidebars / widget.
Ashley G
Ya, lihat contoh yang saya tambahkan ke jawaban saya.
sorich87
Contoh Anda sebenarnya tidak berfungsi. Apakah saya kehilangan sesuatu yang jelas?
Ashley G
Sebenarnya saya. wp_enqueue_script tampaknya tidak berfungsi saat diterapkan ke wp_head, tetapi wp_print_scripts tidak. wp_enqueue_script tidak bekerja jika diterapkan ke init seperti: add_action ('init', 'check_widget');
Ashley G
Namun itu memuat skrip di setiap halaman situs, bahkan jika widget hanya aktif di satu sidebar. misalnya jika saya memiliki sidebar untuk halaman blog dan sidebar lain untuk halaman lain. Saya menambahkan widget pencarian ke sidebar blog dan skrip tidak memuat, tetapi juga memuat pada halaman yang tidak memiliki sidebar blog. Saya harus dapat memuat skrip hanya jika widget ada di halaman itu.
Ashley G
3

Hanya ingin berbagi solusi yang saya kerjakan yang memungkinkan saya menjadi sedikit lebih fleksibel dengan implementasi saya. Daripada memiliki fungsi memeriksa berbagai kode pendek, saya memodifikasinya untuk mencari kode pendek tunggal yang mereferensikan fungsi skrip / gaya yang perlu enqueued. Ini akan bekerja untuk kedua metode di kelas lain (seperti plugin yang mungkin tidak melakukan ini sendiri) dan fungsi dalam lingkup. Cukup letakkan kode di bawah ini di functions.php dan tambahkan sintaks berikut ke halaman / posting mana pun yang Anda inginkan CSS & JS tertentu.

Sintaks Halaman / Posting: [loadCSSandJS function = "(class-> method / function name" "]

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

Ini juga akan memungkinkan Anda untuk menambahkan sebanyak yang Anda inginkan pada halaman. Perlu diingat bahwa Anda memang membutuhkan metode / fungsi untuk memuat.

Nick Caporin
sumber
1

Terima kasih telah berbagi kiat ini! Itu memberi saya sedikit sakit kepala, karena pada awalnya itu tidak berhasil. Saya pikir ada beberapa kesalahan (mungkin kesalahan ketik) pada kode di atas has_my_shortcodedan saya menulis ulang fungsinya seperti di bawah ini:

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

Saya pikir ada dua masalah utama: yang breaktidak dalam lingkup pernyataan if, dan itu menyebabkan loop selalu pecah pada iterasi pertama. Masalah lainnya lebih halus dan sulit ditemukan. Kode di atas tidak berfungsi jika kode pendek adalah hal pertama yang ditulis dalam sebuah tulisan. Saya harus menggunakan ===operator untuk menyelesaikan ini.

Bagaimanapun, terima kasih banyak untuk berbagi teknik ini, itu sangat membantu.

jekbau
sumber
1

dengan Wordpress 4.7 ada cara lain untuk mencapai ini di functions.phpfile Anda ,

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

pertama-tama Anda mendaftarkan skrip Anda , yang sebenarnya tidak bisa dicetak pada halaman Anda kecuali jika Anda membuatnya jika kode pendek Anda dipanggil,

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

yang do_shortcode_tagtelah diperkenalkan pada WP 4.7 dan dapat ditemukan di pengembang dokumentasi baru halaman.

Aurovrata
sumber