Adăugarea atributelor suplimentare în tag-ul Script pentru JavaScript third-party

20 aug. 2013, 22:39:36
Vizualizări: 29.6K
Voturi: 29

Am întâmpinat această problemă când am încercat să integrez API-ul Dropbox chooser într-un plugin pe care îl dezvolt.

Documentația API-ului te instruiește să plasezi următorul tag script în partea de sus a fișierului tău:

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

Totul e în regulă și funcționează când îl lipesc direct în pagina care este apelată în secțiunea de administrare. Dar, aș dori să folosesc o variație a funcțiilor wp_register_script(), wp_enqueue_script() și wp_localize_script() pentru a transmite id-ul și data-app-key necesare.

Am încercat câteva variante diferite de acest gen:

add_action('admin_enqueue_scripts', 'add_dropbox_stuff');
function add_dropbox_js() {
    // Înregistrăm scriptul Dropbox
    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() {
        // Înregistrăm și încărcăm scriptul
        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 este înlocuit cu cheia de aplicație corespunzătoare în codul meu. Aș aprecia orice îndrumare. Mulțumesc.

EDIT: Am încercat și cu jQuery, dar fără succes. Am încercat atât la încărcarea documentului cât și la document ready. Primesc eroarea {"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');
7
Comentarii

Ceea ce face wp_localize_script este să afișeze un obiect codat în json în html-ul paginii. Acest obiect este recunoscut de script și astfel îl poți folosi. Ceea ce ai nevoie este să adaugi niște atribute la tag-ul script, așa că wp_localize_script nu te poate ajuta.

gmazzap gmazzap
20 aug. 2013 23:10:40

G. M. are dreptate că wp_localize_script nu creează atribute pentru script. Dar este posibil să transmiți cheia aplicației direct în dropbox.js? Doar o presupunere, dar ai încercat array('appKey'=>"MY_APP_KEY")? Acesta este codul care preia cheia din atribut if(!Dropbox.appKey){Dropbox.appKey=(e=document.getElementById("dropboxjs"))!=null?e.getAttribute("data-app-key"):void 0}

epilektric epilektric
20 aug. 2013 23:21:21

Hei @epilektric Ai putea să pui asta într-un răspuns? Nu prea înțeleg cum să o implementez.

Andrew Bartel Andrew Bartel
21 aug. 2013 00:40:57

@epilektric cu wp_localize_script sigur poți transmite atribute către script. Nu știu dacă va funcționa sau nu, dar nu este o problemă legată de WordPress.

gmazzap gmazzap
21 aug. 2013 01:00:44

@AndrewBartel Nu sunt foarte sigur cum nici eu. Poate acest lucru te va ajuta. http://pippinsplugins.com/use-wp_localize_script-it-is-awesome/

epilektric epilektric
21 aug. 2013 02:39:07

Duplicat ... sau cel puțin foarte apropiat de unul. În prezent nu poate fi închis din cauza recompensei deschise.

kaiser kaiser
28 aug. 2013 14:34:00

Cred că aceasta este o dublură a acestei întrebări.

fuxia fuxia
28 aug. 2013 20:55:52
Arată celelalte 2 comentarii
Toate răspunsurile la întrebare 9
1
29

Începând cu WP 4.1.0, un nou filtru hook este disponibil pentru a realiza acest lucru într-un mod simplu:

script_loader_tag

Folosiți-l în felul următor:

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;
}
1 nov. 2016 01:17:16
Comentarii

se execută acest lucru înainte de orice stocare în cache a JS?

JoaMika JoaMika
22 aug. 2018 14:16:14
7
19

poți încerca să folosești hook-ul de filtrare script_loader_src, de exemplu:

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

Actualizare

tocmai am realizat că src este escapuit de esc_url, așa că am căutat puțin și am găsit filtrul clean_url pe care îl poți folosi pentru a returna valoarea cu id-ul și datele cheii aplicației:

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;
}
28 aug. 2013 00:57:21
Comentarii

Nu funcționează. Înainte de a fi afișat, rezultatul 'script_loader_src' este escapat, astfel încât ghilimelele sunt eliminate și ceea ce afișați este recunoscut ca parte a atributului 'src' și nu ca atribute separate. Acest cod va introduce în markup-ul HTML ceva de genul <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 gmazzap
28 aug. 2013 10:21:02

da, am actualizat răspunsul meu.

Bainternet Bainternet
28 aug. 2013 10:29:41

Excelent! +1, dar încă nu funcționează... Cred însă că o mică modificare ar rezolva problema.

gmazzap gmazzap
28 aug. 2013 10:42:20

Am testat codul după editare și funcționează. Mulțumesc că m-ai învățat ceva nou prin asta.

gmazzap gmazzap
28 aug. 2013 10:45:30

ma bucur că ai reușit să-l faci să funcționeze :)

Bainternet Bainternet
28 aug. 2013 10:45:58

Cred că OP va fi mai fericit decât noi doi. ;)

gmazzap gmazzap
28 aug. 2013 10:49:28

Mulțumesc @Bainternet pentru ajutor, am reușit să funcționeze folosind răspunsul tău.

Andrew Bartel Andrew Bartel
30 aug. 2013 02:40:47
Arată celelalte 2 comentarii
5

OK, se pare (după mine) că cu wp_enqueque_scripts nu este posibil să afișezi id-ul și cheia aplicației ca atribute ale tag-ului script.

Sunt sigur în proporție de 90%, deoarece WP_Dependencies nu este o clasă pe care o cunosc foarte bine, dar uitându-mă la cod mi se pare că nu este posibil.

Dar sunt sigur în proporție de 100% că utilizarea wp_localize_script este nefolositoare pentru scopul tău.

După cum am spus în comentariul meu de mai sus:

Ceea ce face wp_localize_script este să afișeze un obiect codificat json în html-ul paginii. Acest obiect este recunoscut de script și astfel îl poți utiliza.

Ceea ce nu am spus în comentariu este că obiectul codificat json are un nume arbitrar pe care tu îl decizi, de fapt, uitându-ne la sintaxă:

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

Obiectul numit $object_name ar putea fi utilizat de script deoarece se află în scope-ul global și este afișat în html-ul paginii.

Dar $object_name este un nume pe care tu îl decizi, deci poate fi orice.

Așadar, întreabă-te:

cum poate scriptul de pe serverul remote dropbox să folosească o variabilă despre care nu știe cum se numește?

Deci nu există niciun motiv să transmiți id-ul și/sau cheia aplicației către script cu wp_localize_script: trebuie doar să le afișezi ca atribute ale tag-ului script așa cum este menționat în documentația Dropbox API.

Nu sunt dezvoltator js, dar cred că scriptul dropbox face următoarele:

  1. obține toate elementele <script> html din pagină
  2. iterează prin ele căutându-l pe cel cu 'id' == 'dropboxjs'
  3. dacă acel script este găsit, verifică 'data-app-key' al acelui script
  4. verifică dacă cheia aplicației (dacă există) este una validă și te autorizează dacă da

Te rog, notează că nu știu asta sigur, doar presupun.

În acest fel, scriptul încărcat de pe serverul dropbox poate verifica cheia ta de aplicație într-un mod ușor pentru ei și ușor de implementat pentru tine.

Deoarece în prima propoziție am spus că este imposibil să afișezi id-ul și cheia aplicației în script folosind wp_enqueque_scripts, concluzia este că trebuie să le afișezi în markup într-un alt mod.

O metodă care nu miroase prea rău (când nu există alternative) este să folosești hook-ul wp_print_scripts pentru a afișa tag-ul script:

add_action('wp_print_scripts', 'do_dropbox_stuff');

function do_dropbox_stuff() {

  if ( ! is_admin() ) return; // doar pentru zona de administrare

  $app_key = 'CHEIA_MEA_DE_APLICAȚIE';

  // de ce să nu creezi o opțiune pentru asta?
  // $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>';

}
24 aug. 2013 04:14:29
Comentarii

Mulțumesc G.M., am reușit să funcționeze folosind asta. Sunt curios dacă există soluții alternative folosind hook-urile enqueue dar apreciez tot efortul pe care l-ai depus în răspuns.

Andrew Bartel Andrew Bartel
27 aug. 2013 00:59:10

@AndrewBartel Cred că nu există nicio modalitate de a folosi wp_enqueque_scripts în cazul tău, dar dacă găsești una, anunță-ne! :)

gmazzap gmazzap
27 aug. 2013 03:37:53

soluția ta poate crește încărcarea pe server deoarece faci direct o cerere http suplimentară prin folosirea echo. Soluția este bună dar nu este optimizată.

Faisal Shaikh Faisal Shaikh
17 iul. 2018 00:19:46

@FaisalShaikh poți să explici? Declarația echo nu face nicio cerere HTTP din câte îmi dau seama, iar funcția WordPress wp_enqueue_script folosește și ea echo (vezi https://core.trac.wordpress.org/browser/tags/4.9/src/wp-includes/class.wp-scripts.php#L343) Sigur, ai putea reduce numărul de cereri prin combinarea scriptului cu alte scripturi pe care le ai, dar: 1) în acest caz, scriptul există pe un server terț 2) cu HTTP 2 în zilele noastre, combinarea scripturilor ar reduce performanța, nu le-ar îmbunătăți. Poate îmi scapă ceva?

gmazzap gmazzap
17 iul. 2018 17:55:32

@gmazzap ai dreptate. de fapt, am o altă abordare pentru asta. Putem stoca acest script JS de la terți pe serverul nostru și nu cred că combinarea scripturilor ar putea crește încărcarea pe server.

Faisal Shaikh Faisal Shaikh
18 iul. 2018 14:22:08
2

Din răspunsul lui Bainternet de mai sus. Acest cod a funcționat pentru mine.

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

Editare: Singura diferență față de codul lui Bainternet este că am adăugat o condiție pentru a verifica dacă URL-ul scriptului este dropbox și este un fișier .js.

Ignor toate celelalte URL-uri și rescriu doar URL-ul dropbox.

17 feb. 2014 14:14:16
Comentarii

Te rog adaugă o explicație despre ce ai modificat și de ce ai făcut modificarea (sau a trebuit să o faci).

tfrommen tfrommen
17 feb. 2014 14:42:33

Știu că acesta este un răspuns vechi, dar în codul tău de mai sus, ai vrut să returnezi $original_url în interiorul instrucțiunii IF în loc de doar $url?

leromt leromt
12 mar. 2015 23:01:09
0

Mulțumesc pentru toate postările, au fost cu adevărat folositoare. Am creat propria mea versiune pentru a-i oferi o structură și a o face mai ușor de citit și actualizat. Folosește enqueue ca de obicei, folosește script pentru fișierele CSS cu un tag false la final pentru a se încărca în partea de sus. Deși probabil poate fi simplificat într-o oarecare măsură.

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;
}
9 mai 2018 00:39:10
2

Am făcut asta cu plugin-ul meu pentru eCard-uri și este foarte simplu.

Iată o copiere directă din 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>';

Observați că cheia API este transmisă printr-o opțiune.

26 aug. 2013 16:55:59
Comentarii

Cum este folosit $output? Afișat cu echo? Adăugat în wp_print_scripts()?

Andrew Bartel Andrew Bartel
27 aug. 2013 00:57:41

Este fie returnat, fie afișat cu echo, în funcție de funcția ta.

Ciprian Ciprian
27 aug. 2013 13:23:06
0

Am făcut o verificare în codul dropbox.js (versiunea 2) pentru a vedea ce se întâmplă și cum să rezolv această problemă în cel mai bun mod. După cum am descoperit, atributul data-app-key este folosit doar pentru a seta variabila Dropbox.appKey. Am reușit să setez variabila cu următoarea linie suplimentară.

Folosind exemplul JavaScript de pe pagina 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>

În codul meu, am setat Dropbox.appKey în fiecare loc în care fac referire la rutinele JavaScript ale Dropbox. Făcând acest lucru, am putut utiliza wp_enqueue_script() fără parametrii suplimentari.

7 apr. 2014 22:19:19
0

Există o metodă mai simplă de a face acest lucru

 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 );
8 dec. 2015 11:58:44
0

Sintaxă WordPress pentru script_loader_tag:

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

Pentru a adăuga orice atribut, puteți modifica $tag astfel:

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

Ceea ce va escapa corect URL-ul.

28 ian. 2018 12:57:09