Hinzufügen zusätzlicher Attribute im Script-Tag für JS von Drittanbietern

20

Ich bin darauf gestoßen , als ich versucht habe, die Drop-In-Auswahl-API von Dropbox in ein Plugin zu integrieren, das ich gerade schreibe.

In der API-Dokumentation werden Sie aufgefordert, das folgende scriptTag am Anfang Ihrer Datei einzufügen:

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

Alles in Ordnung und gut, und es funktioniert tatsächlich, wenn ich es direkt in die Seite einfügen, die im Admin-Bereich aufgerufen wird. Ich möchte jedoch eine Variation von wp_register_script (), wp_enqueue_script () und wp_localize_script () verwenden, um die erforderliche ID und den Daten-App-Schlüssel zu übergeben.

Ich habe ein paar verschiedene Variationen davon ausprobiert:

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

Und:

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 wird in meinem Code durch den entsprechenden Anwendungsschlüssel ersetzt. Würde mich über jede Richtung freuen. Vielen Dank.

EDIT: Auch versucht, es mit etwas jquery zu tun, aber ohne Erfolg. Versuchte es auf Dokument laden und auf Dokument bereit. Ich erhalte die Meldung {"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');
Andrew Bartel
quelle
2
Was wp_localize_scripttun, ist ein json-codiertes Objekt in der HTML-Ausgabe der Seite zu drucken. Dieses Objekt wird vom Skript erkannt und kann verwendet werden. Sie müssen dem Skript-Tag einige Attribute hinzufügen und wp_localize_scriptkönnen Ihnen daher nicht helfen.
gmazzap
2
GM ist korrekt und erstellt wp_localize_scriptkeine Skriptattribute. Aber ist es möglich, den App-Schlüssel direkt an dropbox.js zu übergeben? Nur eine Vermutung, aber haben Sie es versucht array('appKey'=>"MY_APP_KEY")? Dies ist der Code, der den Schlüssel aus dem Attribute packtif(!Dropbox.appKey){Dropbox.appKey=(e=document.getElementById("dropboxjs"))!=null?e.getAttribute("data-app-key"):void 0}
epilektric
Hey @epilektric Könnten Sie das in eine Antwort setzen? Ich verfolge nicht ganz, wie ich es implementieren soll.
Andrew Bartel
@epilektric mit wp_localize_scriptSicherheit können Sie Attribute an das Skript übergeben. Ich weiß wirklich nicht, ob das funktionieren wird oder nicht, es ist jedoch keine worpress-bezogene Angelegenheit.
gmazzap
@ AndrewBartel Ich bin mir auch nicht sicher, wie. Vielleicht hilft das ja. pippinsplugins.com/use-wp_localize_script-it-is-awesome
epilektric

Antworten:

18

Sie können versuchen, den script_loader_srcFilterhaken zu verwenden, zB:

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

Aktualisieren

Ich habe gerade selbst herausgefunden, dass esc_url das src-Kommando enthält, also habe ich bei genauerem Hinsehen den clean_urlFilter gefunden, mit dem Sie den Wert mit Ihrer ID und Ihren App-Schlüsseldaten zurückgeben können:

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
quelle
Es funktioniert nicht Vor dem Drucken wird das Ergebnis von 'script_loader_src' maskiert, sodass Anführungszeichen entfernt werden und das, was Sie ausgeben, als Teil des Attributs 'src' und nicht als separate Attribute erkannt wird. Dieser Code wird in das HTML-Markup so etwas wie<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
Ja, ich habe meine Antwort aktualisiert.
Bainternet
3
Ich habe den Code nach der Bearbeitung getestet und er funktioniert. Danke, dass du mir damit etwas beigebracht hast.
gmazzap
1
Ich denke, OP wird glücklicher sein als du und ich. ;)
gmazzap
1
Vielen Dank an @Bainternet für Ihre Hilfe.
Andrew Bartel
14

Seit WP 4.1.0 ist ein neuer Filterhaken verfügbar, um dies einfach zu erreichen:

script_loader_tag

Verwenden Sie es so:

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
quelle
wird dies ausgeführt, bevor ein JS-Caching stattfindet?
Joanna Mikalai
3

OK, es scheint mir, dass es mit wp_enqueque_scriptsnicht möglich ist , die ID und den App-Schlüssel als Script-Tag-Attribute auszudrucken.

Ich bin mir zu 90% sicher, da WP_Dependencieses sich nicht um eine Klasse handelt, die ich gut kenne, sondern um den Code. Es scheint mir nicht möglich zu sein.

Aber ich bin sicher , dass bei 100% , dass die Verwendung wp_localize_scriptist für Ihren Anwendungsbereich nicht sinnvoll .

Wie ich oben in meinem Kommentar sagte:

Wp_localize_script gibt ein json-codiertes Objekt in der HTML-Ausgabe der Seite aus. Dieses Objekt wird vom Skript erkannt und kann verwendet werden.

Was ich in dem Kommentar nicht gesagt habe, ist, dass das json-codierte Objekt ein willkürlicher Name ist, den Sie in der Tat anhand der Syntax bestimmen:

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

Das Objekt mit dem Namen $object_name könnte durch das Skript verwendet werden , da im globalen Bereich und in dem HTML - Code der Seite gedruckt.

Aber den $object_nameNamen entscheidest du , also kann es alles sein .

Fragen Sie sich also:

Wie kann das Skript auf dem Remote-Dropbox-Server eine Variable verwenden, von der sie nicht wissen, wie sie aufgerufen wird?

Es gibt also überhaupt keinen Grund , ID und / oder App-Schlüssel an das Skript zu übergeben wp_localize_script: Sie müssen sie nur als Skript-Tag-Attribute drucken, wie in Dropbox API-Dokumenten beschrieben.

Ich bin kein JS-Entwickler, aber ich denke, was Dropbox-Skript tut, ist:

  1. Holen Sie sich alle <script>HTML-Elemente auf der Seite
  2. radle durch sie und suche den mit der 'id' == 'dropboxjs'
  3. Wenn dieses Skript gefunden wird, sehen Sie sich den 'Daten-App-Schlüssel' dieses Skripts an
  4. Überprüfen Sie, ob dieser App-Schlüssel (falls vorhanden) gültig ist, und autorisieren Sie Sie, falls dies der Fall ist

Bitte beachten Sie, dass ich das nicht sicher weiß, ich rate nur .

Auf diese Weise kann das vom Dropbox-Server geladene Skript Ihren App-Schlüssel auf eine Weise überprüfen, die für sie einfach und für Sie leicht zu implementieren ist.

Da ich im ersten Satz gesagt habe, dass es nicht möglich ist, die ID und den App-Schlüssel im Skript mithilfe wp_enqueque_scriptsvon auszudrucken, besteht die Moral der Geschichte darin, dass Sie sie im Markup auf eine andere Weise ausdrucken müssen.

Ein Weg, der nicht zu viel riecht (wenn es keine Alternativen gibt), ist, wp_print_scriptsHook zu verwenden, um das Skript-Tag zu drucken:

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
quelle
Danke GM, ich habe es geschafft, damit zu arbeiten. Ich bin interessiert zu sehen, ob es alternative Lösungen gibt, die die Enqueue-Haken verwenden, aber ich schätze all die Gedanken, die Sie in die Antwort gesteckt haben.
Andrew Bartel
@ AndrewBartel Ich denke, es gibt keine Möglichkeit, wp_enqueque_scripts in Ihrem Fall zu verwenden, aber wenn Sie eine finden, lassen Sie es uns wissen! :)
gmazzap
Ihre Lösung kann die Auslastung des Servers erhöhen, da Sie durch Ausführen von Echo direkt eine weitere http-Anforderung stellen. Die Lösung ist gut, aber nicht optimiert.
Faisal Shaikh
@FaisalShaikh Pflege zu erklären? Die echoAnweisung führt keine HTTP-Anfrage aus, soweit ich das beurteilen kann, und WordPress wp_enqueue_scriptgibt auch ein Echo aus (siehe core.trac.wordpress.org/browser/tags/4.9/src/wp-includes/… ) Anzahl der Anfragen durch Kombinieren des Skripts mit einem anderen Skript, das Sie haben, aber: 1) Das Skript ist in diesem Fall auf einem Server eines Drittanbieters vorhanden. 2) Wenn Sie das Skript heutzutage mit HTTP 2 kombinieren, wird die Leistung verringert, nicht erhöht. Vielleicht vermisse ich etwas?
gmazzap
@gmazzap du hast recht. Eigentlich habe ich einen anderen Weg, dies zu tun. Wir können diesen dritten Teil js auf unserem Server speichern und ich glaube wirklich nicht, dass das Kombinieren von Skripten die Last auf dem Server erhöhen kann.
Faisal Shaikh
1

Aus der obigen Antwort von Bainternet. Dieser Code hat bei mir funktioniert.

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

Bearbeiten: Der einzige Unterschied zum Bainternet-Code ist, dass ich eine Bedingung hinzugefügt habe, um zu überprüfen, ob die Skript-URL dropbox ist und es sich um eine .js-Datei handelt.

Ich ignoriere alle anderen URLs und schreibe die Dropbox-URL neu.

user2914440
quelle
2
Bitte erläutern Sie, was Sie geändert haben und warum Sie es geändert haben (oder ändern mussten).
Beginn
Ich weiß, dass dies eine alte Antwort ist, aber wollten Sie in Ihrem obigen Code $ original_url in der IF-Anweisung statt nur $ url zurückgeben?
Leromt
1

Ich habe im dropbox.js-Code (v2) nachgesehen, was passiert ist und wie dies am besten gelöst werden kann. Wie sich herausstellt, wird der Daten-App-Schlüssel nur zum Setzen der Variablen Dropbox.appKey verwendet. Ich kann die Variable mit der folgenden zusätzlichen Zeile setzen.

Verwenden des Javascript-Beispiels auf der Dropbox-Seite 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>

In meinem Code setze ich den Dropbox.appKey an jeder Stelle, an der ich auf die JavaScript-Routinen von Dropbox verweise. Dadurch konnte ich wp_enqueue_script () ohne die zusätzlichen Parameter verwenden.

Michaelkay
quelle
0

Ich habe das mit meinem eCards-Plugin gemacht und es ist wirklich einfach.

Hier ist ein direktes Kopieren / Einfügen aus dem 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>';

Beachten Sie, dass der API-Schlüssel über eine Option übergeben wird.

Ciprian
quelle
Wie wird $ output verwendet? Echo? Zu wp_print_scripts hinzufügen ()?
Andrew Bartel
Es wird je nach Ihrer Funktion entweder zurückgegeben oder als Echo ausgegeben.
Ciprian
0

Es gibt einen einfacheren Weg, dies zu tun

 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
quelle
0

Wordpress-Syntax für script_loader_tag :

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

Um ein beliebiges Attribut hinzuzufügen, können Sie Ihr $ -Tag folgendermaßen ändern:

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

Welche URL wird korrekt entkommen.

JackLinkers
quelle
0

Vielen Dank für all die Beiträge, die wirklich geholfen haben. Ich habe meine eigene Version gerollt, um sie zu strukturieren und das Lesen und Aktualisieren zu vereinfachen. Verwenden Sie Enqueue wie gewohnt. Verwenden Sie Skript für CSS-Dateien mit einem falschen Tag am Ende, damit es oben geladen wird. Obwohl es wahrscheinlich etwas vereinfacht werden kann.

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
quelle