
How to integrate extension configuration into bin/configure
Introduction
Simple plugins can embed configuration data in the 'Plugin' topic added to the System web when the plugin is installed. This technique is maintained for compatibility with TWiki, but it is very inefficient and is discouraged in Foswiki.
Instead, the Foswiki
configure interface supports enhanced configuration for extensions (i.e. beyond simple "Enabled" for plugins). The benefits are:
- Performance is much better because plugin topics don't have to be parsed for every request
- No need for site admins to modify files from the installed package (which should always be read-only)
- Complex Perl data structures can be initialized
- Single administration interface
bin/configure for both core and extension settings
- Increased security for sensitive configuration data and account information
This topic describes
how an extension author can make their settings be picked up by
configure.
Overview
Here is the high-level overview:
- Create a
Config.spec file in the extension directory
- In SVN trunk, this is
XXX/lib/Foswiki/Plugins/XXX/Config.spec for a plugin named XXX, YYY/lib/Foswiki/Contrib/YYY/Config.spec for a contrib (or Skin, or anything else) named YYY.
- in a live installation, this is the
lib/Foswiki/Plugins/XXX/ directory for a plugin named XXX
- In that spec file, add your configuration requirements by following the style of the examples below.
- When
configure is run the configuration options will be available through the interface. The default settings read will be saved along with the rest of the configuration.
Examples:
# ---+ Extensions
# ---++ JSCalendarContrib
# **STRING 30**
# Calendar style. The following styles are shipped by default with the
# Mishoo DHTML calendar: # blue, blue2, brown, green, setup, system, tas, win2k-1, win2k-2,
# win2k-cold-1, win2k-cold-2. Your local site may have other locally-defined styles.
$Foswiki::cfg{JSCalendarContrib}{style} = 'blue';
# **STRING 5**
# Controls what language is used in calendars.
$Foswiki::cfg{JSCalendarContrib}{lang} = 'en';
1;
In the above example, the configuration for
JSCalendarContrib is being added as a subsection of the
Extensions section. There are two configuration items, indicated by the type declarations
**STRING 30** and
**STRING 5**. Each type declaration is followed by a comment (which is displayed in
configure) and the actual declaration
$Foswiki::cfg{...} = ...;.
STRING 30 tells configure that the value expected is a string, and it should display a 30 character wide prompt box.
From
Plugins.Foswiki::Plugins::Plugins.EditTablerowPlugin
# ---+ Extensions
# ---++ EditTablerowPlugin
# **BOOLEAN**
# Debug setting
$Foswiki::cfg{Plugins}{EditTablerowPlugin}{DEBUG} = $FALSE;
1;
Here a different type,
BOOLEAN, is being used. For a full list of the available types, see
below.
A note on performance: If you are writing a plugin, and all your configuration settings are in your
.spec file, then remember to set
our $NO_PREFS_IN_TOPIC=1 in your
plugin (as described in
lib/Foswiki/Plugins/EmptyPlugin.pm). This will tell Foswiki that it doesn't have to parse the plugin topic for settings every time it runs.
The details of .spec files
.spec files are executable perl files that are read by
configure using the perl
do function. Their purpose is twofold:
- to allow an extension author to include new fields in the
$Foswiki::cfg configuration hash that can then be referred to by the extension.
- to support setting those values from the
configure interface.
configure reads
.spec files twice; once using
do to extract the default values for each field, and then again to extract
formatted comments that tell
configure how to present the field in the
configure UI.
.spec files are
only read by
configure. When Foswiki runs, it reads
LocalSite.cfg (generated by
configure) but
not .spec files. So any changes you make to a
.spec file will not be seen in Foswiki until after you run
configure and save.
Structure of a .spec file
A
.spec file is structured using Foswiki-syntax headings.
---+ defines a top level section, while
---++ will create a running subsection within that section.
All extensions (Plugins, Skins, Applications, Contribs etc) should use the
---+ Extensions section. You can place configuration into other sections, but keeping everything inside Extensions makes the
configure interface cleaner for the end user. All extensions should define their own sub-section. For example,
# ---+ Extensions
# ---++ MyContrib
# This extension supports firtling, graunching, munging and general dibbling.
After the heading comes a header comment for the section, and then a list of one or more fields. Each field is introduced by a
type comment which describes how the field is to be presented in
configure. For example,
# **STRING 30 EXPERT**
# Options for the <tt>graunch</tt> command
introduces a field which is expected to take a string value and will be prompted for using a 30-character wide text field. The field type name may be followed by one or more attributes which further refine the type - in the example above,
30 is an attribute that declares the width of the text field, and
EXPERT indicates that the setting is only for experts. More detail on types and their attributes can be found below.
The type declaration is followed by a descriptive comment (which can be formatted using raw HTML,
not Foswiki syntax).
# **SELECT blue rinse,mullet,beehive**
# Style setting. This sets the required <strong>hair style</strong>.
After this comment comes the default value for the field. This value will be overridden by the value read from
LocalSite.cfg when
configure is run. It exists just to make that all fields
have a value.
$Foswiki::cfg{MyContrib}{style} = 'blue rinse';

When an extension is first installed, Foswiki will
not pick up these defaults until after
configure has been run and the configuration saved. To prevent your extension from falling over when run this way, you should always provide intelligent defaults for configuration items
in the code.
Putting it all together, we get the
.spec for
MyContrib:
#---+ Extensions
#---++ MyContrib
# This extension supports graunching, munging and general dibbling.
# **STRING 30 EXPERT**
# Options for the <tt>graunch</tt> command
$Foswiki::cfg{MyContrib}{graunch} = "--flibble --nomunge";
# **SELECT blue rinse,mullet,beehive**
# Style setting. This sets the required <bold>hair style</bold>.
$Foswiki::cfg{MyContrib}{style} = 'blue rinse';
Namespaces
Keep your configuration values in the appropriate namespace. Plugins each have their own configuration namespace,
viz.
$Plugins.Foswiki::Cfg{Plugins}{XXX} where
XXX is the name of the plugin. All
Enabled flags and
{Module} settings are already in this namespace
e.g.
$Plugins.Foswiki::cfg{Plugins}{ActionTrackerPlugin}{Enabled} = 1;
Contribs, Skins, AddOns and Applications should all occupy the
Extensions namespace
e.g.
$Plugins.Foswiki::cfg{Extensions}{MailInContrib}{DEBUG} = 0;.
The namespaces for Plugins and Extensions are deliberately kept separate because Plugins can be selectively enabled and disabled, whereas other types of extension are always enabled if they are installed.
Types
The following field types are supported in
.spec files:
| Type name |
Description |
Attributes |
Example |
| BOOLEAN |
Boolean value |
- |
**BOOLEAN** |
| COMMAND |
String representing an operating system command |
- |
**COMMAND** |
| LANGUAGE |
| NUMBER |
Numerical value |
- |
**NUMBER** |
| OCTAL |
Octal (permissions) value |
- |
**OCTAL** |
| PASSWORD |
Password (hidden) |
- |
**PASSWORD** |
| PATH |
File path |
- |
**PATH** |
| PERL |
Arbitrary perl value |
- |
**PERL** |
| REGEX |
Regular expression |
- |
**COMMAND** |
| SELECT |
Choices |
Comma-separated list of legal values |
**SELECT crypt,sha1,md5,plain** |
| SELECTCLASS |
Choice of classes/packages, where package names may be matched from disc. |
List of package names. Package specifications may include wildcards; in the example, all package with names ending in Login will be selected from the Foswiki::Client package. none is a special name used to indicate no choice. |
**SELECTCLASS none,Plugins.Foswiki::Client::*Login** |
| STRING |
Arbitrary text string |
width |
**STRING 30** |
| URL |
Absolute URL |
- |
**URL** |
| URLPATH |
Relative URL |
- |
**URLPATH** |
All fields support some common attributes:
EXPERT |
Indicates that this is an expert setting. This just generates a slightly different UI. |
M |
Indicates this setting is mandatory (must have a value for Foswiki to run) |
H |
If this is present, the field will not be shown in configure |
Note that these types are supported because there is a
.pm file for the type in the
lib/Foswiki/Configure/Types directory. Extensions may add other types by installing an appropriate
.pm to this directory. The .pm may define the following functions:
prompt |
Generates the HTML to prompt for a value |
string2value |
Used to convert from the string returned by $query->param() to the actual stored value |
equals |
Used to compare two values of this type |
onUpdate |
Invoked if a value of this type is changed |
See the code for examples and function specs.
A note on the PERL type
The
PERL type allows you to enter simple perl data structures for values. The value entered by a user must be valid perl, but that is the limit of the checking. If you use the
PERL type, you are strongly recommended to implement a Checker for the field (see Checkers, below).
PERL H Switchboard entries
If your extension will be implementing a new CGI script, you also have to populate a Switchboard entry. This can be entered as a "Hidden PERL" type spec.
Note that the user must visit and save in /bin/configure to apply the hidden attribute even though it may appear that nothing has changed. See
Development/FoswikiStandAlone#Note_to_Extension_Developers for more details.
# **PERL H**
# This setting is required to enable executing "myscript" script from the bin directory
$Foswiki::cfg{SwitchBoard}{myscript} = {
package => 'Foswiki::Contrib::MyContrib',
function => 'myFunction',
context => { view => 1 },
};
Checkers
configure supports optional
checkers for values. These checkers are short pieces of perl code that validate the values entered by the
configure user and generate informational messages. Checkers are packages in
lib/Foswiki/Configure/Checkers that are named for the field they check. Checker packages define a single function,
check. This function is used to perform value validation. For example, we might have a
.spec as follows:
#---+ Extensions
#---++ MyContrib
# The contrib is responsible for firtling, graunching, munging and general dibbling.
# **SELECT blue rinse,mullet,beehive**
# Style setting. This sets the <i>required</i> hair style.
$Foswiki::cfg{MyContrib}{style} = 'blue rinse';
A checker for this item would be installed in
lib/Foswiki/Configure/Checkers/MyContrib/style.pm, and would contain:
package Foswiki::Configure::Checkers::MyContrib::style;
use base 'Foswiki::Configure::Checkers::Checker';
sub check {
my $this = shift; # This object is used to generate warning and error strings
if ($Foswiki::cfg{MyContrib}{style} eq 'mullet') {
return $this->WARNING("Mullets went out of fashion in the 1980's");
} elsif ($Foswiki::cfg{MyContrib}{style} eq 'blue rinse') {
return $this->ERROR("Blue rinses are reserved for little old ladies");
}
return '';
}
The string returned by
check will be used to generate a warning/error message in
configure. Checkers can also be used to 'guess' values based on platform inspection. See
lib/Foswiki/Configure/Checkers/DataDir.pm for an example of this approach.
There are many checkers pre-installed in Foswiki to check the standard configuration items. You can
read the code of these checkers to gain inspiration for your own.
Specialised User Interfaces (UIs)
configure supports the inclusion of specialised UIs for very complex applications. For example, the extensions installer is a specialised UI, as is the Plugin enabler. Specialised UIs are packages stored in the
lib/Foswiki/Configure/UIs directory. You have to be very expert to use them, and there is almost no documentation. Contact
CrawfordCurrie if you need help with this.
Related topics: System.Plugins,
ExtensionDeveloperGuide