Here is a handy design pattern for developing wordpress widgets. For this post, we will be generating a sidebar widget with a title and text body. The title corresponds to another page within your wordpress site and hyperlinks to that page. Here is an example of what we are going for:
First, start by creating a shortcode that handles generating your output:
function pixo_pagelink_shortcode( $atts, $content = null ) { $title = $atts['title']; if ($title == '') { return '<p>No page supplied</p>'; } $url = get_page_url_by_title($title); if ($url=='') { return '<p>Page not found: '.$title.'</p>'; } $output = '<div class="page-link">'; $output .= '<p class="page-link-title">'; $output .= '<a href="' . $url . '">' . $title . ' &#xbb;</a>'; $output .= '</p>'; $output .= '<p class="page-link-content">'.$content.'</p>'; $output .= '</div>'; // return do_shortcode( $output ); } add_shortcode( 'pagelink', 'pixo_pagelink_shortcode' );
get_page_url_by_title
is a custom function I wrote because wordpress does not have a core function to do this in a single step:
function get_page_url_by_title( $page_title ) { $page = get_page_by_title( html_entity_decode($page_title) ); if ($page == null) { return ''; } $url = get_permalink( $page->ID ); return $url; }
At this point, you can drop your short code into any page or post to verify it works correctly. Now we move onto your widget, which essentially becomes a wrapper to the shortcode. Here the widget form elements are passed directly as attributes and content to your shortcode. Continuing the example from above…
class pixo_pagelink_widget extends WP_Widget { public function __construct() { // constructor code parent::__construct( 'pixo_pagelink_widget', // base ID 'Pagelink Widget', array( 'description' => 'Add a sidebar link to another page in your site.') ); } public function widget( $args, $instance ) { // outputs content of the widgetarea if ($instance['title'] == '') { return; } $shortcode = '[pagelink title="' . $instance['title'] . '"]' . $instance['blurb'] . '[/pagelink]'; echo $args['before_widget']; echo do_shortcode( $shortcode ); echo $args['after_widget']; } public function form( $instance ) { // outputs the options form on the admin screen if ( isset( $instance[ 'title' ] ) ) { $title = $instance[ 'title' ]; } else { $title = ''; } if ( isset( $instance[ 'blurb' ] ) ) { $blurb = $instance[ 'blurb' ]; } else { $blurb = ''; } ?> <p> <label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e('Page Title:'); ?></label> <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 for="<?php echo $this->get_field_id( 'blurb' ); ?>"><?php _e('Text:'); ?></label> <textarea class="widefat" id="<?php echo $this->get_field_id('blurb'); ?>" name="<?php echo $this->get_field_name('blurb'); ?>" type="text"><?php echo esc_attr($blurb); ?></textarea> </p> <?php } public function update( $new_instance, $old_instance ) { // processes widget options to be saved $instance = array(); $instance['title'] = ( ! empty($new_instance['title']) ) ? strip_tags( $new_instance['title']): ''; $instance['blurb'] = ( ! empty($new_instance['blurb']) ) ? strip_tags( $new_instance['blurb']): ''; return $instance; } } add_action( 'widgets_init', create_function( '', 'return register_widget("pixo_pagelink_widget");') );
Taking this approach offers two benefits:
- Reducing the complexity of your code by breaking up functionality into components.
- Better reusability. What if the client decides they want this not just in a sidebar, but in a post body too
- Better testability. No chance of confusing an error in your widget as a problem with the shortcode
Recent Comments
4.26.2018 - MSSQL Long Text Field Truncated In PHP
4.22.2018 - MSSQL SmallDateTime Field Can Cause PHP To Silently Crash
4.12.2018 - VIN Barcode Scanner Product Innovation
4.7.2018 - Drupal 8 Roadmap
3.24.2018 - VIN Barcode Scanner Product Innovation