File Coverage

blib/lib/Mojolicious/Plugin/JSONConfig.pm
Criterion Covered Total %
statement 22 22 100.0
branch 4 6 66.6
condition 2 2 100.0
subroutine 6 6 100.0
pod 3 3 100.0
total 37 39 94.8


line stmt bran cond sub pod time code
1             package Mojolicious::Plugin::JSONConfig;
2 5     5   41 use Mojo::Base 'Mojolicious::Plugin::Config';
  5         10  
  5         46  
3              
4 5     5   38 use Mojo::JSON qw(from_json);
  5         19  
  5         304  
5 5     5   35 use Mojo::Template;
  5         12  
  5         58  
6              
7             sub parse {
8 8     8 1 26 my ($self, $content, $file, $conf, $app) = @_;
9              
10 8         23 my $config = eval { from_json $self->render($content, $file, $conf, $app) };
  8         22  
11 8 100       39 die qq{Can't load configuration from file "$file": $@} if $@;
12 7 50       24 die qq{Configuration file "$file" did not return a JSON object} unless ref $config eq 'HASH';
13              
14 7         40 return $config;
15             }
16              
17 15     15 1 39 sub register { shift->SUPER::register(shift, {ext => 'json', %{shift()}}) }
  15         106  
18              
19             sub render {
20 12     12 1 30 my ($self, $content, $file, $conf, $app) = @_;
21              
22             # Application instance and helper
23 12         26 my $prepend = q[no strict 'refs'; no warnings 'redefine'; my $app = shift; sub app; local *app = sub { $app };]
24             . q[use Mojo::Base -strict; no warnings 'ambiguous';];
25              
26 12   100     123 my $mt = Mojo::Template->new($conf->{template} // {})->name($file);
27 12         61 my $output = $mt->prepend($prepend . $mt->prepend)->render($content, $app);
28 12 50       155 return ref $output ? die $output : $output;
29             }
30              
31             1;
32              
33             =encoding utf8
34              
35             =head1 NAME
36              
37             Mojolicious::Plugin::JSONConfig - JSON configuration plugin
38              
39             =head1 SYNOPSIS
40              
41             # myapp.json (it's just JSON with embedded Perl)
42             {
43             %# Just a value
44             "foo": "bar",
45              
46             %# Nested data structures are fine too
47             "baz": ["♥"],
48              
49             %# You have full access to the application
50             "music_dir": "<%= app->home->child('music') %>"
51             }
52              
53             # Mojolicious
54             my $config = $app->plugin('JSONConfig');
55             say $config->{foo};
56              
57             # Mojolicious::Lite
58             my $config = plugin 'JSONConfig';
59             say $config->{foo};
60              
61             # foo.html.ep
62             %= config->{foo}
63              
64             # The configuration is available application-wide
65             my $config = app->config;
66             say $config->{foo};
67              
68             # Everything can be customized with options
69             my $config = plugin JSONConfig => {file => '/etc/myapp.conf'};
70              
71             =head1 DESCRIPTION
72              
73             L is a JSON configuration plugin that preprocesses its input with L.
74              
75             The application object can be accessed via C<$app> or the C function. A default configuration filename in the
76             application home directory will be generated from the value of L (C<$moniker.json>). You can
77             extend the normal configuration file C<$moniker.json> with C specific ones like C<$moniker.$mode.json>, which
78             will be detected automatically.
79              
80             These configuration values are currently reserved:
81              
82             =over 2
83              
84             =item C
85              
86             If this configuration value has been set in L when this plugin is loaded, it will not do anything
87             besides loading deployment specific plugins.
88              
89             =item C
90              
91             "plugins": [{"SetUserGroup": {"user": "sri", "group": "staff"}}]
92              
93             One or more deployment specific plugins that should be loaded right after this plugin has been loaded.
94              
95             =back
96              
97             The code of this plugin is a good example for learning to build new plugins, you're welcome to fork it.
98              
99             See L for a list of plugins that are available by default.
100              
101             =head1 OPTIONS
102              
103             L inherits all options from L and supports the following
104             new ones.
105              
106             =head2 template
107              
108             # Mojolicious::Lite
109             plugin JSONConfig => {template => {line_start => '.'}};
110              
111             Attribute values passed to L object used to preprocess configuration files.
112              
113             =head1 METHODS
114              
115             L inherits all methods from L and implements the
116             following new ones.
117              
118             =head2 parse
119              
120             $plugin->parse($content, $file, $conf, $app);
121              
122             Process content with L and parse it with L.
123              
124             sub parse ($self, $content, $file, $conf, $app) {
125             ...
126             $content = $self->render($content, $file, $conf, $app);
127             ...
128             return $hash;
129             }
130              
131             =head2 register
132              
133             my $config = $plugin->register(Mojolicious->new);
134             my $config = $plugin->register(Mojolicious->new, {file => '/etc/foo.conf'});
135              
136             Register plugin in L application and merge configuration.
137              
138             =head2 render
139              
140             $plugin->render($content, $file, $conf, $app);
141              
142             Process configuration file with L.
143              
144             sub render ($self, $content, $file, $conf, $app) {
145             ...
146             return $content;
147             }
148              
149             =head1 SEE ALSO
150              
151             L, L, L.
152              
153             =cut