Carga condicional de JavaScript/CSS para shortcodes

23 jun 2011, 18:07:29
Vistas: 17.8K
Votos: 41

Lancé un plugin que crea un shortcode y requiere cargar un archivo JavaScript y uno CSS en cualquier página que contenga ese shortcode. Podría simplemente hacer que el script/estilo se cargue en todas las páginas, pero no es la mejor práctica. Solo quiero cargar los archivos en páginas que llaman al shortcode. Encontré dos métodos para hacer esto, pero ambos tienen problemas.

Método 1 establece una bandera en true dentro de la función manejadora del shortcode, y luego verifica ese valor dentro de un callback de wp_footer. Si es true, usa wp_print_scripts() para cargar el JavaScript. El problema con esto es que solo funciona para JavaScript y no para CSS, porque CSS debe declararse dentro de <head>, lo que solo puedes hacer durante un hook temprano como init o wp_head.

Método 2 se ejecuta temprano y "echa un vistazo" para ver si el shortcode existe en el contenido de la página actual. Me gusta mucho más este método que el primero, pero el problema es que no detectará si la plantilla llama a do_shortcode().

Por lo tanto, me inclino por usar el segundo método y luego intentar detectar si hay una plantilla asignada, y si es así, analizarla en busca del shortcode. Antes de hacer eso, quería consultar si alguien conoce un método mejor.

Actualización: He integrado la solución en mi plugin. Si alguien está curioso por verla implementada en un entorno real, puede descargarla o examinarla.

Actualización 2: A partir de WordPress 3.3, ahora es posible llamar a wp_enqueue_script() directamente dentro de un callback de shortcode, y el archivo JavaScript se cargará en el pie de página del documento. Técnicamente esto también es posible para archivos CSS, pero debe considerarse una mala práctica porque mostrar CSS fuera de la etiqueta <head> viola las especificaciones W3C, puede causar FOUC (Flash of Unstyled Content) y puede forzar al navegador a volver a renderizar la página.

10
Comentarios

He utilizado una variación del Método 1 en el pasado. Cargar JS para el shortcode en el footer, cargar CSS para el shortcode en línea. Funciona, pero es un poco chapucero. Espero una mejor solución.

EAMann EAMann
23 jun 2011 18:14:52

Los principales problemas con el CSS en línea son que es difícil sobrescribirlo con otros estilos y que no utiliza el método wp_enqueue_styles().

Ian Dunn Ian Dunn
23 jun 2011 19:05:16

¿Cuánto CSS tienes?

mfields mfields
23 jun 2011 19:35:32

¿Cuántas líneas de JavaScript?

mfields mfields
23 jun 2011 19:36:42

Son aproximadamente 30 líneas de CSS y 100 líneas de JavaScript, pero eso es irrelevante. Deben incluirse de la manera CORRECTA, sin importar el tamaño. Consulta los comentarios en las respuestas para conocer las razones.

Ian Dunn Ian Dunn
23 jun 2011 19:45:43

El JavaScript es la parte fácil. La mejor manera de hacer esto está bajo "Jedi" aquí: http://scribu.net/wordpress/optimal-script-loading.html

mfields mfields
23 jun 2011 19:55:27

30 líneas no es mucho, lo minificaría y lo imprimiría en el head dentro de una etiqueta style en todas las vistas. Proporciona un filtro y/o configuración que permita al usuario deshabilitar los estilos si lo desea.

mfields mfields
23 jun 2011 19:59:12

@mfields, ya conozco ese método, lo vinculé en la pregunta... Por favor lee RTFQ antes de comentar ;)

Ian Dunn Ian Dunn
23 jun 2011 21:02:10

Entonces ya conoces la MEJOR forma de manejar el javascript ;) La MEJOR forma en mi opinión para manejar el css es "30 líneas no es mucho, lo minificaría y lo imprimiría en el head dentro de una etiqueta style en todas las vistas. Proporciona un filtro y/o configuración que permita al usuario deshabilitar los estilos si lo desea." Si necesitas usar wp_enqueue_script() adelante, no creo que sea necesario ya que añade otra petición HTTP. Minificar -> imprimir en wp_head() -> permitir que otras extensiones filtren la salida.

mfields mfields
23 jun 2011 21:14:52

Creo que archivos separados son más limpios y mejor organizados. La minificación puede ser realizada por el servidor en tiempo de ejecución.

Ian Dunn Ian Dunn
23 jun 2011 21:40:56
Mostrar los 5 comentarios restantes
Todas las respuestas a la pregunta 7
9
11

Basándome en mi propia experiencia, he utilizado una combinación de los métodos 1 y 2: la arquitectura y scripts del pie de página del 1, y la técnica de "mirar hacia adelante" del 2.

Para el "mirar hacia adelante", uso expresiones regulares en lugar de stripos; preferencia personal, más rápido y puede verificar si hay shortcode "malformado":

preg_match( '#\[ *shortcode([^\]])*\]#i', $content );

Si te preocupa que los autores usen do_shortcode manualmente, optaría por instruirlos a usar una llamada de acción encolar manualmente tu estilo pre-registrado.

ACTUALIZACIÓN: Para el autor perezoso que nunca lee el manual, muestra un mensaje para resaltar el error de sus formas ;)

function my_shortcode()
{
    static $enqueued;
    if ( ! isset( $enqueued ) )
        $enqueued = wp_style_is( 'my_style', 'done' ); // almacenar en caché para no repetir si se llama varias veces

    // hacer shortcode
    $output = '';

    if ( ! $enqueued )
        // puedes mostrar el mensaje solo en la primera ocurrencia envolviéndolo en el if anterior
        $output .= <<<HTML
<p>¡Atención! Debes encolar manualmente la hoja de estilos del shortcode si llamas a <code>do_shortcode()</code> directamente.</p>
<p>Usa <code>wp_enqueue_style( 'my_style' );</code> antes de tu llamada a <code>get_header()</code> dentro de tu plantilla.</p>
HTML;

    return $output;
}
23 jun 2011 21:23:00
Comentarios

Ese es un buen punto. Idealmente me gustaría que funcione sin que tengan que hacer nada extra, porque la mitad de las veces probablemente no leerán el FAQ primero, así que asumirán que está roto, pero podría terminar haciendo eso. Podría registrar los scripts en cada página, pero solo encolarlos si detecto un shortcode. Entonces, los usuarios podrían engancharse a init y llamar a las funciones de encolado en plantillas específicas donde se necesiten, asumiendo que no es demasiado tarde en la ejecución en ese punto. Además, WP tiene get_shortcode_regex() incorporado.

Ian Dunn Ian Dunn
23 jun 2011 21:54:54

Si los usuarios son hábiles implementando do_shortcode(), ¿no es razonable asumir que también son hábiles siguiendo instrucciones para encolar el estilo del shortcode?

Chip Bennett Chip Bennett
23 jun 2011 22:16:03

Cierto, pero obtendrá la regex para todos los shortcodes, no solo los tuyos ;) "Podría registrar los scripts en cada página" ¡Probablemente también el mejor método! Nota que no necesitan engancharse a init, solo en cualquier lugar antes de wp_head. Para el desarrollador perezoso, verifica wp_style_is( 'my_style_handle', 'done' ) dentro de tu shortcode. Si es falso, muestra un error visible que les indique qué hacer.

TheDeadMedic TheDeadMedic
23 jun 2011 22:17:52

@Chip - No me preocupa que no sean capaces de seguir las instrucciones, sino que no sepan que se supone que deben hacerlo, ya que el 99% de las veces no necesitas hacer nada adicional.

Ian Dunn Ian Dunn
24 jun 2011 01:05:05

@Ian mi pensamiento era que agregar do_shortcode() a la plantilla ya es de por sí "hacer algo adicional" - y los usuarios que harían ese algo-extra ya sabrían sobre la necesidad de encolar el estilo, o estarían más dispuestos/propensos a seguir instrucciones especiales.

Chip Bennett Chip Bennett
24 jun 2011 02:03:16

@TheDeadMedic - Lo integré con mi código y actualicé la pregunta con enlaces por si alguien quiere verlo desarrollado. Gracias nuevamente por tu ayuda :)

Ian Dunn Ian Dunn
26 jun 2011 08:27:34

@Ian ¡Genial! Gracias por volver con una actualización, tanto para nosotros como para los que lleguen aquí desde Google más tarde ;)

TheDeadMedic TheDeadMedic
26 jun 2011 08:41:34

Está bien, pero no estoy de acuerdo en que preg_match sea más rápido que strpos http://lzone.de/articles/php-string-search.htm

Bainternet Bainternet
5 feb 2012 19:57:30

@Bainternet No necesariamente - preg_match vs stripos (sin distinción de mayúsculas/minúsculas) - de cualquier forma, estamos hablando de diferencias mínimas. En retrospectiva, creo que debería haber evitado el término "más rápido" - realmente quería dar a entender que era más eficiente para la tarea en cuestión (en lugar de usar múltiples stripos para acomodar varios formatos de shortcode).

TheDeadMedic TheDeadMedic
9 feb 2012 20:35:16
Mostrar los 4 comentarios restantes
6

Llego tarde respondiendo a esta pregunta, pero como Ian inició este hilo en la lista wp-hackers hoy, me hizo pensar que vale la pena responderla, especialmente considerando que he estado planeando agregar tal funcionalidad a algunos plugins en los que he estado trabajando.

Un enfoque a considerar es verificar en la primera carga de página si el shortcode se usa realmente y luego guardar el estado de uso del shortcode en una meta clave del post. Aquí está cómo:

Guía Paso a Paso

  1. Establece una bandera $shortcode_used en 'no'.
  2. En la propia función del shortcode, establece la bandera $shortcode_used en 'yes'.
  3. Configura un hook 'the_content' con prioridad 12, que es después de que WordPress haya procesado los shortcodes, y verifica la meta del post buscando un valor '' usando la clave "_has_{$shortcode_name}_shortcode". (Un valor de '' se retorna cuando no existe una meta clave para el ID del post.)
  4. Usa un hook 'save_post' para borrar la meta del post, limpiando la bandera persistente para ese post en caso de que el usuario cambie el uso del shortcode.
  5. También en el hook 'save_post', usa wp_remote_request() para enviar una petición HTTP GET no bloqueante al permalink propio del post, para disparar la primera carga de página y el establecimiento de la bandera persistente.
  6. Finalmente, configura un 'wp_print_styles' y verifica la meta del post para un valor de 'yes', 'no' o '' usando la clave "_has_{$shortcode_name}_shortcode". Si el valor es 'no', no sirvas el recurso externo. Si el valor es 'yes' o '', prosigue y sirve el recurso externo.

Y eso debería funcionar. He escrito y probado un plugin de ejemplo para mostrar cómo funciona todo esto.

Código del Plugin de Ejemplo

El plugin se activa con un shortcode [trigger-css] que establece los elementos <h2> de la página en blanco sobre rojo para que puedas ver fácilmente que funciona. Asume un subdirectorio css que contiene un archivo style.css con este CSS:

/*
 * Nombre del archivo: css/style.css
 */
h2 {
  color: white;
  background: red;
}

Y a continuación está el código de un plugin funcional:

<?php
/**
 * Plugin Name: CSS on Shortcode
 * Description: Muestra cómo cargar condicionalmente un shortcode
 * Author: Mike Schinkel <mike@newclarity.net>
 */
class CSS_On_Shortcode {

  /**
   * @var CSS_On_Shortcode
   */
  private static $_this;

  /**
   * @var string 'yes'/'no' vs. true/false ya que get_post_meta() retorna '' para false y no encontrado.
   */
  var $shortcode_used = 'no';

  /**
   * @var string
   */
  var $HAS_SHORTCODE_KEY = '_has_trigger-css_shortcode';
  /**
   *
   */
  function __construct() {
    self::$_this = $this;
    add_shortcode( 'trigger-css', array( $this, 'do_shortcode' ) );
    add_filter( 'the_content', array( $this, 'the_content' ), 12 ); // DESPUÉS de do_shortcode() de WordPress
    add_action( 'save_post', array( $this, 'save_post' ) );
    add_action( 'wp_print_styles', array( $this, 'wp_print_styles' ) );
  }

  /**
   * @return CSS_On_Shortcode
   */
  function this() {
    return self::$_this;
  }

  /**
   * @param array $arguments
   * @param string $content
   * @return string
   */
  function do_shortcode( $arguments, $content ) {
    /**
     * Si este shortcode se está usando, captura el valor para guardarlo en post_meta en el filtro 'the_content'.
     */
    $this->shortcode_used = 'yes';
    return '<h2>ESTE POST AÑADIRÁ CSS PARA HACER LAS ETIQUETAS H2 BLANCO SOBRE ROJO</h2>';
  }

  /**
   * Borra el valor meta 'has_shortcode' para que pueda ser regenerado
   * en la primera carga de página en caso de que el uso del shortcode haya cambiado.
   *
   * @param int $post_id
   */
  function save_post( $post_id ) {
    delete_post_meta( $post_id, $this->HAS_SHORTCODE_KEY );
    /**
     * Ahora carga el post asincrónicamente vía HTTP para preestablecer el valor meta para $this->HAS_SHORTCODE_KEY.
     */
    wp_remote_request( get_permalink( $post_id ), array( 'blocking' => false ) );
  }

  /**
   * @param array $args
   *
   * @return array
   */
  function wp_print_styles( $args ) {
    global $post;
    if ( 'no' != get_post_meta( $post->ID, $this->HAS_SHORTCODE_KEY, true ) ) {
      /**
       * Solo omitir si está establecido en 'no', ya que '' es desconocido.
       */
      wp_enqueue_style( 'css-on-shortcode', plugins_url( 'css/style.css', __FILE__ ) );
    }
   }

  /**
   * @param string $content
   * @return string
   */
  function the_content( $content ) {
    global $post;
    if ( '' === get_post_meta( $post->ID, $this->HAS_SHORTCODE_KEY, true ) ) {
      /**
       * Es la primera vez que se ve este shortcode para este post.
       * Guarda una meta clave para que la próxima vez sepamos que este post usa este shortcode.
       */
      update_post_meta( $post->ID, $this->HAS_SHORTCODE_KEY, $this->shortcode_used );
    }
    /**
     * Elimina este filtro ahora. No lo necesitamos para este post de nuevo.
     */
    remove_filter( 'the_content', array( $this, 'the_content' ), 12 );
    return $content;
  }

}
new CSS_On_Shortcode();

Capturas de Pantalla de Ejemplo

Aquí hay una serie de capturas de pantalla

Editor de Post Básico, Sin Contenido

Editor de WordPress vacío

Visualización de Post, Sin Contenido

Página de post vacía

Editor de Post Básico con Shortcode [trigger-css]

Editor de WordPress con shortcode

Visualización de Post con Shortcode [trigger-css]

Página de post con estilo aplicado

No Estoy Seguro si es 100%

Creo que lo anterior debería funcionar en casi todos los casos, pero como acabo de escribir este código no puedo estar 100% seguro. Si puedes encontrar situaciones donde no funcione, me gustaría saberlo para poder corregir el código en algunos plugins a los que acabo de agregar esto. Gracias de antemano.

2 ene 2013 08:57:23
Comentarios

¿Entonces cinco plugins usando tu enfoque desencadenarán cinco solicitudes remotas cada vez que se guarde una publicación? Preferiría usar una expresión regular en post_content. ¿Y qué hay de los shortcodes en los widgets?

fuxia fuxia
2 ene 2013 09:02:29

@toscho El disparo de la carga de la publicación es en realidad opcional; solo está ahí para asegurar que el usuario no tenga que ver la primera carga de página con los externos cargados. Además, es una llamada no bloqueante, así que en teoría no deberías notarlo. Para nuestro código lo estamos haciendo en una clase base, así que la clase base puede manejar hacerlo solo una vez. Podríamos engancharnos al hook 'pre_http_request' y deshabilitar múltiples llamadas a la misma URL mientras el hook 'save_post' esté activo, pero preferiría esperar hasta ver una necesidad real de eso, ¿no? En cuanto a los Widgets, podría mejorarse para manejarlos, pero aún no es un caso de uso que haya estudiado.

MikeSchinkel MikeSchinkel
2 ene 2013 09:59:16

@toscho - Además, no puedes estar seguro de que el shortcode esté ahí, ya que otro hook podría eliminarlo. La única forma de estar seguro es si la función del shortcode realmente se ejecuta. Así que el enfoque de expresión regular no es 100% confiable.

MikeSchinkel MikeSchinkel
2 ene 2013 10:03:28

Lo sé. No hay una forma a prueba de balas de inyectar CSS para shortcodes (excepto usando <style>).

fuxia fuxia
2 ene 2013 10:05:39

Estoy trabajando con una implementación basada en esta solución y solo quería señalar que este método no se encolará para una vista previa de publicación/página.

mor7ifer mor7ifer
2 ago 2015 17:45:38

Mi solución al problema de vista previa: https://gist.github.com/mor7ifer/e50a9864a372a05b4a3b

mor7ifer mor7ifer
2 ago 2015 18:42:24
Mostrar los 1 comentarios restantes
11

Buscando en Google encontré una posible respuesta. Digo "posible" porque parece buena, debería funcionar, pero no estoy 100% convencido de que sea la mejor manera de hacerlo:

add_action( 'wp_print_styles', 'yourplugin_include_css' );
function yourplugin_include_css() {
    // Verifica si el shortcode existe en el contenido de la página o entrada
    global $post;

    // Eliminé el ' ] ' final... para que pueda aceptar argumentos.
    if ( strstr( $post->post_content, '[yourshortcode ' ) ) {
        echo $csslink;
    }
}

Esto debería poder verificar si la entrada actual está usando un shortcode y agregar una hoja de estilos al elemento <head> de manera apropiada. Pero no creo que funcione para una página de índice (es decir, múltiples entradas en el loop)... Además, es de una publicación de blog de hace 2 años, así que ni siquiera estoy seguro de que funcione con WP 3.1.X.

23 jun 2011 18:34:45
Comentarios

Esto no funcionará si el shortcode tiene argumentos. Si realmente quieres seguir este camino, que es lento, usa get_shortcode_regex() de WP para buscar.

onetrickpony onetrickpony
23 jun 2011 18:39:14

Como dije, respuesta "potencial" que aún no he probado... :-)

EAMann EAMann
23 jun 2011 18:39:56

Eso es básicamente lo mismo que el método 2, pero aún no verifica la plantilla para llamadas a do_shortcode().

Ian Dunn Ian Dunn
23 jun 2011 18:45:17

¿Por qué necesitaría hacer eso? Si llamas manualmente a do_shortcode() en la plantilla, entonces ya sabes que estarás ejecutando el shortcode

onetrickpony onetrickpony
23 jun 2011 18:50:08

No soy yo quien llama al shortcode, es el usuario. Esto es para un plugin distribuido, no uno privado.

Ian Dunn Ian Dunn
23 jun 2011 19:06:51

Vale, entonces por eso quieres un marcado válido :) ¿Estás diciendo que tu plugin instruye al usuario a editar archivos de plantilla y llamar a esa función? Entonces, a menos que crees tu propio analizador PHP, no hay forma de que puedas saber dónde y cuándo se está llamando a esa función...

onetrickpony onetrickpony
23 jun 2011 19:12:24

Siempre quiero un marcado válido, sin importar las circunstancias... El plugin no le dice al usuario que llame a la función, pero siempre es una opción. Un usuario siempre puede llamar cualquier shortcode ya sea escribiéndolo en el área de contenido de una entrada/página, o simplemente llamando do_shortcode() en una plantilla, así que ambas situaciones deben manejarse. Y no creo que necesite escribir mi propio analizador PHP, solo necesito analizar el archivo de plantilla asignado a la página actual (si hay uno) para ver si el shortcode está dentro de él.

Ian Dunn Ian Dunn
23 jun 2011 19:38:02

Suponiendo que pudieras descubrir qué archivo de plantilla está siendo usado por la página actual (lo cual dudo), ¿cómo lo analizarías sin un analizador? ¿expresiones regulares? ¿Y si la línea con el código está comentada? Hay decenas de formas de comentar código PHP

onetrickpony onetrickpony
23 jun 2011 19:59:30

La plantilla asignada simplemente se almacena en la tabla post_meta, ¿qué tiene de difícil descubrirlo? Puedes engancharte a the_posts para acceder al $post actual antes de que se genere cualquier salida. Por 'analizador PHP' asumí que te referías al motor completo, no solo a una función strpos o regex. Las líneas comentadas son un caso extremo que realmente no me preocupa.

Ian Dunn Ian Dunn
23 jun 2011 21:06:22

estás confundiendo las plantillas de páginas (como en el tipo de publicación "página") con los archivos de tema utilizados como plantillas

onetrickpony onetrickpony
23 jun 2011 21:20:18

Ah, te refieres a las plantillas por defecto (por ejemplo, single.php, home.php) en lugar de una plantilla personalizada creada específicamente para una página (por ejemplo, map.php), ¿verdad? Es un buen punto. Apuesto a que hay una manera de averiguar cuál se está utilizando, pero no la sé de memoria.

Ian Dunn Ian Dunn
23 jun 2011 21:44:48
Mostrar los 6 comentarios restantes
0

Utilizando una combinación de la respuesta de TheDeadMedic y la documentación de get_shortcode_regex() documentación (que en realidad no encontró mis shortcodes), creé una función simple para encolar scripts para múltiples shortcodes. Dado que wp_enqueue_script() en shortcodes solo añade al footer, esto puede ser útil ya que maneja tanto scripts para el header como para el footer.


function add_shortcode_scripts() {
    global $wp_query;   
    $posts = $wp_query->posts;
    $scripts = array(
        array(
            'handle' => 'map',
            'src' => 'http://maps.googleapis.com/maps/api/js?sensor=false',
            'deps' => '',
            'ver' => '3.0',
            'footer' => false
        ),
        array(
            'handle' => 'contact-form',
            'src' => get_template_directory_uri() . '/library/js/jquery.validate.min.js',
            'deps' => array( 'jquery' ),
            'ver' => '1.11.1',
            'footer' => true
        )   
    );

    foreach ( $posts as $post ) {
        foreach ( $scripts as $script ) {
            if ( preg_match( '#\[ *' . $script['handle'] . '([^\]])*\]#i', $post->post_content ) ) {
                // encolar css y/o js
                if ( wp_script_is( $script['handle'], 'registered' ) ) {
                    return;
                } else {
                    wp_register_script( $script['handle'], $script['src'], $script['deps'], $script['ver'], $script['footer'] );
                    wp_enqueue_script( $script['handle'] );
                }
            }
        }
    }
}
add_action( 'wp', 'add_shortcode_scripts' );
30 nov 2013 21:52:06
1

Finalmente también encontré una solución para la carga condicional de CSS que funciona para mi plugin www.mapsmarker.com y me gustaría compartirla con ustedes. Verifica si mi shortcode se utiliza dentro del archivo de plantilla actual y en header.php/footer.php, y si es así, encola la hoja de estilos necesaria en el encabezado:

  function prefix_template_check_shortcode( $template ) {
    $searchterm = '[mapsmarker';
    $files = array( $template, get_stylesheet_directory() . DIRECTORY_SEPARATOR . 'header.php', get_stylesheet_directory() . DIRECTORY_SEPARATOR . 'footer.php' );
    foreach( $files as $file ) {
        if( file_exists($file) ) {
            $contents = file_get_contents($file);
            if( strpos( $contents, $searchterm )  ) {
                wp_enqueue_style('
leafletmapsmarker', LEAFLET_PLUGIN_URL . 'leaflet-dist/leaflet.css');
                  break; 
            }
        }
    }
  return $template;
  }  
  add_action('template_include','prefix_template_check_shortcode' );
12 dic 2012 23:29:42
Comentarios

un poco aparte pero ¿no asume esto que la gente está usando header.php y footer.php? ¿Qué pasa con los métodos de envoltura de temas como los descritos en http://scribu.net/wordpress/theme-wrappers.html? ¿O temas como roots que mantienen sus partes de plantilla en otro lugar?

orionrush orionrush
3 mar 2013 14:32:51
0

Para mi plugin, descubrí que a veces los usuarios tienen un constructor de temas que almacena shortcodes en los metadatos del post. Esto es lo que uso para detectar si el shortcode de mi plugin está presente en el post actual o en sus metadatos:

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

       // determinar si esta página contiene el shortcode "my_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' );
6 nov 2015 02:24:01
14

porque el CSS debe declararse dentro de <head>

Para archivos CSS puedes cargarlos dentro de la salida de tu shortcode:

<style type="text/css">
  @import "ruta/a/tu/archivo.css"; 
</style>

Establece una constante o similar después de esto, como MI_CSS_CARGADO (solo incluye el CSS si la constante no está definida).

Ambos métodos que mencionas son más lentos que este enfoque.

Para archivos JS puedes hacer lo mismo si el script que estás cargando es único y no tiene dependencias externas. Si este no es el caso, cárgalo en el footer, pero usa la constante para determinar si necesita cargarse o no...

23 jun 2011 18:22:16
Comentarios

Cargar CSS fuera del elemento <head> no es un marcado adecuado. Es cierto que la validación es solo una guía, pero si estamos intentando seguir esa guía, hace que cargar la hoja de estilos dentro del resultado del shortcode sea una mala idea.

EAMann EAMann
23 jun 2011 18:29:09

Los bloques de CSS en línea son marcado válido, incluso en XHTML según lo que recuerdo. No hay razón para no usarlos cuando no tienes otra alternativa aceptable.

onetrickpony onetrickpony
23 jun 2011 18:32:37

Según la herramienta de validación de W3C: <style type="text/css"> El elemento nombrado arriba fue encontrado en un contexto donde no está permitido. Esto podría significar que has anidado elementos incorrectamente -- como un elemento "style" en la sección "body" en lugar de dentro del "head". Así que los estilos en línea (<element style="..."></element>) son válidos, pero los elementos <style> en línea no lo son.

EAMann EAMann
23 jun 2011 18:36:59

Sí, sé que es una posibilidad, pero se considera una mala práctica. Podría causar FOUC, forzar al navegador a volver a renderizar la página y fallar en el validador W3C. Tampoco funcionará con wp_enqueue_style(), haciendo imposible que otros desarrolladores de temas/plugins puedan sustituir fácilmente sus propios scripts/estilos.

Ian Dunn Ian Dunn
23 jun 2011 18:41:04

@EAMann. Cierto, error mío, pensé que validaría. Aún así, la validación W3C no significa nada...

onetrickpony onetrickpony
23 jun 2011 18:43:17

@One Trick Pony Em... Significa algo para mí. Y significa algo para cualquier otro desarrollador que respeto. No la sigo ciegamente, pero sería raro que considere aceptable cualquier cosa que rompa los estándares.

Ian Dunn Ian Dunn
23 jun 2011 18:49:06

Si no lo sigues ciegamente, ¿puedes proporcionar razones por las cuales esta práctica es mala?

onetrickpony onetrickpony
23 jun 2011 18:51:00

Di 4 razones en mi comentario anterior...

Ian Dunn Ian Dunn
23 jun 2011 19:11:02

Se considera una mala práctica, pero esto es precisamente lo que hace el shortcode de galería del núcleo de WordPress: imprime un bloque css en línea. Es un poco mejor que usar el atributo style y funciona. Mi plugin que tiene un shortcode simplemente imprime el css en el head en cada vista. No hay mucho de ello :)

mfields mfields
23 jun 2011 19:42:13

@mfields, si hago eso, otros desarrolladores de temas/plugins no podrían reemplazar los archivos con los suyos. No importa si el núcleo lo hace, sigue siendo una mala práctica.

Ian Dunn Ian Dunn
23 jun 2011 19:47:29

hazlo filtrable y cualquier otro plugin o tema puede hacer lo que quiera con él. Si configuran el filtro para devolver una cadena vacía, no se imprimirá nada.

mfields mfields
23 jun 2011 19:51:50

No mencionaste ninguna razón objetiva en contra de esta práctica. De todos modos no importa; solo veo dos opciones aquí: Cargar siempre CSS/scripts (optimizándolos en tamaño), o estilos en línea condicionales

onetrickpony onetrickpony
23 jun 2011 20:01:08

@mfields, ese es un buen punto, pero prefiero el enfoque de enqueue_style.

Ian Dunn Ian Dunn
23 jun 2011 21:09:49

@One Trick Pony, creo que estás equivocado, pero estoy cansado de discutir sobre eso.

Ian Dunn Ian Dunn
23 jun 2011 21:10:02
Mostrar los 9 comentarios restantes