Ajout d'attributs supplémentaires dans la balise de script pour JS tiers

20

Je suis tombé sur cela lors de la tentative d'intégration de l' API de sélection de Dropbox à un plugin que j'écris.

La documentation de l'API vous demande de placer la scriptbalise suivante en haut de votre fichier:

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

Tout va bien et bon, et cela fonctionne réellement quand je le colle directement dans la page appelée dans la section admin. Mais, j'aimerais utiliser une variante de wp_register_script (), wp_enqueue_script () et wp_localize_script () pour transmettre l'ID et la clé d'application de données nécessaires.

J'ai essayé quelques variantes différentes de ceci:

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

Et:

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 est remplacé par la clé d'application appropriée dans mon code. J'apprécierais n'importe quelle direction. Merci.

EDIT: J'ai également essayé de le faire avec un peu de jquery, mais en vain. Je l'ai essayé au chargement du document et sur le document prêt. J'obtiens un {"error": "Invalid app_key"} return.

$('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
la source
2
Qu'est wp_localize_script- ce que c'est d'imprimer un objet codé json dans la sortie html de la page. Cet objet est reconnu par le script et vous pouvez donc l'utiliser. Ce dont vous avez besoin est d'ajouter des attributs à la balise de script et wp_localize_scriptne peut donc pas vous aider.
gmazzap
2
GM est correct qui wp_localize_scriptne crée pas d'attributs de script. Mais est-il possible de passer la clé de l'application directement dans dropbox.js? Juste une supposition, mais avez-vous essayé array('appKey'=>"MY_APP_KEY")? C'est le code qui récupère la clé de l'attributif(!Dropbox.appKey){Dropbox.appKey=(e=document.getElementById("dropboxjs"))!=null?e.getAttribute("data-app-key"):void 0}
epilektric
Hey @epilektric Pourriez-vous mettre cela dans une réponse? Je ne suis pas tout à fait en train de suivre comment l'implémenter.
Andrew Bartel
@epilektric avec la wp_localize_scriptcertitude que vous pouvez passer des attributs au script. Je ne sais vraiment pas si cela fonctionnera ou non, mais ce n'est pas une question liée au stress.
gmazzap
@AndrewBartel, je ne sais pas trop comment. Peut-être que cela vous aidera. pippinsplugins.com/use-wp_localize_script-it-is-awesome
epilektric

Réponses:

18

vous pouvez essayer d'utiliser le script_loader_srccrochet du filtre, par exemple:

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

Mise à jour

je viens de comprendre que le src est échappé par esc_url, donc en regardant un peu plus, j'ai trouvé le clean_urlfiltre que vous pouvez utiliser pour renvoyer la valeur avec votre identifiant et les données clés de l'application:

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
la source
Ça ne marche pas. Avant d'être imprimé, le résultat de 'script_loader_src' est échappé, donc les guillemets sont supprimés et ce que vous sortez est reconnu comme faisant partie de l'attribut 'src' et non comme des attributs séparés. Ce code mettra dans le balisage html quelque chose comme<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
oui j'ai mis à jour ma réponse.
Bainternet
3
J'ai testé le code après ma modification et cela fonctionne. Merci de m'avoir appris quelque chose avec ça.
gmazzap
1
Je pense que OP sera plus heureuse que toi et moi. ;)
gmazzap
1
Merci @Bainternet pour votre aide, faites-le fonctionner en utilisant votre réponse.
Andrew Bartel
14

Depuis WP 4.1.0, un nouveau crochet de filtre est disponible pour y parvenir facilement:

script_loader_tag

Utilisez-le de cette façon:

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
la source
cela s'exécute-t-il avant toute mise en cache JS?
Joanna Mikalai
3

OK, il me semble (avec) que ce wp_enqueque_scriptsn'est pas possible d'imprimer l'identifiant et la clé d'application en tant qu'attributs de balise de script.

Je suis sûr à 90%, car WP_Dependencies n'est pas un cours que je connais bien, mais en regardant le code ça ne me semble pas possible.

Mais je suis sûr à 100% que l'utilisation wp_localize_scriptn'est pas utile pour votre portée .

Comme je l'ai dit dans mon commentaire ci-dessus:

Ce que wp_localize_script fait est d'imprimer un objet codé json dans la sortie html de la page. Cet objet est reconnu par le script et vous pouvez donc l'utiliser.

Ce que je n'ai pas dit dans le commentaire, c'est que l'objet codé json comme un nom arbitraire que vous décidez, en fait, en regardant la syntaxe:

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

L'objet nommé $object_name pourrait être utilisé par le script car il est dans la portée globale et imprimé dans le html de la page.

Mais $object_namec'est un nom que vous décidez, donc ça peut être tout .

Alors demandez-vous:

comment le script dans le serveur de dropbox distant peut utiliser une variable dont ils ne savent pas comment s'appelle?

Il n'y a donc aucune raison de transmettre l'identifiant et / ou la clé d'application au script avec wp_localize_script: il vous suffit de les imprimer en tant qu'attributs de balise de script comme cela est dit dans les documents de l'API Dropbox.

Je ne suis pas développeur js, mais je pense que le script dropbox fait:

  1. Avoir tout <script> éléments html de la page
  2. parcourez-les à la recherche de celui avec le 'id' == 'dropboxjs'
  3. si ce script est trouvé, en regardant la «clé d'application de données» de ce script
  4. vérifier si cette clé d'application (si présente) est valide et vous autoriser si c'est le cas

S'il vous plaît, notez que je ne le sais pas, je suppose .

De cette façon, le script chargé à partir du serveur de dropbox peut vérifier la clé de votre application d'une manière simple pour eux et facile à implémenter pour vous.

Parce que dans la première phrase, j'ai dit qu'il n'était pas possible d'imprimer l'identifiant et la clé d'application dans le script en utilisantwp_enqueque_scripts , la morale de l'histoire est que vous devez les imprimer dans le balisage d'une autre manière.

Une façon qui ne sent pas trop (quand il n'y a pas d'alternative) est d'utiliser le wp_print_scriptshook pour imprimer la balise de 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>';

}
gmazzap
la source
Merci GM, je l'ai fait fonctionner avec ça. Je suis intéressé de voir s'il existe des solutions alternatives utilisant les crochets de mise en file d'attente, mais j'apprécie toute la réflexion que vous avez apportée à la réponse.
Andrew Bartel
@AndrewBartel Je pense qu'il n'y a aucun moyen d'utiliser wp_enqueque_scripts dans votre cas, mais si vous en trouvez un, faites-le nous savoir! :)
gmazzap
votre solution peut augmenter la charge sur le serveur car vous effectuez directement 1 demande http supplémentaire en faisant écho. La solution est bonne mais pas optimisée.
Faisal Shaikh
@FaisalShaikh tiens à expliquer? La echodéclaration ne fait aucune demande HTTP pour autant que je sache , et WordPress wp_enqueue_scriptfait également un écho (voir core.trac.wordpress.org/browser/tags/4.9/src/wp-includes/… ) Vous pourriez sûrement réduire le nombre de requêtes en combinant le script avec un autre script que vous avez mais: 1) les scripts existent dans un serveur tiers dans ce cas 2) avec HTTP 2 de nos jours, la combinaison du script réduirait les performances, pas les augmenterait. Alors peut-être que je manque quelque chose?
gmazzap
@gmazzap vous avez raison. en fait, j'ai une façon différente de le faire. Nous pouvons stocker cette 3e partie js sur notre serveur et je ne pense vraiment pas que la combinaison de scripts puisse augmenter la charge sur le serveur.
Faisal Shaikh
1

D'après la réponse de Bainternet ci-dessus. Ce code a fonctionné pour moi.

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

Edit: La seule différence avec le code Bainternet est que j'ai ajouté une condition pour vérifier si l'URL du script est dropbox et s'il s'agit d'un fichier .js.

J'ignore toutes les autres URL et réécris l'URL de la boîte de dépôt.

user2914440
la source
2
Veuillez ajouter quelques explications sur ce que vous changez et pourquoi vous l'avez changé (ou avez dû le changer).
tfrommen
Je sais que c'est une ancienne réponse, mais dans votre code ci-dessus, vouliez-vous renvoyer $ original_url à l'intérieur de l'instruction IF au lieu de simplement $ url?
leromt
1

J'ai fait quelques vérifications dans le code dropbox.js (v2) pour voir ce qui se passait et comment le résoudre au mieux. Il s'avère que la clé d'application de données n'est utilisée que pour définir la variable Dropbox.appKey. J'ai pu définir la variable avec la ligne supplémentaire suivante.

En utilisant l'exemple javascript sur la page 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>

Dans mon code, j'ai défini Dropbox.appKey à chaque endroit où je fais référence aux routines javascript Dropbox. Faire cela m'a permis d'utiliser wp_enqueue_script () sans les paramètres supplémentaires.

Michaelkay
la source
0

Je l'ai fait avec mon plugin eCards et c'est vraiment simple.

Voici un copier / coller direct du 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>';

Notez que la clé API est transmise via une option.

Ciprian
la source
Comment est utilisé $ output? Écho? Ajouter à wp_print_scripts ()?
Andrew Bartel
Il est soit renvoyé, soit renvoyé, selon votre fonction.
Ciprian
0

Il existe un moyen plus simple de le faire

 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
la source
0

Syntaxe Wordpress pour script_loader_tag :

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

Pour ajouter un attribut, vous pouvez modifier votre $ tag de cette façon:

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

Qui échappera correctement à l'URL.

JackLinkers
la source
0

Merci pour toutes les publications, ils ont vraiment aidé. J'ai fait rouler ma propre version pour lui donner une certaine structure et la rendre plus facile à lire et à mettre à jour. Utilisez la mise en file d'attente comme d'habitude, utilisez le script pour les fichiers CSS avec une fausse balise à la fin afin qu'elle se charge en haut. Bien qu'il puisse probablement être quelque peu simplifié.

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
la source