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