บุคคลที่ 3 ควรใช้ $ wp_scripts / $ wp_styles-> add_data หรือไม่


31

ภายในชั้นเรียนที่มีอยู่วิธีการตั้งชื่อWP_Dependencies add_dataฟังก์ชั่นนี้เพิ่มข้อมูลให้กับสคริปต์ / สไตล์ที่ได้รับการจัดคิวระหว่างการโหลด WordPress การอ้างถึงการใช้งานทั่วไปสำหรับฟังก์ชั่นนี้คือการเพิ่มเงื่อนไขเมื่อเพิ่มสไตล์ชีทที่มีการกำหนดเป้าหมายที่ IE เวอร์ชันต่าง ๆ ตัวอย่างเช่นหากต้องการกำหนดเป้าหมายเป็น IE8 และต่ำกว่า:

function test_wp_print_styles() {
    global $wp_styles;

    wp_enqueue_style( 'test-style', get_template_directory_uri() . '/css/test.css', array(), 1, 'all' );
    $wp_styles->add_data( 'test-style', 'conditional', 'lte ie8' );
}
add_action( 'wp_print_styles', 'test_wp_print_styles' );

สิ่งนี้จะแสดงผลเป็น:

<!--[if lte ie8]>
<link rel='stylesheet' id='test-style-css'  href='http://trunkosaurus.dev/wp-content/themes/twentyeleven/css/test.css?ver=1' type='text/css' media='all' />
<![endif]--> 

เมื่อฉันมองผ่าน Core ฉันเห็นสถานที่จำนวนหนึ่งที่ใช้วิธีการนี้:

  • WP_Styles->add_inline_style(): เพิ่มสไตล์แบบอินไลน์หลังจากสไตล์ชีตที่อ้างอิง (ทำผ่านWP_Styles->print_inline_style())

  • WP_Scripts->localize(): เพิ่มวัตถุที่เข้ารหัส json (ห่อด้วยwp_localize_script()ฟังก์ชัน"สาธารณะ" เพิ่มเติม)

  • wp_plupload_default_settings() : เพิ่มออบเจ็กต์ที่เข้ารหัส json (สร้างจากอาร์เรย์หลายมิติ) สำหรับสคริปต์ 'wp-plupload' (โปรดทราบว่าสิ่งนี้จะเกิดขึ้นใน 3.4)

  • เมื่อลงทะเบียน / จัดคิวสคริปต์และสไตล์การเพิ่มข้อมูลสำหรับสคริปต์เริ่มต้น ( wp-includes/script-loader.php)

จากการอ่านผ่านการใช้งานของวิธีการนั้นไม่ปรากฏว่ามีกรณีการใช้งานเฉพาะ ในwp_plupload_default_settingsดูเหมือนว่าจะอนุญาตให้มีการฉีดข้อมูลโดยพลการ ในwp_register_scriptดูเหมือนว่าจะใช้เพื่อแยกความแตกต่างระหว่างสคริปต์ส่วนหัวและส่วนท้าย ในadd_inline_styleมันถูกใช้เพื่อแสดงถึงรูปแบบอินไลน์ที่ควรจะเพิ่มหลังจากที่สไตล์ชีทที่ระบุมีการจัดคิว

การใช้งานที่ยอดเยี่ยมสำหรับฟังก์ชั่นนี้จะเหมือนกับโค้ดต่อไปนี้ซึ่งคุณกำลังจัดคิวสคริปต์ภายนอก แต่จำเป็นต้องส่ง vars การกำหนดค่าบางอย่างซึ่งบางส่วนมาจาก DB:

function zdt_enqueue_add_this() {
    global $wp_scripts;

    wp_enqueue_script( 'zdt-add-this', 'http://s7.addthis.com/js/250/addthis_widget.js#pubid=myidhere' );

    // Contrived example of database call to get a twitter handle stored in the db
    $author_twitter_handle = zdt_get_twitter_handle();

    $js = "var addthis_share = { templates : { twitter: '{{title}} {{url}} (by @" . sanitize_key( $author_twitter_handle ) . "' } };\n";
    $js .= 'var addthis_config = { ui_header_color: "#FFFFFF", ui_header_background: "#FA9628", ui_cobrand: "My Site" };';

    $wp_scripts->add_data( 'zdt-add-this', 'data', $js );
}
add_action( 'wp_enqueue_scripts', 'zdt_enqueue_add_this' );

สิ่งนี้จะส่งผลให้:

<script type='text/javascript'>
/* <![CDATA[ */
var addthis_share = { templates : { twitter: '{{title}} {{url}} (by @tollmanz' } };
var addthis_config = { ui_header_color: "#FFFFFF", ui_header_background: "#FA9628", ui_cobrand: "My Site" };
/* ]]> */
</script>
<script type='text/javascript' src='http://s7.addthis.com/js/250/addthis_widget.js?ver=3.4-beta4-20731#pubid=myidhere'></script>

โปรดทราบว่าสิ่งนี้ไม่สามารถทำได้wp_localize_scriptเพราะaddthis_shareวัตถุมีคุณสมบัติภายในคุณสมบัติ ( ฉันเคยเขียนเกี่ยวกับวิธีแฮ็กค่อนข้างรอบนี้มาก่อน )

แก้ไข: ฉันผิดในการระบุนี้ wp_localize_scriptจัดการกับอาร์เรย์หลายมิติได้ดี

วิธีนี้ดูเหมือนว่าจะทำงานได้ดีจริงๆด้วยเหตุผลดังต่อไปนี้:

  1. อนุญาตให้คุณแนบข้อมูลเข้ากับหมายเลขอ้างอิงสคริปต์เพื่อให้มีการจัดคิวสคริปต์อย่างเหมาะสมเสมอ นอกจากนี้จะเป็นการฉลาดเกี่ยวกับการลบสคริปต์สคริปต์ออกคำสั่งและการวางสคริปต์
  2. อนุญาตให้คุณใช้ PHP ส่ง vars ไปยัง JS
  3. ดูเหมือนว่ามีการจัดระเบียบมากกว่าการใช้wp_print_stylesพิมพ์สคริปต์ตามอำเภอใจที่ดำเนินการในภายหลังโดยสคริปต์ที่จัดคิว

มีบางสิ่งที่ใช้งานไม่ได้ตามที่คาดหวังซึ่งทำให้ฉันกังวลเกี่ยวกับวิธีการนี้ ปัญหาหนึ่งคือถ้าคุณใช้wp_localize_scriptพร้อมกับ$wp_scripts->add_dataคุณสามารถได้ผลลัพธ์ที่ไม่คาดคิด ตัวอย่างเช่น

// Contrived example of database call to get a twitter handle stored in the db
$author_twitter_handle = zdt_get_twitter_handle();

$js = "var addthis_share = { templates : { twitter: '{{title}} {{url}} (by @" . sanitize_key( $author_twitter_handle ) . "' } };\n";
$js .= 'var addthis_config = { ui_header_color: "#FFFFFF", ui_header_background: "#FA9628", ui_cobrand: "My Site" };';

$wp_scripts->add_data( 'zdt-add-this', 'data', $js );
wp_localize_script( 'zdt-add-this', 'addthis_share', array( 'var' => 'val' ) );

ผลิต:

<script type='text/javascript'>
/* <![CDATA[ */
var addthis_share = { templates : { twitter: '{{title}} {{url}} (by @tollmanz' } };
var addthis_config = { ui_header_color: "#FFFFFF", ui_header_background: "#FA9628", ui_cobrand: "My Site" };
var addthis_share = {"var":"val"};
/* ]]> */
</script>
<script type='text/javascript' src='http://s7.addthis.com/js/250/addthis_widget.js?ver=3.4-beta4-20731#pubid=myidhere'></script>

ในขณะที่สคริปต์นี้:

// Contrived example of database call to get a twitter handle stored in the db
$author_twitter_handle = zdt_get_twitter_handle();

$js = "var addthis_share = { templates : { twitter: '{{title}} {{url}} (by @" . sanitize_key( $author_twitter_handle ) . "' } };\n";
$js .= 'var addthis_config = { ui_header_color: "#FFFFFF", ui_header_background: "#FA9628", ui_cobrand: "My Site" };';

wp_localize_script( 'zdt-add-this', 'addthis_share', array( 'var' => 'val' ) );
$wp_scripts->add_data( 'zdt-add-this', 'data', $js );

ผลิต:

<script type='text/javascript'>
/* <![CDATA[ */
var addthis_share = { templates : { twitter: '{{title}} {{url}} (by @tollmanz' } };
var addthis_config = { ui_header_color: "#FFFFFF", ui_header_background: "#FA9628", ui_cobrand: "My Site" };
/* ]]> */
</script>
<script type='text/javascript' src='http://s7.addthis.com/js/250/addthis_widget.js?ver=3.4-beta4-20731#pubid=myidhere'></script>

dataสำคัญที่ถูกกำหนดโดยwp_localize_scriptจะถูกเขียนทับโดยในท้ายที่สุดการเรียกร้องให้$wp_scripts->add_dataในขณะที่ถ้าคุณเรียกwp_localize_scriptสองครั้งสำหรับสคริปต์เดียวกันสตริงจะถูกตัดแบ่งได้อย่างถูกต้อง

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

ฉันยังดูที่ Core Trac เพื่อดูว่ามีเบาะแสใด ๆ เกี่ยวกับวัตถุประสงค์ของฟังก์ชันหรือไม่ ฉันพบตั๋วหนึ่งใบ (http://core.trac.wordpress.org/ticket/11520) (หนึ่งมหากาพย์ที่นั้น) ที่สำรวจวิธีอื่น ๆ ในการเพิ่ม JS โดยพลการ ดังนั้นดูเหมือนว่ามีความสนใจในการสร้างวิธีที่ดีกว่าในการเพิ่ม JS โดยพลการ แต่ไม่แน่ใจว่าadd_dataควรเป็นส่วนหนึ่งของกระบวนการหรือไม่

คำถามหลักของฉันคือ: นักพัฒนาควรใช้ฟังก์ชั่นนี้หรือไม่? ในบางกรณี (เช่นwp_register_script) ดูเหมือนว่าฟังก์ชั่น "ส่วนตัว" ที่บุคคลที่สามไม่ควรใช้ อย่างไรก็ตามในกรณีอื่น ๆ (เช่นwp_plupload_default_settings) ดูเหมือนว่าเป็นวิธีที่เหมาะสมอย่างสมบูรณ์ในการฉีด JS โดยพลการก่อนที่จะมีสคริปต์ที่เข้าคิว

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

คำตอบ:


4

ฟังก์ชั่นนี้เพิ่มข้อมูลให้กับสคริปต์ / สไตล์ที่ได้รับการจัดคิวระหว่างการโหลด WordPress

ไม่ได้จริงๆ มันจะเพิ่มข้อมูลไปยังสคริปต์ / registeredรูปแบบแล้วซึ่งถูก

คีย์ข้อมูลที่ตั้งค่าโดยwp_localize_scriptจะถูกเขียนทับในที่สุดโดยการเรียกไป$wp_scripts->add_dataที่ในขณะที่ถ้าคุณเรียกwp_localize_scriptสองครั้งสำหรับสคริปต์เดียวกันสตริงจะถูกเชื่อมต่ออย่างถูกต้อง

ขวา. พวกเขาทั้งสองเรียก API พื้นฐาน (ไม่สามารถเข้าถึงได้ภายใน) เพื่อให้ได้รับการเขียนทับ (ตามที่คุณระบุ) $this->get_data( $handle, 'data' );นี้เกิดขึ้นเมื่อมันสาย

คำถาม

คำถามหลักของฉันคือ: นักพัฒนาควรใช้ฟังก์ชั่นนี้หรือไม่?

ตอบ

พูดง่ายๆ: ใช่เมื่อคุณไม่มีโอกาสทำสิ่งที่คุณต้องการ

ตัวอย่างอื่น: ตรวจสอบว่ามีการลงทะเบียนสคริปต์ (เช่นjson2/jquery) แล้วย้ายไปยังส่วนท้าย (ตรวจสอบextra['group'])

// Move scripts to the footer - in case it isn't already there
if ( ! $wp_scripts->get_data( 'json2', 'group' ) )
    $wp_scripts->add_data( 'json2', 'group', 1 );

if ( ! $wp_scripts->get_data( 'jquery', 'group' ) )
    $wp_scripts->add_data( 'jquery', 'group', 1 );

หมายเหตุ: สิ่งนี้ใช้งานได้กับข้อมูลที่ยื่นใต้extraเท่านั้น!

หมายเหตุเพิ่มเติม

ตอบโต้คำถาม: คุณเคยลองเพิ่มการพึ่งพาสคริปต์ที่ลงทะเบียนโดยแกนหรือไม่? สำหรับเช่น: พยายามที่จะเพิ่มJSON2เป็น deps jQueryที่จำเป็นในการ สิ่งนี้เป็นไปไม่ได้หากไม่ขัดขวางglobal $wp_scripts:

global $wp_scripts;

$scripts = array( 
     'jquery'      => array( 'json2' )
    ,'jquery-form' => array( 'json2' ) 
);

foreach ( $scripts as $handle => $deps )
{
    // Ugly hack: Intercept the global to force the "natural"/needed order: JSON2 » jQuery
    $deps_default =& $wp_scripts->registered[ $handle ]->deps;
    $wp_scripts->registered[ $handle ]->deps = array_merge( $deps_default, $deps );
}

มีหลายสิ่งที่ชั้นเรียนไม่สามารถทำได้ ดังนั้นการใช้สิ่งที่ต้องการ->add_data()คือIMOที่ถูกต้องอย่างเต็มที่ เพียงแค่ใช้สิ่งที่คุณได้รับเพราะมันยังดีกว่าอยู่ดีเพราะขาดชั้นเรียนหลัก


"รอจนกว่าแกนจะเพิ่มความเป็นไปได้ในการเพิ่มการพึ่งพาสคริปต์เริ่มต้น & ในตัว" คุณเปิดตั๋วใน trac หรือไม่
scribu

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

ถ้าอย่างนั้นฉันคิดว่าฉันจะต้องถามที่นี่: ประโยชน์ของการโหลด JSON2 ก่อน jQuery คืออะไร?
scribu

ไม่มีสิ่งใดเป็นตัวอย่างนามธรรม หากคุณพยายามหาตัวอย่างที่มีรายละเอียดมากขึ้นคุณอาจนึกภาพหนึ่งห้องสมุดที่ต้องการJSON2แต่ยังต้องโหลดมาก่อนjQuery: ลองตั้งชื่อUberjQueryกัน Btw: เมื่อคุณทำดีกับ diggin 'เป็นหลักทำไมคุณไม่ใช้เวลาและเขียนคำตอบ? ฉันคิดว่ามันจะคุ้มค่ากับเวลาที่อ่าน
ไกเซอร์

ขอบคุณสำหรับความคิดของคุณไกเซอร์! ฉันกำลังมองหาวิธีเพิ่ม JS อย่างแน่นอนซึ่งสนับสนุนโดย "API" ในขณะที่ฉันรู้ว่าฉันสามารถโค้งงอเพื่อทำสิ่งต่าง ๆ ทุกอย่างที่สามารถนำไปสู่รหัสไม่แน่นอน ยินดีที่ได้ทราบว่ามันมีจุดประสงค์เพื่ออะไรมากกว่าสิ่งที่สามารถทำได้และแน่นอนสามารถทำได้หลายอย่างด้วยกัน
tollmanz

1

มีการถกเถียงกันอย่างมากใน WP 3.3 เกี่ยวกับวิธีจัดการกับข้อมูลสคริปต์:

http://core.trac.wordpress.org/ticket/11520

โปรดทราบว่าคุณสามารถผ่านอาร์เรย์ที่ซ้อนกันไปได้wp_localize_data()แล้ว:

wp_localize_script( 'jquery', 'jQueryL10n', array(
    'foo' => array(
        'bar' => array( 'apple', 'orange' )
    ),
) );

ดังนั้นฉันจะใช้add_data()ถ้าไม่มี API ระดับสูงสำหรับสิ่งที่ฉันต้องทำด้วยความเข้าใจว่าพฤติกรรมของมันอาจเปลี่ยนไปในบางกรณีเช่นเมื่อมีการต่อข้อมูลเข้าด้วยกัน


ขอบคุณสำหรับการป้อนข้อมูลของคุณ Scribu! ตลกที่คุณเชื่อมโยงกับตั๋วนั้น! ฉันเชื่อมโยงกับมันในโพสต์ของฉัน แต่มีมากเกิดขึ้นในที่ฉันไม่ได้จับที่อาร์เรย์หลายมิติได้รับการสนับสนุนในขณะนี้
tollmanz

ฮา ... แก้ไขได้ดี! ฉันไม่สับสนกับตั๋วนั้นอย่างที่ฉันคิด
tollmanz

@tollmanz ใช่มันค่อนข้างสับสนโดยเฉพาะอย่างยิ่งถ้าคุณไม่ได้อยู่ใน IRC ในเวลานั้น
scribu

Mr. @ungestaltbar แสดงวิธีการเพิ่มอาร์เรย์หลายมิติให้ฉันเมื่อเดือนที่แล้ว ไม่ทราบว่านี่เป็นแกนหลักอยู่แล้ว
ไกเซอร์

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