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