Writing A Plugin

From e107 Wiki
Jump to: navigation, search

e107 Wiki: English | Русский | Deutsch | Français | Magyar | Português | Български | Česky | Nederlands | Ελληνικά | Italiano | Norske | Polska | Slovenščina | Español | Svenska | Translate: Wiki | Page

logo_wiki.png

Current Release 1.0.4 | e107.org | Download | Changelog | Forum | Plugins | Themes | RSS Feed of Latest Changes | Atom Feed of Latest Changes


How to write a plugin
Main page > I : First Aid > II : Development > III : Administration > IV : How To's > V : Plugin Writing > VI : Theming & Shortcodes



Contents

Overview

This article aims to lead the plugin writing beginner through the basics of writing a simple plugin for e107. It will not go in to detail on every aspect of plugin writing.

Certain assumptions are made, specifically that you are familiar with the basics of:

  • e107 and what a plugin is
  • the PHP programming language
  • HTML and Cascading Stylesheets (CSS)

The example plugin in this article is called myplugin. It will have an admin page where some preferences can be set by the site administrator, a main page and a menu.

Directory Structure

All plugins reside in their own folder within the e107_plugins folder. Prior to e107 0.7, if the plugin required a menu then the folder name had to end with _menu. With 0.7, this is no longer the case, this is mentioned just because you will still see many plugins with this suffix on the folder names.

Actually, within your plugins folder there are only a few rules as to what goes where. After that, you are free to create whatever directory structure suits your plugin best.

For this example, we will use a fairly common structure within your plugins folder. Here's the basic layout we will be using:

e107_plugins (dir)
|
+--myplugin (dir)
|  |
|  +--images (dir)
|  |  +-- icon_16.png
|  |  +-- icon_32.png
|  |
|  +--languages (dir)
|  |  +-- myplugin_English.php
|  |
|  +--plugin.php
|  +--admin_menu.php
|  +--admin_config.php
|  +--admin_readme.php
|  +--help.php
|  +--myplugin.php
|  +--myplugin_menu.php

Note the files prefixed admin_ not only identify the files as being admin pages rather than main site pages, they also ensure, by the prefix, that the sites Admin theme is used when these pages are displayed and not the main site theme.

Alternately, you can declare the variable $eplug_admin and set it to true in any file that represents an admin page.
Attention ! This variable should be declared before calling class2.php

Code: Identifying an admin page using $eplug_admin
$eplug_admin = true;

Plugin Files

plugin.php

This file defines many attributes of the plugin. It must be called plugin.php (case sensitive).

The file basically contains a list of PHP variables with values that tell e107 information about the plugin such as the plugins name, version, author, etc.

The file is read when the e107 Admin->Plugin Manager page is displayed and is used when a plugin is installed, updated or uninstalled. It can also be read by e107 under other circumstances.

See plugin.php for more details about this file.

myplugin_English.php (language file)

A file consisting of PHP define() statements. Each statement defines constant that has some text as its value. This text will, at some point, be displayed on the screen. These constants are then used throughout the rest of the plugin where that text is required.

This file can then be translated into other languages to easily convert the whole plugin in to a different language.

It is a good idea to always create a language file for your plugin even if you are only using a small amount of pre-defined text on your plugins pages. If you don't, it can be quite a chore to add one later in development.

icon_16.png/icon_32.png

Two image files, the first is 16x16 pixels, the 2nd is 32x32. They do not have to be PNG files, other file types are allowed.

References to these files are added to the plugin.php file and used by e107 to display icons next to your plugin in various sections of the Admin area.

myplugin.php

This is the main page of your plugin, it will be viewed with a URL like:

mywebsite.com/e107_plugins/myplugin/myplugin.php

Its job is to format the HTML for the 'main' section of the page. The main section is the bit that isn't the header, footer or a menu area. Obviously, where this is depends on the theme that is in use, but this should not concern you. Just concentrate on writing the HTML to display whatever you need.

This file needs to perform certain actions at the start and end to ensure the whole page is displayed correctly. Fortunately, this is not much and is nicely hidden from you by e107.

Code: myplugin.php
<?php
   // always include the class2.php file - this is the main e107 file
   require_once("../../class2.php");
   
   define('PAGE_NAME','My Plugin Page Title');

   // this generates all the HTML up to the start of the main section
   require_once(HEADERF);

   // Include plugin language file, check first for site's preferred language
   include_lan(e_PLUGIN."myplugin/languages/myplugin_".e_LANGUAGE.".php");

   // write your PHP code to generate the required HTML here
   $text = "my HTML goes here";
   $text .= "more HTML for our plugin";

   // Ensure the pages HTML is rendered using the theme layout.
   $ns->tablerender(MYPLUGIN_LAN_TITLE, $text);

   // this generates all the HTML (menus etc.) after the end of the main section
   require_once(FOOTERF);
?>

So, what's going on in this file?

First, we include class2.php. This is essential and is almost always the first thing we do with a plugins page file. class2.php is the heart of e107 - it initialises all sorts of things, too much to go into (or worry about) here.

Second, we set page title (the title on the top of browser window).

Next, we include a file called HEADERF. This is a constant that has been set by class2.php and we don't need to know what the real file name is (because we trust e107!). This bit basically generates the HTML for the start of the page up to the start of the 'main' area. Notice it is a e107 specific 'require_once' used here, this function allows for when debugging is set to on.

The language file is included next. include_lan checks that the set language (e_LANGUAGE) exists, if not, it defaults the language to English.

The main part of our myplugin.php is next. It doesn't look like much here, but this will expand quickly as we add the code to generate the required HTML. Note that, unlike some PHP conventions, we do not echo our HTML directly to the page. Instead we assign/append it to a variable ($text) that is used in the next step.

The penultimate step is to pass our HTML to e107 to get it displayed on the page. To do this we use a well known variable (a variable that has been set by e107 and is guaranteed to be available) - $ns. $ns is actually an instance of an e107Table class that is already declared so we can use it.

To pass our HTML to e107 we call the e107Table classes tablerender function ($ns->tablerender(). This takes two parameters, the page title and the HTML for the page. In our example the page title is a constant that we would have defined in our language file, the HTML is the value of the $text variable. $ns->tablerender(MYPLUGIN_LAN_TITLE, $text);

Finally, we include the file FOOTERF. Like HEADERF it is a constant set by e107 and we don't actually care what is is just so long as we include it. This generates the HTML for the rest of the page, from the end of the 'main' section onwards.

myplugin_menu.php

If the plugin has a menu file (any file whose name ends in _menu.php then this menu will be available for selection on the e107 Admin->Menus page and can be positioned in any of the available menu areas as defined by the users theme.

This file has no predefined structure other than it must pass the HTML it generates to e107 for including in the page at the end.

The file is included by e107 when it is needed, you cannot assume that the menu is before or after your page or any other menu so you cannot (generally) assume that certain things has happened.

Code: basic myplugin_menu.php
<?php
   $text = "some HTML";
   $ns->tablerender(MYPLUGIN_LAN_MENU_TITLE, $text);
?>

admin_menu.php

This file defines the menu that is displayed in the Admin area of your plugin. The menu provides links to any options, configuration, data input, etc. pages that your plugin might need to allow an Administrator to perform administrator tasks.

For example, you may have a preferences page to allow the Administrator to tailor your plugin to only make it available to members of a specific userclass or to set the number of items displayed on the main page.

There are four basic steps that you should do in this file:

  • include your language file (optional but a good idea)
  • define your menu title
  • define your menu item(s)
  • generate the menu


Code: admin_menu.php
<?php
   $menutitle  = "MyPlugin Options";

   $butname[]  = "Preferences";
   $butlink[]  = "admin_config.php";
   $butid[]    = "config";

   $butname[]  = "Read Me";
   $butlink[]  = "admin_readme.php";
   $butid[]    = "readme";

   global $pageid;
   for ($i=0; $i<count($butname); $i++) {
      $var[$butid[$i]]['text'] = $butname[$i];
      $var[$butid[$i]]['link'] = $butlink[$i];
   };

   show_admin_menu($menutitle, $pageid, $var);
?>

Note: for clarity, I have not used a language file in the above example.

First, we give our menu a title ($menutitle). Not essential we assign it to a variable here but may be useful to do so in a more complex menu.

Next, we add our two menu options, each has three parts - Name, PHP file, ID. The Name is the text that will be displayed to the user, the PHP file is the plugins file that will handle the functionality for that admin menu and the ID is a unique (within you plugin) identifier for the menu option (an example of its use is to highlight the selected menu option in some way to distinguish it from other menu options).

The menu options are then used to build a fairly complex array. Don't worry too much at this stage how this works if you don't understand it, just follow the pattern exactly as above.

Finally, we call a function to pass our menu details back to e107 to include it in the Admin page.

help.php

A simple file this one. It is used to display some help text to the Administrator when they are viewing your plugin's Admin pages.

Code: help.php
<?php
   $text = "some help text";
   $ns->tablerender("MyPlugin Help", $text);
?>

The help text is free format and can be whatever you think appropriate.

Convention is that the text is split into paragraphs and that paragraphs have an option bold heading. Uses the standard HTML markup paragraph (<p> and </p>) and bold (<b> and </b>) tags for this.

admin_config.php

This page is included here purely to show an example of an admin preferences page. Equally, it could have been a page that adds, updates and deletes from a plugins database table (if it had one).

The idea is not to show how to write the 'preferences' or 'database' code (as there are many ways of doing this) but to give the PHP file structure that goes around this functionality.

Code: admin_config.php
<?php
   // Remember that we must include class2.php
   require_once("../../class2.php");

   // Check current user is an admin, redirect to main site if not
   if (!getperms("P")) {
      header("location:".e_HTTP."index.php");
      exit;
   }

   // Include page header stuff for admin pages
   require_once(e_ADMIN."auth.php");

   // Handle preferences form being submitted
   // n.b. to complex to list in this example

   // Our informative text
   $text = "Generate some HTML for our preference form";

   // The usual, tell e107 what to include on the page
   $ns->tablerender("MyPlugin Read Me", $text);

   require_once(e_ADMIN."footer.php");
?>

Note: See point "Something on auth.php (Workaround on a problem)" for further informations on including your own scripts in this script. --Marco.link 03:40, 23 August 2006 (CDT)


Menu Configuration

Some plugins have a 'Configure' option within the drop-down on the 'Menus' page. This is (obviously) intended to allow quick configuration of options affecting that menu display.

There are two ways of linking to this option.

The simplest is to include a file 'config.php' within your plugin directory - this executes whatever configuration code is required.

For plugins with multiple menus, you can have multiple configuration files, named menufilename_config.php.

You must go for one option or the other!

In many cases the file will contain a simple redirect to the admin_config.php menu, perhaps with an associated query:

Code: Config Redirect Code
<?php
require_once("../../class2.php");
header("location:".e_PLUGIN."calendar_menu/admin_config.php?forthcoming");
?>


admin_readme.php

This is non-functional but it is always a good idea to include it.

It should give some information about your plugin, what it does, current version, recent changes/updates, contact e-mail - that sort of thing.

Code: admin_readme.php
<?php
   // Remember that we must include class2.php
   require_once("../../class2.php");

   // Check current user is an admin, redirect to main site if not
   if (!getperms("P")) {
      header("location:".e_HTTP."index.php");
      exit;
   }

   // Include page header stuff for admin pages
   require_once(e_ADMIN."auth.php");

   // Our informative text
   $text = "Some informative text with HTML markup as required";

   // The usual, tell e107 what to include on the page
   $ns->tablerender("MyPlugin Read Me", $text);

   require_once(e_ADMIN."footer.php");
?>

myplugin_sql.php

This file contains the SQL that creates the tables used by the plugin.

It isn't actually PHP code, just plain text.

It is used by the e107 Database Tool to check the validity of the plugins tables. If a discrepancy is found between this file and the table in the database then the administrator can choose to attempt to repair the table.

Code: myplugin_sql.php
CREATE TABLE myplugin_table (
   myplugin_id                 int(11)        NOT NULL default 0,
   myplugin_status             tinyint(1)     NOT NULL default 0,
   myplugin_category           tinyint(1)     NOT NULL default 0,
   myplugin_notes              text           NOT NULL default '',
   myplugin_datestamp          int(10)        NOT NULL default 0,
   PRIMARY KEY (myplugin_id)
) TYPE=MyISAM;

Also see Hints and Tips and Tutorials