Poner en cola secuencias de comandos / estilos cuando el código corto está presente

47

¿Cuál es la manera ideal de registrar / poner en cola los scripts y / o los estilos para usarlos en complementos?

Recientemente hice un complemento complemento simple para agregar el avatar del usuario / gravatar con un código corto. Tengo diferentes opciones de estilo para mostrar el avatar (cuadrado, redondo, etc.) y decidí poner el css directamente en el código corto.

Sin embargo, ahora me doy cuenta de que este no es un buen enfoque, ya que repetirá el css cada vez que se use el shortcode en una página. He visto varios otros enfoques en este sitio y el códice wp tiene dos ejemplos propios, por lo que es difícil saber qué enfoque es más consistente y más rápido.

Estos son los métodos que actualmente conozco:

Método 1: incluir directamente en el código abreviado - Esto es lo que estoy haciendo actualmente en el complemento, pero no parece bueno ya que repite el 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: utilice la clase para poner en cola los scripts o los estilos de forma condicional

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: usar 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: usar 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');
    
pregunta Bryan Willis 18.10.2014 - 09:07

6 respuestas

34

Encontré otra manera que me funciona bien:

Aquí hay un ejemplo de complemento que usa este método que te permite usar get_avatar como código corto. La hoja de estilo solo se pone en cola cuando el shortcode está presente.

Uso (los valores predeterminados de la identificación al usuario actual):

[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' );
}
    
respondido por el jblanche 15.06.2015 - 14:28
25

Antes de comenzar la respuesta, debo decir que con respecto a este tema, css y js no son lo mismo.

La razón es simple: mientras que agregar js al cuerpo de la página (en pie de página) es una forma común y válida de irse, css debe colocarse en la sección <head> de la página: incluso si la mayoría de los navegadores puede procesar correctamente css en el cuerpo de la página, eso no es un código HTML válido.

Cuando se representa un shortcode, ya se imprimió la sección <head> , esto significa que js puede agregarse sin ningún problema en el pie de página, pero css debe agregarse antes de el shortcode se representa.

Scripts

Si su código abreviado solo necesita js, tiene suerte y solo puede usar wp_enqueue_script en el cuerpo de la devolución de llamada de código abreviado:

add_shortcode( 'myshortcode', 'my_handle_shortcode' );

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

Al hacerlo, su script se agrega al pie de página y solo una vez, incluso si el shortcode se usa más de una vez en la página.

Estilos

Si el código necesita estilos, entonces debe actuar antes realmente se ejecuta el shortcode.

Hay diferentes maneras de hacer esto:

  1. mire todas las publicaciones en la consulta actual y agregue los estilos de shortcode si es necesario. Esto es lo que haces tanto en el método # 3 como en el # 4 en OP. De hecho, ambos métodos hacen lo mismo, pero se agregó has_shortcode en WP 3.6, mientras que get_shortcode_regex está disponible desde la versión 2.5, así que use get_shortcode_regex solo si quiere que su complemento sea compatible con versiones anteriores.

  2. siempre agregue estilo de código abreviado, en todas las páginas

Problemas

El problema con el # 1 es el rendimiento. Las expresiones regulares son bastante lentas y el lanzamiento de expresiones regulares en un bucle de todas las publicaciones puede ralentizar la página constantemente. Por otra parte, es una tarea bastante común en temas para mostrar solo extractos de publicaciones en archivos y mostrar contenido completo con códigos cortos solo en vistas singulares. Si eso sucede, cuando se muestre un archivo, su complemento lanzará una expresión regular que coincidirá en un bucle con el objetivo de agregar un estilo que nunca se utilizará: un doble impacto innecesario en el rendimiento: ralentizar la generación de páginas + solicitud HTTP adicional innecesaria

El problema con el # 2 es el rendimiento, otra vez. Agregar estilo a todas las páginas significa agregar una solicitud HTTP adicional para todas las páginas, incluso cuando no sea necesario. Incluso si el tiempo de generación de la página del lado del servidor no se ve afectado, el tiempo total de representación de la página lo será, y para todas las páginas del sitio.

Entonces, ¿qué debe hacer un desarrollador de complementos?

Creo que lo mejor que se puede hacer es agregar una página de opciones al complemento, donde los usuarios pueden elegir si el código abreviado debe manejarse en una vista singular solo o incluso en archivos. En ambos casos, es mejor proporcionar otra opción para elegir los tipos de publicación que habilitan el código corto.

De esa manera es posible enganchar "template_redirect" para verificar si la consulta actual cumple con los requisitos y, en ese caso, agregar el estilo.

Si el usuario elige usar shortcode solo en vistas de publicación singulares, es una buena idea verificar si la publicación tiene shortcode o no: una vez que solo se requiere una expresión regular no debe ralentizar mucho la página.

Si el usuario elige usar shortcode incluso en archivos, evitaría ejecutar expresiones regulares para todas las publicaciones si el número de publicaciones es alto y simplemente pongo el estilo en la cola si la consulta cumple los requisitos.

Lo que se debe considerar "alto" a este respecto se debe obtener utilizando algunas pruebas de rendimiento o, como alternativa, agregue otra opción y permita a los usuarios elegir.

    
respondido por el gmazzap 18.10.2014 - 10:49
5

Para mi complemento, encontré que a veces los usuarios tienen un creador de temas que tiene un código corto almacenado en metadatos de publicación . Esto es lo que estoy usando para detectar si el código abreviado de mi complemento está presente en la publicación actual o en la metadatos de la publicación :

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' );
    
respondido por el zdenekca 06.11.2015 - 01:18
2

Lo hago:

class My_Shortcode {

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

y enganche el gancho en otras funciones (u otros complementos):

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

Descubrí mi propio complemento, si el código corto está presente en el 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');
    
respondido por el Gino 21.12.2016 - 17:33
0

WordPress tiene una función incorporada para hacer algo basado en un estado de presentación de Shortcode específico. El nombre de la función es has_shortcode() . Puede usar el siguiente código para poner en cola su estilo y sus 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' );
}

Aquí usé is_a( $post, 'WP_Post' ) para verificar si el objeto $post pertenece a la clase WP_Post y usé $post->post_content para verificar el contenido de la publicación.

Puede obtener más información en aquí sobre la función has_shortcode ().

    
respondido por el Arif Rahman 07.10.2018 - 19:04