NAME

Config::Context::ConfigScoped - Use Config::Scoped config files with Config::Context

SYNOPSIS

use Config::Context;

my $config_text = '
    Location /users {
        user_area = 1
    }

    LocationMatch '\.*(jpg|gif|png)$' {
        image_file = 1
    }
';

my $conf = Config::Context->new(
    string        => $config_text,
    driver        => 'ConfigScoped',
    match_sections => [
        {
            name          => 'Location',
            match_type    => 'path',
        },
        {
            name          => 'LocationMatch',
            match_type    => 'regex',
        },
    ],
);

my %config = $conf->context('/users/~mary/index.html');

use Data::Dumper;
print Dumper(\%config);
--------
$VAR1 = {
    'title'         => 'User Area',
    'image_file'    => undef,
};

my %config = $conf->context('/users/~biff/images/flaming_logo.gif');
print Dumper(\%config);
--------
$VAR1 = {
    'title'         => 'User Area',
    'image_file'    => 1,
};

DESCRIPTION

This module uses Config::Scoped to parse config files for Config::Context. See the Config::Context docs for more information.

DEFAULT OPTIONS

In addition to the options normally enabled by Config::Scoped, the following options are turned on by default:

warnings => {
    parameter   => 'off',
    declaration => 'off',
}

You can change this behaviour by passing a different value to driver_params to new:

my $conf = Config::Context->new(
    driver => 'ConfigScoped',
    driver_options => {
        ConfigScoped = > {
            warnings => {
                parameter  => 'on',
            }
        },
    },
);

CONSTRUCTOR

new(...)

my $driver = Config::Context::ConfigScoped->new(
    file             => $config_file,
    lower_case_names => 1,  # optional
    options          => {
        # ...
    }
);

or:

my $driver = Config::Context::ConfigScoped->new(
    string           => $config_string,
    lower_case_names => 1,  # optional
    options          => {
        # ...
    }
);

Returns a new driver object, using the provided options.

METHODS

parse()

Returns the data structure for the parsed config.

files()

Returns a list of all the config files read, including any config files included in the main file.

config_module

Returns the module used to parse the config. In this case: Config::Scoped

CAVEATS

Limitations of hash merging with included files

When one Config::Scoped file includes another, and they both contain declarations, the declarations are merged. For instance:

# config1.conf
%include config2.conf
section /users {
    title     = 'Members Area';
}

# config2.conf
section /users {
    user_area = 1;
    title     = 'users area';
}

This will result in:

{
     'section' => {
                     '/users' => {
                                'user_area' => '1',
                                'title' => 'Members Area',
                                 },
                  },
}

However, if you use hashes instead of declarations, then the second hash with the same name will completely overwrite the first one. For instance:

# config1.conf
%include config2.conf
section = {
    '/users' = {
        title     = 'Members Area';
    }
}

# config2.conf
section = {
    '/users' = {
        user_area = 1;
        title     = 'users area';
    }
}

This will result in:

{
     'section' => {
                     '/users' => {
                                'title' => 'Members Area',
                                 },
                  },
}

This is important to keep in mind because Config::Scoped does not allow nested declarations.

Default Section

When using the Config::Context::ConfigScoped driver, you must be careful with the use of the default section, since Config::Scoped does its own inheritance from the global scope into named sections. See the documentation for Config::Context::ConfigScoped for more information.

So for instance, the following will not work as expected.

private_area = 0
image_file   = 0

LocationMatch admin {
    private_area = 1
}

LocationMatch '\.(gif)|(jpg)|(png)$' {
    image_file  = 1
}

Since this is equivalent to:

LocationMatch admin {
    image_file   = 0
    private_area = 1
}

LocationMatch '\.(gif)|(jpg)|(png)$' {
    private_area = 0
    image_file  = 1
}

Values set in the default section are inherited into sections before those sections are matched.

One solution is to use hashes, rather than declarations:

private_area = 0
image_file   = 0

LocationMatch = {

    admin = {
        private_area = 1
    }

    '\.(gif)|(jpg)|(png)$' = {
        image_file  = 1
    }
}

This works, because in Config::Scoped, hashes do not inherit parameters from their enclosing scope.

_GLOBAL Scope automatically merged

Normally, if there are no declarations in a Config::Scope file, all configuration is placed under a key called _GLOBAL. Config::Context::ConfigScoped detects this condition and moves the data under _GLOBAL up a level. Basically, it does the equivalent of:

$config = $config->{_GLOBAL};

The reason for this is to allow use of hashes instead of declarations to enable default values.

Quote block names

Instead of:

LocationMatch \.*(jpg|gif|png)$ {
    # some configuration
}

use:

LocationMatch '\.*(jpg|gif|png)$' {
    # some configuration
}

Note that regular expression characters don't have to be quoted beyond this.

SEE ALSO

Config::Context
CGI::Application::Plugin::Config::Context
Config::Scoped

COPYRIGHT & LICENSE

Copyright 2004-2005 Michael Graham, All Rights Reserved.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.