Adicionando atributos adicionais na tag de script para JS de terceiros

20

Eu me deparei com isso ao tentar integrar a gota do Dropbox na API do seletor a um plug-in que estou escrevendo.

A documentação da API instrui você a colocar a seguinte scripttag na parte superior do seu arquivo:

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

Tudo bem e bem, e na verdade funciona quando colo diretamente na página chamada na seção admin. Mas, eu gostaria de usar algumas variações de wp_register_script (), wp_enqueue_script () e wp_localize_script () para passar a identificação necessária e a chave de aplicativo de dados.

Eu tentei algumas variações diferentes disso:

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 é substituído pela chave apropriada do aplicativo no meu código. Apreciaria qualquer direção. Obrigado.

EDIT: Também tentei fazê-lo com algum jquery, mas sem sucesso. Tentei no carregamento do documento e no documento pronto. Recebo um retorno de {"error": "app_key inválido"}.

$('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
fonte
2
O que wp_localize_scriptfazer é imprimir um objeto codificado em json na saída html da página. Este objeto é reconhecido pelo script e, portanto, você pode usá-lo. O que você precisa é adicionar alguns atributos à tag de script e, portanto, wp_localize_scriptnão pode ajudá-lo.
gmazzap
2
GM está correto que wp_localize_scriptnão cria atributos de script. Mas é possível passar a chave do aplicativo diretamente no dropbox.js? Apenas um palpite, mas você já tentou array('appKey'=>"MY_APP_KEY")? Este é o código que agarra a chave do atributoif(!Dropbox.appKey){Dropbox.appKey=(e=document.getElementById("dropboxjs"))!=null?e.getAttribute("data-app-key"):void 0}
epilektric
Hey @epilektric Você poderia responder isso? Não estou entendendo bem como implementá-lo.
precisa
@epilektric com wp_localize_scriptcerteza você pode passar atributos para o script. Eu realmente não sei se isso vai funcionar ou não, no entanto, não é um assunto relacionado ao worpress.
gmazzap
@AndrewBartel Eu também não tenho certeza de como. Talvez isso ajude. pippinsplugins.com/use-wp_localize_script-it-is-awesome
epilektric

Respostas:

18

você pode tentar usar o script_loader_srcgancho de filtro, por exemplo:

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

Atualizar

Eu apenas descobri que o src é escapado por esc_url, então, procurando um pouco mais, encontrei o clean_urlfiltro que você pode usar para retornar o valor com seus dados-chave de identificação e aplicativo:

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
fonte
Isso não funciona. Antes de ser impresso, o resultado de 'script_loader_src' é escapado; portanto, as aspas são removidas e o que você produz é reconhecido como parte do atributo 'src' e não como atributos separados. Esse código colocará na marcação html algo como<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
sim, eu atualizei minha resposta.
Bainternet 28/08/2013
3
Testei o código após a minha edição e funciona. Obrigado por me ensinar algo com isso.
gmazzap
1
Eu acho que OP será mais feliz do que você e eu. ;)
gmazzap
1
Obrigado @Bainternet pela ajuda, consegui trabalhar usando sua resposta.
Andrew Bartel
14

Desde o WP 4.1.0, um novo gancho de filtro está disponível para isso facilmente:

script_loader_tag

Use desta maneira:

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
fonte
isso é executado antes que ocorra o armazenamento em cache do JS?
Joanna Mikalai
3

OK, parece (para mim) que wp_enqueque_scriptsnão é possível imprimir o ID e a chave do aplicativo como atributos da tag de script.

Tenho certeza de 90%, porque WP_Dependenciesnão é uma classe que eu conheço bem, mas olhando o código Parece-me impossível.

Mas tenho 100% de certeza de que o uso nãowp_localize_script é útil para o seu escopo .

Como eu disse no meu comentário acima:

O que o wp_localize_script faz é imprimir um objeto codificado em json na saída html da página. Este objeto é reconhecido pelo script e, portanto, você pode usá-lo.

O que eu não disse no comentário é que o objeto codificado em json como um nome arbitrário que você decide, de fato, olhando para a sintaxe:

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

O objeto nomeado $object_name poderia ser usado pelo script porque está no escopo global e impresso no html da página.

Mas o $object_nameé um nome que você decide, para que possa ser tudo .

Então pergunte a si mesmo:

como o script no servidor dropbox remoto pode fazer uso de uma variável que eles não sabem como é chamada?

Portanto, não há nenhuma razão para passar a ID e / ou a chave do aplicativo para o script wp_localize_script: basta imprimi-los como atributos de tag de script, como é dito nos documentos da API do Dropbox.

Não sou desenvolvedor js, mas acho que o script do dropbox é:

  1. pegue tudo <script> elementos html na página
  2. percorra-os procurando aquele com o 'id' == 'dropboxjs'
  3. se esse script for encontrado, olhando para a 'chave do aplicativo de dados' desse script
  4. verifique se a chave do aplicativo (se presente) é válida e autorize-o, se for o caso

Por favor, note que eu não sei disso com certeza, estou apenas supondo .

Dessa forma, o script carregado no servidor da caixa de depósito pode verificar a chave do aplicativo de uma maneira fácil para eles e fácil de implementar para você.

Como na primeira frase eu disse que não é possível imprimir o ID e a chave do aplicativo no script wp_enqueque_scripts, a moral da história é que você deve imprimi-los na marcação de outra maneira.

Uma maneira que não cheira muito (quando não há alternativas) é usar wp_print_scriptshook para imprimir a tag 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
fonte
Graças GM, eu consegui trabalhar usando isso. Estou interessado em ver se há soluções alternativas usando os ganchos de enfileiramento, mas agradeço todo o pensamento que você colocou na resposta.
Andrew Bartel
@AndrewBartel Acho que não há como usar wp_enqueque_scripts no seu caso, mas se você encontrar um, avise-nos! :)
gmazzap
sua solução pode aumentar a carga no servidor, pois você está fazendo mais uma solicitação http diretamente, fazendo eco. A solução é boa, mas não otimizada.
Faisal Shaikh
@FaisalShaikh gostaria de explicar? A echodeclaração não faz nenhuma solicitação HTTP, tanto quanto eu posso dizer, e o WordPress também wp_enqueue_scriptfaz eco (consulte core.trac.wordpress.org/browser/tags/4.9/src/wp-includes/… ). Certamente você pode reduzir o número de solicitações combinando o script com outro script que você possui, mas: 1) os scripts existem no servidor de terceiros, neste caso 2) com o HTTP 2 atualmente combinando o script reduziria o desempenho, não os aumentaria. Então, talvez eu perca alguma coisa?
gmazzap
@gmazzap você está certo. na verdade, tenho uma maneira diferente de fazer isso. Podemos armazenar esses js da 3ª parte em nosso servidor e realmente não acho que a combinação de scripts possa aumentar a carga no servidor.
Faisal Shaikh
1

Da resposta de Bainternet acima. Este código funcionou para mim.

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: A única diferença do código Bainternet é que eu adicionei uma condição para verificar se o URL do script é dropbox e se é um arquivo .js.

Estou ignorando todos os outros URLs e reescrevendo o URL da caixa de depósito.

user2914440
fonte
2
Por favor, adicione algumas explicações sobre o que você muda e por que você mudou (ou teve que mudar).
tfrommen
Eu sei que essa é uma resposta antiga, mas no seu código acima, você quis retornar $ original_url dentro da instrução IF em vez de apenas $ url?
leromt 12/03/2015
1

Fiz algumas checagens no código dropbox.js (v2) para ver o que estava acontecendo e a melhor forma de solucionar isso. Como se vê, a chave de aplicativo de dados é usada apenas para definir a variável Dropbox.appKey. Eu sou capaz de definir a variável com a seguinte linha extra.

Usando o exemplo javascript na página do 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>

No meu código, defino o Dropbox.appKey em todos os lugares em que faço referência às rotinas javascript do Dropbox. Fazer isso me permitiu usar wp_enqueue_script () sem os parâmetros extras.

Michaelkay
fonte
0

Eu fiz isso com meu plug-in eCards e é realmente simples.

Aqui está uma cópia / colagem direta do plug-in:

$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>';

Observe que a chave da API é passada através de uma opção.

Ciprian
fonte
Como o $ output é usado? Ecoou? Adicionar a wp_print_scripts ()?
Andrew Bartel
É retornado ou ecoado, dependendo da sua função.
Ciprian
0

Existe uma maneira mais simples de fazer isso

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

Sintaxe do Wordpress para script_loader_tag :

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

Para adicionar qualquer atributo, você pode modificar sua tag $ desta maneira:

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

O que escapará corretamente do URL.

JackLinkers
fonte
0

Obrigado por todas as publicações, eles realmente ajudaram. Eu rolei minha própria versão para dar a ela alguma estrutura e facilitar a leitura e a atualização. Use o enfileiramento normalmente, use o script para arquivos CSS com uma tag falsa no final, para que seja carregado na parte superior. Embora provavelmente possa ser um pouco simplificado.

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
fonte