Dodawanie dodatkowych atrybutów w znaczniku skryptu dla JS innej firmy

20

Natknąłem się na to, próbując zintegrować upuszczenie Dropbox w API selektora z wtyczką, którą piszę.

Dokumentacja interfejsu API nakazuje umieszczenie następującego scriptznacznika u góry pliku:

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

Wszystko dobrze i dobrze, i faktycznie działa, gdy wklejam go bezpośrednio na stronę wywoływaną w sekcji admin. Ale chciałbym użyć pewnej odmiany wp_register_script (), wp_enqueue_script () i wp_localize_script (), aby przekazać wymagany identyfikator i klucz aplikacji danych.

Wypróbowałem kilka różnych odmian tego:

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

I:

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 zostaje zastąpiony odpowiednim kluczem aplikacji w moim kodzie. Byłbym wdzięczny za każdy kierunek. Dzięki.

EDYCJA: Próbowałem też zrobić to przy pomocy jquery, ale bezskutecznie. Próbowałem po załadowaniu dokumentu i przygotowaniu dokumentu. Otrzymuję zwrot {„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');
Andrew Bartel
źródło
2
Co wp_localize_scriptto jest wydrukować obiekt zakodowany w formacie json na wyjściu HTML strony. Ten obiekt jest rozpoznawany przez skrypt i można go używać. Musisz dodać niektóre atrybuty do tagu skryptu, więc wp_localize_scriptnie mogę ci pomóc.
gmazzap
2
GM ma rację, wp_localize_scriptnie tworzy atrybutów skryptu. Ale czy można przekazać klucz aplikacji bezpośrednio do dropbox.js? Tylko zgadnij, ale próbowałeś array('appKey'=>"MY_APP_KEY")? Jest to kod, który pobiera klucz z atrybutuif(!Dropbox.appKey){Dropbox.appKey=(e=document.getElementById("dropboxjs"))!=null?e.getAttribute("data-app-key"):void 0}
epilektric
Hej @epilektric Czy potrafisz podać odpowiedź? Nie bardzo podążam za tym, jak to zaimplementować.
Andrew Bartel,
@epilektric z wp_localize_scriptpewnością możesz przekazać atrybuty do skryptu. Naprawdę nie wiem, czy to zadziała, czy nie, ale nie jest to kwestia związana z niepokojem.
gmazzap
@AndrewBartel Nie jestem pewien, jak to zrobić. Może to pomoże. pippinsplugins.com/use-wp_localize_script-it-is-awesome
epilektryczny

Odpowiedzi:

18

możesz spróbować użyć script_loader_srczaczepu filtra, np .:

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

Aktualizacja

właśnie zorientowałem się, że src ucieka przez esc_url, więc szukając trochę więcej, znalazłem clean_urlfiltr, którego można użyć do zwrócenia wartości z identyfikatorem i kluczowymi danymi aplikacji:

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;
}
Bainternet
źródło
To nie działa Przed wydrukowaniem wynik „script_loader_src” jest poprzedzany znakami ucieczki, więc cytaty są usuwane, a dane wyjściowe są rozpoznawane jako część atrybutu „src”, a nie jako osobne atrybuty. Ten kod <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>
wstawi
tak, zaktualizowałem swoją odpowiedź.
Bainternet
3
Testowałem kod po mojej edycji i działa. Dziękuję za nauczenie mnie czegoś z tym.
gmazzap
1
Myślę, że OP będzie szczęśliwszy niż ty i ja. ;)
gmazzap
1
Dziękuję @Bainternet za pomoc, sprawił, że zadziałało, używając Twojej odpowiedzi.
Andrew Bartel,
14

Od wersji WP 4.1.0 dostępny jest nowy hak filtra, aby łatwo to osiągnąć:

script_loader_tag

Użyj tego w ten sposób:

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;
}
ClemC
źródło
czy wykonuje się to zanim nastąpi buforowanie JS?
Joanna Mikalai
3

OK, wydaje mi się, że wp_enqueque_scriptsnie jest możliwe wydrukować identyfikatora i klucza aplikacji jako atrybutów znaczników skryptu.

Jestem pewien, że na 90%, ponieważ WP_Dependencies nie jest to klasa, którą znam dobrze, ale patrząc na kod Wydaje mi się to niemożliwe.

Ale jestem pewien, że w 100% użycie niewp_localize_script jest przydatne w twoim zakresie .

Jak powiedziałem w moim komentarzu powyżej:

Skrypt wp_localize_script drukuje obiekt zakodowany w formacie json na wyjściu HTML strony. Ten obiekt jest rozpoznawany przez skrypt i można go używać.

To, czego nie powiedziałem w komentarzu, to to, że obiekt zakodowany w formacie json jako dowolna nazwa, którą decydujesz, patrząc na składnię:

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

Nazwany obiekt $object_name może być używany przez skrypt, ponieważ znajduje się w zasięgu globalnym i jest drukowany w html strony.

Ale $object_nameto nazwa, którą decydujesz, więc może być wszystkim .

Zapytaj więc siebie:

w jaki sposób skrypt na zdalnym serwerze Dropbox może korzystać ze zmiennej, której nie znają, jak się nazywa?

Nie ma więc żadnego powodu, aby przekazywać identyfikator i / lub klucz aplikacji do skryptu za pomocą wp_localize_script: wystarczy wydrukować je jako atrybuty tagu skryptu, jak powiedziano w dokumentacji API Dropbox.

Nie jestem programistą js, ale myślę, że to, co robi skrypt Dropbox, to:

  1. weź wszystko <script> elementy HTML na stronie
  2. przeglądaj je, szukając „id” == „dropboxjs”
  3. jeśli ten skrypt zostanie znaleziony, patrząc na „klucz aplikacji danych” tego skryptu
  4. sprawdź, czy klucz aplikacji (jeśli jest obecny) jest prawidłowy, i jeśli tak, autoryzuj

Pamiętaj, że nie wiem tego na pewno, po prostu zgaduję .

W ten sposób skrypt załadowany z serwera Dropbox może sprawdzić klucz aplikacji w sposób dla nich łatwy i łatwy do wdrożenia.

Ponieważ w pierwszym zdaniu powiedziałem, że nie można wydrukować identyfikatora i klucza aplikacji w skrypcie przy użyciuwp_enqueque_scripts , morał tej historii jest taki, że musisz wydrukować je w znaczniku w inny sposób.

Sposobem, który nie pachnie zbyt mocno (gdy nie ma alternatywy) jest użycie wp_print_scriptshaka do wydrukowania znacznika skryptu:

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

}
gmazzap
źródło
Dzięki GM, mam to do pracy przy użyciu tego. Chciałbym zobaczyć, czy istnieją alternatywne rozwiązania z użyciem haczyków w kolejce, ale doceniam całą myśl, którą włożyłeś w odpowiedź.
Andrew Bartel,
@AndrewBartel Myślę, że nie ma sposobu na użycie skryptu wp_enqueque_scripts w twoim przypadku, ale jeśli go znajdziesz, daj nam znać! :)
gmazzap
Twoje rozwiązanie może zwiększyć obciążenie serwera, ponieważ bezpośrednio wykonujesz 1 dodatkowe żądanie HTTP, wykonując echo. Rozwiązanie jest dobre, ale nie zoptymalizowane.
Faisal Shaikh
@FaisalShaikh chcesz wyjaśnić? O echoile mi wiadomo, instrukcja nie wysyła żadnych żądań HTTP, a WordPress wp_enqueue_scriptwykonuje również echo (patrz core.trac.wordpress.org/browser/tags/4.9/src/wp-include/... ) Z pewnością można zmniejszyć liczba żądań poprzez połączenie skryptu z innym skryptem, który masz, ale: 1) skrypty istnieją w tym przypadku na serwerze innej firmy 2) z HTTP 2 w dzisiejszych czasach połączenie skryptu zmniejszyłoby wydajność, a nie je zwiększyło. Więc może coś mi umknęło?
gmazzap
@gmazzap masz rację. w rzeczywistości mam inny sposób, aby to zrobić. Możemy przechowywać tę trzecią część js na naszym serwerze i naprawdę nie uważam, że łączenie skryptu może zwiększyć obciążenie serwera.
Faisal Shaikh
1

Z odpowiedzi Bainternet powyżej. Ten kod działał dla mnie.

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

Edycja: Jedyną różnicą w stosunku do kodu Bainternet jest to, że dodałem warunek, aby sprawdzić, czy adres URL skryptu to dropbox i czy to plik .js.

Ignoruję wszystkie pozostałe adresy URL i przepisuję adres URL skrzynki odbiorczej.

użytkownik2914440
źródło
2
Dodaj wyjaśnienie, co zmieniłeś i dlaczego to zmieniłeś (lub musiałeś to zmienić).
tfrommen
Wiem, że to stara odpowiedź, ale czy w powyższym kodzie chciałeś zwrócić $ original_url w instrukcji IF zamiast tylko $ url?
leromt
1

Sprawdziłem kod dropbox.js (v2), aby zobaczyć, co się dzieje i jak najlepiej rozwiązać ten problem. Jak się okazuje, klucz aplikacji danych służy jedynie do ustawienia zmiennej Dropbox.appKey. Mogę ustawić zmienną z następującą dodatkową linią.

Korzystając z przykładu javascript na stronie 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>

W moim kodzie ustawiam Dropbox.appKey w każdym miejscu, w którym odwołuję się do procedur javascript Dropbox. Dzięki temu mogłem używać wp_enqueue_script () bez dodatkowych parametrów.

Michaelkay
źródło
0

Zrobiłem to z moją wtyczką eKartek i jest to naprawdę proste.

Oto bezpośrednia kopia / wklej z wtyczki:

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

Zauważ, że klucz API jest przekazywany przez opcję.

Ciprian
źródło
Jak wykorzystywane jest wyjście $? Echoed? Dodać do wp_print_scripts ()?
Andrew Bartel,
Jest on zwracany lub powtarzany, w zależności od funkcji.
Ciprian
0

Jest na to prostszy sposób

 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 );
Max Kondrachuk
źródło
0

Składnia Wordpress dla script_loader_tag :

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

Aby dodać dowolny atrybut, możesz zmodyfikować swój tag $ w ten sposób:

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

Który poprawnie uniknie adresu URL.

JackLinkers
źródło
0

Dzięki za wszystkie posty, naprawdę pomogły. Rzuciłem własną wersję, aby nadać jej strukturę i ułatwić czytanie i aktualizację. Użyj normalnej kolejki, użyj skryptu dla plików CSS z fałszywym znacznikiem na końcu, aby ładował się u góry. Chociaż można to nieco uprościć.

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;
}
wpNewby
źródło