Mettre en file d'attente conditionnelle le script / la feuille de style d'un widget dans HEAD (uniquement lorsqu'il est présent sur la page!)

13

J'ai essayé de charger des scripts et des styles pour un widget WordPress avec les conditions suivantes ...

  1. Les scripts DOIVENT se charger dans la TETE (sinon ils se cassent).
  2. Les scripts doivent se charger UNIQUEMENT lorsque le widget s'affiche réellement (ils sont assez lourds).

J'ai fait beaucoup de recherches, et cela semble être un problème courant (non résolu) ... mais j'espère que quelqu'un ici a réussi à mettre en œuvre une solution de contournement.

C'est le meilleur que j'ai eu jusqu'à présent ...

Ce qui suit est un widget simple qui imprime du texte dans la barre latérale. Il charge avec succès jQuery conditionnellement (lorsque le widget est réellement affiché) ... mais seulement dans le pied de page! (Remarque: il peut également ne fonctionner que sur WordPress 3.3 , bien que ce hack puisse fournir une compatibilité descendante).

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");') );

Il semble qu'une fois que WordPress commence à gérer les widgets, il est trop tard pour mettre en file d'attente (ou même annuler l'enregistrement de quelque chose mis en file d'attente plus tôt).

Toutes les idées seraient très appréciées!

Marque.

Mark Jeldi
la source

Réponses:

15

Wordpress comme une belle fonction is_active_widgetque vous pouvez utiliser dans votre __construct et tester si le widget est présent dans la page actuelle et ajouter vos scripts / styles en fonction de cet ex:

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
la source
Merci pour votre réponse, Bainternet! Je viens de tester votre code et malheureusement, bien que le javascript se charge effectivement de manière conditionnelle, il se charge toujours dans le pied de page ... même s'il est appelé dans wp_head. Très étrange! (btw, il le fait toujours sans l'instruction "true" footer). En outre, l'écho de la feuille de style la charge, que le widget se trouve sur la page ou non. Des idées?
Mark Jeldi
wp_headest appelé une fois que les scripts de tête sont déjà imprimés, il ne les chargera que dans le pied de page, mais vous pouvez les reproduire (au lieu de les mettre en file d'attente) tout comme la feuille de style echo '<script src="path/to/script.js"></script>';et quant à la feuille de style, il n'est pas possible qu'elle soit chargée est que les widgets ne sont pas actifs
Bainternet
essayez d'utiliser wp_enqueue_scriptsau lieu de wp_headdans votre action. Cela vous permettra de mettre le javascript dans la tête ou le pied de page. http://codex.wordpress.org/Function_Reference/wp_enqueue_script
Nick
Merci, Nick! J'ai essayé wp_enqueue_scripts, et bien qu'il charge le javascript dans la tête, il ne se chargera pas conditionnellement.
Mark Jeldi
0

Alternativement, vous pouvez essayer le plug-in "Widget Logic" ... il utilise des instructions conditionnelles pour le chargement du widget.

C'est tout à fait le contraire - mais le résultat devrait être comme prévu.

wp_print_scripts & wp_print_styles peuvent être les bons hooks, ajoutez simplement des actions à ces hooks avec la priorité 100 quelque chose - pour être le tout dernier dans la file d'attente. wp_enqueue_script (), wp_enqueue_style (), wp_deregister_script (), wp_deregister_style () ...

Vos problèmes avec le code ci-dessus peuvent ne pas avoir le paramètre de priorité (non testé)? Codex WP

Martin Zeitler
la source
Merci Syslogic! J'ai également essayé Widget Logic, pensant que je pouvais me connecter à son filtre widget_content. Pas de chance malheureusement. Il utilise ob_start pour tamponner la sortie du widget afin que vous puissiez le manipuler avant qu'il ne soit imprimé à l'écran, mais cela se produit encore trop tard pour déclencher quoi que ce soit dans la tête. À moins que vous ne connaissiez peut-être une solution?
Mark Jeldi
Peut-être une combinaison de la solution de Bainternet qui semble très bien avec la logique des widgets? De cette façon, vous pouvez définir quel widget charger où - et aussi ce qui doit être chargé. L'ajout de propres instructions conditionnelles au functions.php d'un thème peut aider à améliorer davantage.
Martin Zeitler
-1

Vous pouvez simplement utiliser wp_enqueue_script ou wp_enqueue_style dans la méthode (fonction) du widget dans votre classe Widget personnalisée et il ne chargera les scripts que si le widget est actif. Voir les détails et l'exemple ici: https://wpshed.com/wordpress/load-scripts-styles-widget-active/

iStefan
la source
Les réponses de lien uniquement sont tout simplement mauvaises car les liens rompent avec le temps. Vous devez au moins résumer le contenu du lien. Dans tous les cas, c'est juste faux, car l'OP a besoin des scripts dans l'en-tête de la page.
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 ); }Le "faux" au et fait référence au chargement du script dans l'en-tête ou le pied de page. Pour résumer à nouveau, utilisez wp_enqueue_script ou wp_enqueue_style dans la méthode widget (fonction) . C'est ainsi que les développeurs de WordPress.com/org le font.
iStefan
Le commentaire aurait dû être une modification de la réponse;) mais lorsque le widget est "affiché", vous avez déjà fait la partie tête de la page et ne pouvez donc pas mettre JS en file d'attente sans cela.
Mark Kaplun