Thêm thuộc tính bổ sung trong thẻ Script cho JS bên thứ 3


20

Tôi gặp phải vấn đề này khi cố gắng tích hợp API trình chọn của Dropbox vào plugin tôi đang viết.

Tài liệu API hướng dẫn bạn đặt scriptthẻ sau vào đầu tệp của bạn:

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

Tất cả đều tốt và tốt, và nó thực sự hoạt động khi tôi trực tiếp dán nó vào trang được gọi trong phần quản trị. Nhưng, tôi muốn sử dụng một số biến thể của wp_register_script (), wp_enqueue_script () và wp_localize_script () để truyền id và khóa ứng dụng dữ liệu cần thiết.

Tôi đã thử một vài biến thể khác nhau của điều này:

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

Và:

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 được thay thế bằng khóa ứng dụng phù hợp trong mã của tôi. Sẽ đánh giá cao bất kỳ hướng. Cảm ơn.

EDIT: Cũng đã cố gắng làm điều đó với một số jquery, nhưng không có kết quả. Đã thử nó trên tải tài liệu và trên tài liệu đã sẵn sàng. Tôi nhận được trả về {"lỗi": "Không hợp lệ 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
Điều wp_localize_scriptcần làm là in một đối tượng được mã hóa json trong đầu ra html của trang. Đối tượng này được nhận dạng bởi tập lệnh và vì vậy bạn có thể sử dụng nó. Những gì bạn cần là thêm một số thuộc tính vào thẻ script và vì vậy wp_localize_scriptkhông thể giúp bạn.
gmazzap

2
GM là chính xác mà wp_localize_scriptkhông tạo thuộc tính tập lệnh. Nhưng có thể chuyển khóa ứng dụng trực tiếp vào dropbox.js không? Chỉ là một phỏng đoán nhưng bạn đã thử array('appKey'=>"MY_APP_KEY")? Đây là mã lấy khóa từ thuộc tínhif(!Dropbox.appKey){Dropbox.appKey=(e=document.getElementById("dropboxjs"))!=null?e.getAttribute("data-app-key"):void 0}
epilektric

Này @epilektric Bạn có thể trả lời câu hỏi đó không? Tôi không hoàn toàn làm theo cách thực hiện nó.
Andrew Bartel

@epilektric wp_localize_scriptchắc chắn bạn có thể chuyển các thuộc tính cho tập lệnh. Tôi thực sự không biết điều này có hiệu quả hay không, tuy nhiên nó không phải là vấn đề liên quan.
gmazzap

@AndrewBartel Tôi cũng không chắc lắm. Có thể điều này sẽ giúp. pippinsplugins.com/use-wp_localize_script-it-is-awgie
epilektric

Câu trả lời:


18

bạn có thể thử sử dụng script_loader_srcmóc lọc, vd:

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

Cập nhật

Tôi chỉ tự mình nhận ra rằng src được esc_url thoát ra, vì vậy tìm kiếm thêm một chút tôi đã tìm thấy clean_urlbộ lọc mà bạn có thể sử dụng để trả về giá trị với dữ liệu khóa id và ứng dụng của bạn:

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

Nó không hoạt động. Trước khi được in, kết quả của 'script_loader_src' đã được thoát, do đó, dấu ngoặc kép bị loại bỏ và những gì bạn xuất ra được công nhận là một phần của thuộc tính 'src' và không phải là thuộc tính riêng biệt. Mã này sẽ đưa vào đánh dấu html một cái gì đó như<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

vâng tôi đã cập nhật câu trả lời của tôi.
Bai Internet

3
Tôi đã kiểm tra mã sau khi chỉnh sửa và nó hoạt động. Cảm ơn đã dạy một cái gì đó cho tôi với điều này.
gmazzap

1
Tôi nghĩ OP sẽ hạnh phúc hơn bạn một tôi. ;)
gmazzap

1
Cảm ơn @BaiNET vì sự giúp đỡ của bạn, giúp nó hoạt động bằng cách sử dụng câu trả lời của bạn.
Andrew Bartel

14

Kể từ WP 4.1.0, một móc lọc mới có sẵn để đạt được điều này một cách dễ dàng:

script_loader_tag

Sử dụng theo cách này:

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

điều này có thực thi trước khi bất kỳ bộ nhớ đệm JS nào diễn ra không?
Joanna Mikalai

3

OK, dường như (với tôi) rằng wp_enqueque_scriptskhông thể in id và khóa ứng dụng làm thuộc tính thẻ script.

Tôi chắc chắn ở mức 90%, vì WP_Dependencieskhông phải là một lớp mà tôi biết rõ, nhưng nhìn vào mã Có vẻ như tôi không thể.

Nhưng tôi chắc chắn 100% rằng việc sử dụng wp_localize_scriptkhông hữu ích cho phạm vi của bạn .

Như tôi đã nói trong nhận xét của tôi ở trên:

Những gì wp_localize_script làm là in một đối tượng được mã hóa json trong đầu ra html của trang. Đối tượng này được nhận dạng bởi tập lệnh và vì vậy bạn có thể sử dụng nó.

Điều tôi chưa nói trong bình luận là đối tượng được mã hóa json như một tên tùy ý mà bạn quyết định, trên thực tế, nhìn vào cú pháp:

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

Đối tượng có tên $object_name có thể được sử dụng bởi tập lệnh vì nằm trong phạm vi toàn cầu và được in bằng html của trang.

Nhưng đó $object_namelà một cái tên mà bạn quyết định, vì vậy nó có thể là tất cả .

Vì vậy, hãy tự hỏi:

Làm thế nào tập lệnh trong máy chủ dropbox từ xa có thể sử dụng một biến mà họ không biết được gọi như thế nào?

Vì vậy, không có lý do nào để chuyển id và / hoặc khóa ứng dụng cho tập lệnh với wp_localize_script: bạn chỉ cần in chúng dưới dạng các thuộc tính thẻ tập lệnh như được nói trong tài liệu API Dropbox.

Tôi không phải là nhà phát triển js, nhưng tôi nghĩ kịch bản dropbox làm gì là:

  1. lấy tất cả các <script>phần tử html trong trang
  2. quay vòng qua họ để tìm kiếm cái có 'id' == 'dropboxjs'
  3. nếu tập lệnh đó được tìm thấy, hãy xem 'khóa dữ liệu ứng dụng' của tập lệnh đó
  4. kiểm tra xem khóa ứng dụng đó (nếu có) có hợp lệ không và ủy quyền cho bạn nếu có

Xin vui lòng lưu ý rằng tôi không biết điều này chắc chắn, tôi chỉ đoán .

Theo cách này, tập lệnh được tải từ máy chủ dropbox có thể kiểm tra khóa ứng dụng của bạn theo cách dễ dàng cho họ và dễ thực hiện cho bạn.

Bởi vì trong câu đầu tiên tôi đã nói rằng không thể in id và khóa ứng dụng trong tập lệnh bằng cách sử dụng wp_enqueque_scripts, đạo đức của câu chuyện là bạn phải in chúng trong phần đánh dấu theo cách khác.

Một cách không có mùi quá nhiều (khi không có lựa chọn thay thế) là sử dụng wp_print_scriptshook để in thẻ script:

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

}

Cảm ơn GM, tôi đã làm cho nó hoạt động bằng cách này. Tôi quan tâm xem liệu có giải pháp thay thế nào sử dụng móc enqueue hay không nhưng tôi đánh giá cao tất cả những suy nghĩ bạn đưa vào câu trả lời.
Andrew Bartel

@AndrewBartel Tôi nghĩ không có cách nào để sử dụng wp_enqueque_scripts trong trường hợp của bạn, nhưng nếu bạn tìm thấy một cái, hãy cho chúng tôi biết! :)
gmazzap

giải pháp của bạn có thể tăng tải trên máy chủ khi bạn trực tiếp thực hiện thêm 1 yêu cầu http bằng cách thực hiện echo. Giải pháp tốt nhưng không được tối ưu hóa.
Faisal Shaikh

@FaisalShaikh quan tâm giải thích? Các echotuyên bố không thực hiện bất kỳ yêu cầu HTTP như xa như tôi có thể nói, và WordPress wp_enqueue_scriptkhông một tiếng vang cũng (xem core.trac.wordpress.org/browser/tags/4.9/src/wp-includes/... ) Chắc chắn bạn có thể giảm số lượng yêu cầu bằng cách kết hợp tập lệnh với một số tập lệnh khác mà bạn có nhưng: 1) tập lệnh tồn tại trong máy chủ của bên thứ 3 trong trường hợp 2) với HTTP 2 hiện nay kết hợp tập lệnh sẽ làm giảm hiệu suất, không làm tăng chúng. Vì vậy, có lẽ tôi bỏ lỡ một cái gì đó?
gmazzap

@gmazzap bạn nói đúng. Thật ra, tôi có một cách khác để làm điều này. Chúng tôi có thể lưu trữ phần 3 js này vào máy chủ của mình và tôi thực sự không cảm thấy việc kết hợp tập lệnh có thể tăng tải cho máy chủ.
Faisal Shaikh

1

Từ trả lời của BaiNET ở trên. Mã này làm việc cho tôi.

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

Chỉnh sửa: Sự khác biệt duy nhất từ ​​mã Bai Internet là, tôi đã thêm một điều kiện để kiểm tra xem URL tập lệnh có phải là dropbox không và đó có phải là tệp .js không.

Tôi đang bỏ qua tất cả các URL khác và viết lại URL của hộp thư đến.


2
Vui lòng thêm một số giải thích về những gì bạn thay đổi và lý do tại sao bạn thay đổi nó (hoặc phải thay đổi nó).
tfrommen

Tôi biết đây là một phản hồi cũ nhưng trong mã của bạn ở trên, bạn có nghĩa là trả lại $ original_url bên trong câu lệnh IF thay vì chỉ $ url?
leromt

1

Tôi đã thực hiện một số kiểm tra trong mã dropbox.js (v2) để xem điều gì đang xảy ra và cách giải quyết vấn đề này tốt nhất. Hóa ra, khóa dữ liệu-ứng dụng chỉ được sử dụng để đặt biến Dropbox.appKey. Tôi có thể đặt biến với dòng phụ sau.

Sử dụng ví dụ javascript trên trang 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>

Trong mã của tôi, tôi đặt Dropbox.appKey ở mọi nơi tôi tham chiếu các thói quen javascript của Dropbox. Làm điều này cho phép tôi sử dụng wp_enqueue_script () mà không cần các tham số phụ.


0

Tôi đã làm điều này với plugin eCards của tôi và nó thực sự đơn giản.

Đây là bản sao / dán trực tiếp từ plugin:

$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>';

Lưu ý khóa API được chuyển qua một tùy chọn.


$ Sản lượng được sử dụng như thế nào? Tiếng vọng? Thêm vào wp_print_scripts ()?
Andrew Bartel

Nó được trả về hoặc lặp lại, tùy thuộc vào chức năng của bạn.
Ciprian

0

Có một cách đơn giản hơn để làm điều này

 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

Cú pháp Wordpress cho script_loader_tag :

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

Để thêm bất kỳ thuộc tính nào, bạn có thể sửa đổi thẻ $ của mình theo cách này:

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

Mà sẽ thoát URL chính xác.


0

Cảm ơn tất cả các bài viết, họ thực sự giúp đỡ. Tôi đã cuộn phiên bản của riêng mình để cung cấp cho nó một số cấu trúc và làm cho nó dễ đọc và cập nhật hơn. Sử dụng enqueue như bình thường, sử dụng tập lệnh cho các tệp CSS có thẻ sai ở cuối để nó tải ở đầu. Mặc dù nó có thể được đơn giản hóa phần nào.

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