Skip to main content.

Saturday, October 30, 2004

This article is oriented towards plugin authors. It explains how you can use plugin options in combinations with the Nucleus parser functions in order to allow easy templating of the plugin-generated output.

Note that this article is actually sort of a draft. I started to write it exactly 2 months ago, and I have a feeling that it will never get finished, so I'm publishing it as-is. The most important part of the article, the sample code, can be found here: NewsFeed and NewsFeed_Parser plugins. They're both unfinished and not compatible with other versions of the plugin. Their implementation also slightly differs from what's in the code samples below.

The NP_NewsFeed plugin

I'm going to convert the NP_NewsFeed plugin as an example. I've used this converted version on my dutch weblog (Karma Universe) to include links to the latest items on this dev blog.

The NewsFeed plugin was originally written by Xiffy, and was later adapted by Admun.

The problem

The main problem I had with the NP_NewsFeed code, was the lack of tweakability. Some options were provided to define CSS classes, but that wasn't enough for me. I wanted a nice ans simple unordered list, instead of a bunch of meaningless div tags. Without hacking into the source, these changes could not be made.

An idea! Plugin options as templates.

Did you know that the textarea plugin option type has no limit on the length of the stored data? (one small note: prior to v2.5, the limit was 128 chars...).

How about turning those plugin options into a template like the Nucleus skins and templates?

Getting started is easy: get a default template, and use that one as default value for your option.

$defaultHeader = '<ul class="newsfeed">';
$defaultItem   = '<li><a href="<%link%>" title="<%shortdescription%>"><%title%></a></li>';
$defaultFooter = '</ul>';
$defaultFeedNA = 'Feed temporarily unavailable';

$this->createOption('tplHead', 'Header Template', 'textarea', $defaultHeader);
$this->createOption('tplItem', 'Item Template', 'textarea', $defaultItem);
$this->createOption('tplFoot', 'Header Template', 'textarea', $defaultFooter);
$this->createOption('tplFeedNA', 'Feed Not Available Template', 'textarea', $defaultFeedNA);

The next problem is parsing the template where you need it. Luckily, you can use some built-in Nucleus core code. There are two ways to do this:

  1. The simple way, with less flexibility: using the TEMPLATE::fill method
  2. The hard way, with lots of flexibility: using the PARSER class

I've worked out versions of NP_NewsFeed using both of these methods.

Simple: TEMPLATE:fill

The static fill method in the template class takes a template and an associative array containing the values to replace.

Below is part of the NP_NewsFeed code, simplified as to not take the attention away from the main topic: template parsing

$tplHead = $this->getOption('tplHead');
$tplItem = $this->getOption('tplItem');
$tplFoot = $this->getOption('tplFoot');		

$aGeneralVars = array(
	'sitetitle' => htmlspecialchars($siteTitle),
	'url' => htmlspecialchars($siteUrl)
);

// header    
echo TEMPLATE::fill($tplHead, $aGeneralVars);

// items    
for ($i = $start; $i < $end; $i++) 
{
	$feeditem =& $feed[$i];

	$aVars = array(
		'link' => htmlspecialchars($feeditem['link']),
		'description' => htmlspecialchars($feeditem['description']),
		'title' => htmlspecialchars($feeditem['title']),
		'shortdescription' => htmlspecialchars($feeditem['description'])
	);

	echo TEMPLATE::fill($tplItem, $aVars);
}

// footer    
echo TEMPLATE::fill($tplFoot, $aGeneralVars);

While this method is very easy to use, it has some shortcomings:

  • It's not possible to pass parameters to a templatevar.
  • Since the fill method replaces string one after another, it can lead to unexpected results if the expansion of a variable contains a new templatevar. No endless loops will occur, though.

Harder: The PARSER class

Quite a bit harder is the usage of the PARSER class. For an introduction, see the How does the parser work? article in the Inside Nucleus series.

To use the parser class, you'll need to define an extra class in your code. This class will be responsible for handling the variables inside the template.

References

Comments

karma, this is a very good starting point for very useful plugin infrastructure. 8) Meanwhile, I was just thinking about what is the best way to deal with body/more formating the other day... it seem to me there is no universal API to process the body for output currently. The problem now is in many plugins have to manually reformat skinvar like image/media/popup and other plugin specific skinvar. I was thinking if there is a way for a plugin to tight to and reformat the body for output, it will be great.

Posted by ed$ at Monday, November 01, 2004 03:40:33

Sorry, I just wanna test the Comment Spam protection.

Posted by Rene at Friday, December 17, 2004 15:32:23

checking the captcha :)

Posted by Raine Walker at Monday, January 03, 2005 04:38:50

Add Comment

This item is closed, it's not possible to add new comments to it or to vote on it