Our Blog

Related Posts

Automating Plugin/Module Updates on Pantheon. We automated the process to apply plugin and module updates on Pantheon sites with a simple command.

Listen to Pixo and Four Kitchens' case studies on how we decoupled Drupal and Wordpress site architectures to separate CMS content from the front end.

How to achieve Pantheon's one-click-update functionality for Drupal and Wordpress while retaining your git history using git-graft.

Popular Tags

Recent Comments

Cameron Macintosh

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:
widget-1

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 . ' &amp;#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

Comments

2 thoughts on “WordPress Design Pattern: Shortcode Powered Widgets

  1. Thanks for this!

    It’s helped me to advance my thinking a little about integrating different aspects of a CMS project I’ve inherited and need to keep developing. I hadn’t ever done much with shortcodes, and was also facing the prospect writing a lot of redundant sidebar code, when I came across your pattern and it sort of clicked.

    So here’s an outline of my new “use case” for your pattern:

    I took some existing code I had written for bringing related posts into the sidebar, and re-wrote it as a shortcode — then added a widget to leverage the same shortcode in other contexts.

    The shortcode takes (at this point) just two parameters — the name of a tag and number of posts to show — and pulls that number of the most-recent posts with that tag name. My blog contributors will be able to use this shortcode to specify (for example) some “further reading” at the end of a post, and if they’ve thought ahead and cleverly tagged some other posts just for this purpose, up they’ll pop (just title and permalink for now).

    Where your pattern will figure in is at the next-higher level of content organization, when I decide how I want to group contributors, and modify “single.php” to show a different sidebar for each group (architects, researchers, policy analysts, whatever). In those sidebars will be, among other specific customizations, a widget to pull up “related posts” via the same shortcode mechanism, this time controlled by me via the admin, and being more generic in what I target.

    No doubt there are plugins for this already, but it made a great learning experience.

    As an example of how I’m using it in the sidebar:
    http://ghdc.generationsofhope.org/publications/ghdc-architecture-site-design-guidelines/

    I’ll link to a fuller write-up when I get time.

    Reply

Leave a reply

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> 

required

Related Posts

Automating Plugin/Module Updates on Pantheon. We automated the process to apply plugin and module updates on Pantheon sites with a simple command.

Listen to Pixo and Four Kitchens' case studies on how we decoupled Drupal and Wordpress site architectures to separate CMS content from the front end.

How to achieve Pantheon's one-click-update functionality for Drupal and Wordpress while retaining your git history using git-graft.

Recent Comments

Interested in working with us?
CONTACT US