1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
|
package Mojolicious::Plugin::Config;
use Mojo::Base 'Mojolicious::Plugin';
use File::Spec::Functions 'file_name_is_absolute';
use Mojo::Util qw(decode slurp);
sub load {
my ($self, $file, $conf, $app) = @_;
$app->log->debug(qq{Reading configuration file "$file".});
return $self->parse(decode('UTF-8', slurp $file), $file, $conf, $app);
}
sub parse {
my ($self, $content, $file, $conf, $app) = @_;
# Run Perl code
my $config
= eval 'package Mojolicious::Plugin::Config::Sandbox; no warnings;'
. "sub app; local *app = sub { \$app }; use Mojo::Base -strict; $content";
die qq{Can't load configuration from file "$file": $@} if !$config && $@;
die qq{Configuration file "$file" did not return a hash reference.\n}
unless ref $config eq 'HASH';
return $config;
}
sub register {
my ($self, $app, $conf) = @_;
# Config file
my $file = $conf->{file} || $ENV{MOJO_CONFIG};
$file ||= $app->moniker . '.' . ($conf->{ext} || 'conf');
# Mode specific config file
my $mode = $file =~ /^(.*)\.([^.]+)$/ ? join('.', $1, $app->mode, $2) : '';
my $home = $app->home;
$file = $home->rel_file($file) unless file_name_is_absolute $file;
$mode = $home->rel_file($mode) if $mode && !file_name_is_absolute $mode;
$mode = undef unless $mode && -e $mode;
# Read config file
my $config = {};
if (-e $file) { $config = $self->load($file, $conf, $app) }
# Check for default and mode specific config file
elsif (!$conf->{default} && !$mode) {
die qq{Configuration file "$file" missing, maybe you need to create it?\n};
}
# Merge everything
$config = {%$config, %{$self->load($mode, $conf, $app)}} if $mode;
$config = {%{$conf->{default}}, %$config} if $conf->{default};
return $app->defaults(config => $app->config)->config($config)->config;
}
1;
=encoding utf8
=head1 NAME
Mojolicious::Plugin::Config - Perl-ish configuration plugin
=head1 SYNOPSIS
# myapp.conf (it's just Perl returning a hash)
{
foo => "bar",
music_dir => app->home->rel_dir('music')
};
# Mojolicious
my $config = $self->plugin('Config');
say $config->{foo};
# Mojolicious::Lite
my $config = plugin 'Config';
say $config->{foo};
# foo.html.ep
%= $config->{foo}
# The configuration is available application wide
my $config = app->config;
say $config->{foo};
# Everything can be customized with options
my $config = plugin Config => {file => '/etc/myapp.stuff'};
=head1 DESCRIPTION
L<Mojolicious::Plugin::Config> is a Perl-ish configuration plugin.
The application object can be accessed via C<$app> or the C<app> function,
L<strict>, L<warnings>, L<utf8> and Perl 5.10 features are automatically
enabled. You can extend the normal configuration file C<$moniker.conf> with
C<mode> specific ones like C<$moniker.$mode.conf>. A default configuration
filename will be generated from the value of L<Mojolicious/"moniker">.
The code of this plugin is a good example for learning to build new plugins,
you're welcome to fork it.
See L<Mojolicious::Plugins/"PLUGINS"> for a list of plugins that are available
by default.
=head1 OPTIONS
L<Mojolicious::Plugin::Config> supports the following options.
=head2 default
# Mojolicious::Lite
plugin Config => {default => {foo => 'bar'}};
Default configuration, making configuration files optional.
=head2 ext
# Mojolicious::Lite
plugin Config => {ext => 'stuff'};
File extension for generated configuration filenames, defaults to C<conf>.
=head2 file
# Mojolicious::Lite
plugin Config => {file => 'myapp.conf'};
plugin Config => {file => '/etc/foo.stuff'};
Full path to configuration file, defaults to the value of the C<MOJO_CONFIG>
environment variable or C<$moniker.conf> in the application home directory.
=head1 METHODS
L<Mojolicious::Plugin::Config> inherits all methods from
L<Mojolicious::Plugin> and implements the following new ones.
=head2 load
$plugin->load($file, $conf, $app);
Loads configuration file and passes the content to L</"parse">.
sub load {
my ($self, $file, $conf, $app) = @_;
...
return $self->parse($content, $file, $conf, $app);
}
=head2 parse
$plugin->parse($content, $file, $conf, $app);
Parse configuration file.
sub parse {
my ($self, $content, $file, $conf, $app) = @_;
...
return $hash;
}
=head2 register
my $config = $plugin->register(Mojolicious->new);
my $config = $plugin->register(Mojolicious->new, {file => '/etc/app.conf'});
Register plugin in L<Mojolicious> application and merge configuration.
=head1 SEE ALSO
L<Mojolicious>, L<Mojolicious::Guides>, L<http://mojolicio.us>.
=cut
|