Додавання додаткових атрибутів у тег сценарію для сторонніх JS


20

Я зіткнувся з цим при спробі інтегрувати краплі Dropbox у 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 замінюється відповідним ключем програми в моєму коді. Був би вдячний у будь-якому напрямку. Спасибі.

EDIT: Також намагався зробити це з деякими jquery, але безрезультатно. Спробували його під час завантаження документа та документа. Я отримую повернення {"error": "Invalid 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
GM правильний, що 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, чи не могли б ви це відповісти? Я не зовсім стежу за тим, як це реалізувати.
Ендрю Бартель

@epilektric із wp_localize_scriptвпевненістю, що ви можете передати атрибути сценарію. Я дійсно не знаю, чи це спрацює чи ні, однак це не питання, пов'язане з попередженням.
гмаззап

@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фільтр, який можна використовувати для повернення значення за допомогою ваших ідентифікаційних даних та ключових даних програми:

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' уникнути, тому лапки викреслюються, а те, що ви виводите, визнається частиною атрибута '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
Я думаю, що ОП буде щасливішим, ніж ти. ;)
gmazzap

1
Дякуємо @Bainternet за вашу допомогу, працюючи з вашою відповіддю.
Ендрю Бартель

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?
Джоанна Миколай

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: вам потрібно просто роздрукувати їх як атрибути тегів сценарію, як сказано в документах API Dropbox.

Я не js-розробник, але я думаю, що це сценарій dropbox:

  1. дістати всіх <script> html елементи на сторінці
  2. пройдіться по них, шукаючи той із "id" == "dropboxjs"
  3. якщо цей скрипт знайдеться, переглядаючи "ключ-додаток даних" цього сценарію
  4. перевірте, чи є ключ програми (якщо він є) дійсним, і авторизуйте вас, якщо так

Зверніть увагу, що я цього не знаю точно, я просто здогадуюсь .

Таким чином, скрипт, завантажений з сервера випадок, може перевірити ваш ключ програми таким чином, щоб він був легким для них і простий у здійсненні для вас.

Тому що в першому реченні я сказав , що це НЕ можливо , щоб надрукувати ідентифікатор і ключ додатки в сценарії з використаннямwp_enqueque_scripts , мораль цієї історії є те , що ви повинні надрукувати їх в розмітці і по - іншому.

Спосіб, який не надто пахне (коли немає альтернатив), - це використовувати wp_print_scriptsгачок для друку тегу сценарію:

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

}

Завдяки GM, я змусив це працювати, використовуючи це. Мені цікаво дізнатись, чи існують альтернативні рішення, що використовують гачки, але я ціную всю думку, яку ви вклали у відповідь.
Ендрю Бартель

@AndrewBartel Я думаю, що у вашому випадку немає можливості використовувати wp_enqueque_scripts, але якщо ви знайдете його, повідомте нас! :)
gmazzap

ваше рішення може збільшити навантаження на сервер, оскільки ви безпосередньо робите ще 1 http-запит, роблячи echo. Рішення хороше, але не оптимізоване.
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 ви праві. насправді у мене є інший спосіб це зробити. Ми можемо зберігати цю третю частину js на своєму сервері, і я дійсно не відчуваю, що комбінування сценарію може збільшити навантаження на сервер.
Faisal Shaikh

1

З вищевказаної відповіді Байнтерне. Цей код працював на мене.

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), щоб побачити, що відбувається і як найкраще вирішити це. Як виявляється, ключ даних-додатків використовується лише для встановлення змінної Dropbox.appKey. Я зміг встановити змінну за допомогою наступного додаткового рядка.

Використовуючи приклад javascript на сторінці 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 javascript. Це дозволило мені використовувати 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 передається через опцію.


Як використовується вихід $? Відлуння? Додати до wp_print_scripts ()?
Ендрю Бартель

Він або повертається, або перегукується, залежно від вашої функції.
Кіпріан

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 )

Щоб додати будь-який атрибут, ви можете змінити свій $ тег таким чином:

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 з помилковим тегом в кінці, щоб він завантажувався вгорі. Хоча це, мабуть, може бути дещо спрощене.

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;
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.