{PROJECT} ../../template/doc.en.ini {GRAFIK_LINKS} $home/gifs/li_phpcms.gif {LOGO_1} $home/gifs/cmslogo1.gif {LOGO_2} $home/gifs/cmslogo2.gif {MENU} 00.08.10.07 {TITEL} Plugins for phpCMS {PLUGIN FILE="$home/doc/doc_en/time_user.php" TYPE="DYNAMIC"} {CONTENT} This section is (mainly) for developers. If you do not count yourself in this category you may simply go on reading the other sections of the manual. Detailed knowledge of plug-ins is not needed in order to use phpCMS!

- Description of Plug-Ins
- Use of plug-ins in template files
- Use of plug-ins in content files
- Accessing variables
- An example

Description of Plug-Ins

Plug-ins provide an interface to, and closer integration with, phpCMS' core functions. Output generated by scripts included via {SCRIPT} is sent directly to the browser. Plug-ins, on the other hand, are implemented in a way that allows to store values and results for later use, either during or after parsing, or to alter values in a document.

Advantages of plug-ins vs. included scripts

- (static) output can be cached.
- (static) output can be g-zipped.
- Fields in a content document can be altered at runtime.
- Global settings, like duration of proxy and client caching, can be change on a per page basis.
- Can be included in both template and content files.
- Allow use of server headers.

Disadvantages of plug-ins vs. included scripts

- Custom scripts need more adjustment.
- Requires deeper knowledge of PHP, caching, and phpCMS.
- Although global variables can be read, $GLOBALS[] must be used to create new ones, since plug-ins are executed within a function, while scripts are executed in PHP's global scope.
- No partial caching of pages, as is possible with included scripts.

In case you wrote your own plug-ins for phpCMS that may be of interest to others, please send them in. I will publish them with due credits to the author on www.phpCMS.de.

Use of plug-ins in template files

Plug-ins embedded in a template will be executed in every page generated from that template. Plug-ins are thus useful for things like displaying the creation date of a page, or creating keywords for meta tags.
Plug-ins are executed in the exact location and order within the template they are embedded in. If, for example, you are using a plug-in to change certain tags within a template, and you write the plug-in towards the end of the template, only those tags will be affected that are come after the plug-in.

This is how plug-ins are embedded into a template:

> {PLUGIN FILE="path_to_plugin/plugin.php" TYPE="DYNAMIC"}

The keyword “FILE” describes the path to where the plug-in is located in your file system. The path to the plug-in may be specified either

- using the "$home" variable
- relative to the location of the template
- or as an absolute path, where “absolute” means starting from the server root.

The keyword “TYPE” specifies whether the plug-in needs to be executed each time the page is served. Possible values are “DYNAMIC” and “STATIC”. A plug-in specified as “DYNAMIC” will be executed each time the page is requested by a browser. Neither the client nor any proxy server will be permitted to cache its output. Caching behavior can be controlled directly in the plug-in. A “STATIC” plug-in, on the other hand, will be executed only the first time the page is requested, and its output may then be cached together with the rest of the page. Caching behavior in this case follows the settings globally defined in phpCMS.

The values of both “FILE” and “TYPE” need to be within "straight" quotation marks.

Any output of a plug-in will be inserted where the plug-in is located within the template, and may only be written to the plug-in buffer.

Use of plug-ins in content files

The advantage of embedding plug-ins in content files is that this can be done on a per page basis. This may also free you of the need to define a special template for that plug-in. Another advantage of this is that plug-ins will be executed before the document is processed further. At this time the content file has already been read by phpCMS but no tags have been replaced, nor have the menus and the template(s) been processed.

Embedding plug-ins into content files works the same as has been described for templates above, only this time it is embedded into a content file.

If a plug-in produces any output, the output must be stored in the plug-in buffer. In order for this to work, we need to define a substitute within the template which will later be replaced by the plug-in's output:

> {CONTENT_PLUGIN_0}

Each plug-in is given a number in the order of its appearance within the content file, starting with zero (0). The substitute starts with the keyword "CONTENT_PLUGIN_" followed by the number given to the plug-in.

If a plug-in does not produce any output, or if its function is restricted to changing the contents of another field within the content file, no substitute keyword needs to be placed into the template. In this case the plug-in will be executed nonetheless.

If within the template there is a substitute keyword representing a plug-in, but no plug-in is embedded into the content file, the substitute keyword in the template will be ignored. This means there is no problem with defining a plug-in substitute within your standard template even thought the plug-in is embedded (and executed) only in certain content files.

Accessing variables

Plug-ins can access all variables present in the parser's global scope. This includes any variables sent to a page using the GET or POST methods, HTTP_COOKIE_VARS, etc.

In addition to this, plug-ins can access, and modify, the following variables supplied by the parser:

> $PageContent

> All of the content file's content. The variable is an ARRAY of ARRAY of STRING. You can access individual content fields within the content file by using their respective field names.
> If, for example, you have a field called {TITLE} in your content file, you can access the first line of the contents of this field using: "$PageContent->TITLE[0]". NOTE: all fields are treated as arrays even though they may contain only a single value.

> $CacheState

> Used to manage caching behavior within phpCMS. This variable is a STRING that can take on a value of either "on" or "off". If the variable is set to "on", the content of a document will be cached internally after being parsed by phpCMS. If it is set to "off", it will not be committed to phpCMS's internal cache.
> NOTE though: if another document with the same name is allready stored in the cache, that document will not be deleted and replaced automatically! Therefore, if e.g. you make changes to a template by adding a plug-in to it, you need to flush the cache afterwards. Otherwise the changes you've made will not show in the pages served off the cache.

> $ClientCache

> Used to manage behavior of proxy servers and client cache. This variable is a STRING that can take on a value of either "on" or "off". If set to "on", both proxy and client caching are enabled, otherwise they are disabled.

> $ProxyCacheTime

> This variable is a STRING. Its content is added to the current time and signifies when a page that may be cached by proxy servers or the client should again be retrieved from your server. Caching duration is expressed in seconds. In this example, client caching is to expire after one day:

> > $ProxyCacheTime = 1 * 60 * 60 * 24

> $Tags

> This variable is an ARRAY of ARRAYS of STRINGS. It contains all tags you have defined within your tag file along with the ones supplied by phpCMS. It can be used to add tags, or to change existing tags:

> > $Tags[counter][0] = value to be replaced;
> > $Tags[counter][1] = substitute value;

> "Counter" denotes the numbering of tags in you tags file. $PluginBuffer

> This variable is an ARRAY of STRING. The plugin-in buffer serves to store the output of a plug-in, and to hand it over to phpCMS. If only a single value is handed over, you still need to write to the first element of the array. When using plug-ins in a template, the location of the substitute keyword (with the appropriate numering) determines where in the template the contents of the plug-in buffer are handed over. The same applies to the output of plug-ins used within a content file respectively.

> $CHECK_PAGE->path

> Signifies the path of the file being parsed, relative to the server root.

> $CHECK_PAGE->name

> Signifies the name of the file being parsed.

Functions supplied by phpCMS that can be used with plug-ins:

> string = $PHP->GetDocRoot()

> This gives you the root directory of the server running phpCMS. I wrote this functions after I noticed that the environmental variable $DOCUMENT_ROOT does not point to the server root in all cases.

> string = $PHP->Version($number)

> This gives you the version number of PHP running on your server, where $number can be 1,2,3 or 4, and specifies the position within the version string. Thus if you had PHP version 4.0.2pl1 on your server, $PHP->Version(1) would return "4". $PHP->Version(4) would return "pl1". This function is not yet supported in PHP3.

> string = $PHP->API()

> This returns "mod" if PHP is run as server API. If PHP is run as CGI this function returns "cgi".

> string = $PHP->OS()

> Your server's operating system. Returns "win" for Windows or "nix" for Unix or Linux. Returns an empty string when neither of these OS's is being used.

So, if you wanted to access the file currently being parsed, to get its path and name you might write:

> $File = $PHP->GetDocRoot().'/'.$CHECK_PAGE->path.'/'.$CHECK_PAGE->name;

An example

In this example we are going to build a plug-in that prints out the visitor's IP number and time of visit. A substitute keyword is written into the template so that the plug-in is executed only on those pages that have the plug-in embedded in their content file. The tags <!-- PLUGIN:TIME_USER time --> and <!-- PLUGIN:TIME_USER ip --> get replaced.

Template:

`

    <html>
    <body>
    {MENU NAME="MAIN"}
    <h1>Heading</h1>
    {CONTENT}
    </body>
    </html>

`

Content file:

`

    {PROJECT} /wherever/project.ini
    {MENU} 00.01.01
    {PLUGIN FILE="/wherever/time_user.php" TYPE="DYNAMIC"}
    {CONTENT}
    The current time is <!-- PLUGIN:TIME_USER time -->.
    You have the IP number <!-- PLUGIN:TIME_USER ip -->.

`

PLUGIN (time_user.php):

`

    <?
    $current = count($Tags);
    $Tags[$current][0] = '<!-- PLUGIN:TIME_USER time -->';
    $Tags[$current][1] = date ( "H:i" , time () );
    $Tags[$current+1][0] = '<!-- PLUGIN:TIME_USER ip -->';
    $Tags[$current+1][1] = $REMOTE_ADDR;
    ?>

`

This should produce the following on our page:

> The current time is .
> You have the IP number .

In case it's , and your IP number is :-)

NOTE: There must not be any blank lines or spaces in front of the opening (<?) of after the closing (?>) PHP tag. Otherwise the parser would die with a nasty error message.