Wordpress widget update instances for items that n

2019-06-20 06:47发布

问题:

Recently I realized I do not utilize widgets in WordPress enough when developing sidebars in themes so I have spent the last couple of days researching how to develop them properly. After reviewing a lot of tutorials I have found a number of them on custom building widgets to be outdated. I did see where I should use the construct:

function __construct() {
    parent::__construct(
    // Base ID of your widget
    'foobar_widget', 
    // Widget name will appear in UI
    __('Give them foo Widget', 'foobar_widget_domain'), 
    // Widget description
    array( 'description' => __( 'Development widget for testing', 'foobar_widget_domain' ), ) 
    );
}

The codex is very minimal when it comes to custom widgets. After browsing SO's tags wordpress-widget and widget I didn't see a solution when calling an update for the widget if a textarea is needing tags. A large number of people show calling the title instance as:

$instance['title'] = ( ! empty( $new_instance['title'] ) ) ? strip_tags( $new_instance['title'] ) : '';

In my function form() I am needing a textarea that will take user input code, like a copied Google Adsense ad. The following works but I am unsure if there is a better approach to accepting input from the form:

// Updating widget replacing old instances with new
public function update( $new_instance, $old_instance ) {
    $instance = array();
    $instance['title'] = ( ! empty( $new_instance['title'] ) ) ? strip_tags( $new_instance['title'] ) : '';
    $instance['foo1'] = $new_instance['foo1'];
    return $instance;
    }
}

Is there a better way to return the $instance when you need tags without using PHP's strip_tags() ?

回答1:

I use following awesome code snippet to register a custom widget which takes any HTML

add_action('widgets_init', create_function('', 'register_widget("clean_markup_widget");'));
class Clean_Markup_Widget extends WP_Widget {
    function __construct() {
        parent::WP_Widget('clean_markup_widget', 'ASR Custom Text Widget', array('description'=>'Simple widget for well-formatted markup & text'));
    }
    function widget($args, $instance) {
        extract($args);
        $markup = $instance['markup'];
        //echo $before_widget;
        if ($markup) echo $markup;
        //echo $after_widget;
    }
    function update($new_instance, $old_instance) {
        $instance = $old_instance;
        $instance['markup'] = $new_instance['markup'];
        return $instance;
    }
    function form($instance) {
        if ($instance) $markup = esc_attr($instance['markup']);
        else $markup = __('<p>Clean, well-formatted markup.</p>', 'markup_widget'); ?>
        <p>
            <label for="<?php echo $this->get_field_id('markup'); ?>"><?php _e('Markup/text'); ?></label><br />
            <textarea class="widefat" id="<?php echo $this->get_field_id('markup'); ?>" name="<?php echo $this->get_field_name('markup'); ?>" type="text" rows="16" cols="20" value="<?php echo $markup; ?>"><?php echo $markup; ?></textarea>
        </p>
<?php }
}


回答2:

Is there a better way to return the $instance when you need tags without using PHP's strip_tags() ?

Yes! WordPress has many ways to validate and sanitize user data.

For your case wp_kses_post() should work very well.

It's description is: Sanitize content for allowed HTML tags for post content.

It uses a default list of allowed tags, which you can find in wp-includes/kses.php.

If you wish to only allow specific tags the safest way to do that is by using wp_kses() instead of wp_kses_post().

The difference being that wp_kses() requires a second parameter for $allowed_html instead of using the $allowedposttags global variable.

There are ways to filter or override the $allowedposttags global variable but are probably not the best idea in this case since they will effect other HTML, like post content, in addition to your widget.

You update function with wp_kses_post() would look like this:

// Updating widget replacing old instances with new
public function update( $new_instance, $old_instance ) {
    $instance = array();
    $instance['title'] = ( ! empty( $new_instance['title'] ) ) ? strip_tags( $new_instance['title'] ) : '';
    $instance['foo1'] = wp_kses_post( $new_instance['foo1'] );
    return $instance;
}