A simple little plugin

I’m kinda astounded at how popular the amr-shortcode-any-widget plugin is. The concept and execution is so fairly simple – clever perhaps 😉  but simple.

All it really does is

  • use wp  function to add a sidebar so that any widget settings can be setup using the widgets code
  • add a wordpress shortcode that will use wp functions to run the widget or widget area.  It’ll catch the widget output (so it doesn’t appear at top of the content) and return is as the shortcode so the widget output will appear where you put the shortode.

It certainly doesn’t have any css, any javascript, any jquery, any real settings.  It doesn’t save or create any new files, or impact the .htaccess, or permalinks.  It actually doesn’t do very much at all – truly.

If deactivating the plugin gets rid of an error, it is highly likely that it is because the widget you had in the shortcode sidebar is no longer being used.

Why did it come about?

It started when I wanted a quick fix. I wanted to use Justin Tadlock’s query posts widget plugin – but in a page – to save me having to code up a special template or shortcode.  I realised the key difference between shortcode and widgets and pondered how one could get around this situation where a developer had not offered both a widget and a shortcode or template.

So what is the difference between a widget and a shortcode?

Widgets when called, echo the html straight out. Each piece is output as it is calculated or extracted.

Shortcodes on the other work out the html for each piece and keep building a set of html. The shortcode function returns the total html to the calling code (wordpress). WordPress replaces the [shortcode text] with the html. It does this when it applies the ‘the_content’ filter to the_content.

Know you know this, you can debug these situations:

If you ever see a shortcode plugin that generates the output at the top of the content instead of where the shortcode is, then you know the developer hasn’t quite figured that he or she needs to ‘return’ the html, not ‘echo’ it.

And if the shortcode text just sits there doing nothing after you publish your page, then you know that the theme developer is either ‘not doing it right’ OR perhaps some other plugin is interfering, possibly removing the  ‘the_content’ filters.

How to catch the echoed output and have it appear in the right place?

OK, now the next handy piece is that php lets one buffer the output, rather then letting it echo out directly. So this plugin buffers the output, calls the widget and returns the widget output as the shortcode return value. It does not ‘flush’ the output (else we’d have two lots of the widget html)

Hmm widget settings? how to handle those?

Then I had to find a way for the user to specify the settings for the widget without getting too complicated.

A ‘dummy’ sidebar or widget area was the answer. Users have the same familiar interface. They can test their chosen widget in a normal sidebar and once it works, juts drag and drop that widget into the dummy sidebar.

The plugin knows nothing… well almost nothing

So the plugin does NOT know what widgets are being used, and doesn’t need to know – it’s just calling the widget and catching the widget output to stop it dumping at the top of the content. It then tosses the widget output back out to the shortcode function for wordpress to swop the shortcode text with the output.

That’s the basics.

After that came the extra features that people requested:

  • multiple instances of the same widget meant that id’s had to be used instead of widget names
  • themes where the sidebar background and text was opposite to the page meant that it would be handly to have easy ways to change the css that was being applied, for those who didn’t know how or didnt want to have to add css. Basically one can avoid some css being applied by removing widget classes or changing the html that surrounds the widget – the html tags that the theme is using.
  • then my personal bugbear was when widgets got ‘lost’ when a new theme was tried. So there is a bit of cleverness there to try to remember the widgets being used and add them back in after a new theme activation,
  • and most recently of course the wonderful suggestion to show the widget id at the bottom of the widgets to simplify finding out what id wordpress has assigned to it.

So while it has all these parameters for the shortcode and actually has two shortcodes ( a widget area one too just for fun), all it really does with them, is pass them over to wordpress to pass to the widget, just as wordpress would do when it calls the sidebar code.

Simple.

The “shortcode any widget” handles multiple instances

The shortcode any widget plugin can reference multiple instances of the same widget individually  by targeting the instances unique id.  If you use the general name without the id, it will list all widgets with that name.

EG:

Tags

or

Error: Your requested Widget "Tag Cloud" is not in the "Widgets for Shortcodes" sidebar

  • [do_widget_area sidebar-1]
    • [do_widget_area sidebar-2]
      • [do_widget_area sidebar-3]
        • [do_widget_area widgets_for_shortcodes]
          • [do_widget id="search-3"]
          • [do_widget id="rss-2"]
          • [do_widget id="rss-4"]
        • [do_widget_area wp_inactive_widgets]
          • [do_widget id="search-4"]
          • [do_widget id="search-2"]
          • [do_widget id="recent-posts-2"]
          • [do_widget id="tag_cloud-3"]
          • [do_widget id="text-2"]

        The trick is to be sure that you have the correct id’s, and the id names correct. For example, to double check I added two tag cloud widgets to my play system. The id’s ended up being “tag_cloud-3” and “tag_cloud-4”. You also need a separate do_widget for each – don’t put in the same shortcode
        Note:

        1. the underscore and the hyphen
        2. the fact that they were not numbered 1 and 2, even though I currently had no other tag cloud widgets

        How to find out the widget id?

        In the post or page where you have entered the shortcode, add to the url:

        ?do_widget_debug

        (replace ? with & if you already have a ?)

        If the do_widget shortcode fires, then it will list your sidebars and the widget ids and a bunch of other statements. Find the shortcode sidebar and see what the id of the widget is

        Alternatively:

        In some browser you can hover over your widgets or the edit links in the widget sidebar to really see what the id’s are.

        How to do the shortcode any widget

        and the result is……..

        Multiple widget instances

        Breadcrumbs with increasing indentation

        A vertical use of the Breadcrumb widget

        Indented Breadcrumbs
        Indented Breadcrumbs

        A query was received from Kim asking how to indent successive levels of the breadcrumb widget links.  This was not possible in version 1.1, so version 1.2 has been released with css classes added for each breadcrumb indicating it’s depth in the menu.  This css class allows you then to assign your own styling to the levels.

        Example CSS:

        #amr-breadcrumb .lvl2{ padding-left: 1em;}
        #amr-breadcrumb .lvl3{ padding-left: 2em;}
        #amr-breadcrumb .lvl4{ padding-left: 3em;}

        HTML generated:

        HTML generated
        HTML generated