Aggiunta di attributi aggiuntivi nel tag script per JS di terze parti


20

Mi sono imbattuto in questo quando ho provato a integrare il drop di Dropbox nell'API di selezione in un plug-in che sto scrivendo.

La documentazione dell'API indica di posizionare il seguente scripttag nella parte superiore del 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 bene, e in realtà funziona quando lo incollo direttamente nella pagina che viene chiamata nella sezione admin. Ma vorrei usare alcune varianti di wp_register_script (), wp_enqueue_script () e wp_localize_script () per passare l'id e la chiave-app-dati necessari.

Ho provato un paio di varianti diverse di questo:

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. Gradirei qualsiasi direzione. Grazie.

EDIT: Ho anche provato a farlo con un po 'di jquery, ma senza risultati. Provato sul caricamento del documento e sul documento pronto. Ottengo un {"errore": "App_key non valido"} ritorno.

$('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
Quello che wp_localize_scriptfa è stampare un oggetto con codifica json nell'output html della pagina. Questo oggetto è riconosciuto dallo script e quindi puoi usarlo. Ciò di cui hai bisogno è aggiungere alcuni attributi al tag script e quindi wp_localize_scriptnon puoi aiutarti.
gmazzap

2
GM ha ragione che wp_localize_scriptnon crea attributi di script. Ma è possibile passare la chiave dell'app direttamente in dropbox.js? Solo una supposizione ma hai provato array('appKey'=>"MY_APP_KEY")? Questo è il codice che prende la chiave dall'attributoif(!Dropbox.appKey){Dropbox.appKey=(e=document.getElementById("dropboxjs"))!=null?e.getAttribute("data-app-key"):void 0}
epilektric,

Ehi @epilektric Potresti metterlo in una risposta? Non sto proprio seguendo come implementarlo.
Andrew Bartel,

@epilektric con la wp_localize_scriptcertezza che puoi passare gli attributi allo script. Non so davvero se funzionerà o meno, tuttavia non si tratta di una questione relativa al worpress.
gmazzap

@AndrewBartel Non sono nemmeno sicuro di come. Forse questo aiuterà. pippinsplugins.com/use-wp_localize_script-it-is-awesome
epilektric

Risposte:


18

puoi provare a utilizzare il script_loader_srcgancio del filtro, 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";
}

Aggiornare

ho appena capito che l'src è sfuggito a esc_url, quindi guardando un po 'di più ho trovato il clean_urlfiltro che puoi usare per restituire il valore con i tuoi dati chiave ID e app:

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

Non funziona Prima di essere stampato, il risultato di 'script_loader_src' è sfuggito, quindi le virgolette vengono rimosse e ciò che l'output viene riconosciuto come parte dell'attributo 'src' e non come attributi separati. Questo codice inserirà 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

sì ho aggiornato la mia risposta.
Bainternet,

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

1
Penso che OP sarà più felice di te e di me. ;)
gmazzap

1
Grazie @Bainternet per il tuo aiuto, hai funzionato usando la tua risposta.
Andrew Bartel,

14

A partire da WP 4.1.0, è disponibile un nuovo gancio filtro 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;
}

viene eseguito prima che venga eseguita la memorizzazione nella cache JS?
Joanna Mikalai,

3

OK, mi sembra che con me wp_enqueque_scriptsnon sia possibile stampare l'id e la chiave dell'app come attributi del tag script.

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

Ma sono sicuro al 100% che l'utilizzo nonwp_localize_script è utile per il tuo ambito .

Come ho detto nel mio commento sopra:

Quello che fa wp_localize_script è stampare un oggetto con codifica json nell'output html della pagina. Questo oggetto è riconosciuto dallo script e quindi puoi usarlo.

Quello che non ho detto nel commento è che l'oggetto con codifica json come nome arbitrario che decidi, infatti, guardando la sintassi:

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

L'oggetto denominato $object_name potrebbe essere utilizzato dallo script perché è nell'ambito globale e stampato nell'html della pagina.

Ma il $object_nameè un nome che si decide, quindi può essere tutto .

Quindi chiediti:

come lo script nel server di dropbox remoto può utilizzare una variabile che non sanno come viene chiamata?

Quindi non c'è alcun motivo per passare id e / o chiave app allo script con wp_localize_script: devi solo stamparli come attributi dei tag dello script, come si dice nei documenti API di Dropbox.

Non sono uno sviluppatore js, ma penso che lo script dropbox faccia:

  1. ottieni tutti gli <script>elementi html nella pagina
  2. scorrili cercando quello con "id" == "dropboxjs"
  3. se viene trovato quello script, guardando la 'chiave-app-dati' di quello script
  4. controlla se quella chiave dell'app (se presente) è valida e ti autorizza in tal caso

Per favore, nota che non lo so per certo, sto solo indovinando .

In questo modo, lo script caricato dal server dropbox può controllare la chiave della tua app in modo che sia facile per loro e facile da implementare per te.

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

Un modo che non ha un odore eccessivo (quando non ci sono alternative) è usare l' wp_print_scriptshook per stampare il tag dello 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>';

}

Grazie GM, l'ho fatto funzionare usando questo. Sono interessato a vedere se ci sono soluzioni alternative usando gli hook di accodamento ma apprezzo tutto il pensiero che hai messo nella risposta.
Andrew Bartel,

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

la tua soluzione può aumentare il carico sul server mentre stai facendo direttamente un'altra richiesta http facendo eco. La soluzione è buona ma non ottimizzata.
Faisal Shaikh,

@FaisalShaikh ti interessa spiegare? La echodichiarazione non ha alcuna richiesta HTTP per quanto posso dire, e anche WordPress wp_enqueue_scriptfa un'eco (vedi core.trac.wordpress.org/browser/tags/4.9/src/wp-includes/… ) Sicuramente potresti ridurre il numero di richieste combinando lo script con qualche altro script che hai ma: 1) gli script esistono nel server di terze parti in questo caso 2) con HTTP 2 al giorno d'oggi la combinazione dello script ridurrebbe le prestazioni, non aumentarle. Quindi forse mi manca qualcosa?
gmazzap

@gmazzap hai ragione. in realtà, ho un modo diverso di farlo. Siamo in grado di memorizzare questa js di terza parte nel nostro server e non credo davvero che la combinazione di script possa aumentare il carico sul server.
Faisal Shaikh,

1

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 Bainternet è che ho aggiunto una condizione per verificare se l'URL dello script è dropbox ed è un file .js.

Sto ignorando tutti gli altri URL e riscrivo l'URL della casella personale.


2
Si prega di aggiungere alcune spiegazioni su ciò che si modifica e sul perché è stato modificato (o è stato necessario modificarlo).
martedì

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

1

Ho fatto qualche controllo nel codice dropbox.js (v2) per vedere cosa stava succedendo e come risolverlo al meglio. A quanto pare, la chiave dell'app per i dati viene utilizzata solo per impostare la variabile Dropbox.appKey. Sono in grado di impostare la variabile con la seguente riga aggiuntiva.

Utilizzando l'esempio javascript nella 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>

Nel mio codice ho impostato Dropbox.appKey in ogni luogo in cui faccio riferimento alle routine javascript di Dropbox. In questo modo mi ha permesso di utilizzare wp_enqueue_script () senza i parametri aggiuntivi.


0

L'ho fatto con il mio plugin eCards ed è davvero semplice.

Ecco una copia / incolla 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>';

Si noti che la chiave API viene passata tramite un'opzione.


Come viene utilizzato $ output? Eco? Aggiungi a wp_print_scripts ()?
Andrew Bartel,

Viene restituito o ripetuto, a seconda della funzione.
Ciprian,

0

C'è un modo più semplice per farlo

 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

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

Che sfuggirà correttamente all'URL.


0

Grazie per tutte le pubblicazioni, mi hanno davvero aiutato. Ho fatto il roll della mia versione per darle una struttura e facilitare la lettura e l'aggiornamento. Usa enqueue come di consueto, usa lo script per i file CSS con un tag falso alla fine in modo che si carichi in alto. Anche se probabilmente può essere semplificato in qualche modo.

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;
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.