This document describes how to build Krang add-ons. The Krang add-on facility allows you to develop separate packages of code which can be installed into Krang. An add-on can supply a new element set, a new theme or even a new UI feature. Krang add-ons are separately versioned and can depend on a version of Krang or on other Krang add-ons.
Your first job creating a new addon is to come up with a clever name.
For example, I'll create an addon which magically speeds up Krang and
call it ``Turbo''. Once you've picked a name you can create a skeleton
with krang_addon_framework:
bin/krang_addon_framework --name Turbo
This command creates a directory called Turbo/ inside the
addons/ directory. A single file is created there called
krang_addon.conf.
An addon's files act as an overlay on top of Krang. For example, if
you create a file called templates/Story/new.tmpl in your addon
then it will be used instead of the template in that location in
KRANG_ROOT. The same is true for Perl modules in lib/ and the
files in htdocs/.
This works well for most purposes but occaisonally you'll need
something more powerful when overriding a core Krang library. For
example, imagine that I created Turbo::Story which had a better find()
implementation. Naturally Turbo::Story would inherit from
Krang::Story since aside from the new find() Krang::Story's
implementation should be used.
Krang addons support a file called conf/class.conf which supports
selecting replacement of core libraries. In this case
conf/class.conf inside the Turbo addon would contain:
SetClass Story Turbo::Story
This tells Krang that wherever it would have used Krang::Story previously it should now use Turbo::Story.
An example of using class.conf is included in Krang's test set:
t/addons/LazyLoader-1.00.tar.gz. This addon implements lazy-loading
for Krang::Story.
krang_addon.confThe krang_addon.conf file in an add-on directory controls many
important aspects of the add-on's operation. The file follows the
same Apache-inspired format as Krang's krang.conf file. I'll explain
each available directive.
Name name (required)/^[-\w]$/. For example:
Name Turbo
Version x.y (required)Version 1.01
Files file file ...krang_addon_installer. If
not present then all files (aside from those used for add-on
installation, like krang_addon.conf) are installed into Krang. For
example, Turbo-1.00 might list:
Files docs/turbo.pod lib/Krang/Turbo.pm t/turbo.t
ExcludeFiles file file ...ExcludeFiles README
Files in upgrade/ and krang_addon.conf are excluded
automatically.
RequireKrang x.yRequireKrang 1.00
RequireAddOns name x.y [ name x.y ... ]
RequireAddOns Nitro 2 \
RacingStripes 0
PostInstallScript scriptKRANG_ROOT
will be set in the environment for this script.
UninstallScript scriptKRANG_ROOT
will be set in the environment for this script.
NavigationHandler Modulenavigation_handler() will be called with the navigation
tree as an argument. For example, this code adds a new navigation
section called ``Log Viewer'' with a link called ``View Log'' pointing to
log_viewer.pl:
sub navigation_handler {
my ($pkg, $tree) = @_;
my $node = $tree->new_daughter();
$node->name('Log Tools');
$node = $node->new_daughter();
$node->name('View Log');
$node->link('log_viewer.pl');
}
If this method was placed in a class called LogViewer::NavHandler then krang_addon.conf would contain:
NavigationHandler LogViewer::NavHandler
For more about how navigation works in Krang see Krang::Navigation and Krang::NavigationNode.
InitHandler Moduleinit_handler(). A common use for this handler is to setup
additional library paths or environment variables.
Configured init-handlers are called during compilation of the following modules
Krang::Script Krang::Handler Krang::CGI (in CGI_MODE only)
PreloadHandler Modulepreload_handler(). A common use for this handler is
to preload selective modules into memory to reduce unshared memory of
mod_perl/Apache.
Priority NPriority directive allows you to control the order in which
addons are loaded by Krang. An addon which is loaded earlier will
override a later addon. AddOns are sorted in descending order by
priority so an addon with a Priority of 100 will load before one
with 5.
By default addons have a Priority of 0.
DataSetClasses Module::One Module::Two ...DataSetClasses directive allows you to add new classes to
Krang::DataSet. Objects of these classes can be imported and exported
via KDS files using krang_import and krang_export. Classes listed
here must implement to following methods:
id_meth() - returns the name of the ID-returning method. $id_meth() - must return a unique ID for your objects find() - including count, limit and offset functionality serialize_xml() deserialize_xml()
Note that id_meth() should return a value of the form ``NAME_id'' where
``NAME'' will be used as a short-hand name for your class and must be
unique. For example, Krang::Story returns ``story_id''.
You must also create XML Schema documents in a schema/ directory in your addon.
In order for other people to install your addon you need to build an
addon distribution. This is done with the krang_addon_dist script:
bin/krang_addon_dist Turbo
This command creates a tar-ball called Turbo-1.00.tar.gz from the
source in addons/Turbo/.
Installing a Krang addon is done using the krang_addon_installer on
an addon file:
bin/krang_addon_installer Turbo-1.00.tar.gz
For more details see the krang_addon_installer help:
bin/krang_addon_installer --help
Krang add-ons support the same upgrade facility as Krang. This means you can include an 'upgrade/' directory with standard Krang::Upgrade modules. For example, if Turbo-1.01 is released and must make changes to the database or filesystem then a file called 'upgrade/V1_01.pm' must be created. This file may contain code to run on a per-installation or per-instance basis, just like other Krang upgrade scripts.
Krang's upgrade system is described in the Upgrade System document.