Aggiungere Attributi Aggiuntivi nel Tag Script per JS di Terze Parti

20 ago 2013, 22:39:36
Visualizzazioni: 29.6K
Voti: 29

Mi sono imbattuto in questo problema quando ho cercato di integrare l'API drop-in chooser di Dropbox in un plugin che sto sviluppando.

La documentazione dell'API ti indica di inserire il seguente tag script nella parte superiore del tuo file:

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

Tutto bene e funziona quando lo incollo direttamente nella pagina che viene chiamata nella sezione admin. Tuttavia, vorrei utilizzare qualche variante di wp_register_script(), wp_enqueue_script() e wp_localize_script() per passare l'id e il data-app-key necessari.

Ho provato diverse varianti di questo codice:

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

E:

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 viene sostituito con la chiave dell'applicazione appropriata nel mio codice. Apprezzerei qualsiasi indicazione. Grazie.

MODIFICA: Ho anche provato a farlo con jQuery, ma senza successo. L'ho provato sia al caricamento del documento che quando il documento è pronto. Ottengo un errore {"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
Commenti

Quello che fa wp_localize_script è stampare un oggetto codificato in json nell'output html della pagina. Questo oggetto viene riconosciuto dallo script e quindi puoi usarlo. Ciò di cui hai bisogno è aggiungere alcuni attributi al tag script, e quindi wp_localize_script non può aiutarti.

gmazzap gmazzap
20 ago 2013 23:10:40

G. M. ha ragione sul fatto che wp_localize_script non crea attributi di script. Ma è possibile passare la chiave dell'app direttamente in dropbox.js? Solo un'ipotesi ma hai provato array('appKey'=>"LA_MIA_CHIAVE_APP")? Questo è il codice che prende la chiave dall'attributo if(!Dropbox.appKey){Dropbox.appKey=(e=document.getElementById("dropboxjs"))!=null?e.getAttribute("data-app-key"):void 0}

epilektric epilektric
20 ago 2013 23:21:21

Ciao @epilektric Potresti metterlo in una risposta? Non sto capendo bene come implementarlo.

Andrew Bartel Andrew Bartel
21 ago 2013 00:40:57

@epilektric con wp_localize_script puoi sicuramente passare attributi allo script. Non so se funzionerà o meno, comunque non è una questione relativa a WordPress.

gmazzap gmazzap
21 ago 2013 01:00:44

@AndrewBartel Non sono proprio sicuro di come fare. Forse questo può aiutare. http://pippinsplugins.com/use-wp_localize_script-it-is-awesome/

epilektric epilektric
21 ago 2013 02:39:07

Duplicato ... o almeno molto simile. Attualmente non può essere chiuso a causa della taglia aperta.

kaiser kaiser
28 ago 2013 14:34:00

Penso che questo sia un duplicato di questa domanda.

fuxia fuxia
28 ago 2013 20:55:52
Mostra i restanti 2 commenti
Tutte le risposte alla domanda 9
1
29

Da WP 4.1.0, è disponibile un nuovo hook filter per raggiungere questo obiettivo facilmente:

script_loader_tag

Usalo in questo modo:

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
Commenti

questo viene eseguito prima che avvenga qualsiasi memorizzazione nella cache JS?

JoaMika JoaMika
22 ago 2018 14:16:14
7
19

puoi provare a utilizzare l'hook filter script_loader_src ad esempio:

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

Aggiornamento

ho appena scoperto che lo src viene filtrato da esc_url, quindi cercando un po' ho trovato il filtro clean_url che puoi utilizzare per restituire il valore con il tuo id e i dati della app key:

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 ago 2013 00:57:21
Commenti

Non funziona. Prima di essere stampato, il risultato di 'script_loader_src' viene escapato, quindi gli apici vengono rimossi e ciò che viene outputtato viene riconosciuto come parte dell'attributo 'src' e non come attributi separati. Questo codice produrrà nel markup HTML qualcosa come <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 ago 2013 10:21:02

sì ho aggiornato la mia risposta.

Bainternet Bainternet
28 ago 2013 10:29:41

Ottimo! +1, ma ancora non funziona... Penso però che una piccola modifica possa farlo funzionare.

gmazzap gmazzap
28 ago 2013 10:42:20

Ho testato il codice dopo la mia modifica e funziona. Grazie per avermi insegnato qualcosa con questo.

gmazzap gmazzap
28 ago 2013 10:45:30

sono contento che tu l'abbia fatto funzionare :)

Bainternet Bainternet
28 ago 2013 10:45:58

Penso che l'OP sarà più felice di te e me. ;)

gmazzap gmazzap
28 ago 2013 10:49:28

Grazie @Bainternet per il tuo aiuto, ho risolto utilizzando la tua risposta.

Andrew Bartel Andrew Bartel
30 ago 2013 02:40:47
Mostra i restanti 2 commenti
5

OK, mi sembra (a me) che con wp_enqueque_scripts non sia possibile stampare l'id e la app key come attributi del tag script.

Sono sicuro al 90%, perché WP_Dependencies non è una classe che conosco bene, ma guardando il codice mi sembra non sia possibile.

Ma sono sicuro al 100% che usare wp_localize_script è inutile per il tuo scopo.

Come ho detto nel mio commento sopra:

Ciò che wp_localize_script fa è stampare un oggetto json-encoded nell'html della pagina. Questo oggetto è riconosciuto dallo script e quindi puoi usarlo.

Quello che non ho detto nel commento è che l'oggetto json-encoded ha un nome arbitrario che decidi tu, infatti, guardando la sintassi:

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

L'oggetto chiamato $object_name potrebbe essere usato dallo script perché è nello scope globale e stampato nell'html della pagina.

Ma il $object_name è un nome che decidi tu, quindi può essere qualsiasi cosa.

Quindi chiediti:

come può lo script sul server remoto di Dropbox utilizzare una variabile di cui non conosce il nome?

Quindi non c'è alcun motivo per passare id e/o app key allo script con wp_localize_script: devi semplicemente stamparli come attributi del tag script come indicato nella documentazione delle API di Dropbox.

Non sono uno sviluppatore js, ma penso che lo script di Dropbox faccia questo:

  1. ottiene tutti gli elementi <script> html nella pagina
  2. li cicla cercando quello con 'id' == 'dropboxjs'
  3. se trova quello script, guarda il 'data-app-key' di quello script
  4. verifica se quella app key (se presente) è valida e ti autorizza se è così

Per favore, nota che non lo so con certezza, sto solo ipotizzando.

In questo modo, lo script caricato dal server di Dropbox può verificare la tua app key in un modo che è semplice per loro e facile da implementare per te.

Poiché nella prima frase ho detto che è non possibile stampare l'id e la app key nello script usando wp_enqueque_scripts, la morale della storia è che devi stamparli nel markup in un altro modo.

Un modo che non puzza troppo (quando non ci sono alternative) è usare l'hook wp_print_scripts per stampare il tag script:

add_action('wp_print_scripts', 'do_dropbox_stuff');

function do_dropbox_stuff() {

  if ( ! is_admin() ) return; // solo per l'area admin

  $app_key = 'MY_APP_KEY';

  // perché non creare un'opzione per questo?
  // $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 ago 2013 04:14:29
Commenti

Grazie G.M., ho fatto funzionare tutto usando questo metodo. Sono curioso di vedere se esistono soluzioni alternative utilizzando gli hook enqueue ma apprezzo molto tutto il pensiero che hai messo nella risposta.

Andrew Bartel Andrew Bartel
27 ago 2013 00:59:10

@AndrewBartel Penso che non ci sia modo di usare wp_enqueque_scripts nel tuo caso, ma se ne trovi uno, faccelo sapere! :)

gmazzap gmazzap
27 ago 2013 03:37:53

la tua soluzione può aumentare il carico sul server poiché stai effettuando direttamente 1 richiesta HTTP in più usando echo. La soluzione è buona ma non ottimizzata.

Faisal Shaikh Faisal Shaikh
17 lug 2018 00:19:46

@FaisalShaikh puoi spiegare? L'istruzione echo non effettua alcuna richiesta HTTP per quanto ne so, e anche la funzione WordPress wp_enqueue_script fa un echo (vedi https://core.trac.wordpress.org/browser/tags/4.9/src/wp-includes/class.wp-scripts.php#L343) Certamente potresti ridurre il numero di richieste combinando lo script con qualche altro script che hai ma: 1) in questo caso lo script esiste su un server di terze parti 2) con HTTP 2 al giorno d'oggi combinare gli script ridurrebbe le prestazioni, non le aumenterebbe. Quindi forse mi sfugge qualcosa?

gmazzap gmazzap
17 lug 2018 17:55:32

@gmazzap hai ragione. in realtà, ho un modo diverso per farlo. Possiamo memorizzare questo js di terze parti sul nostro server e non credo davvero che combinare gli script possa aumentare il carico sul server.

Faisal Shaikh Faisal Shaikh
18 lug 2018 14:22:08
2

Dalla risposta di Bainternet sopra. Questo codice ha funzionato per me.

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

Modifica: L'unica differenza rispetto al codice di Bainternet è che ho aggiunto una condizione per verificare se l'URL dello script è di dropbox e se è un file .js.

Sto ignorando tutti gli altri URL e riscrivendo solo l'URL di dropbox.

17 feb 2014 14:14:16
Commenti

Per favore aggiungi una spiegazione su cosa hai cambiato e perché l'hai modificato (o hai dovuto modificarlo).

tfrommen tfrommen
17 feb 2014 14:42:33

So che questa è una vecchia risposta ma nel tuo codice sopra, intendevi restituire $original_url all'interno dell'istruzione IF invece di solo $url?

leromt leromt
12 mar 2015 23:01:09
0

Grazie per tutti i post, sono stati davvero utili. Ho creato la mia versione per dargli una struttura e renderlo più facile da leggere e aggiornare. Usa enqueue come al solito, utilizza script per i file CSS con un tag false alla fine in modo che venga caricato in cima. Anche se probabilmente può essere semplificato ulteriormente.

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 mag 2018 00:39:10
2

Ho implementato questa funzionalità con il mio plugin eCards ed è davvero semplice.

Ecco una copia diretta dal 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>';

Nota che la chiave API viene passata tramite un'opzione.

26 ago 2013 16:55:59
Commenti

Come viene utilizzato $output? Stampato con echo? Aggiunto a wp_print_scripts()?

Andrew Bartel Andrew Bartel
27 ago 2013 00:57:41

Può essere restituito o stampato con echo, dipende dalla tua funzione.

Ciprian Ciprian
27 ago 2013 13:23:06
0

Ho esaminato il codice dropbox.js (v2) per capire cosa stesse succedendo e trovare la soluzione migliore. È emerso che il data-app-key viene utilizzato solo per impostare la variabile Dropbox.appKey. Sono riuscito a impostare la variabile con la seguente riga aggiuntiva.

Utilizzando l'esempio JavaScript dalla pagina di 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>

Nel mio codice ho impostato Dropbox.appKey in ogni punto in cui faccio riferimento alle routine JavaScript di Dropbox. Questo mi ha permesso di usare wp_enqueue_script() senza i parametri aggiuntivi.

7 apr 2014 22:19:19
0

C'è un modo più semplice per farlo

/**
 * Carica gli attributi per lo script Dropbox
 * @param string $url L'URL dello script da elaborare
 * @return string L'URL modificato con gli attributi aggiuntivi
 */
function load_attributes( $url ){
    if ( 'https://www.dropbox.com/static/api/1/dropins.js' === $url ){
        return "$url' id='dropboxjs' data-app-key='CHIAVE_APP_MIA";
    }

    return $url;
}

// Aggiunge il filtro per modificare l'URL
add_filter( 'clean_url', 'load_attributes', 11, 1 );
8 dic 2015 11:58:44
0

Sintassi WordPress per script_loader_tag :

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

Per aggiungere qualsiasi attributo, puoi modificare il tuo $tag in questo modo:

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

Questo metodo eseguirà correttamente l'escape dell'URL.

28 gen 2018 12:57:09