web-dev-qa-db-fra.com

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

Je me suis heurté à cela en essayant d'intégrer le drop in API de sélecteur de Dropbox à un plugin que j'écris.

La documentation de l'API vous demande de placer la balise script 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 ça marche 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é data-app nécessaires.

J'ai essayé plusieurs variantes 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: Également essayé de le faire avec quelques jQuery, mais en vain. Essayé sur le chargement de document et sur le document prêt. Je reçois un {"erreur": "clé_application non valide"}.

$('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');
18
Andrew Bartel

vous pouvez essayer d'utiliser le crochet de filtre script_loader_src, 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";
}

Mettre à jour

je viens de comprendre moi-même que esc_url échappe au code src. Je cherche donc un peu plus. J'ai trouvé le filtre clean_url que vous pouvez utiliser pour renvoyer la valeur avec votre identifiant et vos données de clé d'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;
}
17
Bainternet

Depuis WP 4.1.0, un nouveau crochet de filtrage 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;
}
10
ClemC

OK, il me semble que, avec wp_enqueque_scripts, il n’est pas possible d’imprimer l’ID et la clé d’application en tant qu’attributs de balise de script.

Je suis sûr à 90%, parce que WP_Dependencies n'est pas une classe que je connais bien, mais en regardant le code, cela ne me semble pas possible.

Mais à 100%, je suis sûr que l'utilisation de wp_localize_script est inutile pour votre champ d'application.

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

Ce que fait wp_localize_script, c'est imprimer un objet encodé en 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é en json est 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 figure dans l'étendue globale et est imprimé dans le code HTML de la page.

Mais le $object_name est un nom que you décide, donc il peut s'agir de everything .

Alors demandez à vous-même:

_ {comment le script du serveur Dropbox distant peut-il utiliser une variable dont ils ne savent pas comment s'appelle?} _

Donc, il y a aucune raison du tout de transmettre l'id et/ou la clé d'application au script avec wp_localize_script: il suffit de les imprimer en tant qu'attributs de balise de script comme indiqué dans la documentation de l'API de Dropbox. .

Je ne suis pas un développeur js, mais je pense que le script de Dropbox est:

  1. obtenir tous les éléments <script> html dans la page
  2. parcourez-les à la recherche de celui avec '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 avec certitude, je ne fais que deviner}.

De cette manière, le script chargé à partir du serveur Dropbox peut vérifier votre clé d'application de manière simple et facile à mettre en œuvre pour vous.

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

Une façon de ne pas trop sentir (quand il n'y a pas d'alternative) est d'utiliser wp_print_scripts hook 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>';

}
3
gmazzap

J'ai vérifié dans le code dropbox.js (v2) pour voir ce qui se passait et comment le résoudre au mieux. En fin de compte, la clé data-app est uniquement utilisée pour définir la variable Dropbox.appKey. J'ai pu définir la variable avec la ligne supplémentaire suivante.

Utilisation de l’exemple javascript de 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, je place Dropbox.appKey à chaque endroit où je fais référence aux routines JavaScript de Dropbox. Cela m'a permis d'utiliser wp_enqueue_script () sans les paramètres supplémentaires.

1
Michaelkay

De 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 par rapport au code Bainternet est que j’ai ajouté une condition pour vérifier si l’URL du script est dropbox et qu’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.

1
user2914440

Je l'ai fait avec mon plugin eCards et c'est très 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.

0
Ciprian

Syntaxe Wordpress pour script_loader_tag :

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

Pour ajouter n'importe quel 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;
}

Ce qui échappera correctement à l'URL.

0
JackLinkers

Merci pour tous les messages, ils ont vraiment aidé. J'ai fait rouler ma propre version pour la structurer 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 balise false à la fin pour qu'elle se charge en haut. Bien que cela 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;
}
0
wpNewby

Il y a 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 );
0
Max Kondrachuk