Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I have a wordpress widget that has the standard outline like:

class my_widget extends WP_Widget{

function my_widget(){
   //do setup stuff
}

function form(){
   //do form stuff
}

function update(){
   //do update stuff
}

function widget($args, $instance){
   //how can we dynamically add style and script here

   //this does not work
   if($instance['val'] == 'test'){
      wp_register_script('test', plugins_url('test.js');
      wp_print_scripts('test');
   }else{
      wp_register_script('diff', plugins_url('diff.js');
      wp_print_scripts('diff');
   }
}

}

I am wondering if it's possible to somehow add scripts dynamically to a wordpress widget... I am guessing that this would have to take place within the widget() method b/c that is the only place where dynamic variables are passed, but the problem is this function appears to be fired after scripts are added.

thanks for your thoughts

share|improve this question
    
How many different scripts are there? Just two? I once used an approach where I registered the scripts for the footer, enqueued them, and then set a automatic hook to dequeue the scripts before they were displayed. If I did display the widget I removed the dequeue hook. Weird, but it worked. Tell me if that would work for you and I'll look up the code. –  Jan Fabry May 4 '11 at 15:03
    
If you are able to locate this code that would be great. I think that is just what I need. I was not able to add scripts to the footer with the wp_widget() function however. Also it sounds like this will not work for style sheets. –  mike May 9 '11 at 2:59
add comment

4 Answers 4

This widget enqueues all possible required scripts for the footer, but it also sets a hook on wp_print_footer_scripts that will deregister the scripts before they are printed, unless you change the array when printing the widget.

class WPSE16208_Widget extends WP_Widget
{
    // Key is script handle, value is boolean:
    // true if it should be printed, false otherwise
    protected $scripts = array();

    public function __construct()
    {
        parent::__construct( 'wpse16208', 'WPSE 16208 Widget' );

        wp_enqueue_script(
            'wpse16208_a',
            plugins_url( 'a.js', __FILE__ ),
            array(),
            false,
            true
        );
        $this->scripts['wpse16208_a'] = false;
        wp_enqueue_script(
            'wpse16208_b',
            plugins_url( 'b.js', __FILE__ ),
            array(),
            false,
            true
        );
        $this->scripts['wpse16208_b'] = false;

        add_action( 'wp_print_footer_scripts', array( &$this, 'remove_scripts' ) );
    }

    public function widget()
    {
        echo 'My widget';

        $this->scripts['wpse16208_a'] = true;
    }

    public function remove_scripts()
    {
        foreach ( $this->scripts as $script => $keep ) {
            if ( ! $keep ) {
                // It seems dequeue is not "powerful" enough, you really need to deregister it
                wp_deregister_script( $script );
            }
        }
    }
}
share|improve this answer
add comment

I'm plucking this code out of my Total Widget Control plugin, so it might throw an error or two. I dunno, just let me know if it does. This is basically the widget code that I use for everything that I build.

    if (!function_exists("register_multiwidget")):

/**
 * Register a widget
 * 
 * @param $widget
 */
function register_multiwidget( $widget = null )
{
    static $widgets;
    if (!isset($widgets))
    {
        $widgets = array();
    }

    if (is_null($widget)) return $widgets;
    if (!is_array($widget)) return false;

    $defaults = array(
        'id' => '1',
        'title' => 'Generic Widget',
        'classname' => '',
        'description' => '',
        'width' => 200,
        'height' => 200,
        'fields' => array(),
    );

    $widgets[$widget['id']] = wp_parse_args($widget, $defaults);

    return true;
}

/**
 * Get the registered widgets
 * 
 * @return array
 */
function get_registered_widgets()
{
    return register_multiwidget();
}

/**
 * Initialize the widgets
 * 
 * @return boolean
 */
function init_registered_widgets()
{
    //initialziing variables
    global $wp_widget_factory;
    $widgets = get_registered_widgets();

    //reasons to fail
    if (empty($widgets) || !is_array($widgets)) return false;

    foreach ($widgets as $id => $widget)
    {
        $wp_widget_factory->widgets[$id] =& new Multiple_Widget_Master( $widget );
    }

    return false;
}

/**
 * Multiple Widget Master Class
 * 
 * This class allows us to easily create qidgets without having to deal with the
 * mass of php code.
 * 
 * @author byrd
 * @since 1.3
 */
class Multiple_Widget_Master extends WP_Widget
{

/**
 * Constructor.
 * 
 * @param $widget
 */
function Multiple_Widget_Master( $widget )
{
    $this->widget = apply_filters('twc_widget_setup', $widget);
    $widget_ops = array(
        'classname' => $this->widget['classname'], 
        'description' => $this->widget['description'] 
    );
    $this->WP_Widget($this->widget['id'], $this->widget['title'], $widget_ops);
}

/**
 * Display the Widget View
 * 
 * @example extract the args within the view template
 extract($args[1]); 

 * @param $args
 * @param $instance
 */
function widget($args, $instance)
{
    //initializing variables
    $widget = $this->widget;
    $widget['number'] = $this->number;

    $args = array(
        'sidebar' => $args,
        'widget' => $widget,
        'params' => $instance,
    );

    $show_view = apply_filters('twc_widget_view', $this->widget['show_view'], $widget, $instance, $args);
            ob_start();
            require_once $show_view;
}

/**
 * Update from within the admin
 * 
 * @param $new_instance
 * @param $old_instance
 */
function update($new_instance, $old_instance)
{
    //initializing variables
    $new_instance = array_map('strip_tags', $new_instance);
    $instance = wp_parse_args($new_instance, $old_instance);

    return $instance;
}

/**
 * Display the options form
 * 
 * @param $instance
 */
function form($instance)
{
    //reasons to fail
    if (empty($this->widget['fields'])) return false;
    do_action('twc_widget_before');

    $defaults = array(
        'id' => '',
        'name' => '',
        'desc' => '',
        'type' => '',
        'options' => '',
        'std' => '',
    );

    foreach ($this->widget['fields'] as $field)
    {
        $field = wp_parse_args($field, $defaults);


        if (isset($field['id']) && array_key_exists($field['id'], $instance))
            $meta = attribute_escape($instance[$field['id']]);

        if ($field['type'] != 'custom' && $field['type'] != 'metabox') 
        {
            echo '<p><label for="',$this->get_field_id($field['id']),'">';
        }
        if (isset($field['name']) && $field['name']) echo $field['name'],':';

        switch ($field['type'])
        {
            case 'text':
                echo '<input type="text" name="', $this->get_field_name($field['id']), '" id="', $this->get_field_id($field['id']), '" value="', $meta ? $meta : $field['std'], '" class="twc_text" />', 
                '<br/><span class="description">', $field['desc'], '</span>';
                break;
            case 'textarea':
                echo '<textarea class="twc_textarea" name="', $this->get_field_name($field['id']), '" id="', $this->get_field_id($field['id']), '" cols="60" rows="4" style="width:97%">', $meta ? $meta : $field['std'], '</textarea>', 
                '<br/><span class="description">', $field['desc'], '</span>';
                break;
            case 'select':
                echo '<select class="twc_select" name="', $this->get_field_name($field['id']), '" id="', $this->get_field_id($field['id']), '">';
                foreach ($field['options'] as $option)
                {
                    echo '<option', $meta == $option ? ' selected="selected"' : '', '>', $option, '</option>';
                }
                echo '</select>', 
                '<br/><span class="description">', $field['desc'], '</span>';
                break;
            case 'radio':
                foreach ($field['options'] as $option)
                {
                    echo '<input class="twc_radio" type="radio" name="', $this->get_field_name($field['id']), '" value="', $option['value'], '"', $meta == $option['value'] ? ' checked="checked"' : '', ' />', 
                    $option['name'];
                }
                echo '<br/><span class="description">', $field['desc'], '</span>';
                break;
            case 'checkbox':
                echo '<input type="hidden" name="', $this->get_field_name($field['id']), '" id="', $this->get_field_id($field['id']), '" /> ', 
                     '<input class="twc_checkbox" type="checkbox" name="', $this->get_field_name($field['id']), '" id="', $this->get_field_id($field['id']), '"', $meta ? ' checked="checked"' : '', ' /> ', 
                '<br/><span class="description">', $field['desc'], '</span>';
                break;
            case 'custom':
                echo $field['std'];
                break;
            case 'metabox':
                if ((isset($_REQUEST['action']) && $_REQUEST['action'] == 'edit')
                || (isset($_REQUEST['action']) && $_REQUEST['action'] == 'add' && isset($_REQUEST['addnew'])))
                echo '</div>
                </div>
                <div id="query_view_params" class="postbox">
                    <div class="handlediv" title="Click to toggle"><br></div>
                    <h3 class="hndle">
                        <span>Query View Parameters</span>
                    </h3>
                    <div class="inside">';
                break;
        }

        if ($field['type'] != 'custom' && $field['type'] != 'metabox') 
        {
            echo '</label></p>';
        }
    }
    do_action('twc_widget_after');
    return;
}

}// ends Master Widget Class
endif;

Now, once you've pasted this into your functions.php file you can start declaring new widgets in seconds. Here's the code to declare a new widget.

    register_multiwidget(array(
'id' => 'first-custom-widget',  // Must be slug compatible, and unique, it's used a lot
'title' => __('aaaFirst Widget'),   
'description' => __('This is my description'),  
'classname' => 'st-custom-wi',  
'show_view' => 'path/to/my/widget_view_file.php',
'fields' => array(
array(
    'name' => 'Text box',
    'desc' => 'Enter something here',
    'id' => 'text',
    'type' => 'text',
    'std' => 'Default value 1'
),
array(
    'type' => 'custom',
    'std' => '<hr/>'
),
array(
    'name' => 'Textarea',
    'desc' => 'Enter big text here',
    'id' => 'textarea',
    'type' => 'textarea',
    'std' => 'Default value 2'

),
array(
    'name' => 'Select box',
    'id' => 'select',
    'type' => 'select',
    'options' => array('Option 1', 'Option 2', 'Option 3')
),
array(
    'name' => 'Radio',
    'id' => 'radio',
    'type' => 'radio',
    'options' => array(
    array('name' => 'Name 1', 'value' => 'Value 1'),
    array('name' => 'Name 2', 'value' => 'Value 2')
    )
),
array(
    'name' => 'Checkbox',
    'id' => 'checkbox',
    'type' => 'checkbox'
),

)
    ));

Declare whatever fields that you want for your widget options with the array above and you're almost done.

The last thing that you need to do is paste your widgets html into your new file path/to/my/widget_view_file.php

At the top of this widget view file add this following code: <?php extract($args[1]); ?> This will break out three variables for you to use:

  1. $sidebar
  2. $widget
  3. $params
share|improve this answer
add comment

Are you looking to have a script only trigger when the widget is being used?

share|improve this answer
    
no, i am looking to dynamically include scripts within a widget, based on the widget $instance –  mike May 4 '11 at 0:47
add comment

You could extend the WP_Widget class and add your init stuff to the constructor or overload the widget() method with your modified code. E.g.

class WPSE_16208_Widget extends WP_Widget {
    function __construct( $id_base = false, $name, $widget_options = array(), $control_options = array() ) {
        parent::__construct($id_base, $name, $widget_options, $control_options);

        // do your stuff on init
    }

    function widget() {
        // overload WP_Widget::widget()
    }
}
share|improve this answer
    
this still does not allow me to dynamically add scripts to the page. I would not be able to add scripts/ style to widget(), and i still cannot send arguments to __construct() –  mike May 4 '11 at 0:45
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.