NAME

App::ZofCMS::PluginReference - docs for all plugins in one document for easy reference

DESCRIPTION

I often found myself reaching out for docs for different plugins cluttering up my browser. The solution - stick all docs into one!.

App::ZofCMS::Plugin::AntiSpamMailTo (version 0.0101)

NAME

Link: App::ZofCMS::Plugin::AntiSpamMailTo

App::ZofCMS::Plugin::AntiSpamMailTo - "smart" HTML escapes to protect mailto:foo@bar.com links from not-so-smart spam bots

SYNOPSIS

In your Main Config file or ZofCMS template:

# include the plugin
plugins => [ qw/AntiSpamMailTo/ ],

# then this: 
plug_anti_spam_mailto => 'bar',
# or this:
plug_anti_spam_mailto => [ qw/foo bar baz/ ],
# or this:
plug_anti_spam_mailto => {
    foo => 'bar',
    baz => 'beer',
},

In your HTML::Template template:

<tmpl_var name="mailto">
# or this:
<tmpl_var name="mailto_0"> <tmpl_var name="mailto_1"> <tmpl_var name="mailto_2">
# or this:
<tmpl_var name="foo"> <tmpl_var name="baz">

DESCRIPTION

The module is an App::ZofCMS plugin which provides means to deploy a technique that many claim to be effective in protecting your <a href="mailto:foo@bar.com"></a> links from dumb spam bots.

The technique is quite simple (and simple to circumvent, but we are talking about dumb spam bots) - the entire contents of href="" attribute are encoded as HTML entities. Dumb spam bots miss the mailto: and go their way. Anyway, on to the business.

This documentation assumes you have read App::ZofCMS, App::ZofCMS::Config and App::ZofCMS::Template

MAIN CONFIG/ZofCMS TEMPLATE FIRST-LEVEL KEYS

plug_anti_spam_mailto

plug_anti_spam_mailto => 'bar',

plug_anti_spam_mailto => [ qw/foo bar baz/ ],

plug_anti_spam_mailto => {
    foo => 'bar',
    baz => 'beer',
},

The plugin takes it's data from plug_anti_spam_mailto first-level key that is in either ZofCMS template or config file. The key takes either a string, arrayref or a hashref as its value. If the key is specified in both main config file and ZofCMS template and the value is of the same type (string, arrayref or hashref) then both values will be interpreted by the plugin; in case of the hashref, any duplicate keys will obtain the value assigned to them in ZofCMS template. Note: if the value is of "type" string specified in both main config file and ZofCMS template it will interpreted as an arrayref with two elements. Now I'll tell you why this all matters:

value is a string

plug_anti_spam_mailto => 'bar',

When the value is a string then in HTML::Template template you'd access the converted data via variable mailto, i.e. <tmpl_var name="mailto">

value is an arrayref or a string in both ZofCMS template and main config file

plug_anti_spam_mailto => [ qw/foo bar baz/ ],

To access converted data when the value is an arrayref you'd use mailto_NUM where NUM is the index of the element in the arrayref. In other words, to access value bar in the example above you'd use <tmpl_var name="mailto_1">

value is a hashref

plug_anti_spam_mailto => {
    foo => 'bar',
    baz => 'beer',
},

You do not have to keep typing mailto to access your converted data. When value is a hashref the values of that hashref are the data to be converted and the keys are the names of <tmpl_var name"">s into which to stick that data. In the example above, to access converted data for beer you'd use <tmpl_var name="baz">

EXAMPLE

ZofCMS template:

plugins => [ qw/AntiSpamMailTo/ ],
plug_anti_spam_mailto => 'mailto:john.foo@example.com',

HTML::Template template:

<a href="<tmpl_var name="mailto">">email to John Foo</a>

App::ZofCMS::Plugin::AutoIMGSize (version 0.0101)

NAME

Link: App::ZofCMS::Plugin::AutoIMGSize

App::ZofCMS::Plugin::AutoIMGSize - automatically get image sizes and generate appropriate <img> tags

SYNOPSIS

In your Main Config or ZofCMS Template file:

plugins => [ qw/AutoIMGSize/ ],
plug_auto_img_size => {
    imgs => {
        logo    => 'pics/top_logo.png'
        kitteh  => 'pics/kitteh.jpg',
        blah    => { 'somewhere/there.jpg' => ' class="foo"' },
    },
},

In your HTML::Template template:

Logo: <tmpl_var name="img_logo">
Kitteh: <tmpl_var name="img_kitteh">
blah: <tmpl_var name="img_blah">

DESCRIPTION

The module is a plugin for App::ZofCMS. It provides means to generate HTML <img ... > tags with automatic image size generation, i.e. the plugin gets the size of the image from the file. Personally, I use it in templates where the size of the image is unknown, if the image is static and you can physically type in the address, it would be saner to do so.

This documentation assumes you've read App::ZofCMS, App::ZofCMS::Config and App::ZofCMS::Template

MAIN CONFIG FILE OR ZofCMS TEMPLATE KEYS

plugins

plugins => [ qw/AutoIMGSize/ ],

You would obvisouly want to add the plugin to the list of plugins to run. Play with priorities if you are loading image paths dynamically.

plug_auto_img_size

plug_auto_img_size => {
    xhtml       => 1,
    t_prefix    => 'img_',
    imgs => {
        logo    => 'pics/logo.png',
        kitteh  => { 'pics/kitteh.jpg' => ' class="kitteh' },
    },
},

The plug_auto_img_size first-level Main Config file or ZofCMS Template file is what makes the plugin run. If you specify this key in both ZofCMS Template and Main Config file then keys set in ZofCMS Template will override the ones set in Main Config file. Note: the imgs key will be completely overridden.

The key takes a hashref as a value. Possible keys/values of that hashref are as follows:

imgs

imgs => [ qw/foo.jpg bar.jpg/ ],
#same as
imgs => {
    'foo.jpg' => 'foo.jpg',
    'bar.jpg' => 'bar.jpg',
},

Mandatory. The imgs key takes either an arrayref or a hashref as a value. If the value is an arrayref, it will be converted to a hashref where keys and values are the same.

The key in the hashref specifies the "name" of the key in {t} ZofCMS Template special key to which the t_prefix (see below) will be prepended. The value specifies the image filename relative to ZofCMS index.pl file (root dir of your website, basically). The value of each key can be either a string or a hashref. If it's a string, it will be taken as a filename of the image. If it is a hashref it must contain only one key/value pair; the key of that hashref will be taken as a filename of the image and the value will be taken as extra HTML attributes to insert into <img> tag. Note that the value, in this case, should begin with a space as to not merge with the width/height attributes. Note 2: unless the value is a hashref, the alt="" attribute will be set to an empty string; otherwise you must include it in "extra" html attributes. Here are a few examples (which assume that t_prefix (see below) is set to its default value: img_; and size of the image is 500px x 500px):

# ZofCMS template:
imgs => [ qw/foo.jpg/ ]

# HTML::Template template:
<tmpl_var name="img_foo.jpg">

# Resulting HTML code:
<img src="/foo.jpg" width="500" height="500" alt="">

Note: that image src="" attribute is made relative to root path of your website (i.e. starts with a slash / character).

# ZofCMS tempalte:
imgs => { foo => 'pics/foo.jpg' },

# HTML::Template template:
<tmpl_var name="img_foo">

# Resulting HTML code:
<img src="/pics/foo.jpg" width="500" height="500" alt="">

Now with custom attributes (note the leading space before alt="" attribute):

# ZofCMS template:
imgs => { foo => { 'pics/foo.jpg' => ' alt="foos" class="foos"' } }

# HTML::Template template:
<tmpl_var name="img_foo">

# Resulting HTML code:
<img src="/pics/foo.jpg" width="500" height="500" alt="foos" class="foos">

Note: if plugin cannot find your image file then the <img> tag will be replaced with ERROR: Not found.

t_prefix

t_prefix => 'img_',

Optional. The t_prefix takes a string as a value, this string will be prepended to the "name" of your images in {t} ZofCMS Template special key. In other words, if you set t_prefix => 'img_', imgs => { foo => 'pics/bar.jpg' }, then in your HTML::Template template you'd insert your image with <tmpl_var name="img_foo">. Defaults to: img_ (note the underscore (_) at the end)

xhtml

xhtml => 1,

Optional. When set to a true value the <img> tag will be closed with />. When set to a false value the <img> tag will be closed with >. Default to: 0 (false)

DEPENDENCIES

The module relies on Image::Size to get image sizes.

App::ZofCMS::Plugin::Base (version 0.0102)

NAME

Link: App::ZofCMS::Plugin::Base

App::ZofCMS::Plugin::Base - base class for App::ZofCMS plugins

SYNOPSIS

package App::ZofCMS::Plugin::Example;

use strict;
use warnings;
use base 'App::ZofCMS::Plugin::Base';

sub _key { 'plug_example' }
sub _defaults { qw/foo bar baz beer/ }
sub _do {
    my ( $self, $conf, $template, $query, $config ) = @_;
}

DESCRIPTION

The module is a base class for App::ZofCMS plugins. I'll safely assume that you've already read the docs for App::ZofCMS, App::ZofCMS::Config and App::ZofCMS::Template

The base class (currently) is only for plugins who take their "config" as a single first-level key in either Main Config File or ZofCMS Template. That key's value must be a hashref.

SUBS TO OVERRIDE

_key

sub _key { 'plug_example' }

The _key needs to return a scalar contain the name of first level key in ZofCMS template or Main Config file. Study the source code of this module to find out what it's used for if it's still unclear.

_defaults

sub _defaults { qw/foo bar baz beer/ }

The _defaults sub needs to return a list of default arguments in a key/value pairs. By default it returns an empty list.

_do

sub _do {
    my ( $self, $conf, $template, $query, $config ) = @_;
}

The _do sub is where you'd do all of your processing. The @_ will contain $self, $conf, $template, $query and $config (in that order) where $self is your plugin's object, $conf is the plugin's configuration hashref (what the user would specify in ZofCMS Template or Main Config File, the key of which is returned by _key() sub), the $template is the hashref of ZofCMS template that is being processed, the $query is a query parameters hashref where keys are names of the params and values are their values. Finally, the $config is App::ZofCMS::Config object.

MOAR!

Feel free to email me the requests for extra functionality for this base class.

App::ZofCMS::Plugin::BreadCrumbs (version 0.0102)

NAME

Link: App::ZofCMS::Plugin::BreadCrumbs

App::ZofCMS::Plugin::BreadCrumbs - add "breadcrumbs" navigation to your sites

SYNOPSIS

In your ZofCMS template:

plugins => [ qw/BreadCrumbs/ ]

In your HTML::Template template:

<tmpl_var name="breadcrumbs">

DESCRIPTION

The module is a plugin for App::ZofCMS. It provides means to add a "breadcrumbs" (http://en.wikipedia.org/wiki/Breadcrumb_(navigation)) to your pages.

This documentation assumes you've read App::ZofCMS, App::ZofCMS::Config and App::ZofCMS::Template

HOW DOES IT WORK

The plugin automagically generates breadcrumb links, if your sites are relatively simple and pages are in good hierarchy the plugin will do the Right Thing(tm) most of the time. The links for breadcrumbs are determined as follows. If the page is not called index then the index page in the current "directory" will be added to the breadcrumbs, the "path" will be broken down to pieces and index page in each piece will be added to the breadcrumbs. Note: the examples below assume that the no_pages argument was not specified:

# page
index.pl?page=/foo/bar/baz

# crumbs
/index => /foo/index => /foo/bar/index => /foo/bar/baz


# page
index.pl?page=/foo/bar/beer/index

# crumbs
/index => /foo/index/ => /foo/bar/index => /foo/bar/beer/index

FIRST-LEVEL ZofCMS TEMPLATE KEYS

plugins

plugins => [ qw/BreadCrumbs/ ]

First and obvious you need to add BreadCrumbs to the list of plugins to execute. Just this will already make the plugin execute, i.e. having the breadcrumbs key (see below) is not necessary.

breadcrumbs

breadcrumbs => {}, # disable the plugin

# lots of options
breadcrumbs => {
    direct      => 1,
    span        => 1,
    no_pages => [ '/comments' ],
    key         => 'page_title',
    text_re     => qr/([^-]+)/,
    change      => {
        qr/foo/ => 'foos',
        qr/bar/ => 'bars',
    },
    replace     => {
        qr/foo/ => 'foos',
        qr/bar/ => 'bars',
    },
},

The breadcrumbs first-level ZofCMS template key controls the behaviour of the plugin. The key takes a hashref as a value. Do NOT specify this key if you wish to use all the defaults, as specifying an empty hashref as a value will disable the plugin for that given page. Possible keys/values of that hashref are as follows:

direct

{ direct => 1 },

Optional. Takes either true or false values. When set to a false value the breadcrumb links will all be of form /index.pl?page=/index. When set to a true value the links will be of form /index which is useful when you are making your URIs with something like mod_rewrite. Defaults to: false

span

{ span => 1 },

Optional. The span key takes either true or false values. When set to a true value, the plugin will generate <span> based breadcrumbs. When set to a false value, the plugin will generate <ul> based breadcrumbs. Default to: false.

no_pages

{ no_pages => [ '/comments', '/index' ], }

Optional. Takes an arrayref as a value. Each element of that array must be a dir + page (as described in Note on page and dir query parameters in App::ZofCMS::Config). If a certain element of that array matches the page in the breadcrumbs being generated it will be removed from the breadcrumbs. In other words, if you specify no_pages => [ '/index' ] the "index" page of the "root" directory will not show up in the breadcrumbs. By default is not specified.

key

{ key => 'title', }

Optional. When walking up the "tree" of pages plugin will open ZofCMS templates for those pages and use the key key's value as the text for the link. Only first-level keys are supported. Defaults to: title

text_re

{ text_re => qr/([^-]+)/ }

Optional. Takes a regex (qr//) as a value which must contain a capturing set of parentheses. When specified will run the regex on the value of key (see above) key's value and whatever was captured in the capturing parentheses will be used for the text of the link. By default is not specified.

change

change => {
    qr/foo/ => 'foos',
    qr/bar/ => 'bars',
},

Optional. Takes a hashref as a value. The keys of that hashref are regexen (qr//) and the values are the text with which the entire text of the link will be replaced if that particular regex matches. In other words, if you specify change => { qr/foo/ => 'foo' } and your link text is lots and lots of foos it will turn into just foo. By default is not specified.

replace

replace => {
    qr/foo/ => 'foos',
    qr/bar/ => 'bars',
},

Optional. Same as change key described above, except replace will replace the matching part with the text provided as a value. In other words, if you specify replace => { qr/foo/ => 'BAR' } and your link text is lots and lots of foos it will turn into lots and lots of BARs. By default is not specified.

HTML::Template TEMPLATE VARIABLES

<tmpl_var name="breadcrumbs">

The plugin set one key - breadcrumbs - in {t} special key which means that you can stick <tmpl_var name="breadcrumbs"> in any of your HTML::Template templates and this is where the breadcrumbs will be placed.

App::ZofCMS::Plugin::Comments (version 0.0102)

NAME

Link: App::ZofCMS::Plugin::Comments

App::ZofCMS::Plugin::Comments - drop-in visitor comments support.

SYNOPSIS

In your "main config" file:

comments_plugin => {
    dsn         => "DBI:mysql:database=test;host=localhost",
    user        => 'test',
    pass        => 'test',
    email_to    => [ 'admin@example.com', 'admin2@example.com' ],
},

In your ZofCMS template:

plugins => [ qw/Comments/ ],

In your "comments" page HTML::Template template, which we set to be /comments by default:

<tmpl_var name="zofcms_comments_form">

In any page on which you wish to have comments:

<tmpl_var name="zofcms_comments_form">
<tmpl_var name="zofcms_comments">

DESCRIPTION

The module is a plugin for App::ZofCMS. It provides means to easily add "visitor comments" to your pages. The plugin offers configurable flood protection ( $x comments per $y seconds ) as well as ability to notify you of new comments via e-mail. The "moderation" function is also implemented, what that means is that you (the admin) would get two links (via e-mail) following one of them will approve the comment; following the other will simply delete the comment from the database.

I am an utterly lazy person, thus you may find that not everything you may want to configure in the plugin is configurable. The plugin is yet to undergo (at the time of this writing) deployment testing, as in how flexible it is. If you'd like to see some features added, don't be shy to drop me a line to zoffix@cpan.org

This documentation assumes you've read App::ZofCMS, App::ZofCMS::Config and App::ZofCMS::Template

HOW IT ALL COMES TOGETHER OR "WHAT'S THAT 'comments' PAGE ANYWAY?"

So here is how it works, you have some page where you added the plugin's functionality. Visitor enters his/hers comment and pressed "Post" button. The request will be POSTed to a "comments" page and depending on what the visitor entered he or she will either get an error with ability to fix it or a "success" message with an ability to go back to the page on which the comment was created. The reason for this "comments" page is that I couldn't figure out a simple way to have the comments markup inserted with simple <tmpl_var> and keep any page on which the plugin was used small enough for the user to see the error message easily.

The "comments" must have <tmpl_var name="zofcms_comments_form"> on it somewhere for the plugin to work.

MAIN CONFIG OR ZofCMS TEMPLATES?

If you have a sharp eye, you've noticed that plugin's configuration was placed into the 'main config file' in the SYNOPSIS. You actually don't have to do that and can keep plugin's configuration in your ZofCMS template, but personally I find it much easier to just drop it into the main config and enable it on per-page basis by sticking only Comments in the list of the plugins on ZofCMS templates.

THE SQL TABLES!

Under the hood the plugin uses DBI to stick data into SQL tables. Generally speaking you shouldn't have trouble using the plugin with $database_of_your_choice; however, the plugin was tested only with MySQL database. Before you can use the plugin you need to create one or two tables in your database. The columns have to be named those names and be in that order:

# comments table
CREATE TABLE comments (name VARCHAR(100), email VARCHAR(200), comment TEXT, page VARCHAR(100), remote_host TEXT, time VARCHAR(11));

#moderation table
CREATE TABLE mod_comments (name VARCHAR(100), email VARCHAR(200), comment TEXT, page VARCHAR(100), remote_host TEXT, time VARCHAR(11), id TEXT);

Now, the note on value types. The name, email and comment is the data that the comment poster posts. Since the maximum lengths of those fields are configurable, pick the value types you think fit. The page column will contain the "page" on which the comment was posted. In other words, if the comment was posted on http://example.com/?page=/foo/bar/baz, the page cell will contain /foo/bar/baz. The remote_host is obtained from CGI's remote_host() method. The time cell is obtained from the call to time() and the id in moderation table is generated with rand() . time() . rand() (keep those flames away plz).

COMMENT MODERATION

When moderation of comments is turned on in the plugin you will get two links e-mailed when a new comment was submitted. One is "approve" and another one is "deny". Functions of each are self explanatory. What happens is that the comment is first placed in the "moderation table". If you click "approve", the comment is moved into the "comments table". If the comment is denied by you, it is simply deleted from the "moderation table". There is a feature that allows all comments that are older than $x seconds (see mod_out_time argument) to be deleted from the "moderation table" automatically.

WHAT? NO CAPTCHA?

You will notice that there is no "captcha" (http://en.wikipedia.org/wiki/Captcha) thing done with comments form generated by the plugin. The reason for that is that I hate them... pure hate. I think the worst captcha I ever came across was this: http://www.zoffix.com/new/captcha-wtf.png. But most of all, I think they are plain annoying.

In this plugin I implemented a non-annoying "captcha" mechanizm suggested by one of the people I know who claimed it works very well. At the time of this writing I am not yet aware of how "well" it really is. Basically, the plugin sticks <input type="hidden" name="zofcms_comments_username" value="your user name"> in the form. When checking the parameters, the plugin checks that this hidden input's value matches. If it doesn't, boot the request. Apparently the technique works much better when the <input> is not of type="hidden" but I am very against "hiding" something with CSS.

So, time will show, if this technique proves to be a failure, expect the plugin to have an option to provide a better "captcha" mechanizm. As for now, this is all you get, although, I am open for good ideas.

GOODIES IN ZofCMS TEMPLATE/MAIN CONFIG FILE

plugins

plugins => [ qw/Comments/ ],

This goes without saying that you'd need to stick 'Comments' into the list of plugins used in ZofCMS template. As opposed to many other plugins this plugin will not bail out of the execution right away if comments_plugin first level key (described below) is not specified in the template (however it will if you didn't specify comments_plugin in neither the ZofCMS template nor the main config file).

comments_plugin

comments_plugin => {
    # mandatory
    dsn             => "DBI:mysql:database=test;host=localhost",
    page            => '/comments',

    #optional in some cases, no defaults
    email_to        => [ 'admin@test.com', 'admin2@test.com' ],

    #optional, but default not specified
    user            => 'test', # user,
    pass            => 'test', # pass
    opts            => { RaiseError => 1, AutoCommit => 1 },
    uri             => 'http://yoursite.com',
    mailer          => 'testfile',
    no_pages        => [ qw(/foo /bar/beer /baz/beer/meer) ],

    # optional, defaults presented here
    sort            => 0
    table           => 'comments',
    mod_table       => 'mod_comments',
    must_name       => 0,
    must_email      => 0,
    must_comment    => 1,
    name_max        => 100,
    email_max       => 200,
    comment_max     => 10000,
    moderate        => 1,
    send_entered    => 1,
    subject         => 'ZofCMS Comments',
    flood_num       => 2,
    flood_time      => 180,
    mod_out_time    => 1209600,
}

Whoosh, now that's a list of options! Luckly, most of them have defaults. I'll go over them in a second. Just want to point out that all these arguments can be set in the "main config file" same way you'd set them in ZofCMS template (the first-level comments_plugin key). In fact, I recommend you set them all in ZofCMS main config file instead of ZofCMS templates, primarily because you'd want to have it duplicated at least twice: once on the "comments page" and once on the page on which you actually want to have visitors' comments functionality. So here are the possible arguments:

dsn

dsn => "DBI:mysql:database=test;host=localhost",

Mandatory. Takes a scalar as a value which must contain a valid "$data_source" as explained in DBI's connect_cached() method (which plugin currently uses).

email_to

email_to => [ 'admin@test.com', 'admin2@test.com' ],

Mandatory unless moderate and send entered are set to a false values. Takes either a scalar or an arrayref as a value. Specifying a scalar is equivalent to specifying an arrayref with just that scalar in it. When moderate or send_entered are set to true values, the e-mail will be sent to each of the addresses specified in the email_to arrayref.

page

page => '/comments',

Optional. This is the "comments page" that I explained in the HOW IT ALL COMES TOGETHER OR "WHAT'S THAT 'comments' PAGE ANYWAY?" section above. Argument takes a string as a value. That value is what you'd set the page query parameter in order to get to the "comments page". Make sure you also prepend the dir. In the example above the comments page is accessed via http://example.com/index.pl?page=comments&dir=/. Defaults to: /comments

user

user => 'test_db_user',

Optional. Specifies the username to use when connecting to the SQL database used by the plugin. By default is not specified.

pass

pass => 'teh_password',

Optional. Specifies the password to use when connecting to the SQL database used by the plugin. By default is not specified.

opts

opts => { RaiseError => 1, AutoCommit => 1 },

Optional. Takes a hashref as a value. Specifies additional options to DBI's connect_cached() method, see DBI's documentation for possible keys/values of this hashref. Defaults to: { RaiseError => 1, AutoCommit => 1 }

uri

uri => 'http://yoursite.com/index.pl?page=/comments',

Optional. The only place in which this argument is used is for generating the "Approve" and "Deny" URIs in the e-mail sent to you when moderate is set to a true value. Basically, here you would give the plugin a URI to your "comments page" (see page argument above). If you don't specify this argument, nothing will explode (hopefully) but you won't be able to "click" the "Approve"/"Deny" URIs.

mailer

mailer => 'testfile',

Optional. When either moderate or send_entered arguments are set to true values, the mailer argument specifies which "mailer" to use to send e-mails. See documentation for Mail::Mailer for possible mailers. By default mailer argument is not specified, thus the "mailers" will be tried until one of them works. When mailer is set to testfile, the mail file will be located at the same place ZofCMS' index.pl file is located.

no_pages

no_pages => [ qw(/foo /bar/beer /baz/beer/meer) ],

Optional. Takes an arrayref as a value. Each element of that arrayref must be a page with dir appended to it, even if dir is / (see the "Note on page and dir query parameters" in App::ZofCMS::Config documentation). Basically, any pages listed here will not be processed by the plugin even if the plugin is listed in plugins first-level ZofCMS template key. By default is not set.

sort

sort => 0,

Optional. Currently accepts only true or false values. When set to a true value the comments on the page will be listed in the "oldest-first" fashion. When set to a false value the comments will be reversed - "newest-first" sorting. Defaults to: 0.

table

table => 'comments',

Optional. Takes a string as a value which must contain the name of SQL table used for storage of comments. See THE SQL TABLES! section above for details. Defaults to: comments

mod_table

mod_table => 'mod_comments',

Optional. Same as table argument (see above) except this one specifies the name of "moderation table", i.e. the comments awaiting moderation will be stored in this SQL table. Defaults to: mod_comments

must_name, must_email and must_comment

must_name    => 0,
must_email   => 0,
must_comment => 1,

Optional. The "post comment" form generated by the plugin contains the Name, E-mail and Comment fields. The must_name, must_email and must_comment arguments take either true or false values. When set to a true value, the visitor must fill the corresponding field in order to post the comment. If field is spefied as "optional" (by setting a false value) and the visitor doesn't fill it, it will default to N/A. By default must_name and must_email are set to false values and must_comment is set to a true value.

name_max, email_max and comment_max

name_max    => 100,
email_max   => 200,
comment_max => 10000,

Optional. Same principle as with must_* arguments explained above, except *_max arguments specify the maximum length of the fields. If visitor enters more than specified by the corresponding *_max argument, he or she (hopefully no *it*s) will get an error. By default name_max is set to 100, email_max is set to 200 and comment_max is set to 10000.

moderate

moderate => 1,

Optional. Takes either true or false values. When set to a true value will enable "moderation" functionality. See COMMENT MODERATION section above for details. When set to a false value, comments will appear on the page right away. Note: when set to a true value e-mail will be automatically sent to email_to addresses. Defaults to: 1

send_entered

send_entered => 1,

Optional. Takes either true or false values, regarded only when moderate argument is set to a false value. When set to a true value will dispatch an e-mail about a new comment to the addresses set in email_to argument. Defaults to: 1

subject

subject => 'ZofCMS Comments',

Optional. Takes a string as a value. Nothing fancy, this will be the "Subject" of the e-mails sent by the plugin (see moderate and send_entered arguments). Defaults to: 'ZofCMS Comments'

flood_num

flood_num => 2,

Optional. Takes a positive integer or zero as a value. Indicates how many comments a visitor may post in flood_time (see below) amount of time. Setting this value to 0 effectively disables flood protection. Defaults to: 2

flood_time

flood_time => 180,

Optional. Takes a positive integer as a value. Specifies the time in seconds during which the visitor may post only flood_num (see above) comments. Defaults to: 180

mod_out_time

mod_out_time => 1209600,

Optional. Takes a positive integer or false value as a value. When set to a positive integer indicates how old (in seconds) the comment in mod_table must get before it will be automatically removed from the mod_table (i.e. "denied"). Comments older than mod_out_time seconds will not actually be deleted until moderation takes place, i.e. until you approve or deny some comment. Setting this value to 0 effectively disables this "auto-delete" feature. Defaults to: 1209600 (two weeks)

EXAMPLES

The examples/ directory of this distribution contains main config file and HTML/ZofCMS templates which were used during testing of this plugin.

PREREQUISITES

This plugin requires more goodies than any other ZofCMS plugin to the date. Plugin needs the following modules for happy operation. Plugin was tested with module versions indicated:

'DBI'            => 1.602,
'URI'            => 1.35,
'HTML::Template' => 2.9,
'HTML::Entities' => 1.35,
'Storable'       => 2.18,
'Mail::Send'     => 2.04,

App::ZofCMS::Plugin::ConditionalRedirect (version 0.0101)

NAME

Link: App::ZofCMS::Plugin::ConditionalRedirect

App::ZofCMS::Plugin::ConditionalRedirect - redirect users based on conditions

SYNOPSIS

In Main Config file or ZofCMS template:

plugins => [ qw/ConditionalRedirect/ ],
plug_redirect => sub { time() % 2 ? 'http://google.com/' : undef },

DESCRIPTION

The module is a plugin for App::ZofCMS. It provides means to redirect user to pages depending on certain conditions, e.g. some key having a value in ZofCMS Template hashref or anything else, really.

This documentation assumes you've read App::ZofCMS, App::ZofCMS::Config and App::ZofCMS::Template

MAIN CONFIG FILE AND ZofCMS TEMPLATE KEYS

plugins

plugins => [ qw/ConditionalRedirect/ ],

plugins => [ { UserLogin => 1000 }, { ConditionalRedirect => 2000 } ],

The obvious is that you'd want to stick this plugin into the list of plugins to be executed. However, since functionality of this plugin can be easily implemented using exec and exec_before special keys in ZofCMS Template, being able to set the priority to when the plugin should be run would probably one of the reasons for you to use this plugin (it was for me at least).

plug_redirect

plug_redirect => sub {
    my ( $template_ref, $query_ref, $config_obj ) = @_;
    return $template_ref->{foo} ? 'http://google.com/' : undef;
}

The plug_redirect first-level key in Main Config file or ZofCMS Template takes a subref as a value. The sub will be executed and its return value will determine where to redirect (if at all). Returning undef from this sub will NOT cause any redirects at all. Returning anything else will be taken as a URL to which to redirect and the plugin will call exit() after printing the redirect headers.

The @_ of the sub will receive the following: ZofCMS Template hashref, query parameters hashref and App::ZofCMS::Config object (in that order).

If you set plug_redirect in both Main Config File and ZofCMS Template, the one in ZofCMS Template will take precedence.

App::ZofCMS::Plugin::Cookies (version 0.0103)

NAME

Link: App::ZofCMS::Plugin::Cookies

App::ZofCMS::Plugin::Cookies - HTTP Cookie handling plugin for ZofCMS

SYNOPSIS

In your ZofCMS template, or in your main config file (under template_defaults or dir_defaults):

set_cookies => [
    [ 'name', 'value' ],
    {
        -name    => 'sessionID',
        -value   => 'xyzzy',
        -expires => '+1h',
        -path    => '/cgi-bin/database',
        -domain  => '.capricorn.org',
        -secure  => 1,
    },
],

DESCRIPTION

This module is a plugin for App::ZofCMS which provides means to read and set HTTP cookies.

SETTING COOKIES

# example 1
set_cookies => [ 'name', 'value' ],

# OR

# example 2
set_cookies => {
        -name    => 'sessionID',
        -value   => 'xyzzy',
        -expires => '+1h',
        -path    => '/cgi-bin/database',
        -domain  => '.capricorn.org',
        -secure  => 1,
},

# OR

# example 3
set_cookies => [
    [ 'name', 'value' ],
    {
        -name    => 'sessionID',
        -value   => 'xyzzy',
        -expires => '+1h',
        -path    => '/cgi-bin/database',
        -domain  => '.capricorn.org',
        -secure  => 1,
    },
],

To set cookies use set_cookies first level key of your ZofCMS template. It's value can be either an arrayref or a hashref. When the value is an arrayref elements of which are not arrayrefs or hashrefs (example 1 above), or when the value is a hashref (example 2 above) it is encapsulated into an arrayref automatically to become as shown in (example 3 above). With that in mind, each element of an arrayref, which is a value of set_cookies key, specifies a certain cookie which plugin must set. When element of that arrayref is an arrayref, it must contain two elements. The first element will be the name of the cookie and the second element will be the value of the cookie. In other words:

set_cookies => [ 'name', 'value', ]

# which is the same as

set_cookies => [ [ 'name', 'value', ]

# which is the same as

CGI->new->cookie( -name => 'name', -value => 'value' );

When the element is a hashref, it will be dereferenced directy into CGI's cookie() method, in other words:

set_cookies => { -name => 'name', -value => 'value' }

# is the same as

CGI->new->cookie( -name => 'name', -value => 'value' );

See documentation of CGI module for possible values.

If set_cookies key is not present, no cookies will be set.

READING COOKIES

All of the cookies are read by the plugin automatically and put into {d}{cookies} (the special key {d} (data) of your ZofCMS template)

You can read those either via exec code (NOT exec_before, plugins are run after) (If you don't know what exec or exec_before are read App::ZofCMS::Template). Other plugins can also read those cookies, just make sure they are run after the Cookies plugin is run (set higher priority number). Below is an example of reading a cookie and displaying it's value in your HTML::Template template using App::ZofCMS::Plugin::Tagged plugin.

# In your ZofCMS template:

    plugins     => [ { Cookies => 10 }, { Tagged => 20 }, ],
    set_cookies => [ foo => 'bar' ],
    t => {
        cookie_foo => '<TAG:TNo cookies:{d}{cookies}{foo}>',
    },

# In one of your HTML::Template templates which are referenced by
# ZofCMS plugin above:

Cookie 'foo': <tmpl_var name="cookie_foo">

When this page is run the first time, no cookies are set, thus {d}{cookies} will be empty and you will see the default value of "No cookies" which we set in Tagged's tag:

Cookie 'foo': No cookies

When the page s run the second time, Cookies plugin will read cookie 'foo' which it set on the first run and will stick its value into {d}{cookies}{foo}. Our Tagged tag will read that value and enter it into the <tmpl_var> we allocated in HTML::Template plugin, thus the result will be:

Cookie 'foo': bar

That's all there is to it, enjoy!

App::ZofCMS::Plugin::DBI (version 0.0202)

NAME

Link: App::ZofCMS::Plugin::DBI

App::ZofCMS::Plugin::DBI - DBI access from ZofCMS templates

SYNOPSIS

In your main config file or ZofCMS template:

dbi => {
    dsn     => "DBI:mysql:database=test;host=localhost",
    user    => 'test', # user,
    pass    => 'test', # pass
    opt     => { RaiseError => 1, AutoCommit => 0 },
},

In your ZofCMS template:

dbi => {
    dbi_get => {
        layout  => [ qw/name pass/ ],
        sql     => [ 'SELECT * FROM test' ],
    },
    dbi_set => sub {
        my $query = shift;
        if ( defined $query->{user} and defined $query->{pass} ) {
            return [
                [ 'DELETE FROM test WHERE name = ?;', undef, $query->{user}      ],
                [ 'INSERT INTO test VALUES(?,?);', undef, @$query{qw/user pass/} ],
            ];
        }
        elsif ( defined $query->{delete} and defined $query->{user_to_delete} ) {
            return [ 'DELETE FROM test WHERE name =?;', undef, $query->{user_to_delete} ];
        }
        return;
    },
},

In your HTML::Template template:

<form action="" method="POST">
    <div>
        <label for="name">Name: </label>
        <input id="name" type="text" name="user" value="<tmpl_var name="query_user">"><br>
        <label for="pass">Pass: </label>
        <input id="pass" type="text" name="pass" value="<tmpl_var name="query_pass">"><br>
        <input type="submit" value="Add">
    </div>
</form>

<table>
    <tmpl_loop name="dbi_var">
        <tr>
            <td><tmpl_var name="name"></td>
            <td><tmpl_var name="pass"></td>
            <td>
                <form action="" method="POST">
                    <div>
                        <input type="hidden" name="user_to_delete" value="<tmpl_var name="name">">
                        <input type="submit" name="delete" value="Delete">
                    </div>
                </form>
            </td>
        </tr>
    </tmpl_loop>
</table>

DESCRIPTION

Module is a App::ZofCMS plugin which provides means to retrieve and push data to/from SQL databases using DBI module.

Current functionality is limited. More will be added as the need arrises, let me know if you need something extra.

This documentation assumes you've read App::ZofCMS, App::ZofCMS::Config and App::ZofCMS::Template

DSN AND CREDENTIALS

dbi => {
    dsn     => "DBI:mysql:database=test;host=localhost",
    user    => 'test', # user,
    pass    => 'test', # pass
    opt     => { RaiseError => 1, AutoCommit => 0 },
},

You can set these either in your ZofCMS template's dbi key or in your main config file's dbi key. The key takes a hashref as a value. The keys/values of that hashref are as follows:

dsn

dsn => "DBI:mysql:database=test;host=localhost",

Specifies the DSN for DBI, see DBI for more information on what to use here.

user and pass

user    => 'test', # user,
pass    => 'test', # pass

The user and pass key should contain username and password for the database you will be accessing with your plugin.

opt

opt => { RaiseError => 1, AutoCommit => 0 },

The opt key takes a hashref of any additional options you want to pass to connect_cached DBI's method.

RETRIEVING FROM AND SETTING DATA IN THE DATABASE

In your ZofCMS template the first-level dbi key accepts a hashref two possible keys: dbi_get for retreiving data from database and dbi_set for setting data into the database. Note: you can also have your dsn, user, pass and opt keys here if you wish.

dbi_get

dbi => {
    dbi_get => {
        layout  => [ qw/name pass/ ],
        single  => 1,
        sql     => [ 'SELECT * FROM test' ],
    },
}

dbi => {
    dbi_get => [
        {
            layout  => [ qw/name pass/ ],
            sql     => [ 'SELECT * FROM test' ],
        },
        {
            layout  => [ qw/name pass time info/ ],
            sql     => [ 'SELECT * FROM bar' ],
        },
    ],
}

The dbi_get key takes either a hashref or an arrayref as a value. If the value is a hashref it is the same as having just that hashref inside the arrayref. Each element of the arrayref must be a hashref with instructions on how to retrieve the data. The possible keys/values of that hashref are as follows:

layout

layout  => [ qw/name pass time info/ ],

Mandatory. Takes an arrayref as an argument. Specifies the name of <tmpl_var name="">s in your <tmpl_loop> (see type argument below) to which map the columns retrieved from the database, see SYNOPSIS section above.

sql

sql => [ 'SELECT * FROM bar' ],

Mandatory. Takes an arrayref as an argument which will be directly dereferenced into the DBI's method call specified by method argument (see below). See App::ZofCMS::Plugin::Tagged for possible expansion of possibilities you have here.

single

single => 1,

Optional. Takes either true or false values. Normally, the plugin will make a datastructure suitable for a <tmpl_loop name="">; however, if you expecting only one row from the table to be returned you can set single parameter to a true value and then the plugin will stuff appropriate values into {t} special hashref where keys will be the names you specified in the layout argument and values will be the values of the first row that was fetched from the database. By default is not specified (false)

type

dbi_get => {
    type    => 'loop'
...

Optional. Specifies what kind of a HTML::Template variable to generate from database data. Currently the only supported value is loop which generates <tmpl_loop> for yor HTML::Template template. Defaults to: loop

name

dbi_get => {
    name    => 'the_var_name',
...

Optional. Specifies the name of the key in the cell (see below) into which to stuff your data. With the default cell argument this will be the name of a HTML::Template var to set. Defaults to: dbi_var

method

dbi_get => {
    method => 'selectall',
...

Optional. Specifies with which DBI method to retrieve the data. Currently the only supported value for this key is selectall which uses selectall_arrayref. Defaults to: selectall

cell

dbi_get => {
    cell => 't'
...

Optional. Specifies the ZofCMS template's first-level key in which to create the name key with data from the database. cell must point to a key with a hashref in it (though, keep autovivification in mind). Possibly the sane values for this are either t or d. Defaults to: t (the data will be available in your HTML::Template templates)

dbi_set

dbi_set => sub {
    my $query = shift;
    if ( defined $query->{user} and defined $query->{pass} ) {
        return [
            [ 'DELETE FROM test WHERE name = ?;', undef, $query->{user}      ],
            [ 'INSERT INTO test VALUES(?,?);', undef, @$query{qw/user pass/} ],
        ];
    }
    elsif ( defined $query->{delete} and defined $query->{user_to_delete} ) {
        return [ 'DELETE FROM test WHERE name =?;', undef, $query->{user_to_delete} ];
    }
    return;
},

dbi_set => [
    'DELETE FROM test WHERE name = ?;', undef, 'foos'
],

dbi_set => [
    [ 'DELETE FROM test WHERE name = ?;', undef, 'foos' ],
    [ 'INSERT INTO test VALUES(?, ?);', undef, 'foos', 'bars' ],
]

Note: the dbi_set will be processed before dbi_get. Takes either a subref or an arrayref as an argument. Multiple instructions can be put inside an arrayref as the last example above demonstrates. Each arrayref will be directly dereferenced into DBI's do() method. Each subref must return either a single scalar, an arrayref or an arrayref of arrayrefs. Returning a scalar is the same as returning an arrayref with just that scalar in it. Returning just an arrayref is the same as returning an arrayref with just that arrayref in it. Each arrayref of the resulting arrayref will be directly dereferenced into DBI's do() method. The subrefs will have the following in their @_ when called: $query, $template, $config, $dbh. Where $query is a hashref of query parameters in which keys are the name of the parameters and values are values. $template is a hashref of your ZofCMS template. $config is the App::ZofCMS::Config object and $dbh is DBI's database handle object.

App::ZofCMS::Plugin::Debug::Dumper (version 0.0101)

NAME

Link: App::ZofCMS::Plugin::Debug::Dumper

App::ZofCMS::Plugin::Debug::Dumper - small debugging plugin that Data::Dumper::Dumper()s interesting portions into {t}

SYNOPSIS

In your Main Config file or ZofCMS Template:

plugins => [ qw/Debug::Dumper/ ],

In your HTML::Template template:

Dump of {t} key: <tmpl_var name="dumper_tt">
Dump of {d} key: <tmpl_var name="dumper_td">
Dump of ZofCMS template: <tmpl_var name="dumper_t">
Dump of query: <tmpl_var name="dumper_q">
Dump of main config: <tmpl_var name="dumper_c">

DESCRIPTION

The module is a small debugging plugin for App::ZofCMS. It uses Data::Dumper to make dumps of 5 things and sticks them into {t} ZofCMS template key so you could display the dumps in your HTML::Template template for debugging purposes.

This documentation assumes you've read App::ZofCMS, App::ZofCMS::Config and App::ZofCMS::Template

MAIN CONFIG FILE OR ZofCMS TEMPLATE

plugins

plugins => [ qw/Debug::Dumper/ ],

plugins => [ { UserLogin => 100 }, { 'Debug::Dumper' => 200 } ],

You need to add the plugin to the list of plugins to execute (duh!). By setting the priority of the plugin you can make dumps before or after some plugins executed.

plug_dumper

plug_dumper => {
    t_prefix    => 'dumper_',
    use_qq      => 1,
    pre         => 1,
    escape_html => 1,
    line_length => 80,
},

The plugin takes configuration via plug_dumper first-level key that can be either in ZofCMS template or Main Config file, same keys set in ZofCMS template will override those keys set in Main Config file. As opposed to many ZofCMS plugins, App::ZofCMS::Plugin::Debug::Dumper will still execute even if the plug_dumper key is not set to anything.

The plug_dumper key takes a hashref as a value. Possible keys/values of that hashref are as follows:

t_prefix

{ t_prefix => 'dumper_', }

Optional. The t_prefix specifies the string to use to prefix the names of the HTML::Template variables generated by the plugin in {t} ZofCMS Template key. See HTML::Template VARIABLES section below for more information. Defaults to: dumper_ ( note the underscore at the end)

use_qq

{ use_qq => 1, }

Optional. Can be set to either true or false values. When set to a true value, the plugin will set $Data::Dumper::Useqq to 1 before making the dumps, this will basically make, e.g. "\n"s instead of generating real new lines in output. See Data::Dumper for more information. Defaults to: 1

pre

{ pre => 1, }

Optional. Can be set to either true or false values. When set to a true value the plugin will wrap all the generated dumps into HTML <pre></pre> tags. Defaults to: 1

escape_html

{ escape_html => 1, }

Optional. Can be set to either true or false values. When set to a true value the plugin will escape HTML code in the dumps. Defaults to: 1

line_length

{ line_length => 150, }

Optional. The line_length key takes a positive integer as a value. This value will specify the maximum length of each line in generated dumps. Strictly speaking it will stick a \n after every line_length characters that are not \n. Special value or 0 will disable line length feature. Defaults to: 150

HTML::Template VARIABLES

The plugin will stick the generated dumps in the {t} ZofCMS template special key; that means that you can dump them out in your HTML::Template templates with <tmpl_var name"">s. The following five variables are available so far:

Dump of {t} key: <tmpl_var name="dumper_tt">
Dump of {d} key: <tmpl_var name="dumper_td">
Dump of ZofCMS template: <tmpl_var name="dumper_t">
Dump of query: <tmpl_var name="dumper_q">
Dump of main config: <tmpl_var name="dumper_c">

The {t} and {d} keys refer to special keys in ZofCMS Templates. The query is the hashref of query parameters passed to the script and main config is your Main Config file hashref. The dumper_ prefix in the <tmpl_var name="">s above is the t_prefix that you can set in plug_dumper configuration key (explained way above). In other words, in your main config file or ZofCMS template you can set: plug_dumper => { t_prefix => '_' } and in HTML::Template templates you'd then use <tmpl_var name="_tt">, <tmpl_var name="_q">, etc.

The names are generated by using $t_prefix . $name, where $t_prefix is t_prefix set in plug_dumper and $name is one of the "variable names" that are as follows:

tt

<tmpl_var name="dumper_tt">

The dump of {t} ZofCMS template special key. Mnemonic: template {t} key.

td

<tmpl_var name="dumper_td">

The dump of {d} ZofCMS template special key. Mnemonic: template {d} key.

t

<tmpl_var name="dumper_t">

The dump of entire ZofCMS template hashref. Mnemonic: template.

q

<tmpl_var name="dumper_q">

The dump of query parameters as a hashref, in parameter/value way. Mnemonic: query.

c

<tmpl_var name="dumper_c">

The dump of your Main Config file hashref. Mnemonic: config.

SPECIAL NOTES

Note that all properly behaving plugins will remove their config data from ZofCMS templates and Main Config files, that list includes this plugin as well, therefore when dumping the ZofCMS template (<tmpl_var name="dumper_t">) after the plugins were executed, you will not see the configuration for those plugins that you wrote.

SEE ALSO

Data::Dumper

App::ZofCMS::Plugin::Debug::Validator::HTML (version 0.0102)

NAME

Link: App::ZofCMS::Plugin::Debug::Validator::HTML

App::ZofCMS::Plugin::Debug::Validator::HTML - debugging plugin for auto validating HTML

SYNOPSIS

In your Main Config file or ZofCMS Template:

plugins => [ 'Debug::Validator::HTML' ]

In your HTML::Template template:

<tmpl_var name="plug_val_html">

Access your page with http://your.domain.com/index.pl?page=/test&plug_val_html=1

Read the validation results \o/

DESCRIPTION

The module is a debugging plugin for App::ZofCMS that provides means to validate the HTML code that you are writing on the spot.

This documentation assumes you've read App::ZofCMS, App::ZofCMS::Config and App::ZofCMS::Template

MAIN CONFIG FILE AND ZofCMS TEMPLATE FIRST-LEVEL KEYS

plugins

plugins => [ qw/Debug::Validator::HTML/ ],

You need to include the plugin in the list of plugins to be executed.

plug_validator_html

# everything is optional
plug_validator_html => {
    t_name          => 'plug_val_html',
    q_name          => 'plug_val_html',
    validator_uri   => 'http://127.0.0.1/w3c-markup-validator/check',
    address         => 'http://your.site.com/index.pl?page=/test', 
}

The plugin takes its optional configuration from plug_validator_html first-level key that takes a hashref as a value. Plugin will still run even if plug_validator_html key is not present. You can set any of the config options in either Main Config File or ZofCMS Template file. Whatever you set in ZofCMS Template file will override the same key if it was set in Main Config File. Possible keys/values are as follows:

t_name

t_name => 'plug_val_html',

Optional. The plugin sets validation results in one of the keys in the {t} special key. The t_name argument specifies the name of that key. See HTML::Template VARIABLES section below for details. Defaults to: plug_val_html

q_name

q_name => 'plug_val_html',

Optional. To trigger the execution of the plugin you need to pass a query parameter that is set to a true value. This is to speed up normal development process (because you don't really want to validate on every refresh) but most importantly it is to prevent infinite loops where the plugin will try to execute itself while fetching your HTML for validation. See SYNOPSIS section for example on how to trigger the validator with this query parameter. Defaults to: plug_val_html

validator_uri

validator_uri   => 'http://127.0.0.1/w3c-markup-validator/check',

Optional. Plugin accesses a W3C markup validator. The validator_uri argument takes a URI pointing to the validator. It would be REALLY GREAT if you'd download the validator for your system and use a local version. Debian/Ubuntu users can do it as simple as sudo apt-get install w3c-markup-validator, others see http://validator.w3.org/source/. If you cannot install a local version of the validator set validator_uri to http://validator.w3.org/check. Defaults to: http://127.0.0.1/w3c-markup-validator/check

address

address => 'http://your.site.com/index.pl?page=/test',

Optional. The plugin uses needs to fetch your page in order to get the markup to validate. Generally you don't need to touch address argument as the plugin will do its black magic to figure out, but in case it fails you can set it or wish to validate some other page that is not the one on which you are displaying the results, you can set the address argument that takes a string that is the URI to the page you wish to validate.

HTML::Template VARIABLES

<tmpl_var name='plug_val_html'>
<tmpl_var name='plug_val_html_link'>

The plugin sets two HTML::Template variables in {t} key; its name is what you set in t_name argument, which defaults to plug_val_html.

If your HTML code is valid, this variable will be replaced with words HTML is valid. Otherwise you'll see either an error message for why validation failed or actual error messages that explain why your HTML is invalid.

The second variable will contain a link to either turn on or turn off validation. The name of that variable is contructed by appending _link to the t_name argument, thus by default it will be <tmpl_var name='plug_val_html_link'>

USAGE NOTES

You'd probably would want to include the plugin to execute in your Main Config File and put the <tmpl_var name=""> in your base template while developing the site. Just don't forget to take it out when you done ;)

PLEASE! Install a local validator. Tons of people already accessing the one that is hosted in http://w3.org, don't make the lag worse.

App::ZofCMS::Plugin::DirTreeBrowse (version 0.0102)

NAME

Link: App::ZofCMS::Plugin::DirTreeBrowse

App::ZofCMS::Plugin::DirTreeBrowse - plugin to display browseable directory tree

SYNOPSIS

SIMPLE VARIANT

In your Main Config file or ZofCMS Template:

plugins     => [ qw/DirTreeBrowse/ ],
plug_dir_tree => {
    auto_html => 1,
    start     => 'pics',
},

In you HTML::Template template:

<p>We are at: <tmpl_var escape='html' name='dir_tree_path'></p>
<tmpl_var name='dir_tree_auto'>

MORE FLEXIBLE VARIANT

In your Main Config file or ZofCMS Template:

plugins     => [ qw/DirTreeBrowse/ ],
plug_dir_tree => {
    start     => 'pics',
},

In your HTML::Template template:

<p>We are at: <tmpl_var escape='html' name='dir_tree_path'></p>

<ul>
    <tmpl_if name="dir_tree_back">
        <li><a href="/index.pl?page=/&dir_tree=<tmpl_var escape='html' name='dir_tree_back'>">UP</a></li>
    </tmpl_if>
<tmpl_loop name='dir_tree_list'>
    <li>
        <tmpl_if name="is_file">
        <a href="/<tmpl_var escape='html' name='path'>"><tmpl_var escape='html' name='name'></a>
        <tmpl_else>
        <a href="/index.pl?page=/&dir_tree=<tmpl_var escape='html' name='path'>"><tmpl_var escape='html' name='name'></a>
        </tmpl_if>
    </li>
</tmpl_loop>
</ul>

DESCRIPTION

The module is an App::ZofCMS plugin that provides means to display a browseable directory three (list of files and other dirs).

This documentation assumes you've read App::ZofCMS, App::ZofCMS::Config and App::ZofCMS::Template

MAIN CONFIG FILE AND ZofCMS TEMPLATE FIRST-LEVEL KEYS

plugins

plugins => [ qw/DirTreeBrowse/ ],

First and foremost, you'd obviously would want to add the plugin into the list of plugins to execute.

plug_dir_tree

plug_dir_tree => {
    start                  => 'pics',
    auto_html              => 'ul_class',
    re                     => qr/[.]jpg$/,
    q_name                 => 'dir_tree',
    t_prefix               => 'dir_tree_',
    display_path_separator => '/',
}

The plug_dir_tree takes a hashref as a value and can be set in either Main Config file or ZofCMS Template file. Keys that are set in both Main Config file and ZofCMS Template file will get their values from ZofCMS Template file. Possible keys/values of plug_dir_tree hashref are as follows:

start

plug_dir_tree => {
    start => 'pics',
},

Mandatory. Specifies the starting directory of the directory three you wish to browse. The directory is relative to your index.pl file and must be web-accessible.

auto_html

plug_dir_tree => {
    start       => 'pics',
    auto_html   => 'ul_class',
},

Optional. When set to a defined value will cause the plugin to generate directory tree HTML automatically, the value then will become the classname for the <ul> element that holds the list of files/dirs. See SYNOPSIS and HTML::Template VARIABLES sectons for more details. Note: the plugin does not append current query to links, so if you wish to add something to the query parameters

re

plug_dir_tree => {
    start => 'pics',
    re    => qr/[.]jpg$/,
}

Optional. Takes a regex (qr//) as a value. When specified only the files matching this regex will be in the list. Note that file and its path will be matched, e.g. pics/old_pics/foo.jpg

q_name

plug_dir_tree => {
    start  => 'pics',
    q_name => 'dir_tree',
}

Optional. The plugin uses one query parameter to reference its position in the directory tree. The q_name key specifies the name of that query parameter. Unless you are using the auto_html option, make sure that your links include this query parameter along with <tmpl_var name="path">. In other words, if your q_name is set to dir_tree you'd make your links: <a href="/index.pl?page=/page_with_this_plugin&dir_tree=<tmpl_var escape='html' name='path'>">. Defaults to: dir_tree

t_prefix

plug_dir_tree => {
    start    => 'pics',
    t_prefix => 'dir_tree_',
}

Optional. The t_prefix specifies the prefix to use for several keys that plugin creates in {t} ZofCMS Template special key. See HTML::Template VARIABLES section below for details. Defaults to: dir_tree_ (note the trailing underscore (_))

display_path_separator

plug_dir_tree => {
    start                  => 'pics',
    display_path_separator => '/',
}

Optional. One of the {t} keys generated by the plugin will contain the current path in the directory tree. If display_path_separator is specified, every / character in that current path will be replaced by whatever display_path_separator is set to. By default is not specified.

HTML::Template VARIABLES

The samples below assume that the plugin is run with all of its optional arguments set to defaults.

When auto_html is turned on

<p>We are at: <tmpl_var escape='html' name='dir_tree_path'></p>
<tmpl_var name='dir_tree_auto'>

dir_tree_path

<p>We are at: <tmpl_var escape='html' name='dir_tree_path'></p>

The <tmpl_var name='dir_three_path'> variable will contain the current path in the directory tree.

dir_tree_auto

<tmpl_var name='dir_tree_auto'>

The <tmpl_var name='dir_tree_auto'> is available when auto_html option is turned on in the plugin. The generated HTML code would be pretty much as the MORE FLEXIBLE VARIANT section in SYNOPSIS demonstrates.

When auto_html is turned off

<p>We are at: <tmpl_var escape='html' name='dir_tree_path'></p>
<ul>
    <tmpl_if name="dir_tree_back">
        <li><a href="/index.pl?page=/&dir_tree=<tmpl_var escape='html' name='dir_tree_back'>">UP</a></li>
    </tmpl_if>
<tmpl_loop name='dir_tree_list'>
    <li>
        <tmpl_if name="is_file">
        <a href="/<tmpl_var escape='html' name='path'>"><tmpl_var escape='html' name='name'></a>
        <tmpl_else>
        <a href="/index.pl?page=/&dir_tree=<tmpl_var escape='html' name='path'>"><tmpl_var escape='html' name='name'></a>
        </tmpl_if>
    </li>
</tmpl_loop>
</ul>

dir_tree_path

<p>We are at: <tmpl_var escape='html' name='dir_tree_path'></p>

The <tmpl_var name='dir_three_path'> variable will contain the current path in the directory tree.

dir_tree_back

<tmpl_if name="dir_tree_back">
    <li><a href="/index.pl?page=/&dir_tree=<tmpl_var escape='html' name='dir_tree_back'>">UP</a></li>
</tmpl_if>

The dir_tree_back will be available when the user browsed to some directory inside the start directory. It will contain the path to the parent directory so the user could traverse up the tree.

dir_tree_list

<tmpl_loop name='dir_tree_list'>
    <li>
        <tmpl_if name="is_file">
        <a href="/<tmpl_var escape='html' name='path'>"><tmpl_var escape='html' name='name'></a>
        <tmpl_else>
        <a href="/index.pl?page=/&dir_tree=<tmpl_var escape='html' name='path'>"><tmpl_var escape='html' name='name'></a>
        </tmpl_if>
    </li>
</tmpl_loop>

The dir_tree_list will contain data structure suitable for <tmpl_loop name="">. Each item of that loop would be an individual file or a directory. The variables that are available in that loop are as follows:

is_file

<tmpl_if name="is_file">
    <a target="_blank" href="/<tmpl_var escape='html' name='path'>"><tmpl_var escape='html' name='name'></a>
<tmpl_else>
    <a href="/index.pl?page=/&dir_tree=<tmpl_var escape='html' name='path'>"><tmpl_var escape='html' name='name'></a>
</tmpl_if>

The is_file will be set whenever the item is a file (as opposed to being a directory). As the example above shows, you'd use this variable as a <tmpl_if name=""> to adjust your links to open the file instead of trying to make the plugin "browse" that file as a directory.

path

<a href="/index.pl?page=/&dir_tree=<tmpl_var escape='html' name='path'>"><tmpl_var escape='html' name='name'></a>

The path variable will contain the path to the directory/file (including the name of that directory/file) starting from the start directory. You'd want to include that as a value of q_name query parameter so the user could traverse the dirs.

name

<a href="/index.pl?page=/&dir_tree=<tmpl_var escape='html' name='path'>"><tmpl_var escape='html' name='name'></a>

The name variable will contain just the name of the file/directory without it's path. You'd want to use this for for displaying the names of the files/dirs to the user.

App::ZofCMS::Plugin::Doctypes (version 0.0101)

NAME

Link: App::ZofCMS::Plugin::Doctypes

App::ZofCMS::Plugin::Doctypes - include DOCTYPEs in your pages without remembering how to spell them

SYNOPSIS

In your Main Config file:

template_defaults => {
    plugins => [ qw/Doctypes/ ],
},

In your HTML::Template files

<tmpl_var name="doctype HTML 4.01 Strict">

DESCRIPTION

If you are like me you definitely don't remember how to properly spell out the DOCTYPE (DOCument TYPE definition) in your pages and always rely on your editor or look it up. Well, fear no more! This little module contains all the common DTDs and will stuff them into {t} ZofCMS template's special key for you to use.

AVAILABLE DTDs

Below are examples of <tmpl_var name=""> that will be substituted into the actual doctypes. The names of the doctypes correspoding to each of those examples are self explanatory. Note: the plugin has two modes (for now). The basic mode is the default one, it will make only DTDs available under BASIC section. The extra mode will include more doctypes.

ENABLING 'EXTRA' MODE

To enable the extra mode: in your ZofCMS template, but most likely you'd want that in your main config file:

plugin_doctype => { extra => 1 },

This would be the first-level key in ZofCMS template as well as main config file.

'BASIC' MODE DTDs

<tmpl_var name="doctype HTML 4.01 Strict">
<tmpl_var name="doctype HTML 4.01 Transitional">
<tmpl_var name="doctype HTML 4.01 Frameset">
<tmpl_var name="doctype XHTML 1.0 Strict">
<tmpl_var name="doctype XHTML 1.0 Transitional">
<tmpl_var name="doctype XHTML 1.0 Frameset">
<tmpl_var name="doctype XHTML 1.1">

'EXTRA' MODE DTDs

<tmpl_var name="doctype XHTML Basic 1.0">
<tmpl_var name="doctype XHTML Basic 1.1">
<tmpl_var name="doctype HTML 2.0">
<tmpl_var name="doctype HTML 3.2">
<tmpl_var name="doctype MathML 1.01">
<tmpl_var name="doctype MathML 2.0">
<tmpl_var name="doctype XHTML + MathML + SVG">
<tmpl_var name="doctype SVG 1.0">
<tmpl_var name="doctype SVG 1.1 Full">
<tmpl_var name="doctype SVG 1.1 Basic">
<tmpl_var name="doctype SVG 1.1 Tiny">
<tmpl_var name="doctype XHTML + MathML + SVG Profile (XHTML as the host language)">
<tmpl_var name="doctype XHTML + MathML + SVG Profile (Using SVG as the host)">

App::ZofCMS::Plugin::FileList (version 0.0101)

NAME

Link: App::ZofCMS::Plugin::FileList

App::ZofCMS::Plugin::FileList - ZofCMS plugin to display lists of files

SYNOPSIS

In your Main Config file or ZofCMS template:

plugins     => [ qw/FileList/ ],
plug_file_list => {
    list => {
        list1 => 'pics',
        list2 => 'pics2',
    },
},

In your HTML::Template template:

<ul>
<tmpl_loop name='list1'>
    <li><a href="/<tmpl_var escape='html' name='path'>"><tmpl_var name='name'></a></li>
</tmpl_loop>
</ul>

<ul>
<tmpl_loop name='list2'>
    <li><a href="/<tmpl_var escape='html' name='path'>"><tmpl_var name='name'></a></li>
</tmpl_loop>
</ul>

DESCRIPTION

Module is a App::ZofCMS plugin which provides means to display lists of files.

This documentation assumes you've read App::ZofCMS, App::ZofCMS::Config and App::ZofCMS::Template

MAIN CONFIG FILE OR ZofCMS TEMPLATE FIRST-LEVEL KEYS

plugins

plugins => [ qw/FileList/ ],

You would definitely want to add the plugin into the list of plugins to execute :)

plug_file_list

plug_file_list => {
    name => 0,
    re   => qr/[.]jpg$/i,
    list => {
        list1 => 'pics',
        list2 => [ qw/pics2 pics3/ ],
    },
},

plug_file_list => {
    list => [ qw/pics pics2/ ],
},

plug_file_list => {
    list => 'pics',
},

You can specify the plug_file_list first-level key in either Main Config File or ZofCMS Template file. Specifying the same keys in both will lead to the ones set in ZofCMS Template take precedence.

The plug_file_list key takes a hashref as a value. Possible keys/values of that hashref are as follows:

list

plug_file_list => {
    list => {
        list1 => 'pics',
        list2 => [ qw/pics2 pics3/ ],
    },
},

plug_file_list => {
    list => [ qw/pics pics2/ ],
},

plug_file_list => {
    list => 'pics',
},

The list key specifies the directories in which to search for files. The value of that key can be either a hashref, arrayref or a scalar. If the value is not a hashref it will be converted into a hashref as follows:

plug_file_list => {
    list => 'pics', # a scalar
},

# same as

plug_file_list => {
    list => [ 'pics' ], # arrayref
},

# same as

# hashref with a key that has a scalar value
plug_file_list => {
    list => {
        plug_file_list => 'pics',
    }
},

# same as

# hashref with a key that has an arrayref value
plug_file_list => {
    list => {
        plug_file_list => [ 'pics' ],
    }
},

The hashref assigned to list (or converted from other values) takes the following meaning: the keys of that hashref are the names of the keys in {t} ZofCMS Template special key and the values are the lists (arrayrefs) of directories in which to search for files. See SYNOPSIS section for some examples. Note that default {t} key would be plug_file_list as is shown in conversion examples above.

re

plug_file_list => {
    re   => qr/[.]jpg$/i,
    list => 'pics',
},

Optional. The re argument takes a regex as a value (qr//). If specified only the files that match the regex will be listed. By default is not specified.

name

plug_file_list => {
    name => 0,
    list => 'foo',
},

Optional. Takes either true or false values, specifies whether or not to create the name <tmpl_var name=""> in the output. See HTML::Template TEMPLATES section below. Defaults to: 1 (*do* create)

HTML::Template TEMPLATES

In HTML::Template templates you'd show the file lists in the following fashion:

<ul>
<tmpl_loop name='plug_file_list'>
    <li><a href="/<tmpl_var escape='html' name='path'>"><tmpl_var name='name'></a></li>
</tmpl_loop>
</ul>

The name of the <tmpl_loop name=""> is what you specified (directly or indirectly) as keys in the list hashref (see above). Inside the loop there are two <tmpl_var name=""> that you can use:

<tmpl_var name='path'>

The <tmpl_var name='path'> will contain the path to the file, that is the directory you specified . '/' . file name.

<tmpl_var name='name'>

The <tmpl_var name='path'> (providing the name key in plug_file_list hashref is set to a true value) will contain just the filename of the file.

App::ZofCMS::Plugin::FileToTemplate (version 0.0101)

NAME

Link: App::ZofCMS::Plugin::FileToTemplate

App::ZofCMS::Plugin::FileToTemplate - read or do() files into ZofCMS Templates

SYNOPSIS

In your ZofCMS Template:

plugins => [ qw/FileToTemplate/ ],
t  => {
    foo => '<FTTR:index.tmpl>',
},

In you HTML::Template template:

<tmpl_var escape='html' name='foo'>

DESCRIPTION

The module is a plugin for App::ZofCMS; it provides functionality to either read (slurp) or do() files and stick them in place of "tags".. read on to understand more.

This documentation assumes you've read App::ZofCMS, App::ZofCMS::Config and App::ZofCMS::Template

ADDING THE PLUGIN

plugins => [ qw/FileToTemplate/ ],

Unlike many other plugins to run this plugin you barely need to include it in the list of plugins to execute.

TAGS

t  => {
    foo => '<FTTR:index.tmpl>',
    bar => '<FTTD:index.tmpl>',
},

Anywhere in your ZofCMS template you can use two "tags" that this plugin provides. Those "tags" will be replaced - depending on the type of tag - with either the contents of the file or the last value returned by the file.

Both tags are in format: opening angle bracket, name of the tag in capital letters, semicolon, filename, closing angle bracket. The filename is relative to your "templates" directory, i.e. the directory referenced by templates key in Main Config file.

<FTTR:filename>

t  => {
    foo => '<FTTR:index.tmpl>',
},

The <FTTR:filename> reads (slurps) the contents of the file and tag is replaced with those contents. You can have several of these tags as values. Be careful reading in large files with this tag. Mnemonic: File To Template Read.

<FTTD:filename>

t => {
    foo => '<FTTD:index.tmpl>',
},

The <FTTD:filename> tag will do() your file and the last returned value will be assigned to the value in which the tag appears, in other words, having foo => '<FTTD:index.tmpl>', and foo => '<FTTD:index.tmpl> blah blah blah', is the same. Using this tag, for example, you can add large hashrefs or config hashrefs into your templates without clobbering them. Note that if the do() cannot find your file or compilation of the file fails, the value with the tag will be replaced by the error message. Mnemomic: File To Template Do.

NON-CORE PREREQUISITES

The plugin requires one non-core module: Data::Transformer

App::ZofCMS::Plugin::FileUpload (version 0.0101)

NAME

Link: App::ZofCMS::Plugin::FileUpload

App::ZofCMS::Plugin::FileUpload - ZofCMS plugin to handle file uploads

SYNOPSIS

In your ZofCMS template:

file_upload => {
    query   => 'uploaded_file',
},
plugins => [ qw/FileUpload/ ],

In your HTML::Template template:

<tmpl_if name="upload_error">
    <p class="error">Upload failed: <tmpl_var name="upload_error">
</tmpl_if>
<tmpl_if name="upload_success">
    <p>Upload succeeded: <tmpl_var name="upload_filename"></p>
</tmpl_if>

<form action="" method="POST" enctype="multipart/form-data">
<div>
    <input type="file" name="uploaded_file">
    <input type="submit" value="Upload">
</div>
</form>

DESCRIPTION

The module is a ZofCMS plugin which provides means to easily handle file uploads.

This documentation assumes you've read App::ZofCMS, App::ZofCMS::Config and App::ZofCMS::Template

FIRST-LEVEL ZofCMS TEMPLATE KEYS

plugins

plugins => [ qw/FileUpload/ ],

First and obvious, you need to stick FileUpload in the list of your plugins.

file_upload

file_upload => {
    query   => 'upload',
    path    => 'zofcms_upload',
    name    => 'foos',
    ext     => '.html',
    content_type => 'text/html',
    on_success => sub {
        my ( $uploaded_file_name, $template, $query, $conf ) = @_;
        # do something useful
    }
},

# or

file_upload => [
    { query   => 'upload1', },
    { query   => 'upload2', },
    {}, # all the defaults
    {
        query   => 'upload4',
        name    => 'foos',
        ext     => '.html',
        content_type => 'text/html',
        on_success => sub {
            my ( $uploaded_file_name, $template, $query, $conf ) = @_;
            # do something useful
        }
    },
],

Plugin takes input from file_upload first level ZofCMS template key which takes an arrayref or a hashref as a value. Passing a hashref as a value is the same as passing an arrayref with just that hashref as an element. Each element of the given arrayref is a hashref which represents one file upload. The possible keys/values of those hashrefs are as follows:

query

{ query => 'zofcms_upload' },

Optional. Specifies the query parameter which is the file being uploaded, in other words, this is the value of the name="" attribute of the <input type="file".... Defaults to: zofcms_upload

path

{ path => 'zofcms_upload', }

Optional. Specifies directory (relative to index.pl) into which the plugin will store uploaded files. Defaults to: zofcms_upload

name

{ name => 'foos', }

Optional. Specifies the name (without the extension) of the local file into which save the uploaded file. Special value of [rand] specifies that the name should be random, in which case it will be created by calling rand() and time() and removing any dots from the concatenation of those two. Defaults to: [rand]

ext

{ ext => '.html', }

Optional. Specifies the extension to use for the name of local file into which the upload will be stored. By default is not specified and therefore the extension will be obtained from the name of the remote file.

content_type

{ content_type => 'text/html', }

{ content_type => [ 'text/html', 'image/jpeg' ], }

Optional. Takes either a scalar string or an arrayref of strings. Specifying a string is equivalent to specifying an arrayref with just that string as an element. Each element of the given arrayref indicates the allowed Content-Type of the uploaded files. If the Content-Type does not match allowed types the error will be shown (see HTML TEMPLATE VARS section below). By default all Content-Types are allowed.

on_success

on_success => sub {
    my ( $uploaded_file_name, $template, $query, $config ) = @_;
    # do something useful
}

Optional. Takes a subref as a value. The specified sub will be executed upon a successful upload. The @_ will contain the following elements: $uploaded_file_name, $template, $query, $config where $uploaded_file_name is the directory + name + extension of the local file into which the upload was stored, $template is a hashref of your ZofCMS template, $query is a hashref of query parameters and $config is the App::ZofCMS::Config object. By default is not specified.

HTML TEMPLATE VARS

Single upload:

<tmpl_if name="upload_error">
    <p class="error">Upload failed: <tmpl_var name="upload_error">
</tmpl_if>
<tmpl_if name="upload_success">
    <p>Upload succeeded: <tmpl_var name="upload_filename"></p>
</tmpl_if>

<form action="" method="POST" enctype="multipart/form-data">
<div>
    <input type="file" name="upload">
    <input type="submit" value="Upload">
</div>
</form>

Multi upload:

<tmpl_if name="upload_error0">
    <p class="error">Upload 1 failed: <tmpl_var name="upload_error0">
</tmpl_if>
<tmpl_if name="upload_success0">
    <p>Upload 1 succeeded: <tmpl_var name="upload_filename0"></p>
</tmpl_if>

<tmpl_if name="upload_error1">
    <p class="error">Upload 2 failed: <tmpl_var name="upload_error1">
</tmpl_if>
<tmpl_if name="upload_success1">
    <p>Upload 2 succeeded: <tmpl_var name="upload_filename1"></p>
</tmpl_if>

<form action="" method="POST" enctype="multipart/form-data">
<div>
    <input type="file" name="upload">
    <input type="file" name="upload2">
    <input type="submit" value="Upload">
</div>
</form>

NOTE: upload of multiple files from a single <input type="file"... is currently not supported. Let me know if you need such functionality. The folowing <tmpl_var name="">s will be set in your HTML::Template template.

SINGLE AND MULTI

If you are handling only one upload, i.e. you have only one hashref in file_upload ZofCMS template key and you have only one <input type="file"... then the HTML::Template variables described below will NOT have any trailing numbers, otherwise each of them will have a trailing number indicating the number of the upload. This number will starts from zero and it will correspond to the index of hashref of file_upload arrayref.

upload_error

# single
<tmpl_if name="upload_error">
    <p class="error">Upload failed: <tmpl_var name="upload_error">
</tmpl_if>

# multi
<tmpl_if name="upload_error0">
    <p class="error">Upload 1 failed: <tmpl_var name="upload_error0">
</tmpl_if>

The upload_error will be set if some kind of an error occurred during the upload of the file. This also includes if the user tried to upload a file of type which is not listed in content_type arrayref.

upload_success

# single
<tmpl_if name="upload_success">
    <p>Upload succeeded: <tmpl_var name="upload_filename"></p>
</tmpl_if>

# multi
<tmpl_if name="upload_success0">
    <p>Upload 1 succeeded: <tmpl_var name="upload_filename0"></p>
</tmpl_if>

The upload_success will be set to a true value upon successful upload.

upload_filename

# single
<tmpl_if name="upload_success">
    <p>Upload succeeded: <tmpl_var name="upload_filename"></p>
</tmpl_if>

# multi
<tmpl_if name="upload_success0">
    <p>Upload 1 succeeded: <tmpl_var name="upload_filename0"></p>
</tmpl_if>

The upload_filename will be set to directory + name + extension of the local file into which the upload was saved.

App::ZofCMS::Plugin::FormChecker (version 0.0301)

NAME

Link: App::ZofCMS::Plugin::FormChecker

App::ZofCMS::Plugin::FormChecker - plugin to check HTML form data.

SYNOPSIS

In ZofCMS template or main config file:

plugins => [ qw/FormChecker/ ],
plug_form_checker => {
    trigger     => 'some_param',
    ok_key      => 't',
    ok_code     => sub { die "All ok!" },
    fill_prefix => 'form_checker_',
    rules       => {
        param1 => 'num',
        param2 => qr/foo|bar/,
        param3 => [ qw/optional num/ ],
        param4 => {
            optional        => 1,
            select          => 1,
            must_match      => qr/foo|bar/,
            must_not_match  => qr/foos/,
            must_match_error => 'Param4 must contain either foo or bar but not foos',
            param           => 'param2',
        },
        param5 => {
            valid_values        => [ qw/foo bar baz/ ],
            valid_values_error  => 'Param5 must be foo, bar or baz',
        },
        param6 => sub { time() % 2 }, # return true or false values
    },
},

DESCRIPTION

The module is a plugin for App::ZofCMS that provides nifteh form checking.

This documentation assumes you've read App::ZofCMS, App::ZofCMS::Config and App::ZofCMS::Template

ZofCMS TEMPLATE/MAIN CONFIG FILE FIRST LEVEL KEYS

The keys can be set either in ZofCMS template or in Main Config file, if same keys are set in both, then the one in ZofCMS template takes precedence.

plugins

plugins => [ qw/FormChecker/ ],

You obviously would want to include the plugin in the list of plugins to execute.

plug_form_checker

# keys are listed for demostrative purposes,
# some of these don't make sense when used together
plug_form_checker => {
    trigger     => 'plug_form_checker',
    ok_key      => 'd',
    ok_redirect => '/some-page',
    ok_code     => sub { die "All ok!" },
    no_fill     => 1,
    fill_prefix => 'plug_form_q_',
    rules       => {
        param1 => 'num',
        param2 => qr/foo|bar/,
        param3 => [ qw/optional num/ ],
        param4 => {
            optional        => 1,
            select          => 1,
            must_match      => qr/foo|bar/,
            must_not_match  => qr/foos/,
            must_match_error => 'Param4 must contain either foo or bar but not foos',
        },
        param5 => {
            valid_values        => [ qw/foo bar baz/ ],
            valid_values_error  => 'Param5 must be foo, bar or baz',
        },
        param6 => sub { time() % 2 }, # return true or false values
    },
},

The plug_form_checker first-level key takes a hashref as a value. Only the rules key is mandatory, the rest are optional. The possible keys/values of that hashref are as follows.

trigger

trigger => 'plug_form_checker',

Optional. Takes a string as a value that must contain the name of the query parameter that would trigger checking of the form. Generally, it would be some parameter of the form you are checking (that would always contain true value, in perl's sense of true) or you could always use <input type="hidden" name="plug_form_checker" value="1">. Defaults to: plug_form_checker

ok_key

ok_key => 'd',

Optional. If the form passed all the checks plugin will set a second level key plug_form_checker to a true value. The ok_key parameter specifies the first level key in ZofCMS template where to put the plug_form_checker key. For example, you can set ok_key to 't' and then in your HTML::Template template use <tmpl_if name="plug_form_checker">FORM OK!</tmpl_if>... but, beware of using the 't' key when you are also using App::ZofCMS::QueryToTemplate plugin, as someone could avoid proper form checking by passing fake query parameter. Defaults to: d ("data" ZofCMS template special key).

ok_redirect

ok_redirect => '/some-page',

Optional. If specified, the plugin will automatically redirect the user to the URL specified as a value to ok_redirect key. Note that the plugin will exit() right after printing the redirect header. By default not specified.

ok_code

ok_code => sub {
    my ( $template, $query, $config ) = @_;
    $template->{t}{foo} = "Kewl!";
}

Optional. Takes a subref as a value. When specfied that subref will be executed if the form passes all the checks. The @_ will contain the following (in that order): hashref of ZofCMS Template, hashref of query parameters and App::ZofCMS::Config object. By default is not specified. Note: if you specify ok_code and ok_redirect the code will be executed and only then user will be redirected.

no_fill

no_fill => 1,

Optional. When set to a true value plugin will not fill query values. Defaults to: 0. When no_fill is set to a false value the plugin will fill in ZofCMS template's {t} special key with query parameter values (only the ones that you are checking, though, see rules key below). This allows you to fill your form with values that user already specified in case the form check failed. The names of the keys inside the {t} key will be formed as follows: $prefix . $query_param_name where $prefix is the value of fill_prefix key (see below) and $query_param_name is the name of the query parameter. Of course, this alone wouldn't cut it for radio buttons or <select> elements. For that, you need to set select => 1 in the ruleset for that particular query parameter (see rules key below); when select rule is set to a true value then the names of the keys inside the {t} key will be formed as follows: $prefix . $query_param_name . '_' . $value. Where the $prefix is the value of fill_prefix key, $query_param_name is the name of the query parameter; following is the underscore (_) and then $value that is the value of the query parameter. Consider the following snippet in ZofCMS template and corresponding HTML::Template HTML code as an example:

plug_form_checker => {
    trigger => 'foo',
    fill_prefix => 'plug_form_q_',
    rules => { foo => { select => 1 } },
}

<form action="" method="POST">
    <input type="text" name="bar" value="<tmpl_var name="plug_form_q_">">
    <input type="radio" name="foo" value="1"
        <tmpl_if name="plug_form_q_foo_1"> checked </tmpl_if>
    >
    <input type="radio" name="foo" value="2"
        <tmpl_if name="plug_form_q_foo_2"> checked </tmpl_if>
    >
</form>

fill_prefix

fill_prefix => 'plug_form_q_',

Optional. Specifies the prefix to use for keys in {t} ZofCMS template special key when no_fill is set to a false value. The "filling" is described above in no_fill description. Defaults to: plug_form_q_ (note the underscore at the very end)

rules

rules       => {
    param1 => 'num',
    param2 => qr/foo|bar/,
    param3 => [ qw/optional num/ ],
    param4 => {
        optional        => 1,
        select          => 1,
        must_match      => qr/foo|bar/,
        must_not_match  => qr/foos/,
        must_match_error => 'Param4 must contain either foo or bar but not foos',
    },
    param5 => {
        valid_values        => [ qw/foo bar baz/ ],
        valid_values_error  => 'Param5 must be foo, bar or baz',
    },
    param6 => sub { time() % 2 }, # return true or false values
},

This is the "heart" of the plugin, the place where you specify the rules for checking. The rules key takes a hashref as a value. The keys of that hashref are the names of the query parameters that you wish to check. The values of those keys are the "rulesets". The values can be either a string, regex (qr//), arrayref, subref, scalarref or a hashref; If the value is NOT a hashref it will be changed into hashref as follows (the actual meaning of resulting hashrefs is described below):

a string

param => 'num',
# same as
param => { num => 1 },

a regex

param => qr/foo/,
# same as
param => { must_match => qr/foo/ },

an arrayref

param => [ qw/optional num/ ],
# same as
param => {
    optional => 1,
    num      => 1,
},

a subref

param => sub { time() % 2 },
# same as
param => { code => sub { time() % 2 } },

a scalarref

param => \'param2',
# same as
param => { param => 'param2' },

rules RULESETS

The rulesets (values of rules hashref) have keys that define the type of the rule and value defines diffent things or just indicates that the rule should be considered. Here is the list of all valid ruleset keys:

rules => {
    param => {
        name            => 'Parameter', # the name of this param to use in error messages
        num             => 1, # value must be numbers-only
        optional        => 1, # parameter is optional
        must_match      => qr/foo/, # value must match given regex
        must_not_match  => qr/bar/, # value must NOT match the given regex
        max             => 20, # value must not exceed 20 characters in length
        min             => 3,  # value must be more than 3 characters in length
        valid_values    => [ qw/foo bar baz/ ], # value must be one from the given list
        code            => sub { time() %2 }, # return from the sub determines pass/fail
        select          => 1, # flag for "filling", see no_fill key above
        param           => 'param1',
        num_error       => 'Numbers only!', # custom error if num rule failed
        mandatory_error => '', # same for if parameter is missing and not optional.
        must_match_error => '', # same for must_match rule
        must_not_match_error => '', # same for must_not_match_rule
        max_error            => '', # same for max rule
        min_error            => '', # same for min rule
        code_error           => '', # same for code rule
        valid_values_error   => '', # same for valid_values rule
        param_error          => '', # same fore param rule
    },
}

You can mix and match the rules for perfect tuning.

name

name => 'Decent name',

This is not actually a rule but the text to use for the name of the parameter in error messages. If not specified the actual parameter name will be used.

num

num => 1,

When set to a true value the query parameter's value must contain digits only.

optional

optional => 1,

When set to a true value indicates that the parameter is optional. Note that you can specify other rules along with this one, e.g.:

optional => 1,
num      => 1,

Means, query parameter is optional, but if it is given it must contain only digits.

must_match

must_match => qr/foo/,

Takes a regex (qr//) as a value. The query parameter's value must match this regex.

must_not_match

must_not_match => qr/bar/,

Takes a regex (qr//) as a value. The query parameter's value must NOT match this regex.

max

max => 20,

Takes a positive integer as a value. Query parameter's value must not exceed max characters in length.

min

min => 3,

Takes a positive integer as a value. Query parameter's value must be at least min characters in length.

valid_values

valid_values => [ qw/foo bar baz/ ],

Takes an arrayref as a value. Query parameter's value must be one of the items in the arrayref.

code

code => sub { time() %2 },

Here you can let your soul dance to your desire. Takes a subref as a value. The @_ will contain the following (in that order): - the value of the parameter that is being tested, the hashref of ZofCMS Template, hashref of query parameters and the App::ZofCMS::Config object. If the sub returns a true value - the check will be considered successfull. If the sub returns a false value, then test fails and form check stops and errors.

param

param => 'param2',

Takes a string as an argument; that string will be interpreted as a name of a query parameter. Values of the parameter that is currently being inspected and the one given as a value must match in order for the rule to succeed. The example above indicates that query parameter param eq query parameter param2.

select

select => 1,

This one is not actually a "rule". This is a flag for {t} "filling" that is described in great detail (way) above under the description of no_fill key.

CUSTOM ERROR MESSAGES IN RULESETS

All *_error keys take strings as values; they can be used to set custom error messages for each test in the ruleset. In the defaults listed below under each *_error, the $name represents either the name of the parameter or the value of name key that you set in the ruleset.

num_error

num_error => 'Numbers only!',

This will be the error to be displayed if num test fails. Defaults to Parameter $name must contain digits only.

mandatory_error

mandatory_error => 'Must gimme!',

This is the error when optional is set to a false value, which is the default, and user did not specify the query parameter. I.e., "error to display for missing mandatory parameters". Defaults to: You must specify parameter $name

must_match_error

must_match_error => 'Must match me!',

This is the error for must_match rule. Defaults to: Parameter $name contains incorrect data

must_not_match_error

must_not_match_error => 'Cannot has me!',

This is the error for must_not_match rule. Defaults to: Parameter $name contains incorrect data

max_error

max_error => 'Too long!',

This is the error for max rule. Defaults to: Parameter $name cannot be longer than $max characters where $max is the max rule's value.

min_error

min_error => 'Too short :(',

This is the error for min rule. Defaults to: Parameter $name must be at least $rule-{min} characters long>

code_error

code_error => 'No likey 0_o',

This is the error for code rule. Defaults to: Parameter $name contains incorrect data

valid_values_error

valid_values_error => 'Pick the correct one!!!',

This is the error for valid_values rule. Defaults to: Parameter $name must be $list_of_values where $list_of_values is the list of the values you specified in the arrayref given to valid_values rule joined by commas and the last element joined by word "or".

param_error

param_error => "Two passwords do not match",

This is the error for param rule. You pretty much always would want to set a custom error message here as it defaults to: Parameter $name does not match parameter $rule->{param} where $rule->{param} is the value you set to param rule.

HTML::Template VARIABLES

<tmpl_if name="plug_form_checker_error">
    <p class="error"><tmpl_var name="plug_form_checker_error"></p>
</tmpl_if>

If the form values failed any of your checks, the plugin will set plug_form_checker_error key in {t} special key explaining the error. The sample usage of this is presented above.

App::ZofCMS::Plugin::FormFiller (version 0.0101)

NAME

Link: App::ZofCMS::Plugin::FormFiller

App::ZofCMS::Plugin::FormFiller - fill HTML form elements' values.

SYNOPSIS

In Main Config file or ZofCMS Template:

plugins => [ qw/FormFiller/ ],
plug_form_filler => {
    params => [ qw/nu_login nu_name nu_email nu_admin nu_aa nu_mm user/ ],
},

DESCRIPTION

The module provides filling of form elements from {t} ZofCMS Template special key or query parameters if those are specified.

This documentation assumes you've read App::ZofCMS, App::ZofCMS::Config and App::ZofCMS::Template

MAIN CONFIG FILE AND ZofCMS TEMPLATE FIRST-LEVEL KEYS

plugins

plugins => [ qw/FormFiller/ ],

Your obviously need to specify the name of the plugin in plugins arrayref for ZofCMS to execute the plugin. However, you'll probably be using another plugin, such as App::ZofCMS::Plugin::DBI to fill the {t} key first, thus don't forget to set right priorities.

plug_form_filler

plug_form_filler => {
    params => [ qw/login name email/ ],
},

plug_form_filler => {
    params => {
         t_login    => 'query_login',
         t_name     => 'query_name',
         t_email    => 'query_email',
    },
},

The plug_form_filler takes a hashref as a value. The possible keys/values of that hashref are as follows:

params

params => {
        t_login    => query_login,
        t_name     => query_name,
        t_email    => query_email,
},

params => [ qw/login name email/ ],
# same as
params => {
    login => 'login',
    name  => 'name',
    email => 'email',
},

Mandatory. The params key takes either a hashref or an arrayref as a value. If the value is an arrayref it will be converted to a hashref where keys and values are the same. The keys of the hashref will be interpreted as keys in the {t} ZofCMS Template special key and values will be interpreted as names of query parameters.

The idea of the plugin is that if query parameter (one of the specified in the params hashref/arrayref) has some value that is different from the corresponding value in the {t} hashref, the plugin will put that value into the {t} ZofCMS Template hashref. This allows you to do, for example, the following: fetch preset values from the database (using App::ZofCMS::Plugin::DBI perhaps) and present them to the user, if the user edits some fields you have have the preset values along with those changes made by the user.

App::ZofCMS::Plugin::FormToDatabase (version 0.0101)

NAME

Link: App::ZofCMS::Plugin::FormToDatabase

App::ZofCMS::Plugin::FormToDatabase - simple insertion of query into database

SYNOPSIS

In your Main Config file or ZofCMS template:

plugins => [ qw/FormToDatabase/ ],
plug_form_to_database => {
    go_field   => 'd|foo',
    values   => [ qw/one two/ ],
    table   => 'form',
    dsn     => "DBI:mysql:database=test;host=localhost",
    user    => 'test',
    pass    => 'test',
    opt     => { RaiseError => 1, AutoCommit => 0 },
},

DESCRIPTION

The module is a simple drop in to stick query into database. The module does not provide any parameter checking and is very basic. For anything more advanced check out App::ZofCMS::Plugin::DBI

This documentation assumes you have read App::ZofCMS, App::ZofCMS::Config and App::ZofCMS::Template

MAIN CONFIG FILE OR ZofCMS TEMPLATE FIRST LEVEL KEYS

plug_form_to_database => {
    go_field   => 'd|foo',
    values   => [ qw/one two/ ],
    table   => 'form',
    dsn     => "DBI:mysql:database=test;host=localhost",
    user    => 'test',
    pass    => 'test',
    opt     => { RaiseError => 1, AutoCommit => 0 },
},

Plugin uses the plug_form_to_database first-level key in ZofCMS template or your main config file. The key takes a hashref as a value. Values set under this key in ZofCMS template will override values set in main config file. Possible keys/values are as follows.

go_field

go_field => 'd|foo',

Optional. Defaults to: d|form_to_database. The go_field key specifies the "go" to the plugin; in other words, if value referenced by the string set under go_field key the plugin will proceed with stuffing your database, otherwise it will not do anything. Generally, you'd do some query checking with a plugin (e.g. App::ZofCMS::Plugin::FormChecker) with lower priority number (so it would be run first) and then set the value referenced by the go_field.

The go_field key takes a string as a value. The string is in format s|key_name - where s is the name of the "source". What follows the "source" letter is a pipe (|) and then they name of the key. The special value of source q (note that it is lowercase) means "query". That is q|foo means, "query parameter 'foo'". Other values of the "source" will be looked for inside ZofCMS template hash, e.g. d|foo means key foo in ZofCMS template special first-level key {d} - this is probably where you'd want to check that for.

Example:

# ZofCMS template:
plugins => [ qw/FormToDatabase/ ],
d       => { foo => 1 },
plug_form_to_database => {
    go_field => 'd|foo',
    ..... # omited for brevity
},

The example above will always stuff the query data into the database because key foo under key d is set to a true value and go_field references that value with d|foo.

values

values => [ qw/one two/ ],

Mandatory. The values key takes an arrayref as a value. The elements of that arrayref represent the names of query parameters that you wish to stick into the database. Under the hood of the module the following is being called:

$dbh->do(
    "INSERT INTO $conf{table} VALUES(" . join(q|, |, ('?')x@values) . ');',
    undef,
    @$query{ @values },
);

Where @values contains values you passed via values key and $dbh is the database handle created by DBI. If you want something more advanced consider using App::ZofCMS::Plugin::DBI instead.

table

table => 'form',

Mandatory. Specifies the name of the table into which you wish to store the data.

dsn

dsn => "DBI:mysql:database=test;host=localhost",

Mandatory. Specifies the dsn to use in DBI connect call. See documentation for DBI and DBD::your_database for proper syntax for this string.

user

user => 'test',

Mandatory. Specifies the user name (login) to use when connecting to the database.

pass

pass => 'test',

Mandatory. Specifies the password to use when connecting to the database.

opt

Optional. Specifies extra options to use in DBI's connect_cached() call. Defaults to: { RaiseError => 1, AutoCommit => 0 }

SEE ALSO

DBI, App::ZofCMS::Plugin::DBI

App::ZofCMS::Plugin::LinksToSpecs::CSS (version 0.0101)

NAME

Link: App::ZofCMS::Plugin::LinksToSpecs::CSS

App::ZofCMS::Plugin::LinksToSpecs::CSS - easily include links to properties in CSS2.1 specification

SYNOPSIS

In your ZofCMS template:

plugins => [ qw/LinksToSpecs::CSS/ ],

In your HTML::Template template:

See: <tmpl_var name="css_text-align"> for text-align property<br>
See: <tmpl_var name="css_display"> for display propery<br>
<tmpl_var name="css_float_p"> is quite neat

DESCRIPTION

The module is a plugin for ZofCMS which allows you to easily link to CSS properties in CSS2.1 specification. Personally, I use it when writing my tutorials, hopefully it will be useful to someone else as well.

ZofCMS TEMPLATE

plugins => [ qw/LinksToSpecs::CSS/ ],

The only thing you'd need in your ZofCMS template is to add the plugin into the list of plugins to execute.

HTML::Template TEMPLATE

See: <tmpl_var name="css_text-align"> for text-align property<br>
See: <tmpl_var name="css_display"> for display propery<br>
<tmpl_var name="css_float_p"> is quite neat

To include links to CSS properties in your HTML code you'd use <tmpl_var name="">. The plugin provides four "styles" of links which are presented below. The PROP stands for any CSS property specified in CSS2.1 specification, LINK stands for the link pointing to the explaination of the given property in CSS specification. Note: everything needs to be lowercased:

<tmpl_var name="css_PROP">
<a href="LINK" title="CSS Specification: 'PROP' property"><code>PROP</code></a>

<tmpl_var name="css_PROP_p">
<a href="LINK" title="CSS Specification: 'PROP' property"><code>PROP</code> property</a>

<tmpl_var name="css_PROP_c">
<a href="LINK" title="CSS Specification: 'PROP' property">PROP</a>

<tmpl_var name="css_PROP_cp">
<a href="LINK" title="CSS Specification: 'PROP' property">PROP property</a>

SEE ALSO

http://w3.org/Style/CSS/

App::ZofCMS::Plugin::LinksToSpecs::HTML (version 0.0101)

NAME

Link: App::ZofCMS::Plugin::LinksToSpecs::HTML

App::ZofCMS::Plugin::LinksToSpecs::HTML - easily include links to elements in HTML 4.01 specification

SYNOPSIS

In your ZofCMS template:

plugins => [ qw/LinksToSpecs::HTML/ ],

In your HTML::Template template:

See: <tmpl_var name="html_div"> for div element<br>
See: <tmpl_var name="html_blockquote"> for blockquote element<br>
<tmpl_var name="html_a_ce"> is used for links.

DESCRIPTION

The module is a plugin for ZofCMS which allows you to easily link to HTML elements in HTML 4.01 specification. Personally, I use it when writing my tutorials, hopefully it will be useful to someone else as well.

ZofCMS TEMPLATE

plugins => [ qw/LinksToSpecs::HTML/ ],

The only thing you'd need in your ZofCMS template is to add the plugin into the list of plugins to execute.

HTML::Template TEMPLATE

See: <tmpl_var name="html_div"> for div element<br>
See: <tmpl_var name="html_blockquote"> for blockquote element<br>
<tmpl_var name="html_a_ce"> is used for links.

To include links to HTML elements in your HTML code you'd use <tmpl_var name="">. The plugin provides four "styles" of links which are presented below. The EL stands for any HTML element specified in HTML 4.01 specification, LINK stands for the link pointing to the explaination of the given element in HTML specification. Note: everything needs to be lowercased:

<tmpl_var name="html_EL">
<a href="LINK" title="HTML Specification: '&amp;lt;EL&amp;gt;' element"><code>&amp;lt;EL&amp;gt;</code></a>

<tmpl_var name="html_EL_e">
<a href="LINK" title="HTML Specification: '&amp;lt;EL&amp;gt;' element"><code>&amp;lt;EL&amp;gt;</code> element</a>

<tmpl_var name="html_EL_c">
<a href="LINK" title="HTML Specification: '&amp;lt;EL&amp;gt;' element">&amp;lt;EL&amp;gt;</a>

<tmpl_var name="html_EL_ce">
<a href="LINK" title="HTML Specification: '&amp;lt;EL&amp;gt;' element">&amp;lt;EL&amp;gt; element</a>

SEE ALSO

http://www.w3.org/TR/html4/

App::ZofCMS::Plugin::NavMaker (version 0.0102)

NAME

Link: App::ZofCMS::Plugin::NavMaker

App::ZofCMS::Plugin::NavMaker - ZofCMS plugin for making navigation bars

SYNOPSIS

In your ZofCMS Template:

nav_maker => [
    qw/Foo Bar Baz/,
    [ qw(Home /home) ],
    [ qw(Music /music) ],
    [ qw(foo /foo-bar-baz), 'This is the title=""', 'this_is_id' ],
],
plugins => [ qw/NavMaker/ ],

In your HTML::Template template:

<tmpl_var name="nav_maker">

Produces this code:

<ul id="nav">
        <li id="nav_foo"><a href="/foo" title="Visit Foo">Foo</a></li>
        <li id="nav_bar"><a href="/bar" title="Visit Bar">Bar</a></li>
        <li id="nav_baz"><a href="/baz" title="Visit Baz">Baz</a></li>
        <li id="nav_home"><a href="/home" title="Visit Home">Home</a></li>
        <li id="nav_music"><a href="/music" title="Visit Music">Music</a></li>
        <li id="this_is_id"><a href="/foo-bar-baz" title="This is the title=&quot;&quot;">foo</a></li>
</ul>

DESCRIPTION

The plugin doesn't do much but after writing HTML code for hundreds of navigation bars I was fed up... and released this tiny plugin.

This documentation assumes you've read App::ZofCMS, App::ZofCMS::Config and App::ZofCMS::Template

FIRST LEVEL ZofCMS TEMPLATE KEYS

plugins

plugins => [ qw/NavMaker/ ],

The obvious one is that you'd want to add NavMaker into the list of your plugins.

nav_maker

nav_maker => [
    qw/Foo Bar Baz/,
    [ qw(Home /home) ],
    [ qw(Music /music) ],
    [ qw(foo /foo-bar-baz), 'This is the title=""', 'this_is_id' ],
],

Takes an arrayref as a value elements of which can either be strings or arrayrefs, element which is a string is the same as an arrayref with just that string as an element. Each of those arrayrefs can contain from one to four elements. They are interpreted as follows:

first element

nav_maker => [ qw/Foo Bar Baz/ ],

# same as

nav_maker => [
    [ 'Foo' ],
    [ 'Bar' ],
    [ 'Baz' ],
],

Mandatory. Specifies the text to use for the link.

second element

nav_maker => [
    [ Foo => '/foo' ],
],

Optional. Specifies the href="" attribute for the link. If not specified will be calculated from the first element (the text for the link) in the following way:

$text =~ s/[\W_]/-/g;
return lc "/$text";

third element

nav_maker => [
    [ 'Foo', '/foo', 'Title text' ],
],

Optional. Specifies the title="" attribute for the link. If not specified the first element (the text for the link) will be used for the title with word Visit prepended.

fourth element

nav_maker => [
    [ 'Foo', '/foo', 'Title text', 'id_of_the_li' ]
],

Optional. Specifies the id="" attribute for the <li> element of this navigation bar item. If not specified will be calculated from the first element (the text of the link) in the following way:

$text =~ s/\W/_/g;
return lc "nav_$text";

USED HTML::Template VARIABLES

nav_maker

<tmpl_var name="nav_maker">

Plugin sets nav_maker key in {t} ZofCMS template special key, to the generated HTML code, simply stick <tmpl_var name="nav_maker"> whereever you wish to have your navigation.

App::ZofCMS::Plugin::QueryToTemplate (version 0.0102)

NAME

Link: App::ZofCMS::Plugin::QueryToTemplate

App::ZofCMS::Plugin::QueryToTemplate - ZofCMS plugin to automagically make query parameters available in the template

SYNOPSIS

In your ZofCMS template, or in your main config file (under template_defaults or dir_defaults):

plugins => [ qw/QueryToTemplate/ ];

In any of your HTML::Template templates:

<tmpl_var name="query_SOME_QUERY_PARAMETER_NAME">

DESCRIPTION

Plugin can be run at any priority level and it does not take any input from ZofCMS template.

Upon plugin's execution it will stuff the {t} first level key (see App::ZofCMS::Template if you don't know what that key is) with all the query parameters as keys and values being the parameter values. Each query parameter key will be prefixed with query_. In other words, if your query looks like this:

http://foo.com/index.pl?foo=bar&baz=beerz

In your template parameter foo would be accessible as query_foo and parameter baz would be accessible via query_baz

Foo is: <tmpl_var name="query_foo">
Baz is: <tmpl_var name="query_baz">

App::ZofCMS::Plugin::QuickNote (version 0.0105)

NAME

Link: App::ZofCMS::Plugin::QuickNote

App::ZofCMS::Plugin::QuickNote - drop-in "quicknote" form to email messages from your site

SYNOPSIS

In your ZofCMS template:

# basic:
quicknote => {
    to  => 'me@example.com',
},

# juicy
quicknote => {
    mailer      => 'testfile',
    to          => [ 'foo@example.com', 'bar@example.com'],
    subject     => 'Quicknote from example.com',
    must_name   => 1,
    must_email  => 1,
    must_message => 1,
    name_max    => 20,
    email_max   => 20,
    message_max => 1000,
    success     => 'Your message has been successfuly sent',
    format      => <<'END_FORMAT',
Quicknote from host {::{host}::} sent on {::{time}::}
Name: {::{name}::}
E-mail: {::{email}::}
Message:
{::{message}::}
END_FORMAT
},

In your HTML::Template template:

<tmpl_var name="quicknote">

DESCRIPTION

The module is a plugin for App::ZofCMS which provides means to easily drop-in a "quicknote" form which asks the user for his/her name, e-mail address and a message he or she wants to send. After checking all of the provided values plugin will e-mail the data which the visitor entered to the address which you specified.

This documentation assumes you've read App::ZofCMS, App::ZofCMS::Config and App::ZofCMS::Template

HTML TEMPLATE

The only thing you'd want to add in your HTML::Template is a <tmpl_var name="quicknote"> the data for this variable will be put into special key {t}, thus you can stick it in secondary templates.

USED FIRST-LEVEL ZofCMS TEMPLATE KEYS

plugins

{
    plugins => [ qw/QuickNote/ ],
}

First and obvious is that you'd want to include the plugin in the list of plugins to run.

quicknote

# basic:
quicknote => {
    to  => 'me@example.com',
},

# juicy
quicknote => {
    mailer      => 'testfile',
    to          => [ 'foo@example.com', 'bar@example.com'],
    subject     => 'Quicknote from example.com',
    must_name   => 1,
    must_email  => 1,
    must_message => 1,
    name_max    => 20,
    email_max   => 20,
    message_max => 1000,
    success     => 'Your message has been successfuly sent',
    format      => <<'END_FORMAT',
Quicknote from host {::{host}::} sent on {::{time}::}
Name: {::{name}::}
E-mail: {::{email}::}
Message:
{::{message}::}
END_FORMAT
},

The quicknote first-level ZofCMS template key is the only thing you'll need to use to tell the plugin what to do. The key takes a hashref as a value. The only mandatory key in that hashref is the to key, the rest have default values. Possible keys in quicknote hashref are as follows:

to

to => 'me@example.com'

to => [ 'foo@example.com', 'bar@example.com'],

Mandatory. Takes either a string or an arrayref as a value. Passing the string is equivalent to passing an arrayref with just one element. Each element of that arrayref must contain a valid e-mail address, upon successful completion of the quicknote form by the visitor the data on that form will be emailed to all of the addresses which you specify here.

mailer

mailer => 'testfile',

Optional. Specifies which mailer to use for sending mail. See documentation for Mail::Mailer for possible mailers. When using the testfile mailer the file will be located in the same directory your in which your index.pl file is located. By default plugin will do the same thing Mail::Mailer will (search for the first available mailer).

subject

subject => 'Quicknote from example.com',

Optional. Specifies the subject line of the quicknote e-mail. Defaults to: Quicknote

must_name, must_email and must_message

must_name   => 1,
must_email  => 1,
must_message => 1,

Optional. The must_name, must_email and must_message arguments specify whether or not the "name", "e-mail" and "message" form fields are mandatory. When set to a true value indicate that the field is mandatory. When set to a false value the form field will be filled with N/A unless specified by the visitor. Visitor will be shown an error message if he or she did not specify some mandatory field. By default only the must_message argument is set to a true value (thus the vistior does not have to fill in neither the name nor the e-mail).

name_max, email_max and message_max

name_max    => 20,
email_max   => 20,
message_max => 1000,

Optional. Alike must_* arguments, the name_max, email_max and message_max specify max lengths of form fields. Visitor will be shown an error message if any of the parameters exceed the specified maximum lengths. By default the value for name_max is 100, value for email_max is 200 and value for message_max 10000

success

success => 'Your message has been successfuly sent',

Optional. Specifies the text to display to your visitor when the quicknote is successfuly sent. Defaults to: 'Your message has been successfuly sent'.

format

    format      => <<'END_FORMAT',
Quicknote from host {::{host}::} sent on {::{time}::}
Name: {::{name}::}
E-mail: {::{email}::}
Message:
{::{message}::}
END_FORMAT

Optional. Here you can specify the format of the quicknote e-mail which plugin will send. The following special sequences will be replaced by corresponding values:

{::{host}::}        - the host of the person sending the quicknote
{::{time}::}        - the time the message was sent ( localtime() )
{::{name}::}        - the "Name" form field
{::{email::}        - the "E-mail" form field
{::{message}::}     - the "Message" form field

Default format is shown above and in SYNOPSIS.

GENERATED HTML

Below is the HTML code generated by the plugin. Use CSS to style it.

# on successful send
<p class="quicknote_success"><tmpl_var name="success"></p>

# on error
<p class="quicknote_error"><tmpl_var name="error"></p>


# the form itself
<form class="quicknote" action="" method="POST">
<div>
    <input type="hidden" name="quicknote_username" value="your full name">
    <input type="hidden" name="page" value="index">
    <ul>
        <li>
            <label for="quicknote_name">Name:</label
            ><input type="text" name="quicknote_name" id="quicknote_name"
            value="">
        </li>
        <li>
            <label for="quicknote_email">E-mail: </label
            ><input type="text" name="quicknote_email" id="quicknote_email"
            value="">
        </li>
        <li>
            <label for="quicknote_message">Message: </label
            ><textarea name="quicknote_message" id="quicknote_message"
            cols="40" rows="10"></textarea>
        </li>
    </ul>
    <input type="submit" value="Send">
</div>
</form>

App::ZofCMS::Plugin::StyleSwitcher (version 0.0101)

NAME

Link: App::ZofCMS::Plugin::StyleSwitcher

App::ZofCMS::Plugin::StyleSwitcher - CSS Style switcher plugin

SYNOPSIS

In your ZofCMS template but most likely in your Main Config File:

plugins => [ qw/StyleSwitcher/ ],
plug_style_switcher => {
    dsn                     => "DBI:mysql:database=test;host=localhost",
    user                    => 'test',
    pass                    => 'test',
    opt                     => { RaiseError => 1, AutoCommit => 1 },
    styles => {
        main => 'main.css',
        alt  => [ 'alt.css', '[IE]alt_ie.css' ],
    },
},

In your HTML::Template template:

<head>
    <tmpl_var name="style_switcher_style">
...

<body>
    <tmpl_var name="style_switcher_toggle">
....

DESCRIPTION

The module provides means to have what is known as "Style Switcher" thingie on your webpages. In other words, having several CSS stylesheets per website.

The http://alistapart.com/stories/alternate/ describes the concept in more detail. It also provides JavaScript based realization of the idea; this plugin does not rely on javascript at all.

FIRST-LEVEL ZofCMS TEMPLATE AND MAIN CONFIG FILE KEYS

plugins

plugins => [ qw/StyleSwitcher/ ],

You need to include the plugin in the list of plugins to execute.

plug_style_switcher

plug_style_switcher => {
    dsn                     => "DBI:mysql:database=test;host=localhost",
    user                    => 'test',
    pass                    => 'test',
    opt                     => { RaiseError => 1, AutoCommit => 1 },
    create_table            => 0,
    q_name                  => 'style',
    q_ajax_name             => 'plug_style_switcher_ajax',
    t_prefix                => 'style_switcher_',
    table                   => 'style_switcher',
    max_time                => 2678400, # one month
    default_style           => 'main',
    xhtml                   => 0,
    # styles => {}
    styles => {
        main => 'main.css',
        alt  => [ 'alt.css', '[IE]alt_ie.css' ],
    },
},

The plugin reads it's configuration from plug_style_switcher first-level ZofCMS Template or Main Config file template. Keys that are set in ZofCMS Template will override same ones that are set in Main Config file. Considering that you'd want the CSS style settings to be set on an entire site, it only makes sense to set this plugin up in your Main Config file.

dsn

dsn => "DBI:mysql:database=test;host=localhost",

Mandatory. The plugin needs access to an SQL database supported by DBI module. The dsn key takes a scalar as a value that contains the DSN for your database. See DBI for details.

user and pass

user => 'test',
pass => 'test',

Mandatory. The user and pass arguments specify the user name (login) and password for your database.

opt

opt => { RaiseError => 1, AutoCommit => 1 },

Optional. The opt key takes a hashref as a value. This hashref will be directly passed as "additional arguments" to DBI's connect_cached() method. See DBI for details. Defaults to: { RaiseError => 1, AutoCommit => 1 },

table

table => 'style_switcher',

Optional. Specifies the name of the table in which to store the style-user data. Defaults to: style_switcher

create_table

create_table => 0,

Optional. Takes either true or false values. Defaults to: 0 (false). When set to a true value plugin will automatically create the SQL tables that is needed for the plugin. Just set it to a true value, load any page that calls the plugin, and remove this setting. Alternatively you can create the table yourself: CREATE TABLE style_switcher ( host VARCHAR(200), style TEXT, time VARCHAR(10) );

q_name

q_name => 'style',

Optional. Takes a string as a value that must contain the name of the query parameter that will contain the name of the style to "activate". Defaults to: style

q_ajax_name

q_ajax_name => 'plug_style_switcher_ajax',

Optional. Some of you may want to change styles with JS along with keeping style information server-side. For this plugin supports the q_ajax_name, it must contain the name of a query parameter which you'd pass with your Ajax call (sorry to those who really dislike calling it Ajax). The value of this parameter needs to be a true value. When plugin will see this query parameter set to a true value, it will set the style (based on the value of the query parameter referenced by q_name plugin setting; see above) and will simply exit. Defaults to: plug_style_switcher_ajax

t_prefix

t_prefix => 'style_switcher_',

Optional. The plugin sets two keys in ZofCMS Template {t} special key. The t_prefix takes a string as a value; that string will be prefixed to those two keys that are set. See HTML::Template VARIABLES section below for imformation on those two keys. Defaults to: style_switcher_ (note the underscore (_) at the end).

max_time

max_time => 2678400, # one month

Optional. Takes a positive integer as a value that indicates how long (in seconds) to keep the style information for the user. The time is updated every time the user accesses the plugin. The plugin identifies the "user" by contatenating user's User-Agent HTTP header and his/her/its host name. Note that old entries are deleted only when someone sets the style; in other words, if you set max_time to one month and no one ever changes their style and that user comes back after two month the setting will be preserved. Defaults to: 2678400 (one month)

default_style

default_style => 'main',

Optional. Takes a string as a value that must be one of the keys in styles hashref (see below). This will be the "default" style. In other words, if the plugin does not find the particular user in the database it will make the default_style style active.

xhtml

xhtml => 0,

Optional. Takes either true or false values. When set to a true value will close <link> elements with an extra / to keep it XHTML friendly. Defaults to: 0

styles

styles => {
    main => 'main.css',
    alt  => [ 'alt.css', '[IE]alt_ie.css' ],
},

Mandatory. Takes a hashref as a value. The keys of a that hashref are the names of your styles. The name of the key is what you'd pass as a value of a query parameter indicated by plugin's q_name parameter. The value can be either a string or an arrayref. If the value is a string then it will be converted into an arrayref with just that element in it. Each element of that arrayref will be converted into a <link> element where the href="" attribute will be set to that element of the arrayref. Each element can contain string [IE] (including the square brackets) as the first four characters, in that case the href="" will be wrapped in <!--[if IE]> conditional comments (if you don't know what those are, see: http://haslayout.net/condcom).

HTML::Template VARIABLES

Note: examples include the default t_prefix in names of <tmpl_var>s.

style

<tmpl_var name="style_switcher_style">

The style variable will contain appropriate <link> elements. You'd want to put this variable somewhere in HTML <head>

toggle

<tmpl_var name="style_switcher_toggle">

The toggle variable will contain a style toggle link. By clicking this link user can load the next style (sorted alphabetically by its name). You don't have to use this one and write your own instead.

SEE ALSO

http://alistapart.com/stories/alternate/

App::ZofCMS::Plugin::Syntax::Highlight::CSS (version 0.0102)

NAME

Link: App::ZofCMS::Plugin::Syntax::Highlight::CSS

App::ZofCMS::Plugin::Syntax::Highlight::CSS - provide syntax highlighted CSS code snippets on your site

SYNOPSIS

In ZofCMS template:

{
    body        => \'index.tmpl',
    highlight_css => {
        foocss => '* { margin: 0; padding: 0; }',
        bar     => sub { return '* { margin: 0; padding: 0; }' },
        beer    => \ 'filename.of.the.file.with.CSS.in.datastore.dir',
    },
    plugins     => [ qw/Syntax::Highlight::CSS/ ],
}

In HTML::Template template:

<tmpl_var name="foocss">
<tmpl_var name="bar">
<tmpl_var name="beer">

DESCRIPTION

The module is a plugin for App::ZofCMS. It provides means to include CSS (Cascading Style Sheets) code snippets with syntax highlights on your pages.

This documentation assumes you've read App::ZofCMS, App::ZofCMS::Config and App::ZofCMS::Template

USED FIRST-LEVEL ZofCMS TEMPLATE KEYS

plugins

{
    plugins => [ qw/Syntax::Highlight::CSS/ ],
}

First and obvious is that you'd want to include the plugin in the list of plugins to run.

highlight_css

{
    highlight_css => {
        foocss  => '* { margin: 0; padding: 0; }',
        bar     => sub { return '* { margin: 0; padding: 0; }' },
        beer    => \ 'filename.of.the.file.with.CSS.in.datastore.dir',
    },
}

The highlight_css is the heart key of the plugin. It takes a hashref as a value. The keys of this hashref except for two special keys described below are the name of <tmpl_var name=""> tags in your HTML::Template template into which to stuff the syntax-highlighted code. The value of those keys can be either a scalar, subref or a scalarref. They are interpreted by the plugin as follows:

scalar

highlight_css => {
    foocss => '* { margin: 0; padding: 0; }'
}

When the value of the key is a scalar it will be interpreted as CSS code to be highlighted. This will do it for short snippets.

scalarref

highlight_css => {
    beer    => \ 'filename.of.the.file.with.CSS.in.datastore.dir',
},

When the value is a scalarref it will be interpreted as the name of a file in the data_store dir. That file will be read and its contents will be understood as CSS code to be highlighted. If an error occured during opening of the file, your <tmpl_var name=""> tag allocated for this entry will be populated with an error message.

subref

highlight_css => {
    bar     => sub { return '* { margin: 0; padding: 0; }' },
},

When the value is a subref, it will be executed and its return value will be taken as CSS code to highlight. The @_ of that sub when called will contain the following: $template, $query, $config where $template is a hashref of your ZofCMS template, $query is a hashref of the parameter query whether it's a POST or a GET request, and $config is the App::ZofCMS::Config object.

SPECIAL KEYS IN highlight_css

highlight_css => {
    nnn => 1,
    pre => 0,
},

There are two special keys, namely nnn and pre, in highlight_css hashref. Their values will affect the resulting highlighted CSS code.

nnn

highlight_css => {
    nnn => 1,
}

Instructs the highlighter to activate line numbering. Default value: 0 (disabled).

pre

highlight_css => {
    nnn => 0,
}

Instructs the highlighter to surround result by <pre>...</pre> tags. Default value: 1 (enabled).

highlight_css_before

{
    highlight_css_before => '<div class="my-highlights">',
}

Takes a scalar as a value. When specified, every highlighted CSS code will be prefixed with whatever you specify here.

highlight_css_after

{
    highlight_after => '</div>',
}

Takes a scalar as a value. When specified, every highlighted CSS code will be postfixed with whatever you specify here.

GENERATED CODE

Given '* { margin: 0; padding: 0; }' as input plugin will generate the following code (line-breaks were edited):

<pre class="css-code">
    <span class="ch-sel">*</span> {
    <span class="ch-p">margin</span>:
    <span class="ch-v">0</span>;
    <span class="ch-p">padding</span>:
    <span class="ch-v">0</span>; }
</pre>

Now you'd use CSS to highlight specific parts of CSS syntax. Here are the classes that you can define in your stylesheet:

  • css-code - this is actually the class name that will be set on the <pre>> element if you have that option turned on.

  • ch-sel - Selectors

  • ch-com - Comments

  • ch-p - Properties

  • ch-v - Values

  • ch-ps - Pseudo-selectors and pseudo-elements

  • ch-at - At-rules

  • ch-n - The line numbers inserted when nnn key is set to a true value

SAMPLE CSS CODE FOR HIGHLIGHTING

.css-code {
    font-family: 'DejaVu Sans Mono Book', monospace;
    color: #000;
    background: #fff;
}
    .ch-sel, .ch-p, .ch-v, .ch-ps, .ch-at {
        font-weight: bold;
    }
    .ch-sel { color: #007; } /* Selectors */
    .ch-com {                /* Comments */
        font-style: italic;
        color: #777;
    }
    .ch-p {                  /* Properties */
        font-weight: bold;
        color: #000;
    }
    .ch-v {                  /* Values */
        font-weight: bold;
        color: #880;
    }
    .ch-ps {                /* Pseudo-selectors and Pseudo-elements */
        font-weight: bold;
        color: #11F;
    }
    .ch-at {                /* At-rules */
        font-weight: bold;
        color: #955;
    }
    .ch-n {
        color: #888;
    }

PREREQUISITES

This plugin requires Syntax::Highlight::CSS. You can use zofcms_helper script to locally place it into ZofCMS "core" directory:

zofcms_helper --nocore --core your_sites_core --cpan Syntax::Hightlight::CSS

App::ZofCMS::Plugin::Syntax::Highlight::HTML (version 0.0101)

NAME

Link: App::ZofCMS::Plugin::Syntax::Highlight::HTML

App::ZofCMS::Plugin::Syntax::Highlight::HTML - provide HTML code snippets on your site

SYNOPSIS

In ZofCMS template:

{
    body        => \'index.tmpl',
    highlight_html => {
        foohtml => '<div class="bar">beer</div>',
        bar     => sub { return '<div class="bar">beer</div>' },
        beer    => \ 'filename.of.the.file.with.HTML.in.datastore.dir',
    },
    plugins     => [ qw/Syntax::Highlight::HTML/ ],
}

In HTML::Template template:

<tmpl_var name="foohtml">
<tmpl_var name="bar">
<tmpl_var name="beer">

DESCRIPTION

The module is a plugin for App::ZofCMS. It provides means to include HTML (HyperText Markup Lanugage) code snippets with syntax highlights on your pages.

This documentation assumes you've read App::ZofCMS, App::ZofCMS::Config and App::ZofCMS::Template

USED FIRST-LEVEL ZofCMS TEMPLATE KEYS

plugins

{
    plugins => [ qw/Syntax::Highlight::HTML/ ],
}

First and obvious is that you'd want to include the plugin in the list of plugins to run.

highlight_html

{
    highlight_html => {
        foohtml => '<div class="bar">beer</div>',
        bar     => sub { return '<div class="bar">beer</div>' },
        beer    => \ 'filename.of.the.file.with.HTML.in.datastore.dir',
    },
}

The highlight_html is the heart key of the plugin. It takes a hashref as a value. The keys of this hashref except for two special keys described below are the name of <tmpl_var name=""> tags in your HTML::Template template into which to stuff the syntax-highlighted code. The value of those keys can be either a scalar, subref or a scalarref. They are interpreted by the plugin as follows:

scalar

highlight_html => {
    foohtml => '<div class="bar">beer</div>'
}

When the value of the key is a scalar it will be interpreted as HTML code to be highlighted. This will do it for short snippets.

scalarref

highlight_html => {
    beer    => \ 'filename.of.the.file.with.HTML.in.datastore.dir',
},

When the value is a scalarref it will be interpreted as the name of a file in the data_store dir. That file will be read and its contents will be understood as HTML code to be highlighted. If an error occured during opening of the file, your <tmpl_var name=""> tag allocated for this entry will be populated with an error message.

subref

highlight_html => {
    bar     => sub { return '<div class="bar">beer</div>' },
},

When the value is a subref, it will be executed and its return value will be taken as HTML code to highlight. The @_ of that sub when called will contain the following: $template, $query, $config where $template is a hashref of your ZofCMS template, $query is a hashref of the parameter query whether it's a POST or a GET request, and $config is the App::ZofCMS::Config object.

SPECIAL KEYS IN highlight_html

highlight_html => {
    nnn => 1,
    pre => 0,
},

There are two special keys, namely nnn and pre, in highlight_html hashref. Their values will affect the resulting highlighted HTML code.

nnn

highlight_html => {
    nnn => 1,
}

Instructs the highlighter to activate line numbering. Default value: 0 (disabled).

pre

highlight_html => {
    nnn => 0,
}

Instructs the highlighter to surround result by <pre>...</pre> tags. Default value: 1 (enabled).

highlight_before

{
    highlight_before => '<div class="highlights">',
}

Takes a scalar as a value. When specified, every highlighted HTML code will be prefixed with whatever you specify here.

highlight_after

{
    highlight_after => '</div>',
}

Takes a scalar as a value. When specified, every highlighted HTML code will be postfixed with whatever you specify here.

GENERATED CODE

Given '<foo class="bar">beer</foo>' as input plugin will generate the following code:

<pre>
    <span class="h-ab">&lt;</span><span class="h-tag">foo</span>
    <span class="h-attr">class</span>=<span class="h-attv">"bar</span>"
    <span class="h-ab">&gt;</span>beer<span class="h-ab">&lt;/</span>
    <span class="h-tag">foo</span><span class="h-ab">&gt;</span>
</pre>

Now you'd use CSS to highlight specific parts of HTML syntax. Here are the classes that you can define in your stylesheet (list shamelessly stolen from Syntax::Highlight::HTML documentation):

  • .h-decl - for a markup declaration; in a HTML document, the only markup declaration is the DOCTYPE, like: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">

  • .h-pi - for a process instruction like <?html ...> or <?xml ...?>

  • .h-com - for a comment, <!-- ... -->

  • .h-ab - for the characters '<' and '>' as tag delimiters

  • .h-tag - for the tag name of an element

  • .h-attr - for the attribute name

  • .h-attv - for the attribute value

  • .h-ent - for any entities: &eacute; &#171;

  • .h-lno - for the line numbers

SAMPLE CSS CODE FOR HIGHLIGHTING

Sebastien Aperghis-Tramoni, the author of Syntax::Highlight::HTML, was kind enough to provide sample CSS code defining the look of each element of HTML syntax. It is presented below:

.h-decl { color: #336699; font-style: italic; }   /* doctype declaration  */
.h-pi   { color: #336699;                     }   /* process instruction  */
.h-com  { color: #338833; font-style: italic; }   /* comment              */
.h-ab   { color: #000000; font-weight: bold;  }   /* angles as tag delim. */
.h-tag  { color: #993399; font-weight: bold;  }   /* tag name             */
.h-attr { color: #000000; font-weight: bold;  }   /* attribute name       */
.h-attv { color: #333399;                     }   /* attribute value      */
.h-ent  { color: #cc3333;                     }   /* entity               */

.h-lno  { color: #aaaaaa; background: #f7f7f7;}   /* line numbers         */

PREREQUISITES

Despite the ZofCMS design this module uses Syntax::Highlight::HTML which in turn uses HTML::Parser which needs a C compiler to install.

This module requires Syntax::Highlight::HTML and File::Spec (the later is part of the core)

App::ZofCMS::Plugin::TagCloud (version 0.0103)

NAME

Link: App::ZofCMS::Plugin::TagCloud

App::ZofCMS::Plugin::TagCloud - generate "tag clouds"

SYNOPSIS

In your ZofCMS template or main config file:

plug_tag_cloud => {
    unit => 'em',
    tags => [ qw(
            foo /foo 2
            bar /bar 1
            ber /ber 3
        )
    ],
}

In your HTML::Template template:

<style type="text/css">
    <tmpl_var name="tag_cloud_css">
</style>

<tmpl_var name="tag_cloud">

DESCRIPTION

The module is a plugin for App::ZofCMS; it generates "tag clouds" (bunch of different-sized links).

This documentation assumes you have read App::ZofCMS, App::ZofCMS::Config and App::ZofCMS::Template

ZofCMS TEMPLATE/MAIN CONFIG FILE KEYS

plug_tag_cloud => {
    id          => 'tag_cloud_container',
    class       => 'tag_cloud_tag',
    unit        => 'em',
    shuffle     => 1,
    uri_prefix  => 'http://site.com/',
    fg          => '#00d',
    bg          => 'transparent',
    fg_hover    => '#66f',
    bg_hover    => 'transparent',
    fg_visited  => '#333',
    bg_visited  => 'transparent',
    tags => [ qw(
            foo /foo 2
            bar /bar 1
            ber /ber 3
        )
    ],
}

Plugin gets its data through plug_tag_cloud first-level key in either ZofCMS template or main config file. Specifying this key in ZofCMS template will completely override whatever you set under that key in main config file.

The key takes a hashref as a value. Possible keys/values of that hashref are as follows:

tags

tags => [ qw(
        foo /foo 2
        bar /bar 1
        ber /ber 3
    )
],

# or 

tags => [
    [ qw(foo /foo 2) ],
    [ qw(bar /bar 1) ],
    [ qw(ber /ber 3) ],
],

Mandatory. The tags key takes an arrayref as a value. Elements of that arrayref can be either either plain strings or arrayrefs. You cannot mix the two. If elements are plain strings they will be converted internally into the "arrayref form" by grouping by three (see examples above, they are equivalent).

The elements of the inner arrayrefs are as follows: first element is the text for the link in the tag cloud. Second element is the URI to which the tag points. Third element is the "weight" of the tag, the larger the number the larger the tag will be. The third element actually also serves for the font-size value in the CSS code generated by the plugin.

id

id => 'tag_cloud_container',

Optional. The id key takes a string as a value. This sting will be used for the id="" attribute of the tag cloud <ul> element. Defaults to: zofcms_tag_cloud

class

class => 'tag_cloud_tag',

Optional. The class key takes a string as a value. This sting will be used to generate class names for cloud tags. Defaults to: zofcms_tag_cloud

unit

unit => 'em',

Optional. The unit key takes a string as a value. This string must be a valid CSS unit for font-size property. Whatever you pass in here will be directly used in the generated CSS code and the number for that unit will be taken from the "weight" of the cloud tag (see tags key above). Defaults to: %

shuffle

shuffle => 1,

Optional. Takes either true or false value. When set to a true value the elements of your tag cloud will be shuffled each and every time. Default to: 0

uri_prefix

uri_prefix  => 'http://site.com/',

Optional. The uri_prefix takes a string as a value. This string will be prepended to all of the URIs to which your tags are pointing. Defaults to: empty string.

fg

fg => '#00d',

Optional. Specifies the color to use for foreground on <a href=""> elements; will be directly used for color property in generated CSS code. Defaults to: #00d.

bg

bg => 'transparent',

Optional. Specifies the color to use for background on <a href=""> elements; will be directly used for background property in generated CSS code. Defaults to: transparent.

fg_hover

fg_hover => '#66f',

Optional. Same as fg except this one is used for :hover pseudo-selector. Defaults to: #66f

bg_hover

bg_hover => 'transparent',

Optional. Same as bg except this one is used for :hover pseudo-selector. Defaults to: transparent

fg_visited

fg_visited  => '#333',

Optional. Same as fg except this one is used for :visited pseudo-selector. Defaults to: #333

bg_visited

Optional. Same as bg except this one is used for :visited pseudo-selector. Defaults to: transparent

HTML::Template TEMPLATE VARIABLES

The plugin will stuff two keys into {t} special key in your ZofCMS templates. This means that you can use them in your HTML::Template templates.

tag_cloud

<tmpl_var name="tag_cloud">

This one will contain the HTML code for your tag cloud.

tag_cloud_css

<style type="text/css">
    <tmpl_var name="tag_cloud">
</style>

This one will contain the CSS code for your tag cloud. You obviously don't have to use this one and instead code your own CSS.

EXAMPLE OF GENERATED HTML CODE

<ul id="tag_cloud">
    <li class="tag_cloud_tag3"><a href="http://site.com/ber">ber</a></li>
    <li class="tag_cloud_tag2"><a href="http://site.com/foo">foo</a></li>
    <li class="tag_cloud_tag1"><a href="http://site.com/bar">bar</a></li>
</ul>

EXAMPLE OF GENERATED CSS CODE

#tag_cloud li {
    display: inline;
}
    #tag_cloud a {
        color: #f00;
        background: #00f;
    }
    #tag_cloud a:visited {
        color: #000;
        background: transparent;
    }
    #tag_cloud a:hover {
        color: #FFf;
        background: transparent;
    }
    .tag_cloud_tag1 { font-size: 1em; }
    .tag_cloud_tag2 { font-size: 2em; }
    .tag_cloud_tag3 { font-size: 3em; }

App::ZofCMS::Plugin::Tagged (version 0.0252)

NAME

Link: App::ZofCMS::Plugin::Tagged

App::ZofCMS::Plugin::Tagged - ZofCMS plugin to fill templates with data from query, template variables and configuration using <TAGS>

SYNOPSIS

Your ZofCMS template:

{
    cookie_foo  => '<TAG:TNo cookies:{d}{cookies}{foo}>',
    query_foo   => '[<TAG:Q:{foo}>]',
    set_cookies => [ ['foo', 'bar' ]],
    plugins     => [ { Cookies => 10 }, { Tagged => 20 } ],
    conf => {
        base => 'test.tmpl',
    },
}

In your 'test.tmpl' base HTML::Template template:

Cookie 'foo' is set to: <tmpl_var name="cookie_foo"><br>
Query 'foo' is set to: <tmpl_var name="query_foo">

In ZofCMS template the Cookies plugin is set to run before Tagged plugin, thus on first page access cookies will not be set, and we will access the page without setting the 'foo' query parameter. What do we see:

Cookie 'foo' is set to: No cookies
Query 'foo' is set to: []

No, if we run the page the second time it (now cookies are set with App::ZofCMS::Plugin::Cookies plugin) will look like this:

Cookie 'foo' is set to: bar
Query 'foo' is set to: []

If we pass query parameter 'foo' to the page, setting it to 'beer' our page will look like this:

Cookie 'foo' is set to: bar
Query 'foo' is set to: [beer]

That's the power of Tagged plugin... now I'll explain what those weird looking tags mean.

DESCRIPTION

The module provides means to the user to use special "tags" in scalar values inside ZofCMS template. This provides the ability to display data generated by templates (i.e. stored in {d} first level key), access query or configuration hashref. Possibilities are endless.

This documentation assumes you have read documentation for App::ZofCMS including App::ZofCMS::Config and App::ZofCMS::Template

STARTING WITH THE PRIORITY

First of all, when using App::ZofCMS::Plugin::Tagged with other plugins make sure to set the correct priority. In our example above, we used App::ZofCMS::Plugin::Cookies which reads currently set cookies into {d} special key in ZofCMS template. That's why we set priority of 10 to Cookies plugin and priority of 20 to Tagged plugin - to insure Tagged runs after {d}{cookies} have been filled in.

Note: currently there is no support to run Tagged plugin twice, I'm not sure that will ever be needed, but if you do come across such situation, you can easily cheat. Just copy Tagged.pm in your $core/App/ZofCMS/Plugin/Tagged.pm to Tagged2.pm (and ajust the name accordingly in the package line inside the file). Now you have two Tagged plugins, and you can do stuff like plugins => [ {Tagged => 10}, { SomePlugin => 20 }, { Tagged2 => 30 } ]

THE TAG

foo => '<TAG:Q:{foo}>',
bar => 'beeer <TAG:Qdefault:{bar}>  baz',
baz => 'foo <TAG:T:{d}{baz}[1]{beer}[2]> bar',
nop => "<TAG:NOOP><TAG:T:I'm NOT a tag!!!>",
random => '<TAG::RAND I 100>',

NOTE: everything in the tag is CASE-SENSITIVE

First of all, the tag starts with '<TAG:' and ends with with a closing angle bracket ('>'). The first character that follows '<TAG:' is a cell. It can be either 'Q', 'T' or 'C', which stand for Query, Template and Configuration file. Each of those three cells is a hashref: a hashref of query parameters, your ZofCMS template hashref and your main configuration file hashref.

What follows the cell letter until the colon (':') is the default value, it will be used if whatever your tag references is undefined. Of course, you don't have to define the default value; if you don't - the tag value will be an empty string (not undef). Note: currently you can't use the actual colon (':') in your default variable. Currently it will stay that way, but there are plans to add custom delimiters in the future.

After the colon (':') which signifies the end of the cell and possible default value follows a sequence which would access the value which you are after. This sequence is exactly how you would write it in perl. Let's look at some examples. First, let's define $template, $query and $config variables as T, Q and C "cells", these variables hold respective hashrefs (same as "cells"):

<TAG:Q:{foo}>              same as   $query->{foo}
<TAG:T:{d}{foo}>           same as   $template->{d}{foo}
<TAG:C:{ fo o }{ b a r }>  same as   $config->{"fo o"}{"b a r"}
<TAG:Qnone:{foo}>          same as   $query->{foo} // 'none'
<TAG:Txxx:{t}{bar}>        same as   $template->{t}{bar} // 'xxx'

# arrayrefs are supported as well

<TAG:T:{d}{foo}[0]>        same as   $template->{d}{foo}[0]
<TAG>C:{plugins}[1]>       same as   $config->{plugins}[1]

THE RAND TAG

rand1 => '<TAG:RAND>',
rand2 => '<TAG:RAND 100>',
rand3 => '<TAG:RAND I 200>',
rand4 => '<TAG:RAND100>',
rand5 => '<TAG:RANDI100>',

The RAND tag will be replaced by a pseudo-random number (obtained from perl's rand() function). In it's plainest form, <TAG:RAND>, it will be replaced by exactly what comes out from rand(), in other words, same as calling rand(1). If a letter 'I' follows word 'RAND' in the tag, then int() will be called on the result of rand(). When a number follows word RAND, that number will be used in the call to rand(). In other words, tag <TAG:RAND 100> will be replaced by a number which is obtained by the call to rand(100). Note: the number must be after the letter 'I' if you are using it. You can have spaces between the letter 'I' or the number and the word RAND. In other words, these tags are equal: <TAG:RANDI100> and <TAG:RAND I 100>.

THE NOOP TAG

nop => "<TAG:NOOP><TAG:T:I'm NOT a tag!!!>",

The NOOP tag (read no operation) is a special tag which tells Tagged plugin to stop processing this string as soon as it sees this tag. Tagged will remove the noop tag from the string. The above example would end up looking as nop => "<TAG:T:I'm NOT a tag!!!>",

Note: any tags before the noop tag WILL be parsed.

OPTIONS

{
    tagged_options => { no_parse => 1 },
}

Behaviour options can be set for App::ZofCMS::Plugin::Tagged via tagged_options first level ZofCMS template key. This key takes a hashref as a value. The only currently supported key in that hashref is no_parse which can be either a true or a false value. If it's set to a true value, Tagged will not parse this template.

NOTE ON DEPLOYMENT

This plugin requires Data::Transformer module which is not in Perl's core. If your webserver does not allow instalation of modules from CPAN, run the helper script to copy this module into your $core_dir/CPAN/ directory

zofcms_helper --nocore --core your_sites_core --cpan Data::Transformer

CAVEATS

If your tag references some element of ZofCMS template which itself contains a tag the behaviour is undefined.

SEE ALSO

App::ZofCMS, App::ZofCMS::Config, App::ZofCMS::Template

App::ZofCMS::Plugin::TOC (version 0.0103)

NAME

Link: App::ZofCMS::Plugin::TOC

App::ZofCMS::Plugin::TOC - Table of Contents building plugin for ZofCMS

SYNOPSIS

In your ZofCMS template, or in your main config file (under template_defaults or dir_defaults):

page_toc    => [
    qw/
        #overview
        #beginning
        #something_else
        #conclusion
    /,
],
plugins     => [ qw/TOC/ ],

# OR

page_toc    => [
    [ qw/#overview Overview class_overview/ ],
    [ qw/#beginning Beginning/ ],
    qw/
        #something_else
        #conclusion
    /,
],
plugins     => [ qw/TOC/ ],

In your HTML::Template template:

<tmpl_var name="page_toc">

DESCRIPTION

This plugin provides means to generate "table of contents" lists. For example, the second example in the SYNOPSYS would replace <tmpl_var name="page_toc"> with this:

<ul class="page_toc">
    <li class="class_overview"><a href="#overview">Overview</a></li>
    <li><a href="#beginning">Beginning</a></li>
    <li><a href="#something_else">Something Else</a></li>
    <li><a href="#conclusion">Conclusion</a></li>
</ul>

HOW TO USE

Aside from sticking TOC in your arrayref of plugins in your ZofCMS template (plugins => [ qw/TOC/ ]) and placing <tmpl_var name="page_toc"> in your HTML::Template template you also need to create a page_toc first level key in ZofCMS template. That key's value is an arrayref each element of which can be either an arrayref or a scalar. If the element is a scalar it is the same as it being an arrayref with one element. The element which is an arrayref can contain either one, two or three elements itself. Which represent the following:

arrayref which contains only one element

page_toc => [
    '#foo',
    '#bar-baz',
],

# OR

page_toc => [
    [ '#foo' ],
    [ '#bar-baz' ],
],

The first (and only) element will be used in href="" attribute of the generated link. The text of the link will be determined automatically, in particular the '#' will be removed, first letter will be capitalized and any dashes '-' or underscores '_' will be replaced by a space with the letter following them capitalized. The example above will place the following code in <tmpl_var name="page_toc">:

<ul class="page_toc">
    <li><a href="#foo">Foo</a></li>
    <li><a href="#bar-baz">Bar Baz</a></li>
</ul>

arrayref which contains two elements

page_toc => [
    [ '#foo', 'Foos Lots of Foos!' ],
    [ '#bar-baz', 'Bar-baz' ],
],

The first element will be used in href="" attribute of the generated link. The second element will be used as text for the link. The example above will generate the following code:

<ul class="page_toc">
    <li><a href="#foo">Foos Lots of Foos!</a></li>
    <li><a href="#bar-baz">Bar-baz</a></li>
</ul>

arrayref which contains three elements

page_toc => [
    [ '#foo', 'Foos Lots of Foos!', 'foos' ],
    [ '#bar-baz', 'Bar-baz', 'bars' ],
],

The first element will be used in href="" attribute of the generated link. The second element will be used as text for the link. The third elemenet will be used to create a class="" attribute on the <li> element for the corresponding entry. The example above will generate the following code:

<ul class="page_toc">
    <li class="foos"><a href="#foo">Foos Lots of Foos!</a></li>
    <li class="bars"><a href="#bar-baz">Bar-baz</a></li>
</ul>

Note: the class of the <ul> element is always page_toc

App::ZofCMS::Plugin::UserLogin (version 0.0102)

NAME

Link: App::ZofCMS::Plugin::UserLogin

App::ZofCMS::Plugin::UserLogin - restrict access to pages based on user accounts

SYNOPSIS

In $your_database_of_choice that is supported by DBI create a table. You can have extra columns in it, but the first five must be named as appears below. login_time is the return of Perl's time(). Password will be md5_hex()ed (with Digest::MD5, session_id is rand() . rand() . rand() and role depends on what you set the roles to be:

create TABLE users (
    login TEXT,
    password VARCHAR(32),
    login_time VARCHAR(10),
    session_id VARCHAR(55),
    role VARCHAR(20)
);

Main config file:

template_defaults => {
    plugins => [ { UserLogin => 10000 } ],
},
plug_login => {
    dsn                     => "DBI:mysql:database=test;host=localhost",
    user                    => 'test', # user,
    pass                    => 'test', # pass
    opt                     => { RaiseError => 1, AutoCommit => 0 },
    table                   => 'users',
    login_page              => '/login',
    redirect_on_restricted  => '/login',
    redirect_on_login       => '/',
    redirect_on_logout      => '/',
    not_restricted          => [ qw(/ /index) ],
    restricted              => [ qr/^/ ],
},

In HTML::Template template for '/login' page:

<tmpl_var name="plug_login_form">
<tmpl_var name="plug_login_logout">

DESCRIPTION

The module is a plugin for App::ZofCMS; it provides functionality to restrict access to some pages based on user accounts (which support "roles")

Plugin uses HTTP cookies to set user sessions.

This documentation assumes you've read App::ZofCMS, App::ZofCMS::Config and App::ZofCMS::Template

NOTE ON REDIRECTS

There are quite a few options that redirect the user upon a certain event. The exit() will be called upon a redirect so keep that in mind when setting plugin's priority setting.

DATABASE

Plugin needs access to the database that is supported by DBI module. You'll need to create a table the format of which is described in the first paragraph of SYNOPSYS section above. Note: plugin does not support creation of user accounts. That was left for other plugins (e.g. App::ZofCMS::Plugin::FormToDatabase) considering that you are flexible in what the entry for each user in the database can contain.

ROLES

The "role" of a user can be used to limit access only to certain users. In the database the user can have several roles which are to be separated by commas (,). For example:

foo,bar,baz

The user with that role is member of role "foo", "bar" and "baz".

TEMPLATE/CONFIG FILE SETTINGS

plug_login => {
    dsn                     => "DBI:mysql:database=test;host=localhost",
    user                    => 'test',
    pass                    => 'test',
    opt                     => { RaiseError => 1, AutoCommit => 0 },
    table                   => 'users',
    user_ref    => sub {
        my ( $user_ref, $template ) = @_;
        $template->{d}{plug_login_user} = $user_ref;
    },
    login_page              => '/login',
    redirect_on_restricted  => '/login',
    redirect_on_login       => '/',
    redirect_on_logout      => '/',
    not_restricted          => [ qw(/ /index) ],
    restricted              => [ qr/^/ ],
},

These settings can be set via plug_login first-level key in ZofCMS template, but you probably would want to set all this in main config file via plug_login first-level key.

dsn

dsn => "DBI:mysql:database=test;host=localhost",

Mandatory. The dsn key will be passed to DBI's connect_cached() method, see documentation for DBI and DBD::your_database for the correct syntax of this one. The example above uses MySQL database called test which is location on localhost

user

user => 'test',

Mandatory. Specifies the user name (login) for the database. This can be an empty string if, for example, you are connecting using SQLite driver.

pass

pass => 'test',

Mandatory. Same as user except specifies the password for the database.

table

table => 'users',

Optional. Specifies which table in the database stores user accounts. For format of this table see SYNOPSYS section. Defaults to: users

opt

opt => { RaiseError => 1, AutoCommit => 0 },

Optional. Will be passed directly to DBI's connect_cached() method as "options". Defaults to: { RaiseError => 1, AutoCommit => 0 }

user_ref

user_ref => sub {
    my ( $user_ref, $template ) = @_;
    $template->{d}{plug_login_user} = $user_ref;
},

Optional. Takes a subref as an argument. When specified the subref will be called and its @_ will contain the following: $user_ref, $template_ref, $query_ref, $config_obj, where $user_ref will be either undef (e.g. when user is not logged on) or will contain an arrayref with user data pulled from the SQL table, i.e. an arrayref with all the columns in a table that correspond to the currently logged in user. The $template_ref is the reference to your ZofCMS template, $query_ref is the reference to a query hashref as is returned from CGI's Vars() call. Finally, $config_obj is the App::ZofCMS::Config object. Basically you'd use user_ref to stick user's data into your ZofCMS template for later processing, e.g. displaying parts of it or making it accessible to other plugins. Defaults to: (will stick user data into {d}{plug_login_user} in ZofCMS template)

user_ref    => sub {
    my ( $user_ref, $template ) = @_;
    $template->{d}{plug_login_user} = $user_ref;
},

login_page

login_page => '/login',

login_page => qr|^/log(?:in)?|i;

Optional. Specifies what page is a page with a login form. The check will be done against a "page" that is constructed by $query{dir} . $query{page} (the dir and page are discussed in ZofCMS's core documentation). The value for the login_page key can be either a string or a regex. Note: the access is NOT restricted to pages matching login_page. Defaults to: /login

redirect_on_restricted

redirect_on_restricted => '/uri',

Optional. Specifies the URI to which to redirect if access to the page is denied, e.g. if user does not have an appropriate role or is not logged in. Defaults to: /

redirect_on_login

redirect_on_login  => '/uri',

Optional. Specifies the URI to which to redirect after user successfully logged in. By default is not specified.

redirect_on_logout

redirect_on_logout => '/uri',

Optional. Specifies the URI to which to redirect the user after he or she logged out.

restricted

restricted => [
    qw(/foo /bar /baz),
    qr|^/foo/|i,
    { page => '/admin', role => 'admin' },
    { page => qr|^/customers/|, role => 'customer' },
],

Optional but doesn't make sense to not specify this one. By default is not specified. Takes an arrayref as a value. Elements of this arrayref can be as follows:

a string

restricted => [ qw(/foo /bar) ],

Elements that are plain strings represent direct pages ( page is made out of $query{dir} . $query{page} ). The example above will restrict access only to pages http://foo.com/index.pl?page=foo and http://foo.com/index.pl?page=bar for users that are not logged in.

a regex

restricted => [ qr|^/foo/| ],

Elements that are regexes (qr//) will be matched against the page. If the page matches the given regex access will be restricted to any user who is not logged in.

a hashref

restricted => [
    { page => '/secret', role => \1 },
    { page => '/admin', role => 'customer' },
    { page => '/admin', role => 'not_customer' },
    { page => qr|^/customers/|, role => 'not_customer' },
],

Using hashrefs you can set specific roles that are restricted from a given page. The hashref must contain two keys: the page key and role key. The value of the page key can be either a string or a regex which will be matched against the current page the same way as described above. The role key must contain a role of users that are restricted from accessing the page specified by page key or a scalarref (meaning "any role"). Note you can specify only one role per hashref. If you want to have several roles you need to specify several hashrefs or use not_restricted option described below.

In the example above only logged in users who are NOT members of role customer or not_customer can access /admin page and only logged in users who are NOT members of role not_customer can access pages that begin with /customers/. The page /secret is restricted for everyone (see note on scalarref below).

IMPORTANT NOTE: the restrictions will be checked until the first one matching the page criteria found. Therefore, make sure to place the most restrictive restrictions first. In other words:

restricted => [
    qr/^/,
    { page => '/foo', role => \1 },
],

Will NOT block logged in users from page /foo because qr/^/ matches first. Proper way to write this restriction would be:

restricted => [
    { page => '/foo', role => \1 },
    qr/^/,
],

Note: the role can also be a scalarref; if it is, it means "any role". In other words:

restricted => [ qr/^/ ],

Means "all the pages are restricted for users who are not logged in". While:

restricted => [ { page => qr/^/, role \1 } ],

Means that "all pages are restricted for everyone" (in this case you'd use not_restricted option described below to ease the restrictions).

not_restricted

not_restricted => [
    qw(/foo /bar /baz),
    qr|^/foo/|i,
    { page => '/garbage', role => \1 },
    { page => '/admin', role => 'admin' },
    { page => qr|^/customers/|, role => 'customer' },
],

Optional. The value is the exact same format as for restricted option described above. By default is not specified. The purpose of not_restricted is the reverse of restricted option. Note that pages that match anything in not_restricted option will not be checked against restricted. In other words you can construct rules such as this:

restricted => [
    qr/^/,
    { page => qr|^/admin|, role => \1 },
],
not_restricted => [
    qw(/ /index),
    { page => qr|^/admin|, role => 'admin' },
],

The example above will restrict access to every page on the site that is not / or /index to any user who is not logged in. In addition, pages that begin with /admin will be accessible only to users who are members of role admin.

limited_time

limited_time => 600,

Optional. Takes integer values greater than 0. Specifies the amount of seconds after which user's session expires. In other words, if you set limited_time to 600 and user went to the crapper for 10 minutes, then came back, he's session would expire and he would have to log in again. By default not specified and sessions expire when the cookies do so (which is "by the end of browser's session", let me know if you wish to control that).

no_cookies

no_cookies => 1,

Optional. When set to a false value plugin will set two cookies: md5_hex()ed user login and session ID. When set to a true value plugin will not set any cookies and instead will put session ID into plug_login_session_id key under ZofCMS template's {t} special key.

HTML::Template TEMPLATE

There are two (or three, depending if you set no_cookies to a true value) keys created in ZofCMS template {t} special key, thus are available in your HTML::Template templates:

plug_login_form

<tmpl_var name="plug_login_form">

The plug_login_form key will contain the HTML code for the "login form". You'd use <tmpl_var name="plug_login_form"> on your "login page". Note that login errors, i.e. "wrong login or password" will be automagically display inside that form in a <p class="error">.

plug_login_logout

<tmpl_var name="plug_login_logout">

This one is again an HTML form except for the "logout" button. Drop it anywhere you want.

plug_login_user

<tmpl_if name="plug_login_user">
    Logged in as <tmpl_var name="plug_login_user">.
</tmpl_if>

The plug_login_user will contain the login name of the currently logged in user.

plug_login_session_id

If you set no_cookies argument to a true value, this key will contain session ID.

GENERATED HTML CODE

Below are the snippets of HTML code generated by the plugin; here for the reference when styling your login/logout forms.

login form

<form action="" method="POST" id="zofcms_plugin_login">
<div>
    <input type="hidden" name="page" value="/login">
    <input type="hidden" name="zofcms_plugin_login" value="login_user">
    <ul>
        <li>
            <label for="zofcms_plugin_login_login">Login: </label
            ><input type="text" name="login" id="zofcms_plugin_login_login">
        </li>
        <li>
            <label for="zofcms_plugin_login_pass">Password: </label
            ><input type="password" name="pass" id="zofcms_plugin_login_pass">
        </li>
    </ul>
    <input type="submit" value="Login">
</div>
</form>

login form with a login error

<form action="" method="POST" id="zofcms_plugin_login">
<div><p class="error">Invalid login or password</p>
    <input type="hidden" name="page" value="/login">
    <input type="hidden" name="zofcms_plugin_login" value="login_user">
    <ul>
        <li>
            <label for="zofcms_plugin_login_login">Login: </label
            ><input type="text" name="login" id="zofcms_plugin_login_login">
        </li>
        <li>
            <label for="zofcms_plugin_login_pass">Password: </label
            ><input type="password" name="pass" id="zofcms_plugin_login_pass">
        </li>
    </ul>
    <input type="submit" value="Login">
</div>
</form>

logout form

<form action="" method="POST" id="zofcms_plugin_login_logout">
<div>
    <input type="hidden" name="page" value="/login">
    <input type="hidden" name="zofcms_plugin_login" value="logout_user">
    <input type="submit" value="Logout">
</div>
</form>

App::ZofCMS::PluginReference (version 0.0101)

NAME

Link: App::ZofCMS::PluginReference

App::ZofCMS::PluginReference - docs for all plugins in one document for easy reference

DESCRIPTION

I often found myself reaching out for docs for different plugins cluttering up my browser. The solution - stick all docs into one!.

App::ZofCMS::Plugin::AntiSpamMailTo (version 0.0101)

NAME

Link: App::ZofCMS::Plugin::AntiSpamMailTo

App::ZofCMS::Plugin::AntiSpamMailTo - "smart" HTML escapes to protect mailto:foo@bar.com links from not-so-smart spam bots

SYNOPSIS

In your Main Config file or ZofCMS template:

# include the plugin
plugins => [ qw/AntiSpamMailTo/ ],

# then this: 
plug_anti_spam_mailto => 'bar',
# or this:
plug_anti_spam_mailto => [ qw/foo bar baz/ ],
# or this:
plug_anti_spam_mailto => {
    foo => 'bar',
    baz => 'beer',
},

In your HTML::Template template:

<tmpl_var name="mailto">
# or this:
<tmpl_var name="mailto_0"> <tmpl_var name="mailto_1"> <tmpl_var name="mailto_2">
# or this:
<tmpl_var name="foo"> <tmpl_var name="baz">

DESCRIPTION

The module is an App::ZofCMS plugin which provides means to deploy a technique that many claim to be effective in protecting your <a href="mailto:foo@bar.com"></a> links from dumb spam bots.

The technique is quite simple (and simple to circumvent, but we are talking about dumb spam bots) - the entire contents of href="" attribute are encoded as HTML entities. Dumb spam bots miss the mailto: and go their way. Anyway, on to the business.

This documentation assumes you have read App::ZofCMS, App::ZofCMS::Config and App::ZofCMS::Template

MAIN CONFIG/ZofCMS TEMPLATE FIRST-LEVEL KEYS

plug_anti_spam_mailto

plug_anti_spam_mailto => 'bar',

plug_anti_spam_mailto => [ qw/foo bar baz/ ],

plug_anti_spam_mailto => {
    foo => 'bar',
    baz => 'beer',
},

The plugin takes it's data from plug_anti_spam_mailto first-level key that is in either ZofCMS template or config file. The key takes either a string, arrayref or a hashref as its value. If the key is specified in both main config file and ZofCMS template and the value is of the same type (string, arrayref or hashref) then both values will be interpreted by the plugin; in case of the hashref, any duplicate keys will obtain the value assigned to them in ZofCMS template. Note: if the value is of "type" string specified in both main config file and ZofCMS template it will interpreted as an arrayref with two elements. Now I'll tell you why this all matters:

value is a string

plug_anti_spam_mailto => 'bar',

When the value is a string then in HTML::Template template you'd access the converted data via variable mailto, i.e. <tmpl_var name="mailto">

value is an arrayref or a string in both ZofCMS template and main config file

plug_anti_spam_mailto => [ qw/foo bar baz/ ],

To access converted data when the value is an arrayref you'd use mailto_NUM where NUM is the index of the element in the arrayref. In other words, to access value bar in the example above you'd use <tmpl_var name="mailto_1">

value is a hashref

plug_anti_spam_mailto => {
    foo => 'bar',
    baz => 'beer',
},

You do not have to keep typing mailto to access your converted data. When value is a hashref the values of that hashref are the data to be converted and the keys are the names of <tmpl_var name"">s into which to stick that data. In the example above, to access converted data for beer you'd use <tmpl_var name="baz">

EXAMPLE

ZofCMS template:

plugins => [ qw/AntiSpamMailTo/ ],
plug_anti_spam_mailto => 'mailto:john.foo@example.com',

HTML::Template template:

<a href="<tmpl_var name="mailto">">email to John Foo</a>

App::ZofCMS::Plugin::AutoIMGSize (version 0.0101)

NAME

Link: App::ZofCMS::Plugin::AutoIMGSize

App::ZofCMS::Plugin::AutoIMGSize - automatically get image sizes and generate appropriate <img> tags

SYNOPSIS

In your Main Config or ZofCMS Template file:

plugins => [ qw/AutoIMGSize/ ],
plug_auto_img_size => {
    imgs => {
        logo    => 'pics/top_logo.png'
        kitteh  => 'pics/kitteh.jpg',
        blah    => { 'somewhere/there.jpg' => ' class="foo"' },
    },
},

In your HTML::Template template:

Logo: <tmpl_var name="img_logo">
Kitteh: <tmpl_var name="img_kitteh">
blah: <tmpl_var name="img_blah">

DESCRIPTION

The module is a plugin for App::ZofCMS. It provides means to generate HTML <img ... > tags with automatic image size generation, i.e. the plugin gets the size of the image from the file. Personally, I use it in templates where the size of the image is unknown, if the image is static and you can physically type in the address, it would be saner to do so.

This documentation assumes you've read App::ZofCMS, App::ZofCMS::Config and App::ZofCMS::Template

MAIN CONFIG FILE OR ZofCMS TEMPLATE KEYS

plugins

plugins => [ qw/AutoIMGSize/ ],

You would obvisouly want to add the plugin to the list of plugins to run. Play with priorities if you are loading image paths dynamically.

plug_auto_img_size

plug_auto_img_size => {
    xhtml       => 1,
    t_prefix    => 'img_',
    imgs => {
        logo    => 'pics/logo.png',
        kitteh  => { 'pics/kitteh.jpg' => ' class="kitteh' },
    },
},

The plug_auto_img_size first-level Main Config file or ZofCMS Template file is what makes the plugin run. If you specify this key in both ZofCMS Template and Main Config file then keys set in ZofCMS Template will override the ones set in Main Config file. Note: the imgs key will be completely overridden.

The key takes a hashref as a value. Possible keys/values of that hashref are as follows:

imgs

imgs => [ qw/foo.jpg bar.jpg/ ],
#same as
imgs => {
    'foo.jpg' => 'foo.jpg',
    'bar.jpg' => 'bar.jpg',
},

Mandatory. The imgs key takes either an arrayref or a hashref as a value. If the value is an arrayref, it will be converted to a hashref where keys and values are the same.

The key in the hashref specifies the "name" of the key in {t} ZofCMS Template special key to which the t_prefix (see below) will be prepended. The value specifies the image filename relative to ZofCMS index.pl file (root dir of your website, basically). The value of each key can be either a string or a hashref. If it's a string, it will be taken as a filename of the image. If it is a hashref it must contain only one key/value pair; the key of that hashref will be taken as a filename of the image and the value will be taken as extra HTML attributes to insert into <img> tag. Note that the value, in this case, should begin with a space as to not merge with the width/height attributes. Note 2: unless the value is a hashref, the alt="" attribute will be set to an empty string; otherwise you must include it in "extra" html attributes. Here are a few examples (which assume that t_prefix (see below) is set to its default value: img_; and size of the image is 500px x 500px):

# ZofCMS template:
imgs => [ qw/foo.jpg/ ]

# HTML::Template template:
<tmpl_var name="img_foo.jpg">

# Resulting HTML code:
<img src="/foo.jpg" width="500" height="500" alt="">

Note: that image src="" attribute is made relative to root path of your website (i.e. starts with a slash / character).

# ZofCMS tempalte:
imgs => { foo => 'pics/foo.jpg' },

# HTML::Template template:
<tmpl_var name="img_foo">

# Resulting HTML code:
<img src="/pics/foo.jpg" width="500" height="500" alt="">

Now with custom attributes (note the leading space before alt="" attribute):

# ZofCMS template:
imgs => { foo => { 'pics/foo.jpg' => ' alt="foos" class="foos"' } }

# HTML::Template template:
<tmpl_var name="img_foo">

# Resulting HTML code:
<img src="/pics/foo.jpg" width="500" height="500" alt="foos" class="foos">

Note: if plugin cannot find your image file then the <img> tag will be replaced with ERROR: Not found.

t_prefix

t_prefix => 'img_',

Optional. The t_prefix takes a string as a value, this string will be prepended to the "name" of your images in {t} ZofCMS Template special key. In other words, if you set t_prefix => 'img_', imgs => { foo => 'pics/bar.jpg' }, then in your HTML::Template template you'd insert your image with <tmpl_var name="img_foo">. Defaults to: img_ (note the underscore (_) at the end)

xhtml

xhtml => 1,

Optional. When set to a true value the <img> tag will be closed with />. When set to a false value the <img> tag will be closed with >. Default to: 0 (false)

DEPENDENCIES

The module relies on Image::Size to get image sizes.

App::ZofCMS::Plugin::Base (version 0.0102)

NAME

Link: App::ZofCMS::Plugin::Base

App::ZofCMS::Plugin::Base - base class for App::ZofCMS plugins

SYNOPSIS

package App::ZofCMS::Plugin::Example;

use strict;
use warnings;
use base 'App::ZofCMS::Plugin::Base';

sub _key { 'plug_example' }
sub _defaults { qw/foo bar baz beer/ }
sub _do {
    my ( $self, $conf, $template, $query, $config ) = @_;
}

DESCRIPTION

The module is a base class for App::ZofCMS plugins. I'll safely assume that you've already read the docs for App::ZofCMS, App::ZofCMS::Config and App::ZofCMS::Template

The base class (currently) is only for plugins who take their "config" as a single first-level key in either Main Config File or ZofCMS Template. That key's value must be a hashref.

SUBS TO OVERRIDE

_key

sub _key { 'plug_example' }

The _key needs to return a scalar contain the name of first level key in ZofCMS template or Main Config file. Study the source code of this module to find out what it's used for if it's still unclear.

_defaults

sub _defaults { qw/foo bar baz beer/ }

The _defaults sub needs to return a list of default arguments in a key/value pairs. By default it returns an empty list.

_do

sub _do {
    my ( $self, $conf, $template, $query, $config ) = @_;
}

The _do sub is where you'd do all of your processing. The @_ will contain $self, $conf, $template, $query and $config (in that order) where $self is your plugin's object, $conf is the plugin's configuration hashref (what the user would specify in ZofCMS Template or Main Config File, the key of which is returned by _key() sub), the $template is the hashref of ZofCMS template that is being processed, the $query is a query parameters hashref where keys are names of the params and values are their values. Finally, the $config is App::ZofCMS::Config object.

MOAR!

Feel free to email me the requests for extra functionality for this base class.

App::ZofCMS::Plugin::BreadCrumbs (version 0.0102)

NAME

Link: App::ZofCMS::Plugin::BreadCrumbs

App::ZofCMS::Plugin::BreadCrumbs - add "breadcrumbs" navigation to your sites

SYNOPSIS

In your ZofCMS template:

plugins => [ qw/BreadCrumbs/ ]

In your HTML::Template template:

<tmpl_var name="breadcrumbs">

DESCRIPTION

The module is a plugin for App::ZofCMS. It provides means to add a "breadcrumbs" (http://en.wikipedia.org/wiki/Breadcrumb_(navigation)) to your pages.

This documentation assumes you've read App::ZofCMS, App::ZofCMS::Config and App::ZofCMS::Template

HOW DOES IT WORK

The plugin automagically generates breadcrumb links, if your sites are relatively simple and pages are in good hierarchy the plugin will do the Right Thing(tm) most of the time. The links for breadcrumbs are determined as follows. If the page is not called index then the index page in the current "directory" will be added to the breadcrumbs, the "path" will be broken down to pieces and index page in each piece will be added to the breadcrumbs. Note: the examples below assume that the no_pages argument was not specified:

# page
index.pl?page=/foo/bar/baz

# crumbs
/index => /foo/index => /foo/bar/index => /foo/bar/baz


# page
index.pl?page=/foo/bar/beer/index

# crumbs
/index => /foo/index/ => /foo/bar/index => /foo/bar/beer/index

FIRST-LEVEL ZofCMS TEMPLATE KEYS

plugins

plugins => [ qw/BreadCrumbs/ ]

First and obvious you need to add BreadCrumbs to the list of plugins to execute. Just this will already make the plugin execute, i.e. having the breadcrumbs key (see below) is not necessary.

breadcrumbs

breadcrumbs => {}, # disable the plugin

# lots of options
breadcrumbs => {
    direct      => 1,
    span        => 1,
    no_pages => [ '/comments' ],
    key         => 'page_title',
    text_re     => qr/([^-]+)/,
    change      => {
        qr/foo/ => 'foos',
        qr/bar/ => 'bars',
    },
    replace     => {
        qr/foo/ => 'foos',
        qr/bar/ => 'bars',
    },
},

The breadcrumbs first-level ZofCMS template key controls the behaviour of the plugin. The key takes a hashref as a value. Do NOT specify this key if you wish to use all the defaults, as specifying an empty hashref as a value will disable the plugin for that given page. Possible keys/values of that hashref are as follows:

direct

{ direct => 1 },

Optional. Takes either true or false values. When set to a false value the breadcrumb links will all be of form /index.pl?page=/index. When set to a true value the links will be of form /index which is useful when you are making your URIs with something like mod_rewrite. Defaults to: false

span

{ span => 1 },

Optional. The span key takes either true or false values. When set to a true value, the plugin will generate <span> based breadcrumbs. When set to a false value, the plugin will generate <ul> based breadcrumbs. Default to: false.

no_pages

{ no_pages => [ '/comments', '/index' ], }

Optional. Takes an arrayref as a value. Each element of that array must be a dir + page (as described in Note on page and dir query parameters in App::ZofCMS::Config). If a certain element of that array matches the page in the breadcrumbs being generated it will be removed from the breadcrumbs. In other words, if you specify no_pages => [ '/index' ] the "index" page of the "root" directory will not show up in the breadcrumbs. By default is not specified.

key

{ key => 'title', }

Optional. When walking up the "tree" of pages plugin will open ZofCMS templates for those pages and use the key key's value as the text for the link. Only first-level keys are supported. Defaults to: title

text_re

{ text_re => qr/([^-]+)/ }

Optional. Takes a regex (qr//) as a value which must contain a capturing set of parentheses. When specified will run the regex on the value of key (see above) key's value and whatever was captured in the capturing parentheses will be used for the text of the link. By default is not specified.

change

change => {
    qr/foo/ => 'foos',
    qr/bar/ => 'bars',
},

Optional. Takes a hashref as a value. The keys of that hashref are regexen (qr//) and the values are the text with which the entire text of the link will be replaced if that particular regex matches. In other words, if you specify change => { qr/foo/ => 'foo' } and your link text is lots and lots of foos it will turn into just foo. By default is not specified.

replace

replace => {
    qr/foo/ => 'foos',
    qr/bar/ => 'bars',
},

Optional. Same as change key described above, except replace will replace the matching part with the text provided as a value. In other words, if you specify replace => { qr/foo/ => 'BAR' } and your link text is lots and lots of foos it will turn into lots and lots of BARs. By default is not specified.

HTML::Template TEMPLATE VARIABLES

<tmpl_var name="breadcrumbs">

The plugin set one key - breadcrumbs - in {t} special key which means that you can stick <tmpl_var name="breadcrumbs"> in any of your HTML::Template templates and this is where the breadcrumbs will be placed.

App::ZofCMS::Plugin::Comments (version 0.0101)

NAME

Link: App::ZofCMS::Plugin::Comments

App::ZofCMS::Plugin::Comments - drop-in visitor comments support.

SYNOPSIS

In your "main config" file:

comments_plugin => {
    dsn         => "DBI:mysql:database=test;host=localhost",
    user        => 'test',
    pass        => 'test',
    email_to    => [ 'admin@example.com', 'admin2@example.com' ],
},

In your ZofCMS template:

plugins => [ qw/Comments/ ],

In your "comments" page HTML::Template template, which we set to be /comments by default:

<tmpl_var name="zofcms_comments_form">

In any page on which you wish to have comments:

<tmpl_var name="zofcms_comments_form">
<tmpl_var name="zofcms_comments">

DESCRIPTION

The module is a plugin for App::ZofCMS. It provides means to easily add "visitor comments" to your pages. The plugin offers configurable flood protection ( $x comments per $y seconds ) as well as ability to notify you of new comments via e-mail. The "moderation" function is also implemented, what that means is that you (the admin) would get two links (via e-mail) following one of them will approve the comment; following the other will simply delete the comment from the database.

I am an utterly lazy person, thus you may find that not everything you may want to configure in the plugin is configurable. The plugin is yet to undergo (at the time of this writing) deployment testing, as in how flexible it is. If you'd like to see some features added, don't be shy to drop me a line to zoffix@cpan.org

This documentation assumes you've read App::ZofCMS, App::ZofCMS::Config and App::ZofCMS::Template

HOW IT ALL COMES TOGETHER OR "WHAT'S THAT 'comments' PAGE ANYWAY?"

So here is how it works, you have some page where you added the plugin's functionality. Visitor enters his/hers comment and pressed "Post" button. The request will be POSTed to a "comments" page and depending on what the visitor entered he or she will either get an error with ability to fix it or a "success" message with an ability to go back to the page on which the comment was created. The reason for this "comments" page is that I couldn't figure out a simple way to have the comments markup inserted with simple <tmpl_var> and keep any page on which the plugin was used small enough for the user to see the error message easily.

The "comments" must have <tmpl_var name="zofcms_comments_form"> on it somewhere for the plugin to work.

MAIN CONFIG OR ZofCMS TEMPLATES?

If you have a sharp eye, you've noticed that plugin's configuration was placed into the 'main config file' in the SYNOPSIS. You actually don't have to do that and can keep plugin's configuration in your ZofCMS template, but personally I find it much easier to just drop it into the main config and enable it on per-page basis by sticking only Comments in the list of the plugins on ZofCMS templates.

THE SQL TABLES!

Under the hood the plugin uses DBI to stick data into SQL tables. Generally speaking you shouldn't have trouble using the plugin with $database_of_your_choice; however, the plugin was tested only with MySQL database. Before you can use the plugin you need to create one or two tables in your database. The columns have to be named those names and be in that order:

# comments table
CREATE TABLE comments (name VARCHAR(100), email VARCHAR(200), comment TEXT, page VARCHAR(100), remote_host TEXT, time VARCHAR(11));

#moderation table
CREATE TABLE mod_comments (name VARCHAR(100), email VARCHAR(200), comment TEXT, page VARCHAR(100), remote_host TEXT, time VARCHAR(11), id TEXT);

Now, the note on value types. The name, email and comment is the data that the comment poster posts. Since the maximum lengths of those fields are configurable, pick the value types you think fit. The page column will contain the "page" on which the comment was posted. In other words, if the comment was posted on http://example.com/?page=/foo/bar/baz, the page cell will contain /foo/bar/baz. The remote_host is obtained from CGI's remote_host() method. The time cell is obtained from the call to time() and the id in moderation table is generated with rand() . time() . rand() (keep those flames away plz).

COMMENT MODERATION

When moderation of comments is turned on in the plugin you will get two links e-mailed when a new comment was submitted. One is "approve" and another one is "deny". Functions of each are self explanatory. What happens is that the comment is first placed in the "moderation table". If you click "approve", the comment is moved into the "comments table". If the comment is denied by you, it is simply deleted from the "moderation table". There is a feature that allows all comments that are older than $x seconds (see mod_out_time argument) to be deleted from the "moderation table" automatically.

WHAT? NO CAPTCHA?

You will notice that there is no "captcha" (http://en.wikipedia.org/wiki/Captcha) thing done with comments form generated by the plugin. The reason for that is that I hate them... pure hate. I think the worst captcha I ever came across was this: http://www.zoffix.com/new/captcha-wtf.png. But most of all, I think they are plain annoying.

In this plugin I implemented a non-annoying "captcha" mechanizm suggested by one of the people I know who claimed it works very well. At the time of this writing I am not yet aware of how "well" it really is. Basically, the plugin sticks <input type="hidden" name="zofcms_comments_username" value="your user name"> in the form. When checking the parameters, the plugin checks that this hidden input's value matches. If it doesn't, boot the request. Apparently the technique works much better when the <input> is not of type="hidden" but I am very against "hiding" something with CSS.

So, time will show, if this technique proves to be a failure, expect the plugin to have an option to provide a better "captcha" mechanizm. As for now, this is all you get, although, I am open for good ideas.

GOODIES IN ZofCMS TEMPLATE/MAIN CONFIG FILE

plugins

plugins => [ qw/Comments/ ],

This goes without saying that you'd need to stick 'Comments' into the list of plugins used in ZofCMS template. As opposed to many other plugins this plugin will not bail out of the execution right away if comments_plugin first level key (described below) is not specified in the template (however it will if you didn't specify comments_plugin in neither the ZofCMS template nor the main config file).

comments_plugin

comments_plugin => {
    # mandatory
    dsn             => "DBI:mysql:database=test;host=localhost",
    page            => '/comments',

    #optional in some cases, no defaults
    email_to        => [ 'admin@test.com', 'admin2@test.com' ],

    #optional, but default not specified
    user            => 'test', # user,
    pass            => 'test', # pass
    opts            => { RaiseError => 1, AutoCommit => 1 },
    uri             => 'http://yoursite.com',
    mailer          => 'testfile',
    no_pages        => [ qw(/foo /bar/beer /baz/beer/meer) ],

    # optional, defaults presented here
    sort            => 0
    table           => 'comments',
    mod_table       => 'mod_comments',
    must_name       => 0,
    must_email      => 0,
    must_comment    => 1,
    name_max        => 100,
    email_max       => 200,
    comment_max     => 10000,
    moderate        => 1,
    send_entered    => 1,
    subject         => 'ZofCMS Comments',
    flood_num       => 2,
    flood_time      => 180,
    mod_out_time    => 1209600,
}

Whoosh, now that's a list of options! Luckly, most of them have defaults. I'll go over them in a second. Just want to point out that all these arguments can be set in the "main config file" same way you'd set them in ZofCMS template (the first-level comments_plugin key). In fact, I recommend you set them all in ZofCMS main config file instead of ZofCMS templates, primarily because you'd want to have it duplicated at least twice: once on the "comments page" and once on the page on which you actually want to have visitors' comments functionality. So here are the possible arguments:

dsn

dsn => "DBI:mysql:database=test;host=localhost",

Mandatory. Takes a scalar as a value which must contain a valid "$data_source" as explained in DBI's connect_cached() method (which plugin currently uses).

email_to

email_to => [ 'admin@test.com', 'admin2@test.com' ],

Mandatory unless moderate and send entered are set to a false values. Takes either a scalar or an arrayref as a value. Specifying a scalar is equivalent to specifying an arrayref with just that scalar in it. When moderate or send_entered are set to true values, the e-mail will be sent to each of the addresses specified in the email_to arrayref.

page

page => '/comments',

Optional. This is the "comments page" that I explained in the HOW IT ALL COMES TOGETHER OR "WHAT'S THAT 'comments' PAGE ANYWAY?" section above. Argument takes a string as a value. That value is what you'd set the page query parameter in order to get to the "comments page". Make sure you also prepend the dir. In the example above the comments page is accessed via http://example.com/index.pl?page=comments&dir=/. Defaults to: /comments

user

user => 'test_db_user',

Optional. Specifies the username to use when connecting to the SQL database used by the plugin. By default is not specified.

pass

pass => 'teh_password',

Optional. Specifies the password to use when connecting to the SQL database used by the plugin. By default is not specified.

opts

opts => { RaiseError => 1, AutoCommit => 1 },

Optional. Takes a hashref as a value. Specifies additional options to DBI's connect_cached() method, see DBI's documentation for possible keys/values of this hashref. Defaults to: { RaiseError => 1, AutoCommit => 1 }

uri

uri => 'http://yoursite.com/index.pl?page=/comments',

Optional. The only place in which this argument is used is for generating the "Approve" and "Deny" URIs in the e-mail sent to you when moderate is set to a true value. Basically, here you would give the plugin a URI to your "comments page" (see page argument above). If you don't specify this argument, nothing will explode (hopefully) but you won't be able to "click" the "Approve"/"Deny" URIs.

mailer

mailer => 'testfile',

Optional. When either moderate or send_entered arguments are set to true values, the mailer argument specifies which "mailer" to use to send e-mails. See documentation for Mail::Mailer for possible mailers. By default mailer argument is not specified, thus the "mailers" will be tried until one of them works. When mailer is set to testfile, the mail file will be located at the same place ZofCMS' index.pl file is located.

no_pages

no_pages => [ qw(/foo /bar/beer /baz/beer/meer) ],

Optional. Takes an arrayref as a value. Each element of that arrayref must be a page with dir appended to it, even if dir is / (see the "Note on page and dir query parameters" in App::ZofCMS::Config documentation). Basically, any pages listed here will not be processed by the plugin even if the plugin is listed in plugins first-level ZofCMS template key. By default is not set.

sort

sort => 0,

Optional. Currently accepts only true or false values. When set to a true value the comments on the page will be listed in the "oldest-first" fashion. When set to a false value the comments will be reversed - "newest-first" sorting. Defaults to: 0.

table

table => 'comments',

Optional. Takes a string as a value which must contain the name of SQL table used for storage of comments. See THE SQL TABLES! section above for details. Defaults to: comments

mod_table

mod_table => 'mod_comments',

Optional. Same as table argument (see above) except this one specifies the name of "moderation table", i.e. the comments awaiting moderation will be stored in this SQL table. Defaults to: mod_comments

must_name, must_email and must_comment

must_name    => 0,
must_email   => 0,
must_comment => 1,

Optional. The "post comment" form generated by the plugin contains the Name, E-mail and Comment fields. The must_name, must_email and must_comment arguments take either true or false values. When set to a true value, the visitor must fill the corresponding field in order to post the comment. If field is spefied as "optional" (by setting a false value) and the visitor doesn't fill it, it will default to N/A. By default must_name and must_email are set to false values and must_comment is set to a true value.

name_max, email_max and comment_max

name_max    => 100,
email_max   => 200,
comment_max => 10000,

Optional. Same principle as with must_* arguments explained above, except *_max arguments specify the maximum length of the fields. If visitor enters more than specified by the corresponding *_max argument, he or she (hopefully no *it*s) will get an error. By default name_max is set to 100, email_max is set to 200 and comment_max is set to 10000.

moderate

moderate => 1,

Optional. Takes either true or false values. When set to a true value will enable "moderation" functionality. See COMMENT MODERATION section above for details. When set to a false value, comments will appear on the page right away. Note: when set to a true value e-mail will be automatically sent to email_to addresses. Defaults to: 1

send_entered

send_entered => 1,

Optional. Takes either true or false values, regarded only when moderate argument is set to a false value. When set to a true value will dispatch an e-mail about a new comment to the addresses set in email_to argument. Defaults to: 1

subject

subject => 'ZofCMS Comments',

Optional. Takes a string as a value. Nothing fancy, this will be the "Subject" of the e-mails sent by the plugin (see moderate and send_entered arguments). Defaults to: 'ZofCMS Comments'

flood_num

flood_num => 2,

Optional. Takes a positive integer or zero as a value. Indicates how many comments a visitor may post in flood_time (see below) amount of time. Setting this value to 0 effectively disables flood protection. Defaults to: 2

flood_time

flood_time => 180,

Optional. Takes a positive integer as a value. Specifies the time in seconds during which the visitor may post only flood_num (see above) comments. Defaults to: 180

mod_out_time

mod_out_time => 1209600,

Optional. Takes a positive integer or false value as a value. When set to a positive integer indicates how old (in seconds) the comment in mod_table must get before it will be automatically removed from the mod_table (i.e. "denied"). Comments older than mod_out_time seconds will not actually be deleted until moderation takes place, i.e. until you approve or deny some comment. Setting this value to 0 effectively disables this "auto-delete" feature. Defaults to: 1209600 (two weeks)

EXAMPLES

The examples/ directory of this distribution contains main config file and HTML/ZofCMS templates which were used during testing of this plugin.

PREREQUISITES

This plugin requires more goodies than any other ZofCMS plugin to the date. Plugin needs the following modules for happy operation. Plugin was tested with module versions indicated:

'DBI'            => 1.602,
'URI'            => 1.35,
'HTML::Template' => 2.9,
'HTML::Entities' => 1.35,
'Storable'       => 2.18,
'Mail::Send'     => 2.04,

App::ZofCMS::Plugin::ConditionalRedirect (version 0.0101)

NAME

Link: App::ZofCMS::Plugin::ConditionalRedirect

App::ZofCMS::Plugin::ConditionalRedirect - redirect users based on conditions

SYNOPSIS

In Main Config file or ZofCMS template:

plugins => [ qw/ConditionalRedirect/ ],
plug_redirect => sub { time() % 2 ? 'http://google.com/' : undef },

DESCRIPTION

The module is a plugin for App::ZofCMS. It provides means to redirect user to pages depending on certain conditions, e.g. some key having a value in ZofCMS Template hashref or anything else, really.

This documentation assumes you've read App::ZofCMS, App::ZofCMS::Config and App::ZofCMS::Template

MAIN CONFIG FILE AND ZofCMS TEMPLATE KEYS

plugins

plugins => [ qw/ConditionalRedirect/ ],

plugins => [ { UserLogin => 1000 }, { ConditionalRedirect => 2000 } ],

The obvious is that you'd want to stick this plugin into the list of plugins to be executed. However, since functionality of this plugin can be easily implemented using exec and exec_before special keys in ZofCMS Template, being able to set the priority to when the plugin should be run would probably one of the reasons for you to use this plugin (it was for me at least).

plug_redirect

plug_redirect => sub {
    my ( $template_ref, $query_ref, $config_obj ) = @_;
    return $template_ref->{foo} ? 'http://google.com/' : undef;
}

The plug_redirect first-level key in Main Config file or ZofCMS Template takes a subref as a value. The sub will be executed and its return value will determine where to redirect (if at all). Returning undef from this sub will NOT cause any redirects at all. Returning anything else will be taken as a URL to which to redirect and the plugin will call exit() after printing the redirect headers.

The @_ of the sub will receive the following: ZofCMS Template hashref, query parameters hashref and App::ZofCMS::Config object (in that order).

If you set plug_redirect in both Main Config File and ZofCMS Template, the one in ZofCMS Template will take precedence.

App::ZofCMS::Plugin::Cookies (version 0.0103)

NAME

Link: App::ZofCMS::Plugin::Cookies

App::ZofCMS::Plugin::Cookies - HTTP Cookie handling plugin for ZofCMS

SYNOPSIS

In your ZofCMS template, or in your main config file (under template_defaults or dir_defaults):

set_cookies => [
    [ 'name', 'value' ],
    {
        -name    => 'sessionID',
        -value   => 'xyzzy',
        -expires => '+1h',
        -path    => '/cgi-bin/database',
        -domain  => '.capricorn.org',
        -secure  => 1,
    },
],

DESCRIPTION

This module is a plugin for App::ZofCMS which provides means to read and set HTTP cookies.

SETTING COOKIES

# example 1
set_cookies => [ 'name', 'value' ],

# OR

# example 2
set_cookies => {
        -name    => 'sessionID',
        -value   => 'xyzzy',
        -expires => '+1h',
        -path    => '/cgi-bin/database',
        -domain  => '.capricorn.org',
        -secure  => 1,
},

# OR

# example 3
set_cookies => [
    [ 'name', 'value' ],
    {
        -name    => 'sessionID',
        -value   => 'xyzzy',
        -expires => '+1h',
        -path    => '/cgi-bin/database',
        -domain  => '.capricorn.org',
        -secure  => 1,
    },
],

To set cookies use set_cookies first level key of your ZofCMS template. It's value can be either an arrayref or a hashref. When the value is an arrayref elements of which are not arrayrefs or hashrefs (example 1 above), or when the value is a hashref (example 2 above) it is encapsulated into an arrayref automatically to become as shown in (example 3 above). With that in mind, each element of an arrayref, which is a value of set_cookies key, specifies a certain cookie which plugin must set. When element of that arrayref is an arrayref, it must contain two elements. The first element will be the name of the cookie and the second element will be the value of the cookie. In other words:

set_cookies => [ 'name', 'value', ]

# which is the same as

set_cookies => [ [ 'name', 'value', ]

# which is the same as

CGI->new->cookie( -name => 'name', -value => 'value' );

When the element is a hashref, it will be dereferenced directy into CGI's cookie() method, in other words:

set_cookies => { -name => 'name', -value => 'value' }

# is the same as

CGI->new->cookie( -name => 'name', -value => 'value' );

See documentation of CGI module for possible values.

If set_cookies key is not present, no cookies will be set.

READING COOKIES

All of the cookies are read by the plugin automatically and put into {d}{cookies} (the special key {d} (data) of your ZofCMS template)

You can read those either via exec code (NOT exec_before, plugins are run after) (If you don't know what exec or exec_before are read App::ZofCMS::Template). Other plugins can also read those cookies, just make sure they are run after the Cookies plugin is run (set higher priority number). Below is an example of reading a cookie and displaying it's value in your HTML::Template template using App::ZofCMS::Plugin::Tagged plugin.

# In your ZofCMS template:

    plugins     => [ { Cookies => 10 }, { Tagged => 20 }, ],
    set_cookies => [ foo => 'bar' ],
    t => {
        cookie_foo => '<TAG:TNo cookies:{d}{cookies}{foo}>',
    },

# In one of your HTML::Template templates which are referenced by
# ZofCMS plugin above:

Cookie 'foo': <tmpl_var name="cookie_foo">

When this page is run the first time, no cookies are set, thus {d}{cookies} will be empty and you will see the default value of "No cookies" which we set in Tagged's tag:

Cookie 'foo': No cookies

When the page s run the second time, Cookies plugin will read cookie 'foo' which it set on the first run and will stick its value into {d}{cookies}{foo}. Our Tagged tag will read that value and enter it into the <tmpl_var> we allocated in HTML::Template plugin, thus the result will be:

Cookie 'foo': bar

That's all there is to it, enjoy!

App::ZofCMS::Plugin::DBI (version 0.0202)

NAME

Link: App::ZofCMS::Plugin::DBI

App::ZofCMS::Plugin::DBI - DBI access from ZofCMS templates

SYNOPSIS

In your main config file or ZofCMS template:

dbi => {
    dsn     => "DBI:mysql:database=test;host=localhost",
    user    => 'test', # user,
    pass    => 'test', # pass
    opt     => { RaiseError => 1, AutoCommit => 0 },
},

In your ZofCMS template:

dbi => {
    dbi_get => {
        layout  => [ qw/name pass/ ],
        sql     => [ 'SELECT * FROM test' ],
    },
    dbi_set => sub {
        my $query = shift;
        if ( defined $query->{user} and defined $query->{pass} ) {
            return [
                [ 'DELETE FROM test WHERE name = ?;', undef, $query->{user}      ],
                [ 'INSERT INTO test VALUES(?,?);', undef, @$query{qw/user pass/} ],
            ];
        }
        elsif ( defined $query->{delete} and defined $query->{user_to_delete} ) {
            return [ 'DELETE FROM test WHERE name =?;', undef, $query->{user_to_delete} ];
        }
        return;
    },
},

In your HTML::Template template:

<form action="" method="POST">
    <div>
        <label for="name">Name: </label>
        <input id="name" type="text" name="user" value="<tmpl_var name="query_user">"><br>
        <label for="pass">Pass: </label>
        <input id="pass" type="text" name="pass" value="<tmpl_var name="query_pass">"><br>
        <input type="submit" value="Add">
    </div>
</form>

<table>
    <tmpl_loop name="dbi_var">
        <tr>
            <td><tmpl_var name="name"></td>
            <td><tmpl_var name="pass"></td>
            <td>
                <form action="" method="POST">
                    <div>
                        <input type="hidden" name="user_to_delete" value="<tmpl_var name="name">">
                        <input type="submit" name="delete" value="Delete">
                    </div>
                </form>
            </td>
        </tr>
    </tmpl_loop>
</table>

DESCRIPTION

Module is a App::ZofCMS plugin which provides means to retrieve and push data to/from SQL databases using DBI module.

Current functionality is limited. More will be added as the need arrises, let me know if you need something extra.

This documentation assumes you've read App::ZofCMS, App::ZofCMS::Config and App::ZofCMS::Template

DSN AND CREDENTIALS

dbi => {
    dsn     => "DBI:mysql:database=test;host=localhost",
    user    => 'test', # user,
    pass    => 'test', # pass
    opt     => { RaiseError => 1, AutoCommit => 0 },
},

You can set these either in your ZofCMS template's dbi key or in your main config file's dbi key. The key takes a hashref as a value. The keys/values of that hashref are as follows:

dsn

dsn => "DBI:mysql:database=test;host=localhost",

Specifies the DSN for DBI, see DBI for more information on what to use here.

user and pass

user    => 'test', # user,
pass    => 'test', # pass

The user and pass key should contain username and password for the database you will be accessing with your plugin.

opt

opt => { RaiseError => 1, AutoCommit => 0 },

The opt key takes a hashref of any additional options you want to pass to connect_cached DBI's method.

RETRIEVING FROM AND SETTING DATA IN THE DATABASE

In your ZofCMS template the first-level dbi key accepts a hashref two possible keys: dbi_get for retreiving data from database and dbi_set for setting data into the database. Note: you can also have your dsn, user, pass and opt keys here if you wish.

dbi_get

dbi => {
    dbi_get => {
        layout  => [ qw/name pass/ ],
        single  => 1,
        sql     => [ 'SELECT * FROM test' ],
    },
}

dbi => {
    dbi_get => [
        {
            layout  => [ qw/name pass/ ],
            sql     => [ 'SELECT * FROM test' ],
        },
        {
            layout  => [ qw/name pass time info/ ],
            sql     => [ 'SELECT * FROM bar' ],
        },
    ],
}

The dbi_get key takes either a hashref or an arrayref as a value. If the value is a hashref it is the same as having just that hashref inside the arrayref. Each element of the arrayref must be a hashref with instructions on how to retrieve the data. The possible keys/values of that hashref are as follows:

layout

layout  => [ qw/name pass time info/ ],

Mandatory. Takes an arrayref as an argument. Specifies the name of <tmpl_var name="">s in your <tmpl_loop> (see type argument below) to which map the columns retrieved from the database, see SYNOPSIS section above.

sql

sql => [ 'SELECT * FROM bar' ],

Mandatory. Takes an arrayref as an argument which will be directly dereferenced into the DBI's method call specified by method argument (see below). See App::ZofCMS::Plugin::Tagged for possible expansion of possibilities you have here.

single

single => 1,

Optional. Takes either true or false values. Normally, the plugin will make a datastructure suitable for a <tmpl_loop name="">; however, if you expecting only one row from the table to be returned you can set single parameter to a true value and then the plugin will stuff appropriate values into {t} special hashref where keys will be the names you specified in the layout argument and values will be the values of the first row that was fetched from the database. By default is not specified (false)

type

dbi_get => {
    type    => 'loop'
...

Optional. Specifies what kind of a HTML::Template variable to generate from database data. Currently the only supported value is loop which generates <tmpl_loop> for yor HTML::Template template. Defaults to: loop

name

dbi_get => {
    name    => 'the_var_name',
...

Optional. Specifies the name of the key in the cell (see below) into which to stuff your data. With the default cell argument this will be the name of a HTML::Template var to set. Defaults to: dbi_var

method

dbi_get => {
    method => 'selectall',
...

Optional. Specifies with which DBI method to retrieve the data. Currently the only supported value for this key is selectall which uses selectall_arrayref. Defaults to: selectall

cell

dbi_get => {
    cell => 't'
...

Optional. Specifies the ZofCMS template's first-level key in which to create the name key with data from the database. cell must point to a key with a hashref in it (though, keep autovivification in mind). Possibly the sane values for this are either t or d. Defaults to: t (the data will be available in your HTML::Template templates)

dbi_set

dbi_set => sub {
    my $query = shift;
    if ( defined $query->{user} and defined $query->{pass} ) {
        return [
            [ 'DELETE FROM test WHERE name = ?;', undef, $query->{user}      ],
            [ 'INSERT INTO test VALUES(?,?);', undef, @$query{qw/user pass/} ],
        ];
    }
    elsif ( defined $query->{delete} and defined $query->{user_to_delete} ) {
        return [ 'DELETE FROM test WHERE name =?;', undef, $query->{user_to_delete} ];
    }
    return;
},

dbi_set => [
    'DELETE FROM test WHERE name = ?;', undef, 'foos'
],

dbi_set => [
    [ 'DELETE FROM test WHERE name = ?;', undef, 'foos' ],
    [ 'INSERT INTO test VALUES(?, ?);', undef, 'foos', 'bars' ],
]

Note: the dbi_set will be processed before dbi_get. Takes either a subref or an arrayref as an argument. Multiple instructions can be put inside an arrayref as the last example above demonstrates. Each arrayref will be directly dereferenced into DBI's do() method. Each subref must return either a single scalar, an arrayref or an arrayref of arrayrefs. Returning a scalar is the same as returning an arrayref with just that scalar in it. Returning just an arrayref is the same as returning an arrayref with just that arrayref in it. Each arrayref of the resulting arrayref will be directly dereferenced into DBI's do() method. The subrefs will have the following in their @_ when called: $query, $template, $config, $dbh. Where $query is a hashref of query parameters in which keys are the name of the parameters and values are values. $template is a hashref of your ZofCMS template. $config is the App::ZofCMS::Config object and $dbh is DBI's database handle object.

App::ZofCMS::Plugin::Debug::Dumper (version 0.0101)

NAME

Link: App::ZofCMS::Plugin::Debug::Dumper

App::ZofCMS::Plugin::Debug::Dumper - small debugging plugin that Data::Dumper::Dumper()s interesting portions into {t}

SYNOPSIS

In your Main Config file or ZofCMS Template:

plugins => [ qw/Debug::Dumper/ ],

In your HTML::Template template:

Dump of {t} key: <tmpl_var name="dumper_tt">
Dump of {d} key: <tmpl_var name="dumper_td">
Dump of ZofCMS template: <tmpl_var name="dumper_t">
Dump of query: <tmpl_var name="dumper_q">
Dump of main config: <tmpl_var name="dumper_c">

DESCRIPTION

The module is a small debugging plugin for App::ZofCMS. It uses Data::Dumper to make dumps of 5 things and sticks them into {t} ZofCMS template key so you could display the dumps in your HTML::Template template for debugging purposes.

This documentation assumes you've read App::ZofCMS, App::ZofCMS::Config and App::ZofCMS::Template

MAIN CONFIG FILE OR ZofCMS TEMPLATE

plugins

plugins => [ qw/Debug::Dumper/ ],

plugins => [ { UserLogin => 100 }, { 'Debug::Dumper' => 200 } ],

You need to add the plugin to the list of plugins to execute (duh!). By setting the priority of the plugin you can make dumps before or after some plugins executed.

plug_dumper

plug_dumper => {
    t_prefix    => 'dumper_',
    use_qq      => 1,
    pre         => 1,
    escape_html => 1,
    line_length => 80,
},

The plugin takes configuration via plug_dumper first-level key that can be either in ZofCMS template or Main Config file, same keys set in ZofCMS template will override those keys set in Main Config file. As opposed to many ZofCMS plugins, App::ZofCMS::Plugin::Debug::Dumper will still execute even if the plug_dumper key is not set to anything.

The plug_dumper key takes a hashref as a value. Possible keys/values of that hashref are as follows:

t_prefix

{ t_prefix => 'dumper_', }

Optional. The t_prefix specifies the string to use to prefix the names of the HTML::Template variables generated by the plugin in {t} ZofCMS Template key. See HTML::Template VARIABLES section below for more information. Defaults to: dumper_ ( note the underscore at the end)

use_qq

{ use_qq => 1, }

Optional. Can be set to either true or false values. When set to a true value, the plugin will set $Data::Dumper::Useqq to 1 before making the dumps, this will basically make, e.g. "\n"s instead of generating real new lines in output. See Data::Dumper for more information. Defaults to: 1

pre

{ pre => 1, }

Optional. Can be set to either true or false values. When set to a true value the plugin will wrap all the generated dumps into HTML <pre></pre> tags. Defaults to: 1

escape_html

{ escape_html => 1, }

Optional. Can be set to either true or false values. When set to a true value the plugin will escape HTML code in the dumps. Defaults to: 1

line_length

{ line_length => 150, }

Optional. The line_length key takes a positive integer as a value. This value will specify the maximum length of each line in generated dumps. Strictly speaking it will stick a \n after every line_length characters that are not \n. Special value or 0 will disable line length feature. Defaults to: 150

HTML::Template VARIABLES

The plugin will stick the generated dumps in the {t} ZofCMS template special key; that means that you can dump them out in your HTML::Template templates with <tmpl_var name"">s. The following five variables are available so far:

Dump of {t} key: <tmpl_var name="dumper_tt">
Dump of {d} key: <tmpl_var name="dumper_td">
Dump of ZofCMS template: <tmpl_var name="dumper_t">
Dump of query: <tmpl_var name="dumper_q">
Dump of main config: <tmpl_var name="dumper_c">

The {t} and {d} keys refer to special keys in ZofCMS Templates. The query is the hashref of query parameters passed to the script and main config is your Main Config file hashref. The dumper_ prefix in the <tmpl_var name="">s above is the t_prefix that you can set in plug_dumper configuration key (explained way above). In other words, in your main config file or ZofCMS template you can set: plug_dumper => { t_prefix => '_' } and in HTML::Template templates you'd then use <tmpl_var name="_tt">, <tmpl_var name="_q">, etc.

The names are generated by using $t_prefix . $name, where $t_prefix is t_prefix set in plug_dumper and $name is one of the "variable names" that are as follows:

tt

<tmpl_var name="dumper_tt">

The dump of {t} ZofCMS template special key. Mnemonic: template {t} key.

td

<tmpl_var name="dumper_td">

The dump of {d} ZofCMS template special key. Mnemonic: template {d} key.

t

<tmpl_var name="dumper_t">

The dump of entire ZofCMS template hashref. Mnemonic: template.

q

<tmpl_var name="dumper_q">

The dump of query parameters as a hashref, in parameter/value way. Mnemonic: query.

c

<tmpl_var name="dumper_c">

The dump of your Main Config file hashref. Mnemonic: config.

SPECIAL NOTES

Note that all properly behaving plugins will remove their config data from ZofCMS templates and Main Config files, that list includes this plugin as well, therefore when dumping the ZofCMS template (<tmpl_var name="dumper_t">) after the plugins were executed, you will not see the configuration for those plugins that you wrote.

SEE ALSO

Data::Dumper

App::ZofCMS::Plugin::DirTreeBrowse (version 0.0101)

NAME

Link: App::ZofCMS::Plugin::DirTreeBrowse

App::ZofCMS::Plugin::DirTreeBrowse - plugin to display browseable directory tree

SYNOPSIS

SIMPLE VARIANT

In your Main Config file or ZofCMS Template:

plugins     => [ qw/DirTreeBrowse/ ],
plug_dir_tree => {
    auto_html => 1,
    start     => 'pics',
},

In you HTML::Template template:

<p>We are at: <tmpl_var escape='html' name='dir_tree_path'></p>
<tmpl_var name='dir_tree_auto'>

MORE FLEXIBLE VARIANT

In your Main Config file or ZofCMS Template:

plugins     => [ qw/DirTreeBrowse/ ],
plug_dir_tree => {
    start     => 'pics',
},

In your HTML::Template template:

<p>We are at: <tmpl_var escape='html' name='dir_tree_path'></p>

<ul>
    <tmpl_if name="dir_tree_back">
        <li><a href="/index.pl?page=/&dir_tree=<tmpl_var escape='html' name='dir_tree_back'>">UP</a></li>
    </tmpl_if>
<tmpl_loop name='dir_tree_list'>
    <li>
        <tmpl_if name="is_file">
        <a href="/<tmpl_var escape='html' name='path'>"><tmpl_var escape='html' name='name'></a>
        <tmpl_else>
        <a href="/index.pl?page=/&dir_tree=<tmpl_var escape='html' name='path'>"><tmpl_var escape='html' name='name'></a>
        </tmpl_if>
    </li>
</tmpl_loop>
</ul>

DESCRIPTION

The module is an App::ZofCMS plugin that provides means to display a browseable directory three (list of files and other dirs).

This documentation assumes you've read App::ZofCMS, App::ZofCMS::Config and App::ZofCMS::Template

MAIN CONFIG FILE AND ZofCMS TEMPLATE FIRST-LEVEL KEYS

plugins

plugins => [ qw/DirTreeBrowse/ ],

First and foremost, you'd obviously would want to add the plugin into the list of plugins to execute.

plug_dir_tree

plug_dir_tree => {
    start                  => 'pics',
    auto_html              => 'ul_class',
    re                     => qr/[.]jpg$/,
    q_name                 => 'dir_tree',
    t_prefix               => 'dir_tree_',
    display_path_separator => '/',
}

The plug_dir_tree takes a hashref as a value and can be set in either Main Config file or ZofCMS Template file. Keys that are set in both Main Config file and ZofCMS Template file will get their values from ZofCMS Template file. Possible keys/values of plug_dir_tree hashref are as follows:

start

plug_dir_tree => {
    start => 'pics',
},

Mandatory. Specifies the starting directory of the directory three you wish to browse. The directory is relative to your index.pl file and must be web-accessible.

auto_html

plug_dir_tree => {
    start       => 'pics',
    auto_html   => 'ul_class',
},

Optional. When set to a defined value will cause the plugin to generate directory tree HTML automatically, the value then will become the classname for the <ul> element that holds the list of files/dirs. See SYNOPSIS and HTML::Template VARIABLES sectons for more details. Note: the plugin does not append current query to links, so if you wish to add something to the query parameters

re

plug_dir_tree => {
    start => 'pics',
    re    => qr/[.]jpg$/,
}

Optional. Takes a regex (qr//) as a value. When specified only the files matching this regex will be in the list. Note that file and its path will be matched, e.g. pics/old_pics/foo.jpg

q_name

plug_dir_tree => {
    start  => 'pics',
    q_name => 'dir_tree',
}

Optional. The plugin uses one query parameter to reference its position in the directory tree. The q_name key specifies the name of that query parameter. Unless you are using the auto_html option, make sure that your links include this query parameter along with <tmpl_var name="path">. In other words, if your q_name is set to dir_tree you'd make your links: <a href="/index.pl?page=/page_with_this_plugin&dir_tree=<tmpl_var escape='html' name='path'>">. Defaults to: dir_tree

t_prefix

plug_dir_tree => {
    start    => 'pics',
    t_prefix => 'dir_tree_',
}

Optional. The t_prefix specifies the prefix to use for several keys that plugin creates in {t} ZofCMS Template special key. See HTML::Template VARIABLES section below for details. Defaults to: dir_tree_ (note the trailing underscore (_))

display_path_separator

plug_dir_tree => {
    start                  => 'pics',
    display_path_separator => '/',
}

Optional. One of the {t} keys generated by the plugin will contain the current path in the directory tree. If display_path_separator is specified, every / character in that current path will be replaced by whatever display_path_separator is set to. By default is not specified.

HTML::Template VARIABLES

The samples below assume that the plugin is run with all of its optional arguments set to defaults.

When auto_html is turned on

<p>We are at: <tmpl_var escape='html' name='dir_tree_path'></p>
<tmpl_var name='dir_tree_auto'>

dir_tree_path

<p>We are at: <tmpl_var escape='html' name='dir_tree_path'></p>

The <tmpl_var name='dir_three_path'> variable will contain the current path in the directory tree.

dir_tree_auto

<tmpl_var name='dir_tree_auto'>

The <tmpl_var name='dir_tree_auto'> is available when auto_html option is turned on in the plugin. The generated HTML code would be pretty much as the MORE FLEXIBLE VARIANT section in SYNOPSIS demonstrates.

When auto_html is turned off

<p>We are at: <tmpl_var escape='html' name='dir_tree_path'></p>
<ul>
    <tmpl_if name="dir_tree_back">
        <li><a href="/index.pl?page=/&dir_tree=<tmpl_var escape='html' name='dir_tree_back'>">UP</a></li>
    </tmpl_if>
<tmpl_loop name='dir_tree_list'>
    <li>
        <tmpl_if name="is_file">
        <a href="/<tmpl_var escape='html' name='path'>"><tmpl_var escape='html' name='name'></a>
        <tmpl_else>
        <a href="/index.pl?page=/&dir_tree=<tmpl_var escape='html' name='path'>"><tmpl_var escape='html' name='name'></a>
        </tmpl_if>
    </li>
</tmpl_loop>
</ul>

dir_tree_path

<p>We are at: <tmpl_var escape='html' name='dir_tree_path'></p>

The <tmpl_var name='dir_three_path'> variable will contain the current path in the directory tree.

dir_tree_back

<tmpl_if name="dir_tree_back">
    <li><a href="/index.pl?page=/&dir_tree=<tmpl_var escape='html' name='dir_tree_back'>">UP</a></li>
</tmpl_if>

The dir_tree_back will be available when the user browsed to some directory inside the start directory. It will contain the path to the parent directory so the user could traverse up the tree.

dir_tree_list

<tmpl_loop name='dir_tree_list'>
    <li>
        <tmpl_if name="is_file">
        <a href="/<tmpl_var escape='html' name='path'>"><tmpl_var escape='html' name='name'></a>
        <tmpl_else>
        <a href="/index.pl?page=/&dir_tree=<tmpl_var escape='html' name='path'>"><tmpl_var escape='html' name='name'></a>
        </tmpl_if>
    </li>
</tmpl_loop>

The dir_tree_list will contain data structure suitable for <tmpl_loop name="">. Each item of that loop would be an individual file or a directory. The variables that are available in that loop are as follows:

is_file

<tmpl_if name="is_file">
    <a target="_blank" href="/<tmpl_var escape='html' name='path'>"><tmpl_var escape='html' name='name'></a>
<tmpl_else>
    <a href="/index.pl?page=/&dir_tree=<tmpl_var escape='html' name='path'>"><tmpl_var escape='html' name='name'></a>
</tmpl_if>

The is_file will be set whenever the item is a file (as opposed to being a directory). As the example above shows, you'd use this variable as a <tmpl_if name=""> to adjust your links to open the file instead of trying to make the plugin "browse" that file as a directory.

path

<a href="/index.pl?page=/&dir_tree=<tmpl_var escape='html' name='path'>"><tmpl_var escape='html' name='name'></a>

The path variable will contain the path to the directory/file (including the name of that directory/file) starting from the start directory. You'd want to include that as a value of q_name query parameter so the user could traverse the dirs.

name

<a href="/index.pl?page=/&dir_tree=<tmpl_var escape='html' name='path'>"><tmpl_var escape='html' name='name'></a>

The name variable will contain just the name of the file/directory without it's path. You'd want to use this for for displaying the names of the files/dirs to the user.

App::ZofCMS::Plugin::Doctypes (version 0.0101)

NAME

Link: App::ZofCMS::Plugin::Doctypes

App::ZofCMS::Plugin::Doctypes - include DOCTYPEs in your pages without remembering how to spell them

SYNOPSIS

In your Main Config file:

template_defaults => {
    plugins => [ qw/Doctypes/ ],
},

In your HTML::Template files

<tmpl_var name="doctype HTML 4.01 Strict">

DESCRIPTION

If you are like me you definitely don't remember how to properly spell out the DOCTYPE (DOCument TYPE definition) in your pages and always rely on your editor or look it up. Well, fear no more! This little module contains all the common DTDs and will stuff them into {t} ZofCMS template's special key for you to use.

AVAILABLE DTDs

Below are examples of <tmpl_var name=""> that will be substituted into the actual doctypes. The names of the doctypes correspoding to each of those examples are self explanatory. Note: the plugin has two modes (for now). The basic mode is the default one, it will make only DTDs available under BASIC section. The extra mode will include more doctypes.

ENABLING 'EXTRA' MODE

To enable the extra mode: in your ZofCMS template, but most likely you'd want that in your main config file:

plugin_doctype => { extra => 1 },

This would be the first-level key in ZofCMS template as well as main config file.

'BASIC' MODE DTDs

<tmpl_var name="doctype HTML 4.01 Strict">
<tmpl_var name="doctype HTML 4.01 Transitional">
<tmpl_var name="doctype HTML 4.01 Frameset">
<tmpl_var name="doctype XHTML 1.0 Strict">
<tmpl_var name="doctype XHTML 1.0 Transitional">
<tmpl_var name="doctype XHTML 1.0 Frameset">
<tmpl_var name="doctype XHTML 1.1">

'EXTRA' MODE DTDs

<tmpl_var name="doctype XHTML Basic 1.0">
<tmpl_var name="doctype XHTML Basic 1.1">
<tmpl_var name="doctype HTML 2.0">
<tmpl_var name="doctype HTML 3.2">
<tmpl_var name="doctype MathML 1.01">
<tmpl_var name="doctype MathML 2.0">
<tmpl_var name="doctype XHTML + MathML + SVG">
<tmpl_var name="doctype SVG 1.0">
<tmpl_var name="doctype SVG 1.1 Full">
<tmpl_var name="doctype SVG 1.1 Basic">
<tmpl_var name="doctype SVG 1.1 Tiny">
<tmpl_var name="doctype XHTML + MathML + SVG Profile (XHTML as the host language)">
<tmpl_var name="doctype XHTML + MathML + SVG Profile (Using SVG as the host)">

App::ZofCMS::Plugin::FileList (version 0.0101)

NAME

Link: App::ZofCMS::Plugin::FileList

App::ZofCMS::Plugin::FileList - ZofCMS plugin to display lists of files

SYNOPSIS

In your Main Config file or ZofCMS template:

plugins     => [ qw/FileList/ ],
plug_file_list => {
    list => {
        list1 => 'pics',
        list2 => 'pics2',
    },
},

In your HTML::Template template:

<ul>
<tmpl_loop name='list1'>
    <li><a href="/<tmpl_var escape='html' name='path'>"><tmpl_var name='name'></a></li>
</tmpl_loop>
</ul>

<ul>
<tmpl_loop name='list2'>
    <li><a href="/<tmpl_var escape='html' name='path'>"><tmpl_var name='name'></a></li>
</tmpl_loop>
</ul>

DESCRIPTION

Module is a App::ZofCMS plugin which provides means to display lists of files.

This documentation assumes you've read App::ZofCMS, App::ZofCMS::Config and App::ZofCMS::Template

MAIN CONFIG FILE OR ZofCMS TEMPLATE FIRST-LEVEL KEYS

plugins

plugins => [ qw/FileList/ ],

You would definitely want to add the plugin into the list of plugins to execute :)

plug_file_list

plug_file_list => {
    name => 0,
    re   => qr/[.]jpg$/i,
    list => {
        list1 => 'pics',
        list2 => [ qw/pics2 pics3/ ],
    },
},

plug_file_list => {
    list => [ qw/pics pics2/ ],
},

plug_file_list => {
    list => 'pics',
},

You can specify the plug_file_list first-level key in either Main Config File or ZofCMS Template file. Specifying the same keys in both will lead to the ones set in ZofCMS Template take precedence.

The plug_file_list key takes a hashref as a value. Possible keys/values of that hashref are as follows:

list

plug_file_list => {
    list => {
        list1 => 'pics',
        list2 => [ qw/pics2 pics3/ ],
    },
},

plug_file_list => {
    list => [ qw/pics pics2/ ],
},

plug_file_list => {
    list => 'pics',
},

The list key specifies the directories in which to search for files. The value of that key can be either a hashref, arrayref or a scalar. If the value is not a hashref it will be converted into a hashref as follows:

plug_file_list => {
    list => 'pics', # a scalar
},

# same as

plug_file_list => {
    list => [ 'pics' ], # arrayref
},

# same as

# hashref with a key that has a scalar value
plug_file_list => {
    list => {
        plug_file_list => 'pics',
    }
},

# same as

# hashref with a key that has an arrayref value
plug_file_list => {
    list => {
        plug_file_list => [ 'pics' ],
    }
},

The hashref assigned to list (or converted from other values) takes the following meaning: the keys of that hashref are the names of the keys in {t} ZofCMS Template special key and the values are the lists (arrayrefs) of directories in which to search for files. See SYNOPSIS section for some examples. Note that default {t} key would be plug_file_list as is shown in conversion examples above.

re

plug_file_list => {
    re   => qr/[.]jpg$/i,
    list => 'pics',
},

Optional. The re argument takes a regex as a value (qr//). If specified only the files that match the regex will be listed. By default is not specified.

name

plug_file_list => {
    name => 0,
    list => 'foo',
},

Optional. Takes either true or false values, specifies whether or not to create the name <tmpl_var name=""> in the output. See HTML::Template TEMPLATES section below. Defaults to: 1 (*do* create)

HTML::Template TEMPLATES

In HTML::Template templates you'd show the file lists in the following fashion:

<ul>
<tmpl_loop name='plug_file_list'>
    <li><a href="/<tmpl_var escape='html' name='path'>"><tmpl_var name='name'></a></li>
</tmpl_loop>
</ul>

The name of the <tmpl_loop name=""> is what you specified (directly or indirectly) as keys in the list hashref (see above). Inside the loop there are two <tmpl_var name=""> that you can use:

<tmpl_var name='path'>

The <tmpl_var name='path'> will contain the path to the file, that is the directory you specified . '/' . file name.

<tmpl_var name='name'>

The <tmpl_var name='path'> (providing the name key in plug_file_list hashref is set to a true value) will contain just the filename of the file.

App::ZofCMS::Plugin::FileToTemplate (version 0.0101)

NAME

Link: App::ZofCMS::Plugin::FileToTemplate

App::ZofCMS::Plugin::FileToTemplate - read or do() files into ZofCMS Templates

SYNOPSIS

In your ZofCMS Template:

plugins => [ qw/FileToTemplate/ ],
t  => {
    foo => '<FTTR:index.tmpl>',
},

In you HTML::Template template:

<tmpl_var escape='html' name='foo'>

DESCRIPTION

The module is a plugin for App::ZofCMS; it provides functionality to either read (slurp) or do() files and stick them in place of "tags".. read on to understand more.

This documentation assumes you've read App::ZofCMS, App::ZofCMS::Config and App::ZofCMS::Template

ADDING THE PLUGIN

plugins => [ qw/FileToTemplate/ ],

Unlike many other plugins to run this plugin you barely need to include it in the list of plugins to execute.

TAGS

t  => {
    foo => '<FTTR:index.tmpl>',
    bar => '<FTTD:index.tmpl>',
},

Anywhere in your ZofCMS template you can use two "tags" that this plugin provides. Those "tags" will be replaced - depending on the type of tag - with either the contents of the file or the last value returned by the file.

Both tags are in format: opening angle bracket, name of the tag in capital letters, semicolon, filename, closing angle bracket. The filename is relative to your "templates" directory, i.e. the directory referenced by templates key in Main Config file.

<FTTR:filename>

t  => {
    foo => '<FTTR:index.tmpl>',
},

The <FTTR:filename> reads (slurps) the contents of the file and tag is replaced with those contents. You can have several of these tags as values. Be careful reading in large files with this tag. Mnemonic: File To Template Read.

<FTTD:filename>

t => {
    foo => '<FTTD:index.tmpl>',
},

The <FTTD:filename> tag will do() your file and the last returned value will be assigned to the value in which the tag appears, in other words, having foo => '<FTTD:index.tmpl>', and foo => '<FTTD:index.tmpl> blah blah blah', is the same. Using this tag, for example, you can add large hashrefs or config hashrefs into your templates without clobbering them. Note that if the do() cannot find your file or compilation of the file fails, the value with the tag will be replaced by the error message. Mnemomic: File To Template Do.

NON-CORE PREREQUISITES

The plugin requires one non-core module: Data::Transformer

App::ZofCMS::Plugin::FileUpload (version 0.0101)

NAME

Link: App::ZofCMS::Plugin::FileUpload

App::ZofCMS::Plugin::FileUpload - ZofCMS plugin to handle file uploads

SYNOPSIS

In your ZofCMS template:

file_upload => {
    query   => 'uploaded_file',
},
plugins => [ qw/FileUpload/ ],

In your HTML::Template template:

<tmpl_if name="upload_error">
    <p class="error">Upload failed: <tmpl_var name="upload_error">
</tmpl_if>
<tmpl_if name="upload_success">
    <p>Upload succeeded: <tmpl_var name="upload_filename"></p>
</tmpl_if>

<form action="" method="POST" enctype="multipart/form-data">
<div>
    <input type="file" name="uploaded_file">
    <input type="submit" value="Upload">
</div>
</form>

DESCRIPTION

The module is a ZofCMS plugin which provides means to easily handle file uploads.

This documentation assumes you've read App::ZofCMS, App::ZofCMS::Config and App::ZofCMS::Template

FIRST-LEVEL ZofCMS TEMPLATE KEYS

plugins

plugins => [ qw/FileUpload/ ],

First and obvious, you need to stick FileUpload in the list of your plugins.

file_upload

file_upload => {
    query   => 'upload',
    path    => 'zofcms_upload',
    name    => 'foos',
    ext     => '.html',
    content_type => 'text/html',
    on_success => sub {
        my ( $uploaded_file_name, $template, $query, $conf ) = @_;
        # do something useful
    }
},

# or

file_upload => [
    { query   => 'upload1', },
    { query   => 'upload2', },
    {}, # all the defaults
    {
        query   => 'upload4',
        name    => 'foos',
        ext     => '.html',
        content_type => 'text/html',
        on_success => sub {
            my ( $uploaded_file_name, $template, $query, $conf ) = @_;
            # do something useful
        }
    },
],

Plugin takes input from file_upload first level ZofCMS template key which takes an arrayref or a hashref as a value. Passing a hashref as a value is the same as passing an arrayref with just that hashref as an element. Each element of the given arrayref is a hashref which represents one file upload. The possible keys/values of those hashrefs are as follows:

query

{ query => 'zofcms_upload' },

Optional. Specifies the query parameter which is the file being uploaded, in other words, this is the value of the name="" attribute of the <input type="file".... Defaults to: zofcms_upload

path

{ path => 'zofcms_upload', }

Optional. Specifies directory (relative to index.pl) into which the plugin will store uploaded files. Defaults to: zofcms_upload

name

{ name => 'foos', }

Optional. Specifies the name (without the extension) of the local file into which save the uploaded file. Special value of [rand] specifies that the name should be random, in which case it will be created by calling rand() and time() and removing any dots from the concatenation of those two. Defaults to: [rand]

ext

{ ext => '.html', }

Optional. Specifies the extension to use for the name of local file into which the upload will be stored. By default is not specified and therefore the extension will be obtained from the name of the remote file.

content_type

{ content_type => 'text/html', }

{ content_type => [ 'text/html', 'image/jpeg' ], }

Optional. Takes either a scalar string or an arrayref of strings. Specifying a string is equivalent to specifying an arrayref with just that string as an element. Each element of the given arrayref indicates the allowed Content-Type of the uploaded files. If the Content-Type does not match allowed types the error will be shown (see HTML TEMPLATE VARS section below). By default all Content-Types are allowed.

on_success

on_success => sub {
    my ( $uploaded_file_name, $template, $query, $config ) = @_;
    # do something useful
}

Optional. Takes a subref as a value. The specified sub will be executed upon a successful upload. The @_ will contain the following elements: $uploaded_file_name, $template, $query, $config where $uploaded_file_name is the directory + name + extension of the local file into which the upload was stored, $template is a hashref of your ZofCMS template, $query is a hashref of query parameters and $config is the App::ZofCMS::Config object. By default is not specified.

HTML TEMPLATE VARS

Single upload:

<tmpl_if name="upload_error">
    <p class="error">Upload failed: <tmpl_var name="upload_error">
</tmpl_if>
<tmpl_if name="upload_success">
    <p>Upload succeeded: <tmpl_var name="upload_filename"></p>
</tmpl_if>

<form action="" method="POST" enctype="multipart/form-data">
<div>
    <input type="file" name="upload">
    <input type="submit" value="Upload">
</div>
</form>

Multi upload:

<tmpl_if name="upload_error0">
    <p class="error">Upload 1 failed: <tmpl_var name="upload_error0">
</tmpl_if>
<tmpl_if name="upload_success0">
    <p>Upload 1 succeeded: <tmpl_var name="upload_filename0"></p>
</tmpl_if>

<tmpl_if name="upload_error1">
    <p class="error">Upload 2 failed: <tmpl_var name="upload_error1">
</tmpl_if>
<tmpl_if name="upload_success1">
    <p>Upload 2 succeeded: <tmpl_var name="upload_filename1"></p>
</tmpl_if>

<form action="" method="POST" enctype="multipart/form-data">
<div>
    <input type="file" name="upload">
    <input type="file" name="upload2">
    <input type="submit" value="Upload">
</div>
</form>

NOTE: upload of multiple files from a single <input type="file"... is currently not supported. Let me know if you need such functionality. The folowing <tmpl_var name="">s will be set in your HTML::Template template.

SINGLE AND MULTI

If you are handling only one upload, i.e. you have only one hashref in file_upload ZofCMS template key and you have only one <input type="file"... then the HTML::Template variables described below will NOT have any trailing numbers, otherwise each of them will have a trailing number indicating the number of the upload. This number will starts from zero and it will correspond to the index of hashref of file_upload arrayref.

upload_error

# single
<tmpl_if name="upload_error">
    <p class="error">Upload failed: <tmpl_var name="upload_error">
</tmpl_if>

# multi
<tmpl_if name="upload_error0">
    <p class="error">Upload 1 failed: <tmpl_var name="upload_error0">
</tmpl_if>

The upload_error will be set if some kind of an error occurred during the upload of the file. This also includes if the user tried to upload a file of type which is not listed in content_type arrayref.

upload_success

# single
<tmpl_if name="upload_success">
    <p>Upload succeeded: <tmpl_var name="upload_filename"></p>
</tmpl_if>

# multi
<tmpl_if name="upload_success0">
    <p>Upload 1 succeeded: <tmpl_var name="upload_filename0"></p>
</tmpl_if>

The upload_success will be set to a true value upon successful upload.

upload_filename

# single
<tmpl_if name="upload_success">
    <p>Upload succeeded: <tmpl_var name="upload_filename"></p>
</tmpl_if>

# multi
<tmpl_if name="upload_success0">
    <p>Upload 1 succeeded: <tmpl_var name="upload_filename0"></p>
</tmpl_if>

The upload_filename will be set to directory + name + extension of the local file into which the upload was saved.

App::ZofCMS::Plugin::FormChecker (version 0.0301)

NAME

Link: App::ZofCMS::Plugin::FormChecker

App::ZofCMS::Plugin::FormChecker - plugin to check HTML form data.

SYNOPSIS

In ZofCMS template or main config file:

plugins => [ qw/FormChecker/ ],
plug_form_checker => {
    trigger     => 'some_param',
    ok_key      => 't',
    ok_code     => sub { die "All ok!" },
    fill_prefix => 'form_checker_',
    rules       => {
        param1 => 'num',
        param2 => qr/foo|bar/,
        param3 => [ qw/optional num/ ],
        param4 => {
            optional        => 1,
            select          => 1,
            must_match      => qr/foo|bar/,
            must_not_match  => qr/foos/,
            must_match_error => 'Param4 must contain either foo or bar but not foos',
            param           => 'param2',
        },
        param5 => {
            valid_values        => [ qw/foo bar baz/ ],
            valid_values_error  => 'Param5 must be foo, bar or baz',
        },
        param6 => sub { time() % 2 }, # return true or false values
    },
},

DESCRIPTION

The module is a plugin for App::ZofCMS that provides nifteh form checking.

This documentation assumes you've read App::ZofCMS, App::ZofCMS::Config and App::ZofCMS::Template

ZofCMS TEMPLATE/MAIN CONFIG FILE FIRST LEVEL KEYS

The keys can be set either in ZofCMS template or in Main Config file, if same keys are set in both, then the one in ZofCMS template takes precedence.

plugins

plugins => [ qw/FormChecker/ ],

You obviously would want to include the plugin in the list of plugins to execute.

plug_form_checker

# keys are listed for demostrative purposes,
# some of these don't make sense when used together
plug_form_checker => {
    trigger     => 'plug_form_checker',
    ok_key      => 'd',
    ok_redirect => '/some-page',
    ok_code     => sub { die "All ok!" },
    no_fill     => 1,
    fill_prefix => 'plug_form_q_',
    rules       => {
        param1 => 'num',
        param2 => qr/foo|bar/,
        param3 => [ qw/optional num/ ],
        param4 => {
            optional        => 1,
            select          => 1,
            must_match      => qr/foo|bar/,
            must_not_match  => qr/foos/,
            must_match_error => 'Param4 must contain either foo or bar but not foos',
        },
        param5 => {
            valid_values        => [ qw/foo bar baz/ ],
            valid_values_error  => 'Param5 must be foo, bar or baz',
        },
        param6 => sub { time() % 2 }, # return true or false values
    },
},

The plug_form_checker first-level key takes a hashref as a value. Only the rules key is mandatory, the rest are optional. The possible keys/values of that hashref are as follows.

trigger

trigger => 'plug_form_checker',

Optional. Takes a string as a value that must contain the name of the query parameter that would trigger checking of the form. Generally, it would be some parameter of the form you are checking (that would always contain true value, in perl's sense of true) or you could always use <input type="hidden" name="plug_form_checker" value="1">. Defaults to: plug_form_checker

ok_key

ok_key => 'd',

Optional. If the form passed all the checks plugin will set a second level key plug_form_checker to a true value. The ok_key parameter specifies the first level key in ZofCMS template where to put the plug_form_checker key. For example, you can set ok_key to 't' and then in your HTML::Template template use <tmpl_if name="plug_form_checker">FORM OK!</tmpl_if>... but, beware of using the 't' key when you are also using App::ZofCMS::QueryToTemplate plugin, as someone could avoid proper form checking by passing fake query parameter. Defaults to: d ("data" ZofCMS template special key).

ok_redirect

ok_redirect => '/some-page',

Optional. If specified, the plugin will automatically redirect the user to the URL specified as a value to ok_redirect key. Note that the plugin will exit() right after printing the redirect header. By default not specified.

ok_code

ok_code => sub {
    my ( $template, $query, $config ) = @_;
    $template->{t}{foo} = "Kewl!";
}

Optional. Takes a subref as a value. When specfied that subref will be executed if the form passes all the checks. The @_ will contain the following (in that order): hashref of ZofCMS Template, hashref of query parameters and App::ZofCMS::Config object. By default is not specified. Note: if you specify ok_code and ok_redirect the code will be executed and only then user will be redirected.

no_fill

no_fill => 1,

Optional. When set to a true value plugin will not fill query values. Defaults to: 0. When no_fill is set to a false value the plugin will fill in ZofCMS template's {t} special key with query parameter values (only the ones that you are checking, though, see rules key below). This allows you to fill your form with values that user already specified in case the form check failed. The names of the keys inside the {t} key will be formed as follows: $prefix . $query_param_name where $prefix is the value of fill_prefix key (see below) and $query_param_name is the name of the query parameter. Of course, this alone wouldn't cut it for radio buttons or <select> elements. For that, you need to set select => 1 in the ruleset for that particular query parameter (see rules key below); when select rule is set to a true value then the names of the keys inside the {t} key will be formed as follows: $prefix . $query_param_name . '_' . $value. Where the $prefix is the value of fill_prefix key, $query_param_name is the name of the query parameter; following is the underscore (_) and then $value that is the value of the query parameter. Consider the following snippet in ZofCMS template and corresponding HTML::Template HTML code as an example:

plug_form_checker => {
    trigger => 'foo',
    fill_prefix => 'plug_form_q_',
    rules => { foo => { select => 1 } },
}

<form action="" method="POST">
    <input type="text" name="bar" value="<tmpl_var name="plug_form_q_">">
    <input type="radio" name="foo" value="1"
        <tmpl_if name="plug_form_q_foo_1"> checked </tmpl_if>
    >
    <input type="radio" name="foo" value="2"
        <tmpl_if name="plug_form_q_foo_2"> checked </tmpl_if>
    >
</form>

fill_prefix

fill_prefix => 'plug_form_q_',

Optional. Specifies the prefix to use for keys in {t} ZofCMS template special key when no_fill is set to a false value. The "filling" is described above in no_fill description. Defaults to: plug_form_q_ (note the underscore at the very end)

rules

rules       => {
    param1 => 'num',
    param2 => qr/foo|bar/,
    param3 => [ qw/optional num/ ],
    param4 => {
        optional        => 1,
        select          => 1,
        must_match      => qr/foo|bar/,
        must_not_match  => qr/foos/,
        must_match_error => 'Param4 must contain either foo or bar but not foos',
    },
    param5 => {
        valid_values        => [ qw/foo bar baz/ ],
        valid_values_error  => 'Param5 must be foo, bar or baz',
    },
    param6 => sub { time() % 2 }, # return true or false values
},

This is the "heart" of the plugin, the place where you specify the rules for checking. The rules key takes a hashref as a value. The keys of that hashref are the names of the query parameters that you wish to check. The values of those keys are the "rulesets". The values can be either a string, regex (qr//), arrayref, subref, scalarref or a hashref; If the value is NOT a hashref it will be changed into hashref as follows (the actual meaning of resulting hashrefs is described below):

a string

param => 'num',
# same as
param => { num => 1 },

a regex

param => qr/foo/,
# same as
param => { must_match => qr/foo/ },

an arrayref

param => [ qw/optional num/ ],
# same as
param => {
    optional => 1,
    num      => 1,
},

a subref

param => sub { time() % 2 },
# same as
param => { code => sub { time() % 2 } },

a scalarref

param => \'param2',
# same as
param => { param => 'param2' },

rules RULESETS

The rulesets (values of rules hashref) have keys that define the type of the rule and value defines diffent things or just indicates that the rule should be considered. Here is the list of all valid ruleset keys:

rules => {
    param => {
        name            => 'Parameter', # the name of this param to use in error messages
        num             => 1, # value must be numbers-only
        optional        => 1, # parameter is optional
        must_match      => qr/foo/, # value must match given regex
        must_not_match  => qr/bar/, # value must NOT match the given regex
        max             => 20, # value must not exceed 20 characters in length
        min             => 3,  # value must be more than 3 characters in length
        valid_values    => [ qw/foo bar baz/ ], # value must be one from the given list
        code            => sub { time() %2 }, # return from the sub determines pass/fail
        select          => 1, # flag for "filling", see no_fill key above
        param           => 'param1',
        num_error       => 'Numbers only!', # custom error if num rule failed
        mandatory_error => '', # same for if parameter is missing and not optional.
        must_match_error => '', # same for must_match rule
        must_not_match_error => '', # same for must_not_match_rule
        max_error            => '', # same for max rule
        min_error            => '', # same for min rule
        code_error           => '', # same for code rule
        valid_values_error   => '', # same for valid_values rule
        param_error          => '', # same fore param rule
    },
}

You can mix and match the rules for perfect tuning.

name

name => 'Decent name',

This is not actually a rule but the text to use for the name of the parameter in error messages. If not specified the actual parameter name will be used.

num

num => 1,

When set to a true value the query parameter's value must contain digits only.

optional

optional => 1,

When set to a true value indicates that the parameter is optional. Note that you can specify other rules along with this one, e.g.:

optional => 1,
num      => 1,

Means, query parameter is optional, but if it is given it must contain only digits.

must_match

must_match => qr/foo/,

Takes a regex (qr//) as a value. The query parameter's value must match this regex.

must_not_match

must_not_match => qr/bar/,

Takes a regex (qr//) as a value. The query parameter's value must NOT match this regex.

max

max => 20,

Takes a positive integer as a value. Query parameter's value must not exceed max characters in length.

min

min => 3,

Takes a positive integer as a value. Query parameter's value must be at least min characters in length.

valid_values

valid_values => [ qw/foo bar baz/ ],

Takes an arrayref as a value. Query parameter's value must be one of the items in the arrayref.

code

code => sub { time() %2 },

Here you can let your soul dance to your desire. Takes a subref as a value. The @_ will contain the following (in that order): - the value of the parameter that is being tested, the hashref of ZofCMS Template, hashref of query parameters and the App::ZofCMS::Config object. If the sub returns a true value - the check will be considered successfull. If the sub returns a false value, then test fails and form check stops and errors.

param

param => 'param2',

Takes a string as an argument; that string will be interpreted as a name of a query parameter. Values of the parameter that is currently being inspected and the one given as a value must match in order for the rule to succeed. The example above indicates that query parameter param eq query parameter param2.

select

select => 1,

This one is not actually a "rule". This is a flag for {t} "filling" that is described in great detail (way) above under the description of no_fill key.

CUSTOM ERROR MESSAGES IN RULESETS

All *_error keys take strings as values; they can be used to set custom error messages for each test in the ruleset. In the defaults listed below under each *_error, the $name represents either the name of the parameter or the value of name key that you set in the ruleset.

num_error

num_error => 'Numbers only!',

This will be the error to be displayed if num test fails. Defaults to Parameter $name must contain digits only.

mandatory_error

mandatory_error => 'Must gimme!',

This is the error when optional is set to a false value, which is the default, and user did not specify the query parameter. I.e., "error to display for missing mandatory parameters". Defaults to: You must specify parameter $name

must_match_error

must_match_error => 'Must match me!',

This is the error for must_match rule. Defaults to: Parameter $name contains incorrect data

must_not_match_error

must_not_match_error => 'Cannot has me!',

This is the error for must_not_match rule. Defaults to: Parameter $name contains incorrect data

max_error

max_error => 'Too long!',

This is the error for max rule. Defaults to: Parameter $name cannot be longer than $max characters where $max is the max rule's value.

min_error

min_error => 'Too short :(',

This is the error for min rule. Defaults to: Parameter $name must be at least $rule-{min} characters long>

code_error

code_error => 'No likey 0_o',

This is the error for code rule. Defaults to: Parameter $name contains incorrect data

valid_values_error

valid_values_error => 'Pick the correct one!!!',

This is the error for valid_values rule. Defaults to: Parameter $name must be $list_of_values where $list_of_values is the list of the values you specified in the arrayref given to valid_values rule joined by commas and the last element joined by word "or".

param_error

param_error => "Two passwords do not match",

This is the error for param rule. You pretty much always would want to set a custom error message here as it defaults to: Parameter $name does not match parameter $rule->{param} where $rule->{param} is the value you set to param rule.

HTML::Template VARIABLES

<tmpl_if name="plug_form_checker_error">
    <p class="error"><tmpl_var name="plug_form_checker_error"></p>
</tmpl_if>

If the form values failed any of your checks, the plugin will set plug_form_checker_error key in {t} special key explaining the error. The sample usage of this is presented above.

App::ZofCMS::Plugin::FormFiller (version 0.0101)

NAME

Link: App::ZofCMS::Plugin::FormFiller

App::ZofCMS::Plugin::FormFiller - fill HTML form elements' values.

SYNOPSIS

In Main Config file or ZofCMS Template:

plugins => [ qw/FormFiller/ ],
plug_form_filler => {
    params => [ qw/nu_login nu_name nu_email nu_admin nu_aa nu_mm user/ ],
},

DESCRIPTION

The module provides filling of form elements from {t} ZofCMS Template special key or query parameters if those are specified.

This documentation assumes you've read App::ZofCMS, App::ZofCMS::Config and App::ZofCMS::Template

MAIN CONFIG FILE AND ZofCMS TEMPLATE FIRST-LEVEL KEYS

plugins

plugins => [ qw/FormFiller/ ],

Your obviously need to specify the name of the plugin in plugins arrayref for ZofCMS to execute the plugin. However, you'll probably be using another plugin, such as App::ZofCMS::Plugin::DBI to fill the {t} key first, thus don't forget to set right priorities.

plug_form_filler

plug_form_filler => {
    params => [ qw/login name email/ ],
},

plug_form_filler => {
    params => {
         t_login    => 'query_login',
         t_name     => 'query_name',
         t_email    => 'query_email',
    },
},

The plug_form_filler takes a hashref as a value. The possible keys/values of that hashref are as follows:

params

params => {
        t_login    => query_login,
        t_name     => query_name,
        t_email    => query_email,
},

params => [ qw/login name email/ ],
# same as
params => {
    login => 'login',
    name  => 'name',
    email => 'email',
},

Mandatory. The params key takes either a hashref or an arrayref as a value. If the value is an arrayref it will be converted to a hashref where keys and values are the same. The keys of the hashref will be interpreted as keys in the {t} ZofCMS Template special key and values will be interpreted as names of query parameters.

The idea of the plugin is that if query parameter (one of the specified in the params hashref/arrayref) has some value that is different from the corresponding value in the {t} hashref, the plugin will put that value into the {t} ZofCMS Template hashref. This allows you to do, for example, the following: fetch preset values from the database (using App::ZofCMS::Plugin::DBI perhaps) and present them to the user, if the user edits some fields you have have the preset values along with those changes made by the user.

App::ZofCMS::Plugin::FormToDatabase (version 0.0101)

NAME

Link: App::ZofCMS::Plugin::FormToDatabase

App::ZofCMS::Plugin::FormToDatabase - simple insertion of query into database

SYNOPSIS

In your Main Config file or ZofCMS template:

plugins => [ qw/FormToDatabase/ ],
plug_form_to_database => {
    go_field   => 'd|foo',
    values   => [ qw/one two/ ],
    table   => 'form',
    dsn     => "DBI:mysql:database=test;host=localhost",
    user    => 'test',
    pass    => 'test',
    opt     => { RaiseError => 1, AutoCommit => 0 },
},

DESCRIPTION

The module is a simple drop in to stick query into database. The module does not provide any parameter checking and is very basic. For anything more advanced check out App::ZofCMS::Plugin::DBI

This documentation assumes you have read App::ZofCMS, App::ZofCMS::Config and App::ZofCMS::Template

MAIN CONFIG FILE OR ZofCMS TEMPLATE FIRST LEVEL KEYS

plug_form_to_database => {
    go_field   => 'd|foo',
    values   => [ qw/one two/ ],
    table   => 'form',
    dsn     => "DBI:mysql:database=test;host=localhost",
    user    => 'test',
    pass    => 'test',
    opt     => { RaiseError => 1, AutoCommit => 0 },
},

Plugin uses the plug_form_to_database first-level key in ZofCMS template or your main config file. The key takes a hashref as a value. Values set under this key in ZofCMS template will override values set in main config file. Possible keys/values are as follows.

go_field

go_field => 'd|foo',

Optional. Defaults to: d|form_to_database. The go_field key specifies the "go" to the plugin; in other words, if value referenced by the string set under go_field key the plugin will proceed with stuffing your database, otherwise it will not do anything. Generally, you'd do some query checking with a plugin (e.g. App::ZofCMS::Plugin::FormChecker) with lower priority number (so it would be run first) and then set the value referenced by the go_field.

The go_field key takes a string as a value. The string is in format s|key_name - where s is the name of the "source". What follows the "source" letter is a pipe (|) and then they name of the key. The special value of source q (note that it is lowercase) means "query". That is q|foo means, "query parameter 'foo'". Other values of the "source" will be looked for inside ZofCMS template hash, e.g. d|foo means key foo in ZofCMS template special first-level key {d} - this is probably where you'd want to check that for.

Example:

# ZofCMS template:
plugins => [ qw/FormToDatabase/ ],
d       => { foo => 1 },
plug_form_to_database => {
    go_field => 'd|foo',
    ..... # omited for brevity
},

The example above will always stuff the query data into the database because key foo under key d is set to a true value and go_field references that value with d|foo.

values

values => [ qw/one two/ ],

Mandatory. The values key takes an arrayref as a value. The elements of that arrayref represent the names of query parameters that you wish to stick into the database. Under the hood of the module the following is being called:

$dbh->do(
    "INSERT INTO $conf{table} VALUES(" . join(q|, |, ('?')x@values) . ');',
    undef,
    @$query{ @values },
);

Where @values contains values you passed via values key and $dbh is the database handle created by DBI. If you want something more advanced consider using App::ZofCMS::Plugin::DBI instead.

table

table => 'form',

Mandatory. Specifies the name of the table into which you wish to store the data.

dsn

dsn => "DBI:mysql:database=test;host=localhost",

Mandatory. Specifies the dsn to use in DBI connect call. See documentation for DBI and DBD::your_database for proper syntax for this string.

user

user => 'test',

Mandatory. Specifies the user name (login) to use when connecting to the database.

pass

pass => 'test',

Mandatory. Specifies the password to use when connecting to the database.

opt

Optional. Specifies extra options to use in DBI's connect_cached() call. Defaults to: { RaiseError => 1, AutoCommit => 0 }

SEE ALSO

DBI, App::ZofCMS::Plugin::DBI

App::ZofCMS::Plugin::LinksToSpecs::CSS (version 0.0101)

NAME

Link: App::ZofCMS::Plugin::LinksToSpecs::CSS

App::ZofCMS::Plugin::LinksToSpecs::CSS - easily include links to properties in CSS2.1 specification

SYNOPSIS

In your ZofCMS template:

plugins => [ qw/LinksToSpecs::CSS/ ],

In your HTML::Template template:

See: <tmpl_var name="css_text-align"> for text-align property<br>
See: <tmpl_var name="css_display"> for display propery<br>
<tmpl_var name="css_float_p"> is quite neat

DESCRIPTION

The module is a plugin for ZofCMS which allows you to easily link to CSS properties in CSS2.1 specification. Personally, I use it when writing my tutorials, hopefully it will be useful to someone else as well.

ZofCMS TEMPLATE

plugins => [ qw/LinksToSpecs::CSS/ ],

The only thing you'd need in your ZofCMS template is to add the plugin into the list of plugins to execute.

HTML::Template TEMPLATE

See: <tmpl_var name="css_text-align"> for text-align property<br>
See: <tmpl_var name="css_display"> for display propery<br>
<tmpl_var name="css_float_p"> is quite neat

To include links to CSS properties in your HTML code you'd use <tmpl_var name="">. The plugin provides four "styles" of links which are presented below. The PROP stands for any CSS property specified in CSS2.1 specification, LINK stands for the link pointing to the explaination of the given property in CSS specification. Note: everything needs to be lowercased:

<tmpl_var name="css_PROP">
<a href="LINK" title="CSS Specification: 'PROP' property"><code>PROP</code></a>

<tmpl_var name="css_PROP_p">
<a href="LINK" title="CSS Specification: 'PROP' property"><code>PROP</code> property</a>

<tmpl_var name="css_PROP_c">
<a href="LINK" title="CSS Specification: 'PROP' property">PROP</a>

<tmpl_var name="css_PROP_cp">
<a href="LINK" title="CSS Specification: 'PROP' property">PROP property</a>

SEE ALSO

http://w3.org/Style/CSS/

App::ZofCMS::Plugin::LinksToSpecs::HTML (version 0.0101)

NAME

Link: App::ZofCMS::Plugin::LinksToSpecs::HTML

App::ZofCMS::Plugin::LinksToSpecs::HTML - easily include links to elements in HTML 4.01 specification

SYNOPSIS

In your ZofCMS template:

plugins => [ qw/LinksToSpecs::HTML/ ],

In your HTML::Template template:

See: <tmpl_var name="html_div"> for div element<br>
See: <tmpl_var name="html_blockquote"> for blockquote element<br>
<tmpl_var name="html_a_ce"> is used for links.

DESCRIPTION

The module is a plugin for ZofCMS which allows you to easily link to HTML elements in HTML 4.01 specification. Personally, I use it when writing my tutorials, hopefully it will be useful to someone else as well.

ZofCMS TEMPLATE

plugins => [ qw/LinksToSpecs::HTML/ ],

The only thing you'd need in your ZofCMS template is to add the plugin into the list of plugins to execute.

HTML::Template TEMPLATE

See: <tmpl_var name="html_div"> for div element<br>
See: <tmpl_var name="html_blockquote"> for blockquote element<br>
<tmpl_var name="html_a_ce"> is used for links.

To include links to HTML elements in your HTML code you'd use <tmpl_var name="">. The plugin provides four "styles" of links which are presented below. The EL stands for any HTML element specified in HTML 4.01 specification, LINK stands for the link pointing to the explaination of the given element in HTML specification. Note: everything needs to be lowercased:

<tmpl_var name="html_EL">
<a href="LINK" title="HTML Specification: '&amp;lt;EL&amp;gt;' element"><code>&amp;lt;EL&amp;gt;</code></a>

<tmpl_var name="html_EL_e">
<a href="LINK" title="HTML Specification: '&amp;lt;EL&amp;gt;' element"><code>&amp;lt;EL&amp;gt;</code> element</a>

<tmpl_var name="html_EL_c">
<a href="LINK" title="HTML Specification: '&amp;lt;EL&amp;gt;' element">&amp;lt;EL&amp;gt;</a>

<tmpl_var name="html_EL_ce">
<a href="LINK" title="HTML Specification: '&amp;lt;EL&amp;gt;' element">&amp;lt;EL&amp;gt; element</a>

SEE ALSO

http://www.w3.org/TR/html4/

App::ZofCMS::Plugin::NavMaker (version 0.0102)

NAME

Link: App::ZofCMS::Plugin::NavMaker

App::ZofCMS::Plugin::NavMaker - ZofCMS plugin for making navigation bars

SYNOPSIS

In your ZofCMS Template:

nav_maker => [
    qw/Foo Bar Baz/,
    [ qw(Home /home) ],
    [ qw(Music /music) ],
    [ qw(foo /foo-bar-baz), 'This is the title=""', 'this_is_id' ],
],
plugins => [ qw/NavMaker/ ],

In your HTML::Template template:

<tmpl_var name="nav_maker">

Produces this code:

<ul id="nav">
        <li id="nav_foo"><a href="/foo" title="Visit Foo">Foo</a></li>
        <li id="nav_bar"><a href="/bar" title="Visit Bar">Bar</a></li>
        <li id="nav_baz"><a href="/baz" title="Visit Baz">Baz</a></li>
        <li id="nav_home"><a href="/home" title="Visit Home">Home</a></li>
        <li id="nav_music"><a href="/music" title="Visit Music">Music</a></li>
        <li id="this_is_id"><a href="/foo-bar-baz" title="This is the title=&quot;&quot;">foo</a></li>
</ul>

DESCRIPTION

The plugin doesn't do much but after writing HTML code for hundreds of navigation bars I was fed up... and released this tiny plugin.

This documentation assumes you've read App::ZofCMS, App::ZofCMS::Config and App::ZofCMS::Template

FIRST LEVEL ZofCMS TEMPLATE KEYS

plugins

plugins => [ qw/NavMaker/ ],

The obvious one is that you'd want to add NavMaker into the list of your plugins.

nav_maker

nav_maker => [
    qw/Foo Bar Baz/,
    [ qw(Home /home) ],
    [ qw(Music /music) ],
    [ qw(foo /foo-bar-baz), 'This is the title=""', 'this_is_id' ],
],

Takes an arrayref as a value elements of which can either be strings or arrayrefs, element which is a string is the same as an arrayref with just that string as an element. Each of those arrayrefs can contain from one to four elements. They are interpreted as follows:

first element

nav_maker => [ qw/Foo Bar Baz/ ],

# same as

nav_maker => [
    [ 'Foo' ],
    [ 'Bar' ],
    [ 'Baz' ],
],

Mandatory. Specifies the text to use for the link.

second element

nav_maker => [
    [ Foo => '/foo' ],
],

Optional. Specifies the href="" attribute for the link. If not specified will be calculated from the first element (the text for the link) in the following way:

$text =~ s/[\W_]/-/g;
return lc "/$text";

third element

nav_maker => [
    [ 'Foo', '/foo', 'Title text' ],
],

Optional. Specifies the title="" attribute for the link. If not specified the first element (the text for the link) will be used for the title with word Visit prepended.

fourth element

nav_maker => [
    [ 'Foo', '/foo', 'Title text', 'id_of_the_li' ]
],

Optional. Specifies the id="" attribute for the <li> element of this navigation bar item. If not specified will be calculated from the first element (the text of the link) in the following way:

$text =~ s/\W/_/g;
return lc "nav_$text";

USED HTML::Template VARIABLES

nav_maker

<tmpl_var name="nav_maker">

Plugin sets nav_maker key in {t} ZofCMS template special key, to the generated HTML code, simply stick <tmpl_var name="nav_maker"> whereever you wish to have your navigation.

App::ZofCMS::Plugin::QueryToTemplate (version 0.0102)

NAME

Link: App::ZofCMS::Plugin::QueryToTemplate

App::ZofCMS::Plugin::QueryToTemplate - ZofCMS plugin to automagically make query parameters available in the template

SYNOPSIS

In your ZofCMS template, or in your main config file (under template_defaults or dir_defaults):

plugins => [ qw/QueryToTemplate/ ];

In any of your HTML::Template templates:

<tmpl_var name="query_SOME_QUERY_PARAMETER_NAME">

DESCRIPTION

Plugin can be run at any priority level and it does not take any input from ZofCMS template.

Upon plugin's execution it will stuff the {t} first level key (see App::ZofCMS::Template if you don't know what that key is) with all the query parameters as keys and values being the parameter values. Each query parameter key will be prefixed with query_. In other words, if your query looks like this:

http://foo.com/index.pl?foo=bar&baz=beerz

In your template parameter foo would be accessible as query_foo and parameter baz would be accessible via query_baz

Foo is: <tmpl_var name="query_foo">
Baz is: <tmpl_var name="query_baz">

App::ZofCMS::Plugin::QuickNote (version 0.0105)

NAME

Link: App::ZofCMS::Plugin::QuickNote

App::ZofCMS::Plugin::QuickNote - drop-in "quicknote" form to email messages from your site

SYNOPSIS

In your ZofCMS template:

# basic:
quicknote => {
    to  => 'me@example.com',
},

# juicy
quicknote => {
    mailer      => 'testfile',
    to          => [ 'foo@example.com', 'bar@example.com'],
    subject     => 'Quicknote from example.com',
    must_name   => 1,
    must_email  => 1,
    must_message => 1,
    name_max    => 20,
    email_max   => 20,
    message_max => 1000,
    success     => 'Your message has been successfuly sent',
    format      => <<'END_FORMAT',
Quicknote from host {::{host}::} sent on {::{time}::}
Name: {::{name}::}
E-mail: {::{email}::}
Message:
{::{message}::}
END_FORMAT
},

In your HTML::Template template:

<tmpl_var name="quicknote">

DESCRIPTION

The module is a plugin for App::ZofCMS which provides means to easily drop-in a "quicknote" form which asks the user for his/her name, e-mail address and a message he or she wants to send. After checking all of the provided values plugin will e-mail the data which the visitor entered to the address which you specified.

This documentation assumes you've read App::ZofCMS, App::ZofCMS::Config and App::ZofCMS::Template

HTML TEMPLATE

The only thing you'd want to add in your HTML::Template is a <tmpl_var name="quicknote"> the data for this variable will be put into special key {t}, thus you can stick it in secondary templates.

USED FIRST-LEVEL ZofCMS TEMPLATE KEYS

plugins

{
    plugins => [ qw/QuickNote/ ],
}

First and obvious is that you'd want to include the plugin in the list of plugins to run.

quicknote

# basic:
quicknote => {
    to  => 'me@example.com',
},

# juicy
quicknote => {
    mailer      => 'testfile',
    to          => [ 'foo@example.com', 'bar@example.com'],
    subject     => 'Quicknote from example.com',
    must_name   => 1,
    must_email  => 1,
    must_message => 1,
    name_max    => 20,
    email_max   => 20,
    message_max => 1000,
    success     => 'Your message has been successfuly sent',
    format      => <<'END_FORMAT',
Quicknote from host {::{host}::} sent on {::{time}::}
Name: {::{name}::}
E-mail: {::{email}::}
Message:
{::{message}::}
END_FORMAT
},

The quicknote first-level ZofCMS template key is the only thing you'll need to use to tell the plugin what to do. The key takes a hashref as a value. The only mandatory key in that hashref is the to key, the rest have default values. Possible keys in quicknote hashref are as follows:

to

to => 'me@example.com'

to => [ 'foo@example.com', 'bar@example.com'],

Mandatory. Takes either a string or an arrayref as a value. Passing the string is equivalent to passing an arrayref with just one element. Each element of that arrayref must contain a valid e-mail address, upon successful completion of the quicknote form by the visitor the data on that form will be emailed to all of the addresses which you specify here.

mailer

mailer => 'testfile',

Optional. Specifies which mailer to use for sending mail. See documentation for Mail::Mailer for possible mailers. When using the testfile mailer the file will be located in the same directory your in which your index.pl file is located. By default plugin will do the same thing Mail::Mailer will (search for the first available mailer).

subject

subject => 'Quicknote from example.com',

Optional. Specifies the subject line of the quicknote e-mail. Defaults to: Quicknote

must_name, must_email and must_message

must_name   => 1,
must_email  => 1,
must_message => 1,

Optional. The must_name, must_email and must_message arguments specify whether or not the "name", "e-mail" and "message" form fields are mandatory. When set to a true value indicate that the field is mandatory. When set to a false value the form field will be filled with N/A unless specified by the visitor. Visitor will be shown an error message if he or she did not specify some mandatory field. By default only the must_message argument is set to a true value (thus the vistior does not have to fill in neither the name nor the e-mail).

name_max, email_max and message_max

name_max    => 20,
email_max   => 20,
message_max => 1000,

Optional. Alike must_* arguments, the name_max, email_max and message_max specify max lengths of form fields. Visitor will be shown an error message if any of the parameters exceed the specified maximum lengths. By default the value for name_max is 100, value for email_max is 200 and value for message_max 10000

success

success => 'Your message has been successfuly sent',

Optional. Specifies the text to display to your visitor when the quicknote is successfuly sent. Defaults to: 'Your message has been successfuly sent'.

format

    format      => <<'END_FORMAT',
Quicknote from host {::{host}::} sent on {::{time}::}
Name: {::{name}::}
E-mail: {::{email}::}
Message:
{::{message}::}
END_FORMAT

Optional. Here you can specify the format of the quicknote e-mail which plugin will send. The following special sequences will be replaced by corresponding values:

{::{host}::}        - the host of the person sending the quicknote
{::{time}::}        - the time the message was sent ( localtime() )
{::{name}::}        - the "Name" form field
{::{email::}        - the "E-mail" form field
{::{message}::}     - the "Message" form field

Default format is shown above and in SYNOPSIS.

GENERATED HTML

Below is the HTML code generated by the plugin. Use CSS to style it.

# on successful send
<p class="quicknote_success"><tmpl_var name="success"></p>

# on error
<p class="quicknote_error"><tmpl_var name="error"></p>


# the form itself
<form class="quicknote" action="" method="POST">
<div>
    <input type="hidden" name="quicknote_username" value="your full name">
    <input type="hidden" name="page" value="index">
    <ul>
        <li>
            <label for="quicknote_name">Name:</label
            ><input type="text" name="quicknote_name" id="quicknote_name"
            value="">
        </li>
        <li>
            <label for="quicknote_email">E-mail: </label
            ><input type="text" name="quicknote_email" id="quicknote_email"
            value="">
        </li>
        <li>
            <label for="quicknote_message">Message: </label
            ><textarea name="quicknote_message" id="quicknote_message"
            cols="40" rows="10"></textarea>
        </li>
    </ul>
    <input type="submit" value="Send">
</div>
</form>

App::ZofCMS::Plugin::Syntax::Highlight::CSS (version 0.0102)

NAME

Link: App::ZofCMS::Plugin::Syntax::Highlight::CSS

App::ZofCMS::Plugin::Syntax::Highlight::CSS - provide syntax highlighted CSS code snippets on your site

SYNOPSIS

In ZofCMS template:

{
    body        => \'index.tmpl',
    highlight_css => {
        foocss => '* { margin: 0; padding: 0; }',
        bar     => sub { return '* { margin: 0; padding: 0; }' },
        beer    => \ 'filename.of.the.file.with.CSS.in.datastore.dir',
    },
    plugins     => [ qw/Syntax::Highlight::CSS/ ],
}

In HTML::Template template:

<tmpl_var name="foocss">
<tmpl_var name="bar">
<tmpl_var name="beer">

DESCRIPTION

The module is a plugin for App::ZofCMS. It provides means to include CSS (Cascading Style Sheets) code snippets with syntax highlights on your pages.

This documentation assumes you've read App::ZofCMS, App::ZofCMS::Config and App::ZofCMS::Template

USED FIRST-LEVEL ZofCMS TEMPLATE KEYS

plugins

{
    plugins => [ qw/Syntax::Highlight::CSS/ ],
}

First and obvious is that you'd want to include the plugin in the list of plugins to run.

highlight_css

{
    highlight_css => {
        foocss  => '* { margin: 0; padding: 0; }',
        bar     => sub { return '* { margin: 0; padding: 0; }' },
        beer    => \ 'filename.of.the.file.with.CSS.in.datastore.dir',
    },
}

The highlight_css is the heart key of the plugin. It takes a hashref as a value. The keys of this hashref except for two special keys described below are the name of <tmpl_var name=""> tags in your HTML::Template template into which to stuff the syntax-highlighted code. The value of those keys can be either a scalar, subref or a scalarref. They are interpreted by the plugin as follows:

scalar

highlight_css => {
    foocss => '* { margin: 0; padding: 0; }'
}

When the value of the key is a scalar it will be interpreted as CSS code to be highlighted. This will do it for short snippets.

scalarref

highlight_css => {
    beer    => \ 'filename.of.the.file.with.CSS.in.datastore.dir',
},

When the value is a scalarref it will be interpreted as the name of a file in the data_store dir. That file will be read and its contents will be understood as CSS code to be highlighted. If an error occured during opening of the file, your <tmpl_var name=""> tag allocated for this entry will be populated with an error message.

subref

highlight_css => {
    bar     => sub { return '* { margin: 0; padding: 0; }' },
},

When the value is a subref, it will be executed and its return value will be taken as CSS code to highlight. The @_ of that sub when called will contain the following: $template, $query, $config where $template is a hashref of your ZofCMS template, $query is a hashref of the parameter query whether it's a POST or a GET request, and $config is the App::ZofCMS::Config object.

SPECIAL KEYS IN highlight_css

highlight_css => {
    nnn => 1,
    pre => 0,
},

There are two special keys, namely nnn and pre, in highlight_css hashref. Their values will affect the resulting highlighted CSS code.

nnn

highlight_css => {
    nnn => 1,
}

Instructs the highlighter to activate line numbering. Default value: 0 (disabled).

pre

highlight_css => {
    nnn => 0,
}

Instructs the highlighter to surround result by <pre>...</pre> tags. Default value: 1 (enabled).

highlight_css_before

{
    highlight_css_before => '<div class="my-highlights">',
}

Takes a scalar as a value. When specified, every highlighted CSS code will be prefixed with whatever you specify here.

highlight_css_after

{
    highlight_after => '</div>',
}

Takes a scalar as a value. When specified, every highlighted CSS code will be postfixed with whatever you specify here.

GENERATED CODE

Given '* { margin: 0; padding: 0; }' as input plugin will generate the following code (line-breaks were edited):

<pre class="css-code">
    <span class="ch-sel">*</span> {
    <span class="ch-p">margin</span>:
    <span class="ch-v">0</span>;
    <span class="ch-p">padding</span>:
    <span class="ch-v">0</span>; }
</pre>

Now you'd use CSS to highlight specific parts of CSS syntax. Here are the classes that you can define in your stylesheet:

  • css-code - this is actually the class name that will be set on the <pre>> element if you have that option turned on.

  • ch-sel - Selectors

  • ch-com - Comments

  • ch-p - Properties

  • ch-v - Values

  • ch-ps - Pseudo-selectors and pseudo-elements

  • ch-at - At-rules

  • ch-n - The line numbers inserted when nnn key is set to a true value

SAMPLE CSS CODE FOR HIGHLIGHTING

.css-code {
    font-family: 'DejaVu Sans Mono Book', monospace;
    color: #000;
    background: #fff;
}
    .ch-sel, .ch-p, .ch-v, .ch-ps, .ch-at {
        font-weight: bold;
    }
    .ch-sel { color: #007; } /* Selectors */
    .ch-com {                /* Comments */
        font-style: italic;
        color: #777;
    }
    .ch-p {                  /* Properties */
        font-weight: bold;
        color: #000;
    }
    .ch-v {                  /* Values */
        font-weight: bold;
        color: #880;
    }
    .ch-ps {                /* Pseudo-selectors and Pseudo-elements */
        font-weight: bold;
        color: #11F;
    }
    .ch-at {                /* At-rules */
        font-weight: bold;
        color: #955;
    }
    .ch-n {
        color: #888;
    }

PREREQUISITES

This plugin requires Syntax::Highlight::CSS. You can use zofcms_helper script to locally place it into ZofCMS "core" directory:

zofcms_helper --nocore --core your_sites_core --cpan Syntax::Hightlight::CSS

App::ZofCMS::Plugin::Syntax::Highlight::HTML (version 0.0101)

NAME

Link: App::ZofCMS::Plugin::Syntax::Highlight::HTML

App::ZofCMS::Plugin::Syntax::Highlight::HTML - provide HTML code snippets on your site

SYNOPSIS

In ZofCMS template:

{
    body        => \'index.tmpl',
    highlight_html => {
        foohtml => '<div class="bar">beer</div>',
        bar     => sub { return '<div class="bar">beer</div>' },
        beer    => \ 'filename.of.the.file.with.HTML.in.datastore.dir',
    },
    plugins     => [ qw/Syntax::Highlight::HTML/ ],
}

In HTML::Template template:

<tmpl_var name="foohtml">
<tmpl_var name="bar">
<tmpl_var name="beer">

DESCRIPTION

The module is a plugin for App::ZofCMS. It provides means to include HTML (HyperText Markup Lanugage) code snippets with syntax highlights on your pages.

This documentation assumes you've read App::ZofCMS, App::ZofCMS::Config and App::ZofCMS::Template

USED FIRST-LEVEL ZofCMS TEMPLATE KEYS

plugins

{
    plugins => [ qw/Syntax::Highlight::HTML/ ],
}

First and obvious is that you'd want to include the plugin in the list of plugins to run.

highlight_html

{
    highlight_html => {
        foohtml => '<div class="bar">beer</div>',
        bar     => sub { return '<div class="bar">beer</div>' },
        beer    => \ 'filename.of.the.file.with.HTML.in.datastore.dir',
    },
}

The highlight_html is the heart key of the plugin. It takes a hashref as a value. The keys of this hashref except for two special keys described below are the name of <tmpl_var name=""> tags in your HTML::Template template into which to stuff the syntax-highlighted code. The value of those keys can be either a scalar, subref or a scalarref. They are interpreted by the plugin as follows:

scalar

highlight_html => {
    foohtml => '<div class="bar">beer</div>'
}

When the value of the key is a scalar it will be interpreted as HTML code to be highlighted. This will do it for short snippets.

scalarref

highlight_html => {
    beer    => \ 'filename.of.the.file.with.HTML.in.datastore.dir',
},

When the value is a scalarref it will be interpreted as the name of a file in the data_store dir. That file will be read and its contents will be understood as HTML code to be highlighted. If an error occured during opening of the file, your <tmpl_var name=""> tag allocated for this entry will be populated with an error message.

subref

highlight_html => {
    bar     => sub { return '<div class="bar">beer</div>' },
},

When the value is a subref, it will be executed and its return value will be taken as HTML code to highlight. The @_ of that sub when called will contain the following: $template, $query, $config where $template is a hashref of your ZofCMS template, $query is a hashref of the parameter query whether it's a POST or a GET request, and $config is the App::ZofCMS::Config object.

SPECIAL KEYS IN highlight_html

highlight_html => {
    nnn => 1,
    pre => 0,
},

There are two special keys, namely nnn and pre, in highlight_html hashref. Their values will affect the resulting highlighted HTML code.

nnn

highlight_html => {
    nnn => 1,
}

Instructs the highlighter to activate line numbering. Default value: 0 (disabled).

pre

highlight_html => {
    nnn => 0,
}

Instructs the highlighter to surround result by <pre>...</pre> tags. Default value: 1 (enabled).

highlight_before

{
    highlight_before => '<div class="highlights">',
}

Takes a scalar as a value. When specified, every highlighted HTML code will be prefixed with whatever you specify here.

highlight_after

{
    highlight_after => '</div>',
}

Takes a scalar as a value. When specified, every highlighted HTML code will be postfixed with whatever you specify here.

GENERATED CODE

Given '<foo class="bar">beer</foo>' as input plugin will generate the following code:

<pre>
    <span class="h-ab">&lt;</span><span class="h-tag">foo</span>
    <span class="h-attr">class</span>=<span class="h-attv">"bar</span>"
    <span class="h-ab">&gt;</span>beer<span class="h-ab">&lt;/</span>
    <span class="h-tag">foo</span><span class="h-ab">&gt;</span>
</pre>

Now you'd use CSS to highlight specific parts of HTML syntax. Here are the classes that you can define in your stylesheet (list shamelessly stolen from Syntax::Highlight::HTML documentation):

  • .h-decl - for a markup declaration; in a HTML document, the only markup declaration is the DOCTYPE, like: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">

  • .h-pi - for a process instruction like <?html ...> or <?xml ...?>

  • .h-com - for a comment, <!-- ... -->

  • .h-ab - for the characters '<' and '>' as tag delimiters

  • .h-tag - for the tag name of an element

  • .h-attr - for the attribute name

  • .h-attv - for the attribute value

  • .h-ent - for any entities: &eacute; &#171;

  • .h-lno - for the line numbers

SAMPLE CSS CODE FOR HIGHLIGHTING

Sebastien Aperghis-Tramoni, the author of Syntax::Highlight::HTML, was kind enough to provide sample CSS code defining the look of each element of HTML syntax. It is presented below:

.h-decl { color: #336699; font-style: italic; }   /* doctype declaration  */
.h-pi   { color: #336699;                     }   /* process instruction  */
.h-com  { color: #338833; font-style: italic; }   /* comment              */
.h-ab   { color: #000000; font-weight: bold;  }   /* angles as tag delim. */
.h-tag  { color: #993399; font-weight: bold;  }   /* tag name             */
.h-attr { color: #000000; font-weight: bold;  }   /* attribute name       */
.h-attv { color: #333399;                     }   /* attribute value      */
.h-ent  { color: #cc3333;                     }   /* entity               */

.h-lno  { color: #aaaaaa; background: #f7f7f7;}   /* line numbers         */

PREREQUISITES

Despite the ZofCMS design this module uses Syntax::Highlight::HTML which in turn uses HTML::Parser which needs a C compiler to install.

This module requires Syntax::Highlight::HTML and File::Spec (the later is part of the core)

App::ZofCMS::Plugin::TagCloud (version 0.0103)

NAME

Link: App::ZofCMS::Plugin::TagCloud

App::ZofCMS::Plugin::TagCloud - generate "tag clouds"

SYNOPSIS

In your ZofCMS template or main config file:

plug_tag_cloud => {
    unit => 'em',
    tags => [ qw(
            foo /foo 2
            bar /bar 1
            ber /ber 3
        )
    ],
}

In your HTML::Template template:

<style type="text/css">
    <tmpl_var name="tag_cloud_css">
</style>

<tmpl_var name="tag_cloud">

DESCRIPTION

The module is a plugin for App::ZofCMS; it generates "tag clouds" (bunch of different-sized links).

This documentation assumes you have read App::ZofCMS, App::ZofCMS::Config and App::ZofCMS::Template

ZofCMS TEMPLATE/MAIN CONFIG FILE KEYS

plug_tag_cloud => {
    id          => 'tag_cloud_container',
    class       => 'tag_cloud_tag',
    unit        => 'em',
    shuffle     => 1,
    uri_prefix  => 'http://site.com/',
    fg          => '#00d',
    bg          => 'transparent',
    fg_hover    => '#66f',
    bg_hover    => 'transparent',
    fg_visited  => '#333',
    bg_visited  => 'transparent',
    tags => [ qw(
            foo /foo 2
            bar /bar 1
            ber /ber 3
        )
    ],
}

Plugin gets its data through plug_tag_cloud first-level key in either ZofCMS template or main config file. Specifying this key in ZofCMS template will completely override whatever you set under that key in main config file.

The key takes a hashref as a value. Possible keys/values of that hashref are as follows:

tags

tags => [ qw(
        foo /foo 2
        bar /bar 1
        ber /ber 3
    )
],

# or 

tags => [
    [ qw(foo /foo 2) ],
    [ qw(bar /bar 1) ],
    [ qw(ber /ber 3) ],
],

Mandatory. The tags key takes an arrayref as a value. Elements of that arrayref can be either either plain strings or arrayrefs. You cannot mix the two. If elements are plain strings they will be converted internally into the "arrayref form" by grouping by three (see examples above, they are equivalent).

The elements of the inner arrayrefs are as follows: first element is the text for the link in the tag cloud. Second element is the URI to which the tag points. Third element is the "weight" of the tag, the larger the number the larger the tag will be. The third element actually also serves for the font-size value in the CSS code generated by the plugin.

id

id => 'tag_cloud_container',

Optional. The id key takes a string as a value. This sting will be used for the id="" attribute of the tag cloud <ul> element. Defaults to: zofcms_tag_cloud

class

class => 'tag_cloud_tag',

Optional. The class key takes a string as a value. This sting will be used to generate class names for cloud tags. Defaults to: zofcms_tag_cloud

unit

unit => 'em',

Optional. The unit key takes a string as a value. This string must be a valid CSS unit for font-size property. Whatever you pass in here will be directly used in the generated CSS code and the number for that unit will be taken from the "weight" of the cloud tag (see tags key above). Defaults to: %

shuffle

shuffle => 1,

Optional. Takes either true or false value. When set to a true value the elements of your tag cloud will be shuffled each and every time. Default to: 0

uri_prefix

uri_prefix  => 'http://site.com/',

Optional. The uri_prefix takes a string as a value. This string will be prepended to all of the URIs to which your tags are pointing. Defaults to: empty string.

fg

fg => '#00d',

Optional. Specifies the color to use for foreground on <a href=""> elements; will be directly used for color property in generated CSS code. Defaults to: #00d.

bg

bg => 'transparent',

Optional. Specifies the color to use for background on <a href=""> elements; will be directly used for background property in generated CSS code. Defaults to: transparent.

fg_hover

fg_hover => '#66f',

Optional. Same as fg except this one is used for :hover pseudo-selector. Defaults to: #66f

bg_hover

bg_hover => 'transparent',

Optional. Same as bg except this one is used for :hover pseudo-selector. Defaults to: transparent

fg_visited

fg_visited  => '#333',

Optional. Same as fg except this one is used for :visited pseudo-selector. Defaults to: #333

bg_visited

Optional. Same as bg except this one is used for :visited pseudo-selector. Defaults to: transparent

HTML::Template TEMPLATE VARIABLES

The plugin will stuff two keys into {t} special key in your ZofCMS templates. This means that you can use them in your HTML::Template templates.

tag_cloud

<tmpl_var name="tag_cloud">

This one will contain the HTML code for your tag cloud.

tag_cloud_css

<style type="text/css">
    <tmpl_var name="tag_cloud">
</style>

This one will contain the CSS code for your tag cloud. You obviously don't have to use this one and instead code your own CSS.

EXAMPLE OF GENERATED HTML CODE

<ul id="tag_cloud">
    <li class="tag_cloud_tag3"><a href="http://site.com/ber">ber</a></li>
    <li class="tag_cloud_tag2"><a href="http://site.com/foo">foo</a></li>
    <li class="tag_cloud_tag1"><a href="http://site.com/bar">bar</a></li>
</ul>

EXAMPLE OF GENERATED CSS CODE

#tag_cloud li {
    display: inline;
}
    #tag_cloud a {
        color: #f00;
        background: #00f;
    }
    #tag_cloud a:visited {
        color: #000;
        background: transparent;
    }
    #tag_cloud a:hover {
        color: #FFf;
        background: transparent;
    }
    .tag_cloud_tag1 { font-size: 1em; }
    .tag_cloud_tag2 { font-size: 2em; }
    .tag_cloud_tag3 { font-size: 3em; }

App::ZofCMS::Plugin::Tagged (version 0.0252)

NAME

Link: App::ZofCMS::Plugin::Tagged

App::ZofCMS::Plugin::Tagged - ZofCMS plugin to fill templates with data from query, template variables and configuration using <TAGS>

SYNOPSIS

Your ZofCMS template:

{
    cookie_foo  => '<TAG:TNo cookies:{d}{cookies}{foo}>',
    query_foo   => '[<TAG:Q:{foo}>]',
    set_cookies => [ ['foo', 'bar' ]],
    plugins     => [ { Cookies => 10 }, { Tagged => 20 } ],
    conf => {
        base => 'test.tmpl',
    },
}

In your 'test.tmpl' base HTML::Template template:

Cookie 'foo' is set to: <tmpl_var name="cookie_foo"><br>
Query 'foo' is set to: <tmpl_var name="query_foo">

In ZofCMS template the Cookies plugin is set to run before Tagged plugin, thus on first page access cookies will not be set, and we will access the page without setting the 'foo' query parameter. What do we see:

Cookie 'foo' is set to: No cookies
Query 'foo' is set to: []

No, if we run the page the second time it (now cookies are set with App::ZofCMS::Plugin::Cookies plugin) will look like this:

Cookie 'foo' is set to: bar
Query 'foo' is set to: []

If we pass query parameter 'foo' to the page, setting it to 'beer' our page will look like this:

Cookie 'foo' is set to: bar
Query 'foo' is set to: [beer]

That's the power of Tagged plugin... now I'll explain what those weird looking tags mean.

DESCRIPTION

The module provides means to the user to use special "tags" in scalar values inside ZofCMS template. This provides the ability to display data generated by templates (i.e. stored in {d} first level key), access query or configuration hashref. Possibilities are endless.

This documentation assumes you have read documentation for App::ZofCMS including App::ZofCMS::Config and App::ZofCMS::Template

STARTING WITH THE PRIORITY

First of all, when using App::ZofCMS::Plugin::Tagged with other plugins make sure to set the correct priority. In our example above, we used App::ZofCMS::Plugin::Cookies which reads currently set cookies into {d} special key in ZofCMS template. That's why we set priority of 10 to Cookies plugin and priority of 20 to Tagged plugin - to insure Tagged runs after {d}{cookies} have been filled in.

Note: currently there is no support to run Tagged plugin twice, I'm not sure that will ever be needed, but if you do come across such situation, you can easily cheat. Just copy Tagged.pm in your $core/App/ZofCMS/Plugin/Tagged.pm to Tagged2.pm (and ajust the name accordingly in the package line inside the file). Now you have two Tagged plugins, and you can do stuff like plugins => [ {Tagged => 10}, { SomePlugin => 20 }, { Tagged2 => 30 } ]

THE TAG

foo => '<TAG:Q:{foo}>',
bar => 'beeer <TAG:Qdefault:{bar}>  baz',
baz => 'foo <TAG:T:{d}{baz}[1]{beer}[2]> bar',
nop => "<TAG:NOOP><TAG:T:I'm NOT a tag!!!>",
random => '<TAG::RAND I 100>',

NOTE: everything in the tag is CASE-SENSITIVE

First of all, the tag starts with '<TAG:' and ends with with a closing angle bracket ('>'). The first character that follows '<TAG:' is a cell. It can be either 'Q', 'T' or 'C', which stand for Query, Template and Configuration file. Each of those three cells is a hashref: a hashref of query parameters, your ZofCMS template hashref and your main configuration file hashref.

What follows the cell letter until the colon (':') is the default value, it will be used if whatever your tag references is undefined. Of course, you don't have to define the default value; if you don't - the tag value will be an empty string (not undef). Note: currently you can't use the actual colon (':') in your default variable. Currently it will stay that way, but there are plans to add custom delimiters in the future.

After the colon (':') which signifies the end of the cell and possible default value follows a sequence which would access the value which you are after. This sequence is exactly how you would write it in perl. Let's look at some examples. First, let's define $template, $query and $config variables as T, Q and C "cells", these variables hold respective hashrefs (same as "cells"):

<TAG:Q:{foo}>              same as   $query->{foo}
<TAG:T:{d}{foo}>           same as   $template->{d}{foo}
<TAG:C:{ fo o }{ b a r }>  same as   $config->{"fo o"}{"b a r"}
<TAG:Qnone:{foo}>          same as   $query->{foo} // 'none'
<TAG:Txxx:{t}{bar}>        same as   $template->{t}{bar} // 'xxx'

# arrayrefs are supported as well

<TAG:T:{d}{foo}[0]>        same as   $template->{d}{foo}[0]
<TAG>C:{plugins}[1]>       same as   $config->{plugins}[1]

THE RAND TAG

rand1 => '<TAG:RAND>',
rand2 => '<TAG:RAND 100>',
rand3 => '<TAG:RAND I 200>',
rand4 => '<TAG:RAND100>',
rand5 => '<TAG:RANDI100>',

The RAND tag will be replaced by a pseudo-random number (obtained from perl's rand() function). In it's plainest form, <TAG:RAND>, it will be replaced by exactly what comes out from rand(), in other words, same as calling rand(1). If a letter 'I' follows word 'RAND' in the tag, then int() will be called on the result of rand(). When a number follows word RAND, that number will be used in the call to rand(). In other words, tag <TAG:RAND 100> will be replaced by a number which is obtained by the call to rand(100). Note: the number must be after the letter 'I' if you are using it. You can have spaces between the letter 'I' or the number and the word RAND. In other words, these tags are equal: <TAG:RANDI100> and <TAG:RAND I 100>.

THE NOOP TAG

nop => "<TAG:NOOP><TAG:T:I'm NOT a tag!!!>",

The NOOP tag (read no operation) is a special tag which tells Tagged plugin to stop processing this string as soon as it sees this tag. Tagged will remove the noop tag from the string. The above example would end up looking as nop => "<TAG:T:I'm NOT a tag!!!>",

Note: any tags before the noop tag WILL be parsed.

OPTIONS

{
    tagged_options => { no_parse => 1 },
}

Behaviour options can be set for App::ZofCMS::Plugin::Tagged via tagged_options first level ZofCMS template key. This key takes a hashref as a value. The only currently supported key in that hashref is no_parse which can be either a true or a false value. If it's set to a true value, Tagged will not parse this template.

NOTE ON DEPLOYMENT

This plugin requires Data::Transformer module which is not in Perl's core. If your webserver does not allow instalation of modules from CPAN, run the helper script to copy this module into your $core_dir/CPAN/ directory

zofcms_helper --nocore --core your_sites_core --cpan Data::Transformer

CAVEATS

If your tag references some element of ZofCMS template which itself contains a tag the behaviour is undefined.

SEE ALSO

App::ZofCMS, App::ZofCMS::Config, App::ZofCMS::Template

App::ZofCMS::Plugin::TOC (version 0.0103)

NAME

Link: App::ZofCMS::Plugin::TOC

App::ZofCMS::Plugin::TOC - Table of Contents building plugin for ZofCMS

SYNOPSIS

In your ZofCMS template, or in your main config file (under template_defaults or dir_defaults):

page_toc    => [
    qw/
        #overview
        #beginning
        #something_else
        #conclusion
    /,
],
plugins     => [ qw/TOC/ ],

# OR

page_toc    => [
    [ qw/#overview Overview class_overview/ ],
    [ qw/#beginning Beginning/ ],
    qw/
        #something_else
        #conclusion
    /,
],
plugins     => [ qw/TOC/ ],

In your HTML::Template template:

<tmpl_var name="page_toc">

DESCRIPTION

This plugin provides means to generate "table of contents" lists. For example, the second example in the SYNOPSYS would replace <tmpl_var name="page_toc"> with this:

<ul class="page_toc">
    <li class="class_overview"><a href="#overview">Overview</a></li>
    <li><a href="#beginning">Beginning</a></li>
    <li><a href="#something_else">Something Else</a></li>
    <li><a href="#conclusion">Conclusion</a></li>
</ul>

HOW TO USE

Aside from sticking TOC in your arrayref of plugins in your ZofCMS template (plugins => [ qw/TOC/ ]) and placing <tmpl_var name="page_toc"> in your HTML::Template template you also need to create a page_toc first level key in ZofCMS template. That key's value is an arrayref each element of which can be either an arrayref or a scalar. If the element is a scalar it is the same as it being an arrayref with one element. The element which is an arrayref can contain either one, two or three elements itself. Which represent the following:

arrayref which contains only one element

page_toc => [
    '#foo',
    '#bar-baz',
],

# OR

page_toc => [
    [ '#foo' ],
    [ '#bar-baz' ],
],

The first (and only) element will be used in href="" attribute of the generated link. The text of the link will be determined automatically, in particular the '#' will be removed, first letter will be capitalized and any dashes '-' or underscores '_' will be replaced by a space with the letter following them capitalized. The example above will place the following code in <tmpl_var name="page_toc">:

<ul class="page_toc">
    <li><a href="#foo">Foo</a></li>
    <li><a href="#bar-baz">Bar Baz</a></li>
</ul>

arrayref which contains two elements

page_toc => [
    [ '#foo', 'Foos Lots of Foos!' ],
    [ '#bar-baz', 'Bar-baz' ],
],

The first element will be used in href="" attribute of the generated link. The second element will be used as text for the link. The example above will generate the following code:

<ul class="page_toc">
    <li><a href="#foo">Foos Lots of Foos!</a></li>
    <li><a href="#bar-baz">Bar-baz</a></li>
</ul>

arrayref which contains three elements

page_toc => [
    [ '#foo', 'Foos Lots of Foos!', 'foos' ],
    [ '#bar-baz', 'Bar-baz', 'bars' ],
],

The first element will be used in href="" attribute of the generated link. The second element will be used as text for the link. The third elemenet will be used to create a class="" attribute on the <li> element for the corresponding entry. The example above will generate the following code:

<ul class="page_toc">
    <li class="foos"><a href="#foo">Foos Lots of Foos!</a></li>
    <li class="bars"><a href="#bar-baz">Bar-baz</a></li>
</ul>

Note: the class of the <ul> element is always page_toc

App::ZofCMS::Plugin::UserLogin (version 0.0102)

NAME

Link: App::ZofCMS::Plugin::UserLogin

App::ZofCMS::Plugin::UserLogin - restrict access to pages based on user accounts

SYNOPSIS

In $your_database_of_choice that is supported by DBI create a table. You can have extra columns in it, but the first five must be named as appears below. login_time is the return of Perl's time(). Password will be md5_hex()ed (with Digest::MD5, session_id is rand() . rand() . rand() and role depends on what you set the roles to be:

create TABLE users (
    login TEXT,
    password VARCHAR(32),
    login_time VARCHAR(10),
    session_id VARCHAR(55),
    role VARCHAR(20)
);

Main config file:

template_defaults => {
    plugins => [ { UserLogin => 10000 } ],
},
plug_login => {
    dsn                     => "DBI:mysql:database=test;host=localhost",
    user                    => 'test', # user,
    pass                    => 'test', # pass
    opt                     => { RaiseError => 1, AutoCommit => 0 },
    table                   => 'users',
    login_page              => '/login',
    redirect_on_restricted  => '/login',
    redirect_on_login       => '/',
    redirect_on_logout      => '/',
    not_restricted          => [ qw(/ /index) ],
    restricted              => [ qr/^/ ],
},

In HTML::Template template for '/login' page:

<tmpl_var name="plug_login_form">
<tmpl_var name="plug_login_logout">

DESCRIPTION

The module is a plugin for App::ZofCMS; it provides functionality to restrict access to some pages based on user accounts (which support "roles")

Plugin uses HTTP cookies to set user sessions.

This documentation assumes you've read App::ZofCMS, App::ZofCMS::Config and App::ZofCMS::Template

NOTE ON REDIRECTS

There are quite a few options that redirect the user upon a certain event. The exit() will be called upon a redirect so keep that in mind when setting plugin's priority setting.

DATABASE

Plugin needs access to the database that is supported by DBI module. You'll need to create a table the format of which is described in the first paragraph of SYNOPSYS section above. Note: plugin does not support creation of user accounts. That was left for other plugins (e.g. App::ZofCMS::Plugin::FormToDatabase) considering that you are flexible in what the entry for each user in the database can contain.

ROLES

The "role" of a user can be used to limit access only to certain users. In the database the user can have several roles which are to be separated by commas (,). For example:

foo,bar,baz

The user with that role is member of role "foo", "bar" and "baz".

TEMPLATE/CONFIG FILE SETTINGS

plug_login => {
    dsn                     => "DBI:mysql:database=test;host=localhost",
    user                    => 'test',
    pass                    => 'test',
    opt                     => { RaiseError => 1, AutoCommit => 0 },
    table                   => 'users',
    user_ref    => sub {
        my ( $user_ref, $template ) = @_;
        $template->{d}{plug_login_user} = $user_ref;
    },
    login_page              => '/login',
    redirect_on_restricted  => '/login',
    redirect_on_login       => '/',
    redirect_on_logout      => '/',
    not_restricted          => [ qw(/ /index) ],
    restricted              => [ qr/^/ ],
},

These settings can be set via plug_login first-level key in ZofCMS template, but you probably would want to set all this in main config file via plug_login first-level key.

dsn

dsn => "DBI:mysql:database=test;host=localhost",

Mandatory. The dsn key will be passed to DBI's connect_cached() method, see documentation for DBI and DBD::your_database for the correct syntax of this one. The example above uses MySQL database called test which is location on localhost

user

user => 'test',

Mandatory. Specifies the user name (login) for the database. This can be an empty string if, for example, you are connecting using SQLite driver.

pass

pass => 'test',

Mandatory. Same as user except specifies the password for the database.

table

table => 'users',

Optional. Specifies which table in the database stores user accounts. For format of this table see SYNOPSYS section. Defaults to: users

opt

opt => { RaiseError => 1, AutoCommit => 0 },

Optional. Will be passed directly to DBI's connect_cached() method as "options". Defaults to: { RaiseError => 1, AutoCommit => 0 }

user_ref

user_ref => sub {
    my ( $user_ref, $template ) = @_;
    $template->{d}{plug_login_user} = $user_ref;
},

Optional. Takes a subref as an argument. When specified the subref will be called and its @_ will contain the following: $user_ref, $template_ref, $query_ref, $config_obj, where $user_ref will be either undef (e.g. when user is not logged on) or will contain an arrayref with user data pulled from the SQL table, i.e. an arrayref with all the columns in a table that correspond to the currently logged in user. The $template_ref is the reference to your ZofCMS template, $query_ref is the reference to a query hashref as is returned from CGI's Vars() call. Finally, $config_obj is the App::ZofCMS::Config object. Basically you'd use user_ref to stick user's data into your ZofCMS template for later processing, e.g. displaying parts of it or making it accessible to other plugins. Defaults to: (will stick user data into {d}{plug_login_user} in ZofCMS template)

user_ref    => sub {
    my ( $user_ref, $template ) = @_;
    $template->{d}{plug_login_user} = $user_ref;
},

login_page

login_page => '/login',

login_page => qr|^/log(?:in)?|i;

Optional. Specifies what page is a page with a login form. The check will be done against a "page" that is constructed by $query{dir} . $query{page} (the dir and page are discussed in ZofCMS's core documentation). The value for the login_page key can be either a string or a regex. Note: the access is NOT restricted to pages matching login_page. Defaults to: /login

redirect_on_restricted

redirect_on_restricted => '/uri',

Optional. Specifies the URI to which to redirect if access to the page is denied, e.g. if user does not have an appropriate role or is not logged in. Defaults to: /

redirect_on_login

redirect_on_login  => '/uri',

Optional. Specifies the URI to which to redirect after user successfully logged in. By default is not specified.

redirect_on_logout

redirect_on_logout => '/uri',

Optional. Specifies the URI to which to redirect the user after he or she logged out.

restricted

restricted => [
    qw(/foo /bar /baz),
    qr|^/foo/|i,
    { page => '/admin', role => 'admin' },
    { page => qr|^/customers/|, role => 'customer' },
],

Optional but doesn't make sense to not specify this one. By default is not specified. Takes an arrayref as a value. Elements of this arrayref can be as follows:

a string

restricted => [ qw(/foo /bar) ],

Elements that are plain strings represent direct pages ( page is made out of $query{dir} . $query{page} ). The example above will restrict access only to pages http://foo.com/index.pl?page=foo and http://foo.com/index.pl?page=bar for users that are not logged in.

a regex

restricted => [ qr|^/foo/| ],

Elements that are regexes (qr//) will be matched against the page. If the page matches the given regex access will be restricted to any user who is not logged in.

a hashref

restricted => [
    { page => '/secret', role => \1 },
    { page => '/admin', role => 'customer' },
    { page => '/admin', role => 'not_customer' },
    { page => qr|^/customers/|, role => 'not_customer' },
],

Using hashrefs you can set specific roles that are restricted from a given page. The hashref must contain two keys: the page key and role key. The value of the page key can be either a string or a regex which will be matched against the current page the same way as described above. The role key must contain a role of users that are restricted from accessing the page specified by page key or a scalarref (meaning "any role"). Note you can specify only one role per hashref. If you want to have several roles you need to specify several hashrefs or use not_restricted option described below.

In the example above only logged in users who are NOT members of role customer or not_customer can access /admin page and only logged in users who are NOT members of role not_customer can access pages that begin with /customers/. The page /secret is restricted for everyone (see note on scalarref below).

IMPORTANT NOTE: the restrictions will be checked until the first one matching the page criteria found. Therefore, make sure to place the most restrictive restrictions first. In other words:

restricted => [
    qr/^/,
    { page => '/foo', role => \1 },
],

Will NOT block logged in users from page /foo because qr/^/ matches first. Proper way to write this restriction would be:

restricted => [
    { page => '/foo', role => \1 },
    qr/^/,
],

Note: the role can also be a scalarref; if it is, it means "any role". In other words:

restricted => [ qr/^/ ],

Means "all the pages are restricted for users who are not logged in". While:

restricted => [ { page => qr/^/, role \1 } ],

Means that "all pages are restricted for everyone" (in this case you'd use not_restricted option described below to ease the restrictions).

not_restricted

not_restricted => [
    qw(/foo /bar /baz),
    qr|^/foo/|i,
    { page => '/garbage', role => \1 },
    { page => '/admin', role => 'admin' },
    { page => qr|^/customers/|, role => 'customer' },
],

Optional. The value is the exact same format as for restricted option described above. By default is not specified. The purpose of not_restricted is the reverse of restricted option. Note that pages that match anything in not_restricted option will not be checked against restricted. In other words you can construct rules such as this:

restricted => [
    qr/^/,
    { page => qr|^/admin|, role => \1 },
],
not_restricted => [
    qw(/ /index),
    { page => qr|^/admin|, role => 'admin' },
],

The example above will restrict access to every page on the site that is not / or /index to any user who is not logged in. In addition, pages that begin with /admin will be accessible only to users who are members of role admin.

limited_time

limited_time => 600,

Optional. Takes integer values greater than 0. Specifies the amount of seconds after which user's session expires. In other words, if you set limited_time to 600 and user went to the crapper for 10 minutes, then came back, he's session would expire and he would have to log in again. By default not specified and sessions expire when the cookies do so (which is "by the end of browser's session", let me know if you wish to control that).

no_cookies

no_cookies => 1,

Optional. When set to a false value plugin will set two cookies: md5_hex()ed user login and session ID. When set to a true value plugin will not set any cookies and instead will put session ID into plug_login_session_id key under ZofCMS template's {t} special key.

HTML::Template TEMPLATE

There are two (or three, depending if you set no_cookies to a true value) keys created in ZofCMS template {t} special key, thus are available in your HTML::Template templates:

plug_login_form

<tmpl_var name="plug_login_form">

The plug_login_form key will contain the HTML code for the "login form". You'd use <tmpl_var name="plug_login_form"> on your "login page". Note that login errors, i.e. "wrong login or password" will be automagically display inside that form in a <p class="error">.

plug_login_logout

<tmpl_var name="plug_login_logout">

This one is again an HTML form except for the "logout" button. Drop it anywhere you want.

plug_login_user

<tmpl_if name="plug_login_user">
    Logged in as <tmpl_var name="plug_login_user">.
</tmpl_if>

The plug_login_user will contain the login name of the currently logged in user.

plug_login_session_id

If you set no_cookies argument to a true value, this key will contain session ID.

GENERATED HTML CODE

Below are the snippets of HTML code generated by the plugin; here for the reference when styling your login/logout forms.

login form

<form action="" method="POST" id="zofcms_plugin_login">
<div>
    <input type="hidden" name="page" value="/login">
    <input type="hidden" name="zofcms_plugin_login" value="login_user">
    <ul>
        <li>
            <label for="zofcms_plugin_login_login">Login: </label
            ><input type="text" name="login" id="zofcms_plugin_login_login">
        </li>
        <li>
            <label for="zofcms_plugin_login_pass">Password: </label
            ><input type="password" name="pass" id="zofcms_plugin_login_pass">
        </li>
    </ul>
    <input type="submit" value="Login">
</div>
</form>

login form with a login error

<form action="" method="POST" id="zofcms_plugin_login">
<div><p class="error">Invalid login or password</p>
    <input type="hidden" name="page" value="/login">
    <input type="hidden" name="zofcms_plugin_login" value="login_user">
    <ul>
        <li>
            <label for="zofcms_plugin_login_login">Login: </label
            ><input type="text" name="login" id="zofcms_plugin_login_login">
        </li>
        <li>
            <label for="zofcms_plugin_login_pass">Password: </label
            ><input type="password" name="pass" id="zofcms_plugin_login_pass">
        </li>
    </ul>
    <input type="submit" value="Login">
</div>
</form>

logout form

<form action="" method="POST" id="zofcms_plugin_login_logout">
<div>
    <input type="hidden" name="page" value="/login">
    <input type="hidden" name="zofcms_plugin_login" value="logout_user">
    <input type="submit" value="Logout">
</div>
</form>

AUTHOR

'Zoffix, <'zoffix at cpan.org'> (http://zoffix.com/, http://haslayout.net/, http://zofdesign.com/)

BUGS

Please report any bugs or feature requests to bug-app-zofcms-pluginreference at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=App-ZofCMS-PluginReference. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

SUPPORT

You can find documentation for this module with the perldoc command.

perldoc App::ZofCMS::PluginReference

You can also look for information at:

COPYRIGHT & LICENSE

Copyright 2008 'Zoffix, all rights reserved.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.