Enfileirar Scripts / Estilos quando shortcode está presente

47

Qual é a ideia de registrar / enfileirar scripts e / ou estilos para uso em plug-ins?

Eu recentemente fiz um plugin plugin simples para adicionar o avatar / gravatar do usuário com um shortcode. Eu tenho diferentes opções de estilo para exibir o avatar (quadrado, redondo, etc.) e decidi colocar o css diretamente no shortcode em si.

No entanto, percebo agora que esta não é uma boa abordagem, pois irá repetir o css toda vez que o shortcode for usado em uma página. Eu já vi várias outras abordagens neste site e o codex wp tem até dois exemplos próprios, então é difícil saber qual abordagem é mais consistente e rápida.

Aqui estão os métodos que conheço atualmente:

Método 1: incluir diretamente no shortcode - Isso é o que eu estou fazendo atualmente no plug-in, mas não parece bom, já que ele repete o código.

class My_Shortcode {
function handle_shortcode( $atts, $content="" ) {
/* simply enqueue or print the scripts/styles in the shortcode itself */
?>
<style type="text/css">

</style>
<?php
    return "$content";
     }
}
add_shortcode( 'myshortcode', array( 'My_Shortcode', 'handle_shortcode' ) );

Método 2: use a classe para enfileirar scripts ou estilos condicionalmente

class My_Shortcode {
    static $add_script;
    static function init() {
        add_shortcode('myshortcode', array(__CLASS__, 'handle_shortcode'));
        add_action('init', array(__CLASS__, 'register_script'));
        add_action('wp_footer', array(__CLASS__, 'print_script'));
    }
    static function handle_shortcode($atts) {
        self::$add_script = true;
        // shortcode handling here
    }
    static function register_script() {
        wp_register_script('my-script', plugins_url('my-script.js', __FILE__), array('jquery'), '1.0', true);
    }
    static function print_script() {
        if ( ! self::$add_script )
            return;
        wp_print_scripts('my-script');
    }
}
My_Shortcode::init();

Método 3: usando get_shortcode_regex();

function your_prefix_detect_shortcode() {

    global $wp_query;   
    $posts = $wp_query->posts;
    $pattern = get_shortcode_regex();

    foreach ($posts as $post){
        if (   preg_match_all( '/'. $pattern .'/s', $post->post_content, $matches )
            && array_key_exists( 2, $matches )
            && in_array( 'myshortcode', $matches[2] ) )
        {
            // css/js 
            break;  
        }    
    }
}
add_action( 'wp', 'your_prefix_detect_shortcode' );

Método 4: usando has_shortcode();

function custom_shortcode_scripts() {
    global $post;
    if( is_a( $post, 'WP_Post' ) && has_shortcode( $post->post_content, 'myshortcode') ) {
        wp_enqueue_script( 'my-script');
    }
}
add_action( 'wp_enqueue_scripts', 'custom_shortcode_scripts');
    
por Bryan Willis 18.10.2014 / 09:07
fonte

6 respostas

34

Eu encontrei uma outra maneira que funciona bem para mim:

Aqui está um exemplo de plug-in usando esse método que permite usar get_avatar como shortcode. A folha de estilo só é enfileirada quando o código de acesso está presente.

Uso (o id é padronizado para o usuário atual):

[get_avatar id="" size="32" default="mystery" alt="Profile Photo" class="round"]

function wpse_165754_avatar_shortcode_wp_enqueue_scripts() {
    wp_register_style( 'get-avatar-style', plugins_url( '/css/style.css', __FILE__ ), array(), '1.0.0', 'all' );
}

add_action( 'wp_enqueue_scripts', 'wpse_165754_avatar_shortcode_wp_enqueue_scripts' );
if ( function_exists( 'get_avatar' ) ) {
    function wpse_165754_user_avatar_shortcode( $attributes ) {

        global $current_user;
        get_currentuserinfo();

        extract( shortcode_atts(
                     array(
                         "id"      => $current_user->ID,
                         "size"    => 32,
                         "default" => 'mystery',
                         "alt"     => '',
                         "class"   => '',
                     ), $attributes, 'get_avatar' ) );

        $get_avatar = get_avatar( $id, $size, $default, $alt );

        wp_enqueue_style( 'get-avatar-style' );

        return '<span class="get_avatar ' . $class . '">' . $get_avatar . '</span>';
    }

    add_shortcode( 'get_avatar', wpse_165754_user_avatar_shortcode' );
}
    
por jblanche 15.06.2015 / 14:28
fonte
25

Antes de iniciar a resposta, tenho que dizer que em relação a este tópico, css e js não são os mesmos.

O motivo é simples: enquanto adicionar js ao corpo da página (no rodapé) é uma maneira comum e válida de ir, o css precisa ser colocado na seção <head> da página: mesmo que a maioria dos navegadores pode renderizar corretamente o css no corpo da página, isso não é um código HTML válido.

Quando um shortcode é renderizado, a seção <head> já foi impressa, isso significa que js podem ser adicionados sem qualquer problema no rodapé, mas o css deve ser adicionado antes que o shortcode seja renderizado.

Scripts

Se o seu código de acesso precisa apenas de js, você tem sorte e pode usar apenas wp_enqueue_script no corpo do retorno de chamada de código de acesso:

add_shortcode( 'myshortcode', 'my_handle_shortcode' );

function my_handle_shortcode() {
  wp_enqueue_script( 'myshortcodejs', '/path/to/js/file.js' );
  // rest of code here...
}

Fazendo isso, seu script é adicionado ao rodapé e somente uma vez, mesmo que o código de acesso seja usado mais de uma vez na página.

Estilos

Se você codificar precisa de estilos, então precisa atuar antes que shortcode seja realmente renderizado.

Existem diferentes maneiras de fazer isso:

  1. examine todas as postagens da consulta atual e adicione os estilos de códigos curtos, se necessário. Isto é o que você faz em ambos os métodos # 3 e # 4 no OP. De fato, os dois métodos fazem a mesma coisa, mas has_shortcode foi adicionado no WP 3.6, enquanto get_shortcode_regex está disponível desde a versão 2.5, então use get_shortcode_regex somente se você quiser tornar seu plugin compatível com versões mais antigas.

  2. adicione sempre o estilo shortcode em todas as páginas

Problemas

Problema com o número 1 é o desempenho. Regex são operações muito lentas e lançam regex em um loop de todas as postagens que podem retardar a página consistentemente. Além disso, é uma tarefa bastante comum em temas mostrar apenas trechos de postagem em arquivos e mostrar conteúdo completo com códigos de acesso apenas em visualizações singulares. Se isso acontecer, quando um arquivo for exibido, seu plug-in iniciará uma regex correspondente em um loop com o objetivo de adicionar um estilo que nunca será usado: um impacto desnecessário no desempenho duplo: desaceleração da geração de página + solicitação HTTP desnecessária adicional

O problema com o # 2 é desempenho, novamente. Adicionar estilo a todas as páginas significa adicionar uma solicitação HTTP adicional para todas as páginas, mesmo quando não é necessário. Mesmo que o tempo de geração da página do lado do servidor não seja afetado, o tempo total de processamento da página será e para todas as páginas do site.

Então, o que um desenvolvedor de plugins deve fazer?

Acho que a melhor coisa a fazer é adicionar uma página de opções ao plug-in, onde os usuários podem escolher se o código de acesso deve ser tratado apenas em uma visualização única ou até mesmo em arquivos. Em ambos os casos, é melhor fornecer outra opção para escolher quais tipos de post permitem shortcode.

Dessa forma, é possível ligar "template_redirect" para verificar se a consulta atual atende aos requisitos e, nesse caso, adicionar o estilo.

Se o usuário optar por usar o shortcode somente em visualizações de post no singular, é uma boa idéia verificar se o post tem shortcode ou não: uma vez que apenas um regex é necessário, ele não deve deixar a página mais lenta.

Se o usuário optar por usar shortcode mesmo em arquivos, então eu evitaria executar regex para todas as postagens se o número de postagens for alto e apenas enfileirar o estilo se requisitos de ajuste de consulta.

O que considerar "alto" a esse respeito deve ser usar alguns testes de desempenho ou, como alternativa, adicionar outra opção e escolher os usuários.

    
por gmazzap 18.10.2014 / 10:49
fonte
5

Para meu plug-in, descobri que às vezes os usuários têm um criador de temas que possui shortcode armazenado em post meta data . Aqui está o que estou usando para detectar se o shortcode do meu plug-in está presente nos pós-dados atuais ou pós-meta :

function abcd_load_my_shorcode_resources() {
       global $post, $wpdb;

       // determine whether this page contains "my_shortcode" shortcode
       $shortcode_found = false;
       if ( has_shortcode($post->post_content, 'my_shortcode') ) {
          $shortcode_found = true;
       } else if ( isset($post->ID) ) {
          $result = $wpdb->get_var( $wpdb->prepare(
            "SELECT count(*) FROM $wpdb->postmeta " .
            "WHERE post_id = %d and meta_value LIKE '%%my_shortcode%%'", $post->ID ) );
          $shortcode_found = ! empty( $result );
       }

       if ( $shortcode_found ) {
          wp_enqueue_script(...);
          wp_enqueue_style(...);
       }
}
add_action( 'wp_enqueue_scripts', 'abcd_load_my_shorcode_resources' );
    
por zdenekca 06.11.2015 / 01:18
fonte
2

Eu faço assim:

class My_Shortcode {

    function __construct() {
        do_action('my_start_shortcode'); // call
....

e pegar o gancho em outras funções (ou outros plugins):

function wpse_3232_load_script(){
    wp_enqueue_script('js-myjs');
}
add_action('my_start_shortcode','wpse_3232_load_script',10);
    
por Wladimir Druzhaev 08.08.2017 / 11:51
fonte
1

Eu descobri o meu próprio plugin, se o shortcode estiver presente no widget de texto.

function check_shortcode($text) {

  $pattern = get_shortcode_regex();

   if (   preg_match_all( '/'. $pattern .'/s', $text, $matches )
        && array_key_exists( 2, $matches )
        && in_array( 'myshortcode', $matches[2] ) )
    {
        // myshortcode is being used

        // enque my css and js
        /****** Enqueu RFNB  ******/
        wp_enqueue_style('css-mycss');
        wp_enqueue_script('js-myjs');

        // OPTIONAL ALLOW SHORTCODE TO WORK IN TEXT WIDGET
        add_filter( 'widget_text', 'shortcode_unautop');
        add_filter( 'widget_text', 'do_shortcode'); 

    }

  return $text;

}
add_filter('widget_text', 'check_shortcode');
    
por Gino 21.12.2016 / 17:33
fonte
0

O WordPress possui uma função interna para fazer algo com base em um status específico de apresentação do Shortcode. O nome da função é has_shortcode() . Você pode usar o seguinte código para enfileirar seu estilo e scripts.

<?php
if( is_a( $post, 'WP_Post' ) && has_shortcode( $post->post_content, 'shortcode_tag') ) {
    wp_enqueue_style( 'handle', get_template_directory_uri() . '/your_file_filename.css' );
}

Aqui, usei o is_a( $post, 'WP_Post' ) para verificar se o objeto $post é da classe WP_Post e usei $post->post_content para verificar o conteúdo da postagem.

Você pode obter mais informações sobre aqui sobre a função has_shortcode ().

    
por Arif Rahman 07.10.2018 / 19:04
fonte