Skip to content

DevGuide ConfigDirectives

Violet edited this page Nov 2, 2010 · 2 revisions

MDG: Configuration Directives

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.

Registering File Paths

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

Handlers

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/';
    }
}

Configuration Directive Types

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

Scalars

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.

Arrays

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.'

Hashes

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

Tag Aliases

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

Accessing Configuration Properties in Perl

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.

Tip: When is it best to use a configuration file?

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.

Continue Reading

 


Questions, comments, can't find something? Let us know at our community outpost on Get Satisfaction.

Credits

  • Author: Byrne Reese
  • Edited by: Violet Bliss Dietz
Clone this wiki locally