Newer Older
174 lines | 4.552kb
add files
Yuki Kimoto authored on 2014-03-26
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