Ponga en cola condicionalmente el guión / hoja de estilo de un widget en HEAD (¡solo cuando esté presente en la página!)

13

He estado tratando de cargar scripts y estilos para un widget de WordPress con las siguientes condiciones ...

  1. Las secuencias de comandos DEBEN cargarse en la CABEZA (de lo contrario se rompen).
  2. Las secuencias de comandos SOLO deben cargarse cuando el widget realmente se muestra (son bastante pesadas).

He realizado muchas búsquedas, y este parece ser un problema común (no resuelto) ... pero espero que alguien aquí haya implementado con éxito una solución alternativa.

Esto es lo mejor que tengo hasta ahora ...

El siguiente es un widget simple que imprime texto en la barra lateral. Carga con éxito jQuery condicionalmente (cuando el widget se muestra realmente) ... ¡aunque solo en el pie de página! (Nota: también puede funcionar solo en WordPress 3.3 , aunque este truco puede proporcionar compatibilidad con versiones anteriores).

class BasicWidget extends WP_Widget
{

    function __construct() {
        parent::__construct(__CLASS__, 'BasicWidget', array(
            'classname' => __CLASS__,
            'description' => "This is a basic widget template that outputs text to the sidebar"
        ));
    }

  function form($instance) {
    $instance = wp_parse_args( (array) $instance, array( 'title' => '' ) );
    $title = $instance['title'];
?>
  <p><label for="<?php echo $this->get_field_id('title'); ?>">Title: <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo esc_attr($title); ?>" /></label></p>
<?php
  }

  function update($new_instance, $old_instance) {
    $instance = $old_instance;
    $instance['title'] = $new_instance['title'];
    return $instance;
  }

  function widget($args, $instance) {

    extract($args, EXTR_SKIP);

    echo $before_widget;
    $title = empty($instance['title']) ? ' ' : apply_filters('widget_title', $instance['title']);

    if (!empty($title))
      echo $before_title . $title . $after_title;;

    echo "<h1>This is a basic widget!</h1>";

    echo $after_widget;

        // if we're echoing out content, enqueue jquery.

        if (!empty($after_widget)) {
            wp_enqueue_script('jquery');
        }
    }
}
add_action( 'widgets_init', create_function('', 'return register_widget("BasicWidget");') );

Parece que una vez que WordPress comienza a manejar widgets, es demasiado tarde para poner en cola (o incluso cancelar el registro de algo en cola antes).

¡Cualquier idea sería muy apreciada!

Marca.

Mark Jeldi
fuente

Respuestas:

15

Wordpress como una buena función is_active_widgetque puede usar en su __construir y probar si el widget está presente en la página actual y agregar sus scripts / estilos basados ​​en ese ejemplo:

function __construct() {
    parent::__construct(__CLASS__, 'BasicWidget', array(
        'classname' => __CLASS__,
        'description' => "This is a basic widget template that outputs text to the sidebar"
    ));
     if ( is_active_widget(false, false, $this->id_base) )
        add_action( 'wp_head', array(&$this, 'add_styles_and_scripts') );
}

function add_styles_and_scripts(){
    //since its wp_head you need to echo out your style link:
    echo '<link rel="stylesheet" href="http://example.com/css/style.css" type="text/css" />';
    //as for javascript it can be included using wp_enqueue_script and set the footer parameter to true:
    wp_enqueue_script( 'widget_script','http://example.com/js/script.js',array(),'',true );
}
Bainternet
fuente
Gracias por tu respuesta, Bainternet! Acabo de probar su código y desafortunadamente, aunque el javascript se carga condicionalmente, todavía se carga en el pie de página ... a pesar de que se llama en wp_head. ¡Muy extraño! (por cierto, todavía hace esto sin la instrucción de pie de página "verdadera"). Además, hacer eco de la hoja de estilo hace que se cargue independientemente de si el widget está en la página. ¿Algunas ideas?
Mark Jeldi
wp_headse llama después de que los scripts del encabezado ya están impresos, por lo que solo los cargará en el pie de página, pero puede reproducirlo (en lugar de ponerlo en cola) al igual que la hoja de estilo que usa echo '<script src="path/to/script.js"></script>';y, en cuanto a la hoja de estilo, no es posible que esté cargada es que los widgets no están activos
Bainternet 02 de
intente usar en wp_enqueue_scriptslugar de wp_headen su acción. Esto le permitirá poner el javascript en el encabezado o en el pie de página. http://codex.wordpress.org/Function_Reference/wp_enqueue_script
Nick
Gracias Nick! Intenté wp_enqueue_scripts, y aunque carga el javascript en la cabeza, no se cargará condicionalmente.
Mark Jeldi
0

Alternativamente, puede probar el complemento "Widget Logic" ... usa declaraciones condicionales para la carga del widget.

Eso es bastante al revés, pero el resultado debería ser el esperado.

wp_print_scripts & wp_print_styles pueden ser los ganchos adecuados, solo agregue acciones a estos ganchos con prioridad 100 algo, para ser el último en la cola. wp_enqueue_script (), wp_enqueue_style (), wp_deregister_script (), wp_deregister_style () ...

¿Es posible que sus problemas con el código anterior no tengan el parámetro de prioridad (no probado)? WP codex

Martin Zeitler
fuente
Gracias syslogic! También probé Widget Logic, pensando que podía conectarme a su filtro widget_content. Sin suerte, lamentablemente. Utiliza ob_start para amortiguar la salida del widget para que pueda manipularlo antes de que se imprima en la pantalla, pero esto todavía sucede demasiado tarde para disparar cualquier cosa en la cabeza. ¿A menos que tal vez conozca una solución alternativa?
Mark Jeldi
¿Quizás una combinación de la solución de Bainternet que parece estar bien con la lógica de widgets? De esta manera, podría definir qué widget cargar y dónde, y también qué se cargará. Agregar declaraciones condicionales propias a las funciones de un tema.php podría ayudar a mejorar aún más.
Martin Zeitler
-1

Simplemente puede usar wp_enqueue_script o wp_enqueue_style en el método de widget (función) en su clase Widget personalizada y cargará los scripts solo si el widget está activo. Ver detalles y ejemplo aquí: https://wpshed.com/wordpress/load-scripts-styles-widget-active/

iStefan
fuente
Las respuestas de solo enlace son malas ya que los enlaces se rompen con el tiempo. Al menos deberías resumir lo que hay en el enlace. En cualquier caso, eso es simplemente incorrecto, ya que el OP necesita los scripts en el encabezado de la página.
Mark Kaplun
function widget( $args, $instance ) { wp_enqueue_script( 'wpshed-front-end', plugin_dir_url( __FILE__ ) . 'wpshed-front-end.js', array( 'jquery' ), '1.0.0', false ); }El "falso" en el y se refiere a cargar el script en el encabezado o pie de página. Para resumir nuevamente, use wp_enqueue_script o wp_enqueue_style en el método del widget (función) . Así es como los desarrolladores de WordPress.com/org lo están haciendo.
iStefan
El comentario debería haber sido una edición de la respuesta;) pero cuando el widget se "muestra" ya ha hecho la parte principal de la página y por lo tanto no puede poner JS en ella.
Mark Kaplun