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
|
package Mojolicious::Plugin::JSONConfig;
use Mojo::Base 'Mojolicious::Plugin::Config';
use Mojo::JSON qw(from_json);
use Mojo::Template;
sub parse {
my ($self, $content, $file, $conf, $app) = @_;
my $config = eval { from_json $self->render($content, $file, $conf, $app) };
die qq{Can't load configuration from file "$file": $@} if $@;
die qq{Configuration file "$file" did not return a JSON object} unless ref $config eq 'HASH';
return $config;
}
sub register { shift->SUPER::register(shift, {ext => 'json', %{shift()}}) }
sub render {
my ($self, $content, $file, $conf, $app) = @_;
# Application instance and helper
my $prepend = q[no strict 'refs'; no warnings 'redefine'; my $app = shift; sub app; local *app = sub { $app };]
. q[use Mojo::Base -strict; no warnings 'ambiguous';];
my $mt = Mojo::Template->new($conf->{template} // {})->name($file);
my $output = $mt->prepend($prepend . $mt->prepend)->render($content, $app);
return ref $output ? die $output : $output;
}
1;
=encoding utf8
=head1 NAME
Mojolicious::Plugin::JSONConfig - JSON configuration plugin
=head1 SYNOPSIS
# myapp.json (it's just JSON with embedded Perl)
{
%# Just a value
"foo": "bar",
%# Nested data structures are fine too
"baz": ["♥"],
%# You have full access to the application
"music_dir": "<%= app->home->child('music') %>"
}
# Mojolicious
my $config = $app->plugin('JSONConfig');
say $config->{foo};
# Mojolicious::Lite
my $config = plugin 'JSONConfig';
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 JSONConfig => {file => '/etc/myapp.conf'};
=head1 DESCRIPTION
L<Mojolicious::Plugin::JSONConfig> is a JSON configuration plugin that preprocesses its input with L<Mojo::Template>.
The application object can be accessed via C<$app> or the C<app> function. A default configuration filename in the
application home directory will be generated from the value of L<Mojolicious/"moniker"> (C<$moniker.json>). You can
extend the normal configuration file C<$moniker.json> with C<mode> specific ones like C<$moniker.$mode.json>, which
will be detected automatically.
These configuration values are currently reserved:
=over 2
=item C<config_override>
If this configuration value has been set in L<Mojolicious/"config"> when this plugin is loaded, it will not do anything
besides loading deployment specific plugins.
=item C<plugins>
"plugins": [{"SetUserGroup": {"user": "sri", "group": "staff"}}]
One or more deployment specific plugins that should be loaded right after this plugin has been loaded.
=back
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::JSONConfig> inherits all options from L<Mojolicious::Plugin::Config> and supports the following
new ones.
=head2 template
# Mojolicious::Lite
plugin JSONConfig => {template => {line_start => '.'}};
Attribute values passed to L<Mojo::Template> object used to preprocess configuration files.
=head1 METHODS
L<Mojolicious::Plugin::JSONConfig> inherits all methods from L<Mojolicious::Plugin::Config> and implements the
following new ones.
=head2 parse
$plugin->parse($content, $file, $conf, $app);
Process content with L</"render"> and parse it with L<Mojo::JSON>.
sub parse ($self, $content, $file, $conf, $app) {
...
$content = $self->render($content, $file, $conf, $app);
...
return $hash;
}
=head2 register
my $config = $plugin->register(Mojolicious->new);
my $config = $plugin->register(Mojolicious->new, {file => '/etc/foo.conf'});
Register plugin in L<Mojolicious> application and merge configuration.
=head2 render
$plugin->render($content, $file, $conf, $app);
Process configuration file with L<Mojo::Template>.
sub render ($self, $content, $file, $conf, $app) {
...
return $content;
}
=head1 SEE ALSO
L<Mojolicious>, L<Mojolicious::Guides>, L<https://mojolicious.org>.
=cut
|