Warunkowo kolejkuj skrypt / arkusz stylów widgetu w HEAD (tylko jeśli jest obecny na stronie!)

13

Próbowałem załadować skrypty i style dla widgetu WordPress z następującymi warunkami ...

  1. Skrypty MUSZĄ ładować się do HEAD (w przeciwnym razie się zepsują).
  2. Skrypty muszą się ładować TYLKO wtedy, gdy widżet faktycznie się wyświetla (są dość ciężkie).

Przeprowadziłem wiele poszukiwań i wydaje się, że jest to powszechny (nierozwiązany) problem ... ale mam nadzieję, że ktoś tutaj pomyślnie wdrożył obejście.

To najlepsze, jakie dotychczas miałem ...

Poniżej znajduje się prosty widget, który drukuje tekst na pasku bocznym. Z powodzeniem ładuje jQuery warunkowo (gdy widżet jest faktycznie wyświetlany) ... choć tylko w stopce! (Uwaga: może również działać tylko na WordPress 3.3 , chociaż ten hack może zapewnić zgodność wsteczną).

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

Wydaje się, że gdy WordPress zacznie obsługiwać widżety, jest już za późno, aby umieścić je w kolejce (a nawet wyrejestrować coś zamaskowanego wcześniej).

Jakiekolwiek pomysły będą mile widziane!

Znak.

Mark Jeldi
źródło

Odpowiedzi:

15

Wordpress jako przyjemna funkcja is_active_widget, której można użyć w __construct i przetestować, czy widżet jest obecny na bieżącej stronie i dodać swoje skrypty / style na podstawie tego np .:

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
źródło
Dzięki za odpowiedź, Bainternet! Właśnie testowałem twój kod i niestety, podczas gdy javascript rzeczywiście ładuje się warunkowo, nadal ładuje się w stopce ... mimo że jest wywoływany w wp_head. Bardzo dziwny! (przy okazji nadal robi to bez „prawdziwej” instrukcji stopki). Ponadto echo arkusza stylów powoduje, że ładuje się on niezależnie od tego, czy widżet znajduje się na stronie. Jakieś pomysły?
Mark Jeldi,
wp_headjest wywoływany po wydrukowaniu skryptów głównych, więc załaduje je tylko w stopce, ale możesz je echo (zamiast umieszczać w kolejce), podobnie jak w przypadku arkusza stylów używanego echo '<script src="path/to/script.js"></script>';i, podobnie jak w przypadku arkusza stylów, nie jest możliwe, aby został załadowany to widżety nie są aktywne
Bainternet,
spróbuj użyć wp_enqueue_scriptszamiast wp_headw akcji. Umożliwi to wstawienie javascript do nagłówka lub stopki. http://codex.wordpress.org/Function_Reference/wp_enqueue_script
Nick
Dzięki, Nick! Próbowałem wp_enqueue_scripts i chociaż ładuje javascript do głowy, nie ładuje się warunkowo.
Mark Jeldi
0

Alternatywnie możesz wypróbować wtyczkę „Widget Logic” ... używa ona instrukcji warunkowych do ładowania widżetu.

To całkiem odwrotne myślenie - ale wynik powinien być zgodny z oczekiwaniami.

wp_print_scripts & wp_print_styles mogą być odpowiednimi hakami, po prostu dodaj akcje do tych haków z priorytetem 100 coś - aby być ostatnim w kolejce. wp_enqueue_script (), wp_enqueue_style (), wp_deregister_script (), wp_deregister_style () ...

W Twoich problemach z powyższym kodem może brakować parametru priorytetu (nie testowano)? Kodeks WP

Martin Zeitler
źródło
Dzięki Syslogic! Spróbowałem też Widget Logic, myśląc, że mógłbym podłączyć się do jego filtru widget_content. Niestety, nie ma szczęścia. Wykorzystuje ob_start do buforowania wyjścia widżetu, abyś mógł nim manipulować, zanim zostanie wydrukowany na ekranie, ale wciąż dzieje się to zbyt późno, aby wystrzelić cokolwiek w głowę. Chyba że wiesz o obejściu?
Mark Jeldi
Może kombinacja rozwiązania Bainternet, która wydaje się w porządku z logiką widgetów? W ten sposób możesz określić, który widget ma zostać załadowany - a także co ma zostać załadowane. Dodanie własnych instrukcji warunkowych do funkcji motywu. Php może pomóc w dalszym ulepszaniu.
Martin Zeitler,
-1

Możesz po prostu użyć wp_enqueue_script lub wp_enqueue_style w metodzie widgetu (funkcji) w niestandardowej klasie Widget, a załaduje on skrypty tylko wtedy, gdy widget jest aktywny. Zobacz szczegóły i przykład tutaj: https://wpshed.com/wordpress/load-scripts-styles-widget-active/

iStefan
źródło
Odpowiedzi tylko na łącze są po prostu złe, ponieważ łącza łamią się z czasem. Powinieneś przynajmniej streścić to, co znajduje się w linku. W każdym razie jest to po prostu złe. Ponieważ OP potrzebuje skryptów w nagłówku strony.
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 ); }„Fałsz” na i oznacza ładowanie skryptu w nagłówku lub stopce. Aby podsumować ponownie, użyj wp_enqueue_script lub wp_enqueue_style w metodzie widget (funkcja) . W ten sposób robią to programiści z WordPress.com/org.
iStefan,
Komentarz powinien być edycją odpowiedzi;) ale kiedy widżet jest „wyświetlany”, zrobiłeś już główną część strony i dlatego nie możesz kolejkować JS itno.
Mark Kaplun 11.04.16