17 Apr

writing a plugin for WebME

The core WebME engine doesn’t include Panels functionality, so I’ll use that as the example for the plugin tutorial.

In web design, a Panel is used to display information in a certain location in the layout which should not change throughout the site. For example, you could consider a footer section, sidebar section, or even header section to be a panel. You would want the same information to appear on all pages in that location, but sometimes you might want to change the contents of that panel.

To accomplish this, three things will be needed:

  • A Smarty function to show the plugin in the template. For example, {PANEL name='footer'} or {PANEL name='address'}
  • An admin page to handle the creation/editing of panels.
  • A database table to contain the panel information.

Make sure the ww.plugins directory exists in the root of your WebME and create a subdirectory in it named after the plugin. In this case, /ww.plugins/panels.

In that directory, create a file named plugin.php containing the following:

<?php
$plugin=array(
  'name'=>'Panels',
  'description'=>'Allows content sections to be displayed throughout the site.',
  'frontend'=>array(
    'template_functions'=>array(
      'PANEL'=>array(
        'function' => 'showPanel'
      )
    )
  )
);
function showPanel($vars){
  return 'in the <em>'.htmlspecialchars($vars['name']).'</em> panel';
}

Now you need to add the panel code to the HTML template. In my case, it was ww.skins/orange/h/_default.html. Add this whereever you want the panel code to appear:

<div class="panel">{PANEL name="testing"}</div>

img1

If you view the front-end of your site, you’ll see it’s blank. That’s because the plugin has not been enabled, so the function PANEL doesn’t yet exist. Unfortunately, Smarty doesn’t appear to allow you do do an “{if function_exists(‘PANEL’)}” block to cater for that eventuality, so just make sure to enable the plugin. Go to your admin area (/ww.admin/), and enable it in Options > Plugins. Now it should render better on the front-end.

Next we need to create the database table. In WebME, database management is done by using version-numbers. When the plugin is loaded, its version number is compared against the last version number the system had for that plugin. If the number is higher, then the file upgrade.php in the plugin directory is run.

In the plugin.php file, add 'version'=>1 to the $plugin array, then create the upgrade.php file:

<?php
require SCRIPTBASE.'ww.incs/db.php';
if($version==0){ // panels table
  dbQuery('CREATE TABLE IF NOT EXISTS `panels` (
    `id` int(11) NOT NULL auto_increment,
    `name` text,
    `body` text,
    PRIMARY KEY  (`id`)
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8');
  $version=1;
}

$DBVARS[$pname.'|version']=$version;
config_rewrite();

What happens there is that the previous version number is checked, the database is updated to the latest version, and the config is updated with the new version number.

For the admin area, we want to create a new menu item linking to an admin page specifically for panels. To do this, add an admin section to the $plugin array in plugin.php:

  'admin'=>array(
    'menu'=>array(
      'top'=>'Misc'
    )
  )

That creates the top-level menu ‘Misc’ in the admin area, and a link under it called ‘Panels’ (from the ‘name’ entry in the $plugin array).

Clicking that link opens a page which says “The panels plugin does not have an admin page. Please contact the plugin author.”

To correct that, create a /ww.plugins/panels/index.php page to handle it.

<?php
$id=(int)@$_REQUEST['id'];
if(isset($_REQUEST['action'])){
  if($_REQUEST['action']=='Save Panel'){
    $q='name="'.addslashes(@$_REQUEST['name']).'",body="'.addslashes(@$_REQUEST['body']).'"';
    if($id)dbQuery("update panels set $q where id=$id");
    else{
      dbQuery("insert into panels set $q");
      $id=dbOne("select last_insert_id() as id",'id');
    }
  }
  else if($_REQUEST['action']=='delete'){
    dbQuery("delete from panels where id=$id");
    $id=0;
  }
}
$panels=dbAll('select id,name from panels order by name');
echo '<div id="leftmenu">';
foreach($panels as $p){
  echo '<a href="/ww.admin/plugin.php?_plugin=panels&id=',$p['id'],'"';
  if($p['id'] == $id)echo ' class="thispage"';
  echo '>'.htmlspecialchars($p['name']).'</a>';
}
echo '<a href="/ww.admin/plugin.php?_plugin=panels">New Panel</a></div>';
$r=dbRow('select * from panels where id='.$id);
echo '<div id="hasleftmenu"><h2>Panel</h2>';
echo '<form method="post" action="/ww.admin/plugin.php?_plugin=panels"><table style="width:90%">';
echo '<tr><th>Name</th><td><input name="name" value="',htmlspecialchars(@$r['name']),'" /></td></tr>';
echo '<tr><th>Body</th><td>',fckeditor('body',@$r['body']),'</td></tr>';
echo '<tr><th colspan="2"><input type="hidden" name="id" value="',$id,'" />';
echo '<input type="submit" name="action" value="Save Panel" />';
if($id)echo '<a href="/ww.admin/plugin.php?_plugin=panels&id='.$id.'&action=delete" onclick="return confirm(\'are you sure you want to remove this panel?\')" title="delete">[x]</a>';
echo '</th></tr></table></form>';

Right. Now, use the new panel admin to create a panel. I’ve created a panel named “testing” with “hello world” written in it. Then, we need to display it on the front-end.

To do this, just amend the showPanel function in plugin.php to take care of it. Here is the whole plugin.php file again, with all amendments applied:

<?php
$plugin=array(
  'name'=>'Panels',
  'description'=>'Allows content sections to be displayed throughout the site.',
  'admin'=>array(
    'menu'=>array(
      'top'=>'Misc'
    )
  ),
  'frontend'=>array(
    'template_functions'=>array(
      'PANEL'=>array(
        'function' => 'showPanel'
      )
    )
  ),
  'version'=>1
);
function showPanel($vars){
  $p=dbRow('select body from panels where name="'.addslashes(@$vars['name']).'" limit 1');
  if(!count($p)){
    return '<em>error - panel <strong>'.htmlspecialchars(@$vars['name']).'</strong> does not exist.</em>';
  }
  return $p['body'];
}

This plugin is available in the svn repository (svn checkout http://webworks-webme.googlecode.com/svn/ww.plugins/panels).

Leave a Reply