จัดทำสคริปต์ / รูปแบบเมื่อมีรหัสย่อ


54

วิธีคิดในการลงทะเบียน / จัดคิวสคริปต์และ / หรือรูปแบบเพื่อใช้ในปลั๊กอินคืออะไร

ฉันเพิ่งสร้างปลั๊กอินอย่างง่ายสำหรับปลั๊กอินเพื่อเพิ่มอวตารผู้ใช้ / gravatar ด้วยรหัสย่อ ฉันมีตัวเลือกสไตล์ที่แตกต่างกันสำหรับการแสดงอวตาร (สี่เหลี่ยมจัตุรัสรอบ ฯลฯ ) และตัดสินใจที่จะวาง CSS โดยตรงในตัวย่อ

อย่างไรก็ตามฉันรู้แล้วว่านี่ไม่ใช่วิธีที่ดีเพราะมันจะทำ css ซ้ำทุกครั้งที่มีการใช้รหัสย่อบนหน้าเว็บ ฉันเคยเห็นวิธีการอื่น ๆ ในเว็บไซต์นี้และ wp codex ยังมีสองตัวอย่างของพวกเขาเองดังนั้นจึงเป็นการยากที่จะรู้ว่าวิธีใดที่สอดคล้องและรวดเร็วที่สุด

นี่คือวิธีที่ฉันรู้อยู่ในขณะนี้:

วิธีที่ 1: รวมโดยตรงในย่อ - นี่คือสิ่งที่ฉันกำลังทำอยู่ในปลั๊กอิน แต่ดูเหมือนจะไม่ดีเพราะมันทำซ้ำรหัส

class My_Shortcode {
function handle_shortcode( $atts, $content="" ) {
/* simply enqueue or print the scripts/styles in the shortcode itself */
?>
<style type="text/css">

</style>
<?php
    return "$content";
     }
}
add_shortcode( 'myshortcode', array( 'My_Shortcode', 'handle_shortcode' ) );

วิธีที่ 2: ใช้คลาสสำหรับจัดคิวสคริปต์หรือสไตล์ตามเงื่อนไข

class My_Shortcode {
    static $add_script;
    static function init() {
        add_shortcode('myshortcode', array(__CLASS__, 'handle_shortcode'));
        add_action('init', array(__CLASS__, 'register_script'));
        add_action('wp_footer', array(__CLASS__, 'print_script'));
    }
    static function handle_shortcode($atts) {
        self::$add_script = true;
        // shortcode handling here
    }
    static function register_script() {
        wp_register_script('my-script', plugins_url('my-script.js', __FILE__), array('jquery'), '1.0', true);
    }
    static function print_script() {
        if ( ! self::$add_script )
            return;
        wp_print_scripts('my-script');
    }
}
My_Shortcode::init();

วิธีที่ 3: การใช้ get_shortcode_regex();

function your_prefix_detect_shortcode() {

    global $wp_query;   
    $posts = $wp_query->posts;
    $pattern = get_shortcode_regex();

    foreach ($posts as $post){
        if (   preg_match_all( '/'. $pattern .'/s', $post->post_content, $matches )
            && array_key_exists( 2, $matches )
            && in_array( 'myshortcode', $matches[2] ) )
        {
            // css/js 
            break;  
        }    
    }
}
add_action( 'wp', 'your_prefix_detect_shortcode' );

วิธีที่ 4: การใช้ has_shortcode();

function custom_shortcode_scripts() {
    global $post;
    if( is_a( $post, 'WP_Post' ) && has_shortcode( $post->post_content, 'myshortcode') ) {
        wp_enqueue_script( 'my-script');
    }
}
add_action( 'wp_enqueue_scripts', 'custom_shortcode_scripts');

ฉันคิดว่าMethod 4: Using has_shortcode();ดีที่สุดเพราะจะช่วยให้มั่นใจได้ว่าสคริปต์และสไตล์จะโหลดหนึ่งครั้งหากเนื้อหาโพสต์มีรหัสย่อไม่ว่าจะใช้รหัสย่อหลายรายการก็ตาม แม้ว่ามันอาจจะใช้ไม่ได้กับรหัสย่อที่ใช้ในวิดเจ็ตหรือในแถบด้านข้าง แต่ก็ไม่แน่ใจ หากเป็นปลั๊กอินก็จะไม่แนะนำให้คุณผูกสคริปต์กับรหัสย่อเพราะบางคนอาจเรียกใช้ฟังก์ชั่นของคุณแทนการย่อเพื่อรับผลลัพธ์ที่ต้องการ
Robert hue

คำตอบ:


45

ฉันพบวิธีอื่นที่ใช้งานได้ดีสำหรับฉัน:

  • เมื่อเริ่มต้นปลั๊กอินไม่ enqueue สคริปต์และรูปแบบของคุณ แต่พวกเขาด้วยการลงทะเบียนและ wp_register_stylewp_register_script

  • ต่อไปคุณสามารถโหลดสคริปต์ / สไตล์ตามต้องการ ตัวอย่างเช่นเมื่อคุณแสดงรหัสด้วยและwp_enqueue_style("your_style")wp_enqueue_script("your_script")

นี่คือตัวอย่างปลั๊กอินโดยใช้วิธีนี้ที่ให้คุณใช้ get_avatar เป็นรหัสย่อ สไตล์ชีทถูกจัดคิวเมื่อมีรหัสย่อเท่านั้น

การใช้งาน (ค่าเริ่มต้น id ผู้ใช้ปัจจุบัน):

[get_avatar id="" size="32" default="mystery" alt="Profile Photo" class="round"]

function wpse_165754_avatar_shortcode_wp_enqueue_scripts() {
    wp_register_style( 'get-avatar-style', plugins_url( '/css/style.css', __FILE__ ), array(), '1.0.0', 'all' );
}

add_action( 'wp_enqueue_scripts', 'wpse_165754_avatar_shortcode_wp_enqueue_scripts' );
if ( function_exists( 'get_avatar' ) ) {
    function wpse_165754_user_avatar_shortcode( $attributes ) {

        global $current_user;
        get_currentuserinfo();

        extract( shortcode_atts(
                     array(
                         "id"      => $current_user->ID,
                         "size"    => 32,
                         "default" => 'mystery',
                         "alt"     => '',
                         "class"   => '',
                     ), $attributes, 'get_avatar' ) );

        $get_avatar = get_avatar( $id, $size, $default, $alt );

        wp_enqueue_style( 'get-avatar-style' );

        return '<span class="get_avatar ' . $class . '">' . $get_avatar . '</span>';
    }

    add_shortcode( 'get_avatar', wpse_165754_user_avatar_shortcode' );
}

ลืมฉันถามคำถามนี้เมื่อปีที่แล้ว แต่จริง ๆ แล้วฉันเริ่มทำเช่นนี้ในหลายกรณี มันเหมือนกับการรวมวิธีที่ 1 และ 2
ไบรอันวิลลิส

4
วิธีนี้โหลด CSS ในส่วนท้ายซึ่งแน่นอนมีข้อ จำกัด ?
Jacob Raccuia

1
นี่เป็นวิธีที่ถูกต้องในการทำสิ่งนี้ ใช้วิธีนี้ทุกครั้งที่คุณต้องการโหลดสคริปต์หรือสไตล์ชีทแบบมีเงื่อนไขเมื่อwp_enqueue_scriptshook เกิดขึ้นแล้ว (รหัสย่อจะถูกแยกวิเคราะห์ในระหว่างthe_contentที่เป็นส่วนหนึ่งของthe_postเบ็ดหมายถึงการเข้าคิวเมื่อถูกแยกวิเคราะห์สายเกินไปถ้าคุณไม่ได้ลงทะเบียนสคริปต์)
JRad the Bad

26

ก่อนที่จะเริ่มตอบฉันต้องบอกว่าเกี่ยวกับหัวข้อนี้ css และ js ไม่เหมือนกัน

เหตุผลง่าย ๆ : ในขณะที่เพิ่ม js ลงในเนื้อความของหน้า (ในส่วนท้าย) เป็นวิธีที่ใช้กันทั่วไปและถูกต้อง css ต้องอยู่ใน<head>ส่วนของหน้า: แม้ว่าเบราว์เซอร์ส่วนใหญ่สามารถแสดงผล css ในหน้าได้อย่างเหมาะสม เนื้อหานั่นไม่ใช่รหัส HTML ที่ถูกต้อง

เมื่อมีการสร้างรหัสย่อ<head>ส่วนได้ถูกพิมพ์ไปแล้วหมายความว่าสามารถเพิ่ม js ได้โดยไม่มีปัญหาใด ๆ ในส่วนท้าย แต่ต้องเพิ่ม css ก่อนที่จะมีการสร้างรหัสย่อ

สคริป

หากรหัสย่อของคุณต้องการเพียงแค่คุณเป็นผู้โชคดีและสามารถใช้wp_enqueue_scriptในรูปแบบของการโทรกลับด้วยรหัสย่อได้:

add_shortcode( 'myshortcode', 'my_handle_shortcode' );

function my_handle_shortcode() {
  wp_enqueue_script( 'myshortcodejs', '/path/to/js/file.js' );
  // rest of code here...
}

การทำเช่นนั้นสคริปต์ของคุณจะถูกเพิ่มลงในส่วนท้ายและเพียงครั้งเดียวแม้ว่ารหัสย่อจะถูกใช้มากกว่าหนึ่งครั้งในหน้าเว็บ

รูปแบบ

หากรหัสของคุณต้องการสไตล์คุณต้องดำเนินการก่อนที่จะแสดงรหัสย่อ

มีหลายวิธีในการทำสิ่งนี้:

  1. ดูโพสต์ทั้งหมดในการค้นหาปัจจุบันและเพิ่มรูปแบบรหัสย่อหากจำเป็น นี่คือสิ่งที่คุณทำทั้งในวิธีที่ # 3 และ # 4 ใน OP ในความเป็นจริงทั้งสองวิธีทำสิ่งเดียวกัน แต่has_shortcodeถูกเพิ่มใน WP 3.6 ในขณะที่get_shortcode_regexมีให้ตั้งแต่รุ่น 2.5 ดังนั้นใช้get_shortcode_regexเฉพาะเมื่อคุณต้องการให้ปลั๊กอินของคุณเข้ากันได้กับรุ่นเก่ากว่า

  2. เพิ่มสไตล์รหัสย่อในทุกหน้า

ประเด็น

ปัญหาของ # 1 คือประสิทธิภาพ Regex เป็นการดำเนินการที่ค่อนข้างช้าและการเปิดใช้ regex ในวงของโพสต์ทั้งหมดอาจทำให้หน้าเว็บช้าลงอย่างสม่ำเสมอ ยิ่งไปกว่านั้นมันเป็นงานธรรมดาในรูปแบบที่จะแสดงเฉพาะข้อความที่ตัดตอนมาในที่เก็บถาวรและแสดงเนื้อหาเต็มรูปแบบด้วยรหัสย่อเฉพาะในมุมมองเอกพจน์ หากเกิดขึ้นเมื่อมีการแสดงที่เก็บถาวรปลั๊กอินของคุณจะเปิดใช้งานการจับคู่ regex แบบวนซ้ำโดยมีจุดประสงค์เพื่อเพิ่มสไตล์ที่ไม่เคยใช้: ผลกระทบต่อประสิทธิภาพที่ไม่จำเป็นสองครั้ง: การสร้างหน้าช้าลง + คำขอ HTTP ที่ไม่จำเป็นเพิ่มเติม

ปัญหาของ # 2 คือประสิทธิภาพอีกครั้ง การเพิ่มสไตล์ให้กับทุกหน้าหมายถึงเพิ่มคำขอ HTTP เพิ่มเติมสำหรับทุกหน้าแม้ว่าจะไม่จำเป็นก็ตาม แม้ว่าเวลาในการสร้างหน้าฝั่งเซิร์ฟเวอร์จะไม่ได้รับผลกระทบ แต่เวลาในการแสดงหน้าทั้งหมดจะรวมอยู่และสำหรับหน้าเว็บไซต์ทั้งหมด

ดังนั้นผู้พัฒนาปลั๊กอินควรทำอย่างไร?

ฉันคิดว่าสิ่งที่ดีที่สุดที่ต้องทำคือการเพิ่มหน้าตัวเลือกให้กับปลั๊กอินซึ่งผู้ใช้สามารถเลือกได้ว่าควรจัดการรหัสย่อในมุมมองเอกพจน์เท่านั้นหรือแม้กระทั่งในที่เก็บถาวร ในทั้งสองกรณีดีกว่าที่จะให้ตัวเลือกอื่นเพื่อเลือกประเภทการเปิดใช้งานรหัสย่อ

ในวิธีนั้นเป็นไปได้ที่จะขอ"template_redirect"ตรวจสอบว่าแบบสอบถามปัจจุบันตอบสนองความต้องการและในกรณีนั้นเพิ่มสไตล์

หากผู้ใช้เลือกใช้รหัสย่อในมุมมองโพสต์เอกพจน์เป็นความคิดที่ดีที่จะตรวจสอบว่าโพสต์นั้นมีรหัสย่อหรือไม่: เมื่อจำเป็นต้องใช้ regex เพียงครั้งเดียวเท่านั้นไม่ควรทำให้หน้าเว็บช้าลงมากนัก

หากผู้ใช้เลือกที่จะใช้รหัสผู้ใช้แม้จะอยู่ในที่เก็บแล้วฉันจะหลีกเลี่ยงที่จะเรียกใช้ regex สำหรับเรื่องทั้งหมดถ้าจำนวนโพสต์เป็นที่สูงและเพียงแค่ enqueue สไตล์หากต้องการแบบสอบถามพอดี

สิ่งที่ควรพิจารณา "สูง" ในเรื่องนี้ควรใช้การทดสอบประสิทธิภาพหรือเพิ่มตัวเลือกอื่นและให้ทางเลือกแก่ผู้ใช้


2
เป็นที่น่าสังเกตว่าที่นี่<style>แท็กในส่วนเนื้อหาของเอกสารนั้นถูกต้องตามข้อกำหนด W3C w3.org/TR/html52/document-metadata.html#the-style-element
Isaac Lubow

5

สำหรับปลั๊กอินของฉันฉันพบว่าบางครั้งผู้ใช้มีการสร้างรูปแบบที่มีรหัสที่เก็บไว้ในข้อมูล meta โพสต์ นี่คือสิ่งที่ฉันใช้เพื่อตรวจสอบว่ามีรหัสย่อปลั๊กอินอยู่ในโพสต์ปัจจุบันหรือโพสต์ข้อมูลเมตา :

function abcd_load_my_shorcode_resources() {
       global $post, $wpdb;

       // determine whether this page contains "my_shortcode" shortcode
       $shortcode_found = false;
       if ( has_shortcode($post->post_content, 'my_shortcode') ) {
          $shortcode_found = true;
       } else if ( isset($post->ID) ) {
          $result = $wpdb->get_var( $wpdb->prepare(
            "SELECT count(*) FROM $wpdb->postmeta " .
            "WHERE post_id = %d and meta_value LIKE '%%my_shortcode%%'", $post->ID ) );
          $shortcode_found = ! empty( $result );
       }

       if ( $shortcode_found ) {
          wp_enqueue_script(...);
          wp_enqueue_style(...);
       }
}
add_action( 'wp_enqueue_scripts', 'abcd_load_my_shorcode_resources' );

2

ฉันทำเช่นนั้น:

class My_Shortcode {

    function __construct() {
        do_action('my_start_shortcode'); // call
....

และขอเกี่ยวในฟังก์ชั่นอื่น ๆ (หรือปลั๊กอินอื่น ๆ ):

function wpse_3232_load_script(){
    wp_enqueue_script('js-myjs');
}
add_action('my_start_shortcode','wpse_3232_load_script',10);

1

ฉันค้นหาปลั๊กอินของฉันเองถ้ามีรหัสย่อในวิดเจ็ตข้อความ

function check_shortcode($text) {

  $pattern = get_shortcode_regex();

   if (   preg_match_all( '/'. $pattern .'/s', $text, $matches )
        && array_key_exists( 2, $matches )
        && in_array( 'myshortcode', $matches[2] ) )
    {
        // myshortcode is being used

        // enque my css and js
        /****** Enqueu RFNB  ******/
        wp_enqueue_style('css-mycss');
        wp_enqueue_script('js-myjs');

        // OPTIONAL ALLOW SHORTCODE TO WORK IN TEXT WIDGET
        add_filter( 'widget_text', 'shortcode_unautop');
        add_filter( 'widget_text', 'do_shortcode'); 

    }

  return $text;

}
add_filter('widget_text', 'check_shortcode');

1

WordPress มีฟังก์ชั่นในตัวที่จะทำอะไรบางอย่างตามสถานะรหัสย่อเฉพาะที่นำเสนอ has_shortcode()ชื่อฟังก์ชั่น คุณสามารถใช้รหัสต่อไปนี้เพื่อจัดคิวสไตล์และสคริปต์ของคุณ

ที่นี่ฉันใช้is_a( $post, 'WP_Post' )เพื่อตรวจสอบว่า$postวัตถุเป็นของWP_Postชั้นเรียนและฉันใช้$post->post_contentในการตรวจสอบเนื้อหาโพสต์

if ( is_a( $post, 'WP_Post' ) && has_shortcode( $post->post_content, 'shortcode_tag') ) {
    wp_enqueue_style( 'handle', get_template_directory_uri() . '/your_file_filename.css' );
}

0

ฉันได้รวมตัวอย่างรหัสจากหน้า Wordpress สำหรับhas_shortcode ()และคำตอบที่zndenckaให้มา ฉันสังเกตเห็นว่ามีการเพิ่มฟังก์ชั่น has_shortcode ใน Wordpress 3.6 ดังนั้นฉันจึงตรวจสอบฟังก์ชั่นก่อนว่ามีอยู่หรือไม่ อาจตรวจสอบว่าล้าสมัยเล็กน้อยเนื่องจากมีผู้ใช้ไม่มากจาก wordpress 3.6 อีกต่อไปตามwordpress สถิติของตัวเอง

// This makes sure the styling is already enqueued in the header, so before the shortcode loads in the page/post
function enqueue_shortcode_header_script() {
    global $post;
    if ( function_exists( 'has_shortcode' ) ){  // is added in wordpress 3.6
        // Source: https://codex.wordpress.org/Function_Reference/has_shortcode
        if( is_a( $post, 'WP_Post' ) && has_shortcode( $post->post_content, 'my_shortcode') ) {
            wp_enqueue_style( 'shortcode-css' );
        }
    }
    else if ( isset($post->ID) ) { // Small percentage wordpress users are below 3.6 https://wordpress.org/about/stats/
        global $wpdb;
        $result = $wpdb->get_var(
          $wpdb->prepare(
              "SELECT count(*) FROM $wpdb->postmeta " .
              "WHERE post_id = %d and meta_value LIKE '%%my_shortcode%%'",
               $post->ID )
        );
        if (!empty( $result )) { wp_enqueue_style( 'shortcode-css' ); }
    }
}
add_action( 'wp_enqueue_scripts', 'enqueue_shortcode_header_script');

0

เราสามารถโหลดไฟล์ CSS และ JS ได้อย่างมีเงื่อนไขผ่านรหัสย่อโดยไม่ต้องใช้ฟังก์ชั่นที่ซับซ้อนมากเกินไป :

ก่อนอื่นสมมติว่าเราลงทะเบียนไฟล์ CSS / JS ทั้งหมดของเราก่อนหน้านี้ (บางทีเมื่อwp_enqueue_scriptsรัน)

function prep_css_and_js() {
     wp_register_style('my-css', $_css_url);
     wp_register_script('my-js', $_js_url);
}
add_action( 'wp_enqueue_scripts', 'prep_css_and_js', 5 );

ต่อไปให้ตรวจสอบฟังก์ชั่นรหัสย่อของเรา:

function my_shortcode_func( $atts, $content = null ) {
  if( ! wp_style_is( "my-css", $list = 'enqueued' ) ) { wp_enqueue_style('my-css'); }
  if( ! wp_script_is( "my-js", $list = 'enqueued' ) ) { wp_enqueue_script('my-js'); }
  ...
}

ง่าย เสร็จสิ้น Ergo: เราสามารถ "โหลดไฟล์" css / js แบบมีเงื่อนไข (เฉพาะเมื่อ [shortcode] ทำงาน)

ลองพิจารณาอุดมการณ์ต่อไปนี้:

  • เราต้องการโหลดไฟล์ CSS / JS บางไฟล์ (แต่เฉพาะเมื่อมีการเปิดใช้งานรหัสย่อ)
  • บางทีเราไม่ต้องการให้ไฟล์เหล่านั้นโหลดในทุกหน้าหรือเลยหากไม่มีการใช้รหัสย่อในหน้า / โพสต์ (น้ำหนักเบา)
  • เราสามารถทำสิ่งนี้ได้โดยทำให้แน่ใจว่า WP จะลงทะเบียนไฟล์ css / js ทั้งหมดก่อนที่จะเรียกรหัสย่อและก่อนที่จะเข้าคิว
  • IE: บางทีในระหว่างprep_css_and_js()ฟังก์ชั่นของฉันฉันโหลดไฟล์. css / .js ทั้งหมดที่อยู่ในบางโฟลเดอร์ ...

ตอนนี้ WP เห็นว่าพวกเขาเป็นสคริปต์ที่ลงทะเบียนเราสามารถเรียกพวกเขาอย่างมีเงื่อนไขขึ้นอยู่กับสถานการณ์ที่เป็นจริงรวมถึง แต่ไม่ จำกัด เพียง my_shortcode_func()

ประโยชน์ที่ได้รับ: (ไม่มี MySQL, ไม่มีฟังก์ชั่นขั้นสูงและไม่จำเป็นต้องใช้ตัวกรอง)

  • นี่คือ "WP orthodix", สง่างาม, โหลดเร็ว, ง่ายและสะดวก
  • อนุญาตให้คอมไพเลอร์ / minifiers ตรวจจับสคริปต์ดังกล่าว
  • ใช้ฟังก์ชั่น WP (wp_register_style / wp_register_script)
  • เข้ากันได้กับชุดรูปแบบ / ปลั๊กอินเพิ่มเติมที่อาจต้องการยกเลิกการลงทะเบียนสคริปต์เหล่านั้นด้วยเหตุผลที่แท้จริง
  • จะไม่ทริกเกอร์หลายครั้ง
  • การประมวลผลหรือรหัสที่เกี่ยวข้องน้อยมาก

อ้างอิง:

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.