Newer Older
137 lines | 3.58kb
add files
Yuki Kimoto authored on 2014-03-26
1
package Mojolicious::Plugin::JSONConfig;
2
use Mojo::Base 'Mojolicious::Plugin::Config';
3

            
4
use Mojo::JSON;
5
use Mojo::Template;
6
use Mojo::Util 'encode';
7

            
8
sub parse {
9
  my ($self, $content, $file, $conf, $app) = @_;
10

            
11
  my $json   = Mojo::JSON->new;
12
  my $config = $json->decode($self->render($content, $file, $conf, $app));
13
  my $err    = $json->error;
14
  die qq{Couldn't parse config "$file": $err} if !$config && $err;
15
  die qq{Invalid config "$file".} if !$config || ref $config ne 'HASH';
16

            
17
  return $config;
18
}
19

            
20
sub register { shift->SUPER::register(shift, {ext => 'json', %{shift()}}) }
21

            
22
sub render {
23
  my ($self, $content, $file, $conf, $app) = @_;
24

            
25
  # Application instance and helper
26
  my $prepend = q[my $app = shift; no strict 'refs'; no warnings 'redefine';];
27
  $prepend .= q[sub app; local *app = sub { $app }; use Mojo::Base -strict;];
28

            
29
  # Render and encode for JSON decoding
30
  my $mt = Mojo::Template->new($conf->{template} || {})->name($file);
31
  my $json = $mt->prepend($prepend . $mt->prepend)->render($content, $app);
32
  return ref $json ? die $json : encode 'UTF-8', $json;
33
}
34

            
35
1;
36

            
37
=encoding utf8
38

            
39
=head1 NAME
40

            
41
Mojolicious::Plugin::JSONConfig - JSON configuration plugin
42

            
43
=head1 SYNOPSIS
44

            
45
  # myapp.json (it's just JSON with embedded Perl)
46
  {
47
    "foo"       : "bar",
48
    "music_dir" : "<%= app->home->rel_dir('music') %>"
49
  }
50

            
51
  # Mojolicious
52
  my $config = $self->plugin('JSONConfig');
53
  say $config->{foo};
54

            
55
  # Mojolicious::Lite
56
  my $config = plugin 'JSONConfig';
57
  say $config->{foo};
58

            
59
  # foo.html.ep
60
  %= $config->{foo}
61

            
62
  # The configuration is available application wide
63
  my $config = app->config;
64
  say $config->{foo};
65

            
66
  # Everything can be customized with options
67
  my $config = plugin JSONConfig => {file => '/etc/myapp.conf'};
68

            
69
=head1 DESCRIPTION
70

            
71
L<Mojolicious::Plugin::JSONConfig> is a JSON configuration plugin that
72
preprocesses its input with L<Mojo::Template>.
73

            
74
The application object can be accessed via C<$app> or the C<app> function. You
75
can extend the normal config file C<myapp.json> with C<mode> specific ones
76
like C<myapp.$mode.json>. A default configuration filename will be generated
77
from the value of L<Mojolicious/"moniker">.
78

            
79
The code of this plugin is a good example for learning to build new plugins,
80
you're welcome to fork it.
81

            
82
=head1 OPTIONS
83

            
84
L<Mojolicious::Plugin::JSONConfig> inherits all options from
85
L<Mojolicious::Plugin::Config> and supports the following new ones.
86

            
87
=head2 template
88

            
89
  # Mojolicious::Lite
90
  plugin JSONConfig => {template => {line_start => '.'}};
91

            
92
Attribute values passed to L<Mojo::Template> object used to preprocess
93
configuration files.
94

            
95
=head1 METHODS
96

            
97
L<Mojolicious::Plugin::JSONConfig> inherits all methods from
98
L<Mojolicious::Plugin::Config> and implements the following new ones.
99

            
100
=head2 parse
101

            
102
  $plugin->parse($content, $file, $conf, $app);
103

            
104
Process content with L</"render"> and parse it with L<Mojo::JSON>.
105

            
106
  sub parse {
107
    my ($self, $content, $file, $conf, $app) = @_;
108
    ...
109
    $content = $self->render($content, $file, $conf, $app);
110
    ...
111
    return $hash;
112
  }
113

            
114
=head2 register
115

            
116
  my $config = $plugin->register(Mojolicious->new);
117
  my $config = $plugin->register(Mojolicious->new, {file => '/etc/foo.conf'});
118

            
119
Register plugin in L<Mojolicious> application and merge configuration.
120

            
121
=head2 render
122

            
123
  $plugin->render($content, $file, $conf, $app);
124

            
125
Process configuration file with L<Mojo::Template>.
126

            
127
  sub render {
128
    my ($self, $content, $file, $conf, $app) = @_;
129
    ...
130
    return $content;
131
  }
132

            
133
=head1 SEE ALSO
134

            
135
L<Mojolicious>, L<Mojolicious::Guides>, L<http://mojolicio.us>.
136

            
137
=cut