-
Notifications
You must be signed in to change notification settings - Fork 36
DevGuide ConfigDirectives
The first plugin you built in this guide helped you to create a plugin with a configuration directive. But we only scratched the surface.
A quick review: configuration directives are placed in your Melody's config.cgi
file by a system administrator. Not everyone on an install has the access to the machine to make this kind of change, which limits the utility of configuration directives to some extent. We will explore more user friendly means of configuring Melody later, but for now, let's round out our knowledge of this critical piece of Melody. (See also: Tip: When is it best to use a configuration file?)
Here is the config.yaml
file we were basing previous examples on:
name: Example Plugin for Melody
id: Example
description: This plugin is an example plugin for Melody.
version: 1.0
config_settings:
MyLogPath:
default: /var/log/mt/errors.log
Let's slowly add to this as we talk about additional concepts and features supported by the Melody config_settings registry.
An additional option labeled path
can be used when registering a configuration directive. This option should be used whenever the configuration directive stores a reference to a path on the filesystem (not a url, but a path). This enables Melody to convert all relative paths referenced by the directive to an absolute path automatically.
config_settings:
MyLogPath:
default: /var/log/mt/errors.log
path: 1
Some configuration directives may have a default value, but a default value that may be dependent upon other variables in the system. Therefore a static default value may not suffice. For example, you may have a configuration directive that is dependent upon where you have Apache installed, and it will formulate a path based on that if a explicit value is not set by an administrator.
To achieve this, you need to use the handler
option like so:
config_settings:
MyLogPath:
handler: $Example::Example::Plugin::MyLogPath
path: 1
Then, in your Plugin.pm
file you add the following subroutine (comments have been added to the code to help make sense of what is going on):
sub MyLogPath {
my $mgr = shift; # A reference to MT::ConfigMgr
# if this method is invoked with the intent to set the value,
# go ahead and set the value, then return.
return $mgr->set_internal( 'MyLogPath', @_ ) if @_;
# user is attempting to retrieve the value
my $name = $mgr->get_internal('MyLogPath');
# if a value has been explicitly set, return it
return $name if defined $name;
# Ok, guess what the value should be:
if ($ENV{HTTPD_HOME}) {
return $ENV{HTTPD_HOME} . '/logs';
} else {
return 'logs/';
}
}
Melody supports a type
registry property with configuration directives which controls how their values should be parsed and/or aggregated. There are three types:
- scalar (default)
- array
- hash
Here's what it looks like in the registry:
config_settings:
FavoriteWebSites:
type: array
The default value of the type
property is scalar. This requires that the configuration directive possess only a single value. When two config directives are defined with the same name, then the last value specified take precedence. For example, if your config.cgi
contained the following:
CGIPath /cgi-bin/mt/
MyDirective foo
MyDirective bar
Then the following:
$mgr->get_internal('MyDirective')
Could only return the value "bar" because it was the last to occur in the config file.
Config directives of type 'array' result in Melody aggregating all config directive values that have the same name into an array or list.
For example, if your config.cgi
contained the following:
CGIPath /cgi-bin/mt/
MyDirective foo
MyDirective bar
Then the following:
$mgr->get_internal('MyDirective')
Would return an array containing the values 'foo' and 'bar.'
Config directives of type 'hash' are expressed a little bit differently. Values are expressed in two parts: a hash key, and a hash value. For these types of directives Melody aggregates all config directives of the same name into an hash of key/value pairs.
For example, if your `config.cgi
Questions, comments, can't find something? Let us know at our community outpost on Get Satisfaction. ` contained the following:
CGIPath /cgi-bin/mt/
MyDirective foo 123
MyDirective bar abc
Then the following:
$mgr->get_internal('MyDirective')
Would return a hash containing:
foo => 123
bar => abc
Suppose you set a configuration directive in version 1.0 of your plugin, but then later had the realization that the name you chose for the directive was not ideal. In the next version of your plugin you want to change the name of the directive, but you don't want to break backwards compatibility with users of version 1.0 when they upgrade.
To map one configuration directive to another, use the alias
option like so:
name: Example Plugin for Melody
id: Example
description: This plugin is an example plugin for Melody.
version: 1.0
config_settings:
MyLogPath:
default: /var/log/mt/errors.log
path: 1
MyErrorLogPath:
alias: MyLogPath
Finally, whenever you need to access the value entered by the system administrator for a configuration directive, you can do so using some very simple Perl code:
use MT;
sub some_method {
my ($foo) = @_;
my $log = MT->config('CustomErrorLog');
# do stuff
}
Note: One thing of interest is the static reference to MT
. MT is actually a singleton and as a result there is no need for a developer to instantiate an instance of MT each an every time they need to access its context.
Given that there are multiple ways to collect configuration data, when is it best to use a configuration file instead of via a user interface? This is actually a very difficult question to answer definitively. Consider the following:
-
Will the configuration property need to be modified frequently? If so, you may consider implementing a UI for shear convenience.
-
Will setting the configuration property need to be a highly privileged right on the system? If so, then by placing it in a config file you ensure that only users with direct access to the file system will have permission to edit it.
-
How quickly do I need to introduce a new feature I am planning that requires configuration? If the answer is soon, then there is no quicker way to provide configurable features then via a config directive.
-
Will my feature need to be configured on a blog-by-blog basis? If so, then a config directive is not likely to be an ideal solution.
Questions, comments, can't find something? Let us know at our community outpost on Get Satisfaction.
- Author: Byrne Reese
- Edited by: Violet Bliss Dietz