การเพิ่มคุณสมบัติเพิ่มเติมในแท็กสคริปต์สำหรับ JS ของบุคคลที่สาม


20

ฉันพบปัญหานี้เมื่อพยายามรวม Dropbox ของChooser API ลงในปลั๊กอินที่ฉันกำลังเขียน

เอกสาร API แนะนำให้คุณวางscriptแท็กต่อไปนี้ที่ด้านบนของไฟล์ของคุณ:

<script type="text/javascript" src="https://www.dropbox.com/static/api/1/dropins.js" id="dropboxjs" data-app-key="MY_APP_KEY"></script>

ทั้งหมดดีและดีและมันใช้งานได้จริงเมื่อฉันวางลงในเพจที่เรียกว่าในส่วนผู้ดูแลระบบโดยตรง แต่ฉันต้องการใช้รูปแบบบางอย่างของ wp_register_script (), wp_enqueue_script () และ wp_localize_script () เพื่อส่งรหัสที่จำเป็นและคีย์ข้อมูลแอป

ฉันลองสองสามแบบนี้:

add_action('admin_enqueue_scripts', 'add_dropbox_stuff');
function add_dropbox_js() {
    wp_register_script('dropbox.js','https://www.dropbox.com/static/api/1/dropins.js');
    wp_enqueue_script('dropbox.js');
    wp_localize_script('dropbox.js','dropboxdata',array('id'=>"dropboxjs",'data-app-key'=>"MY_APP_KEY"));
}

และ:

add_action('admin_enqueue_scripts', 'add_dropbox_stuff');
function add_dropbox_stuff() {
        wp_register_script('dropbox.js','https://www.dropbox.com/static/api/1/dropins.js');
        wp_enqueue_script('dropbox.js');
        wp_localize_script('dropbox.js','dropboxdata',array(array('id'=>"dropboxjs"),array('data-app-key'=>"MY_APP_KEY")));
    }

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

แก้ไข: ยังพยายามที่จะทำกับ jQuery บางส่วน แต่จะไม่มีประโยชน์ พยายามในการโหลดเอกสารและในเอกสารพร้อม ฉันได้รับ {"ข้อผิดพลาด": "app_key ไม่ถูกต้อง"} กลับมา

$('script[src="https://www.dropbox.com/static/api/1/dropins.js?ver=3.6"]').attr('id','dropboxjs').attr('data-multiselect','true').attr('data-app-key','MY_APP_KEY');

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

2
จีเอ็มถูกต้องที่wp_localize_scriptไม่ได้สร้างแอตทริบิวต์ของสคริปต์ แต่เป็นไปได้ไหมที่จะส่งรหัสแอปไปยัง dropbox.js โดยตรง แค่เดา ​​แต่คุณได้ลองarray('appKey'=>"MY_APP_KEY")? นี่คือรหัสที่คว้ากุญแจจากแอตทริบิวต์if(!Dropbox.appKey){Dropbox.appKey=(e=document.getElementById("dropboxjs"))!=null?e.getAttribute("data-app-key"):void 0}
epilektric

สวัสดี @epilektric คุณช่วยตอบได้ไหม? ฉันไม่ค่อยได้ติดตามวิธีการใช้งาน
Andrew Bartel

@epilektric ด้วยความwp_localize_scriptมั่นใจว่าคุณสามารถส่งแอตทริบิวต์ไปยังสคริปต์ได้ ฉันไม่รู้จริงๆว่ามันจะใช้งานได้จริงหรือไม่ แต่มันไม่ใช่เรื่องที่เกี่ยวข้อง
gmazzap

@AndrewBartel ฉันก็ไม่แน่ใจเหมือนกัน บางทีนี่อาจช่วยได้ pippinsplugins.com/use-wp_localize_script-it-is-awesome
epilektric

คำตอบ:


18

คุณสามารถลองใช้script_loader_srcตะขอตัวกรองได้เช่น:

add_filter('script_loader_src','add_id_to_script',10,2);
function add_id_to_script($src, $handle){
    if ($handle != 'dropbox.js') 
            return $src;
    return $src."' id='dropboxjs' data-app-key='MY_APP_KEY";
}

ปรับปรุง

ฉันเพิ่งคิดออกเองว่า src หนีโดย esc_url ดังนั้นมองอีกเล็กน้อยฉันพบclean_urlตัวกรองที่คุณสามารถใช้เพื่อคืนค่าด้วย id และคีย์ข้อมูลแอปของคุณ:

add_filter('clean_url','unclean_url',10,3);
function unclean_url( $good_protocol_url, $original_url, $_context){
    if (false !== strpos($original_url, 'data-app-key')){
      remove_filter('clean_url','unclean_url',10,3);
      $url_parts = parse_url($good_protocol_url);
      return $url_parts['scheme'] . '://' . $url_parts['host'] . $url_parts['path'] . "' id='dropboxjs' data-app-key='MY_APP_KEY";
    }
    return $good_protocol_url;
}

มันไม่ทำงาน ก่อนที่จะถูกพิมพ์ผลลัพธ์ของ 'script_loader_src' จะถูก Escape ดังนั้นเครื่องหมายอัญประกาศจะถูกแยกออกและสิ่งที่คุณส่งออกจะได้รับการยอมรับว่าเป็นส่วนหนึ่งของแอตทริบิวต์ 'src' และไม่ใช่คุณลักษณะที่แยกจากกัน รหัสนี้จะใส่มาร์กอัปแบบ html คล้ายกับ<script type='text/javascript' src='https://www.dropbox.com/static/api/1/dropins.js?ver=3.6&#039;id=&#039;dropboxjs&#039;data-app-key=&#039;MY_APP_KEY'></script>
gmazzap

ใช่ฉันปรับปรุงคำตอบของฉัน
Bainternet

3
ฉันทดสอบโค้ดหลังจากแก้ไขแล้วใช้งานได้ ขอบคุณสำหรับการสอนบางอย่างให้ฉันด้วยสิ่งนี้
gmazzap

1
ฉันคิดว่า OP จะมีความสุขมากกว่าที่คุณเป็นฉัน ;)
gmazzap

1
ขอบคุณ @Bainternet สำหรับความช่วยเหลือของคุณทำให้มันทำงานโดยใช้คำตอบของคุณ
Andrew Bartel

14

ตั้งแต่ WP 4.1.0 ตะขอตัวกรองใหม่พร้อมใช้งานเพื่อให้บรรลุสิ่งนี้ได้อย่างง่ายดาย:

script_loader_tag

ใช้วิธีนี้:

add_filter( 'script_loader_tag', 'add_id_to_script', 10, 3 );

function add_id_to_script( $tag, $handle, $source ) {
    if ( 'dropbox.js' === $handle ) {
        $tag = '<script type="text/javascript" src="' . $source . '" id="dropboxjs" data-app-key="MY_APP_KEY"></script>';
    }

    return $tag;
}

สิ่งนี้ดำเนินการก่อนที่จะมีการแคช JS หรือไม่
Joanna Mikalai

3

ตกลงดูเหมือนว่า (สำหรับฉัน) ที่wp_enqueque_scriptsไม่สามารถพิมพ์รหัสและคีย์แอปเป็นแอตทริบิวต์แท็กสคริปต์

ฉันแน่ใจว่า 90% เพราะWP_Dependenciesไม่ใช่ชั้นเรียนที่ฉันรู้จักดี แต่ดูที่รหัสดูเหมือนว่าจะเป็นไปไม่ได้สำหรับฉัน

แต่ฉันแน่ใจ 100% ว่าการใช้wp_localize_scriptเป็นไม่เป็นประโยชน์สำหรับขอบเขตของคุณ

ตามที่ฉันพูดในความคิดเห็นของฉันด้านบน:

สิ่งที่ wp_localize_script ทำคือพิมพ์วัตถุที่เข้ารหัส json ในเอาต์พุต html ของหน้า สคริปต์นี้รู้จักวัตถุและคุณสามารถใช้งานได้

สิ่งที่ฉันไม่ได้กล่าวถึงในความคิดเห็นก็คือวัตถุที่เข้ารหัส json เป็นชื่อที่คุณตัดสินใจในความเป็นจริงแล้วดูที่ไวยากรณ์:

wp_localize_script( $handle, $object_name, $l10n );

สคริปต์ที่มีชื่อ$object_name สามารถใช้งานได้เนื่องจากอยู่ในขอบเขตส่วนกลางและพิมพ์ใน html ของหน้า

แต่$object_nameเป็นชื่อที่คุณตัดสินใจเพื่อที่จะสามารถทุกอย่าง

ดังนั้นถามตัวเองว่า:

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

ดังนั้นจึงไม่มีเหตุผลเลยที่จะส่งรหัสและ / หรือรหัสแอปไปยังสคริปต์ด้วยwp_localize_script: คุณเพียงพิมพ์มันเป็นแอตทริบิวต์แท็กสคริปต์ดังที่ได้กล่าวไว้ในเอกสาร Dropbox API

ฉันไม่ใช่นักพัฒนา js แต่ฉันคิดว่าสคริปต์ดรอปบ็อกซ์ทำคืออะไร:

  1. รับ<script>องค์ประกอบ html ทั้งหมดในหน้า
  2. วนรอบพวกเขาตามหาด้วย 'id' == 'dropboxjs'
  3. หากพบสคริปต์นั้นให้ดูที่ 'data-app-key' ของสคริปต์นั้น
  4. ตรวจสอบว่ารหัสแอปนั้น (ถ้ามี) เป็นรหัสที่ถูกต้องและให้สิทธิ์คุณถ้าเป็นเช่นนั้น

โปรดทราบว่าผมไม่ทราบว่านี้เพื่อตรวจสอบว่าฉันแค่การคาดเดา

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

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

วิธีที่ไม่มีกลิ่นมากเกินไป (เมื่อไม่มีทางเลือก) คือใช้wp_print_scriptshook เพื่อพิมพ์แท็กสคริปต์:

add_action('wp_print_scripts', 'do_dropbox_stuff');

function do_dropbox_stuff() {

  if ( ! is_admin() ) return; // only for admin area

  $app_key = 'MY_APP_KEY';

  // why do not create an option for it?
  // $app_key = get_option('dropbox_app_key');

  if ( empty($app_key) ) return;

  echo '<script type="text/javascript" src="https://www.dropbox.com/static/api/1/dropins.js" id="dropboxjs" data-app-key="' . esc_attr($app_key) . '"></script>';

}

ขอบคุณจีเอ็มฉันได้รับการทำงานโดยใช้สิ่งนี้ ฉันสนใจที่จะดูว่ามีทางเลือกอื่นในการใช้ตะขอเกี่ยวกับการเข้าระบบหรือไม่ แต่ฉันขอขอบคุณทุกความคิดที่คุณตอบไว้
Andrew Bartel

@AndrewBartel ฉันคิดว่าไม่มีวิธีที่จะใช้ wp_enqueque_scripts ในกรณีของคุณ แต่ถ้าคุณพบหนึ่งแจ้งให้เราทราบ! :)
gmazzap

โซลูชันของคุณสามารถเพิ่มโหลดบนเซิร์ฟเวอร์ในขณะที่คุณทำการร้องขอ HTTP อีก 1 รายการโดยตรงโดยทำเสียงสะท้อน การแก้ปัญหาเป็นสิ่งที่ดี แต่ไม่เหมาะ
Faisal Shaikh

@FaisalShaikh สนใจที่จะอธิบายหรือไม่ echoคำสั่งไม่ได้ร้องขอ HTTP ใดเท่าที่ผมสามารถบอกและ WordPress wp_enqueue_scriptไม่สะท้อนได้เป็นอย่างดี (ดูcore.trac.wordpress.org/browser/tags/4.9/src/wp-includes/... ) แน่นอนคุณสามารถลด จำนวนคำขอโดยรวมสคริปต์กับสคริปต์อื่น ๆ ที่คุณมี แต่: 1) สคริปต์มีอยู่ในเซิร์ฟเวอร์บุคคลที่สามในกรณีนี้ 2) กับ HTTP 2 ในปัจจุบันการรวมสคริปต์จะลดประสิทธิภาพไม่เพิ่มขึ้น ดังนั้นฉันอาจจะพลาดบางสิ่งบางอย่าง?
gmazzap

@ gmazzap คุณพูดถูก อันที่จริงฉันมีวิธีที่แตกต่างในการทำเช่นนี้ เราสามารถเก็บส่วนที่ 3 js นี้ลงในเซิร์ฟเวอร์ของเราและฉันไม่รู้สึกว่าการรวมสคริปต์สามารถเพิ่มโหลดบนเซิร์ฟเวอร์
Faisal Shaikh

1

จากคำตอบของ Bainternet ด้านบน รหัสนี้ใช้ได้สำหรับฉัน

function pmdi_dropbox( $good_protocol_url, $original_url, $_context){
    if ( FALSE === strpos($original_url, 'dropbox') or FALSE === strpos($original_url, '.js')) {
        return $url;
    } else {
        remove_filter('clean_url','pmdi_dropbox',10,3);
        $url_parts = parse_url($good_protocol_url);
        return $url_parts['scheme'] . '://' . $url_parts['host'] . $url_parts['path'] . "' id='dropboxjs' data-app-key='APIKEY";
    }
}

แก้ไข: ข้อแตกต่างจากรหัส Bainternet คือฉันเพิ่มเงื่อนไขเพื่อตรวจสอบว่า URL ของสคริปต์เป็นดรอปบ็อกซ์และเป็นไฟล์. js

ฉันไม่สนใจ URL อื่นทั้งหมดและเขียน URL ดรอปบ็อกซ์ใหม่


2
โปรดเพิ่มคำอธิบายเกี่ยวกับสิ่งที่คุณเปลี่ยนแปลงและสาเหตุที่ทำให้คุณเปลี่ยนแปลง (หรือต้องเปลี่ยน)
tfrommen

ฉันรู้ว่านี่เป็นการตอบสนองแบบเก่า แต่ในรหัสของคุณด้านบนคุณหมายถึงการส่งคืน $ original_url ภายในคำสั่ง IF แทนที่จะเป็นแค่ $ url หรือไม่
leromt

1

ฉันทำการตรวจสอบในรหัส dropbox.js (v2) เพื่อดูว่าเกิดอะไรขึ้นและจะแก้ไขได้ดีที่สุด ตามที่ปรากฎ data-app-key จะใช้เพื่อตั้งค่าตัวแปร Dropbox.appKey เท่านั้น ฉันสามารถตั้งค่าตัวแปรด้วยบรรทัดพิเศษต่อไปนี้

การใช้ตัวอย่างจาวาสคริปต์ในหน้า Dropbox https://www.dropbox.com/developers/dropins/chooser/js :

<script>
Dropbox.appKey = "YOUR-APP-ID";
var button = Dropbox.createChooseButton(options);
document.getElementById("container").appendChild(button);
</script>

ในรหัสของฉันฉันตั้ง Dropbox.appKey ในทุก ๆ ที่ที่ฉันอ้างอิงรูทีนจาวาสคริปต์ Dropbox การทำเช่นนี้ทำให้ฉันสามารถใช้ wp_enqueue_script () โดยไม่มีพารามิเตอร์เพิ่มเติม


0

ฉันทำสิ่งนี้กับปลั๊กอิน eCards ของฉันและมันง่ายมาก

นี่คือการคัดลอก / วางโดยตรงจากปลั๊กอิน:

$output .= '<!-- https://www.dropbox.com/developers/chooser -->';
$output .= '<script type="text/javascript" src="https://www.dropbox.com/static/api/1/dropbox.js" id="dropboxjs" data-app-key="' . get_option('ecard_dropbox_private') . '"></script>';
$output .= '<p><input type="dropbox-chooser" name="selected-file" style="visibility: hidden;" data-link-type="direct" /></p>';

สังเกตว่าคีย์ API ถูกส่งผ่านตัวเลือก


$ output ใช้อย่างไร สะท้อน? เพิ่มใน wp_print_scripts () หรือไม่
Andrew Bartel

มันจะถูกส่งกลับหรือสะท้อนขึ้นอยู่กับฟังก์ชั่นของคุณ
Ciprian

0

มีวิธีที่ง่ายกว่าในการทำเช่นนี้

 function load_attributes( $url ){
    if ( 'https://www.dropbox.com/static/api/1/dropins.js' === $url ){
        return "$url' id='dropboxjs' data-app-key='MY_APP_KEY";
    }

    return $url;
}

add_filter( 'clean_url', 'load_attributes', 11, 1 );

0

Wordpress ไวยากรณ์สำหรับscript_loader_tag :

apply_filters( 'script_loader_tag', string $tag, string $handle, string $src )

ในการเพิ่มคุณสมบัติใด ๆ คุณสามารถแก้ไข $ tag ด้วยวิธีนี้:

add_filter('script_loader_tag', 'add_attributes_to_script', 10, 3); 
function add_attributes_to_script( $tag, $handle, $src ) {
    if ( 'dropbox.js' === $handle ) {
        $tag = '<script type="text/javascript" src="' . esc_url( $src ) . '" id="dropboxjs" data-app-key="MY_APP_KEY"></script>';
    } 
    return $tag;
}

ซึ่งจะหลบหนี URL อย่างถูกต้อง


0

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

add_filter('script_loader_tag', 'add_attributes_to_script', 10, 3); 
function add_attributes_to_script( $tag, $handle, $src ) {

    $scripts_to_load = array (

        (0) => Array
          (
            ('name') => 'bootstrap_min_css',
            ('type') => '<link rel="stylesheet" href="',            
            ('integrity') => 'sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB',
            ('close') => ' type="text/css" media="all">'
          ),

        (1) => Array
          (
            ('name') => 'popper_min_js',
            ('type') => '<script type="text/javascript" src="',         
            ('integrity') => 'sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49',
            ('close') => '></script>'
          ),

         (2) => Array
           (
            ('name') => 'bootstrap_min_js', 
            ('type') => '<script type="text/javascript" src="',
            ('integrity') => 'sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T',
            ('close') => '></script>'
           )
    );  

    $key = array_search($handle, array_column($scripts_to_load, 'name'));

    if ( FALSE !== $key){

        $tag = $scripts_to_load[$key]['type'] . esc_url($src) . '" integrity="' . $scripts_to_load[$key]['integrity'] .'" crossorigin="anonymous"' . $scripts_to_load[$key]['close'] . "\n";

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