File Coverage

blib/lib/Articulate.pm
Criterion Covered Total %
statement 15 21 71.4
branch n/a
condition n/a
subroutine 5 6 83.3
pod 1 1 100.0
total 21 28 75.0


line stmt bran cond sub pod time code
1             package Articulate;
2 4     4   19326 use strict;
  4         7  
  4         150  
3 4     4   20 use warnings;
  4         7  
  4         112  
4              
5 4     4   2168 use Moo;
  4         62443  
  4         22  
6             with 'MooX::Singleton';
7              
8 4     4   8406 use Articulate::Service;
  4         13  
  4         19  
9 4     4   1395 use Module::Load ();
  4         8  
  4         1474  
10             our $VERSION = '0.003';
11              
12             =head1 NAME
13              
14             Articulate - A lightweight Perl CMS Framework
15              
16             =head1 WARNING
17              
18             This is very much in alpha. Things will change. Feel free to build things and have fun, but don't hook up anything business-critical just yet!
19              
20             =head1 SYNOPSIS
21              
22             # (in bin/app.pl)
23             use Dancer;
24             use Dancer::Plugin::Articulate;
25             articulate_app->enable;
26             dance;
27              
28             B provides a content management service for your web app. It's lightweight, i.e. it places minimal demands on your app while maximising 'whipuptitude': it gives you a single interface in code to a framework that's totally modular underneath, and it won't claim any URL endpoints for itself.
29              
30             You don't need to redesign your app around Articulate, it's a service that you call on when you need it, and all the 'moving parts' can be switched out if you want to do things your way.
31              
32             It's written in Perl, the fast, reliable 'glue language' that's perfect for agile web development projects, and currently runs on the L and L web frameworks.
33              
34             =head1 GETTING STARTED
35              
36             Don't forget to install Articulate - remember, it's a library, not an app.
37              
38             # From source:
39             perl Makefile.PL
40             make
41             make test
42             make install
43              
44             Check out the examples in the C folder of the distribution.
45              
46             To add Articulate to your own app, you'll need to:
47              
48             =over
49              
50             =item * add it to your C or similar (see example above) using either L or L.
51              
52             =item * edit your C to configure the components you want (check each of the components for a description of their config options - or just borrow a config from one of the examples)
53              
54             =item * write any custom code you want if you don't like what's there, and just swap it out in the config.
55              
56             =item * polish off your front-end, all the backend is taken care of!
57              
58             =back
59              
60             Curious about how it all fits together? Read on...
61              
62             =head1 DESCRIPTION
63              
64             Articulate is a set of components that work together to provide a content management service that will sit alongside an existing Dancer app or form the basis of a new one.
65              
66             If you want to see one in action, grab the source and run:
67              
68             # If you have Dancer and Dancer::Plugin::Articulate installed:
69             cd examples/plain-speaking
70             perl bin/app.pl -e dancer1
71              
72             # Or, if you have Dancer2 and Dancer2::Plugin::Articulate installed:
73             cd examples/plain-speaking
74             perl bin/app.psgi
75              
76             You can see how it's configured by looking at
77              
78             examples/plain-speaking/config.yml
79              
80             Notice that C doesn't directly load anything but the Articulate plugin (which loads config into this module). Everything you need is in C, and you can replace components with ones you've written if your app needs to do different things.
81              
82             =head2 Request/Response lifecycle summary
83              
84             In a B, you parse user input and pick the parameters you want to send to the B. Have a look at L for some examples. The intention is that routes are as 'thin' as possible: business logic should all be done by some part of the service and not in the route handler. The route handler maps endpoints (URLs) to service requests; structured responses are passed back as return values and are picked up by the B.
85              
86             B pass B to B. A B contains a B (like C) and B (like the B you want to create it at and the B you want to place there). See L for more details.
87              
88             The B is responsible for handling requests for managed content. L B to a service B, asking each in turn if they are willing to handle the request (normally the provider will dertermine this based on the request verb). A provider typically checks a user has suitable permission, then interacts with the content storage system.
89              
90             B is controlled by L. It delegates to a storage class which is configured for actions like C and C.
91              
92             Content is stored in a structure called an B (see L), which has a C (see L), the B (which could be a binary blob like an image, plain text, markdown, XML, etc.) and the associated B or B (which is a hashref).
93              
94             Before items can be placed in storage, the service should take care to run them through B. L delegates this to validators, and if there are any applicable validators, they will check if the content is valid. The content may also be B, i.e. further metadata added, like the time at which the request was made (consult L for details).
95              
96             After items are retrieved from storage, there is the opportunity to B them, for instance by including relevant content from elsewhere which belongs in the response. See L for details on this.
97              
98             If at any time uncaught errors are thrown, including recognised L objects, they are caught and handled by L. L should therefore always return an L object.
99              
100             Once the request finds it back to the Route it will typically be B immediately (see L), and the resulting response passed back to the user.
101              
102             =head2 Components
103              
104             The following classes are persistent, configurable B of the system:
105              
106             =over
107              
108             =item * L
109              
110             =item * L
111              
112             =item * L
113              
114             =item * L
115              
116             =item * L
117              
118             =item * L
119              
120             =item * L
121              
122             =item * L
123              
124             =item * L
125              
126             =item * L
127              
128             =back
129              
130             =head2 Data Classes
131              
132             The following classes are used for passing request data between components:
133              
134             =over
135              
136             =item * L
137              
138             =item * L
139              
140             =item * L
141              
142             =item * L
143              
144             =item * L
145              
146             =item * L
147              
148             =item * L
149              
150             =item * L
151              
152             =item * L
153              
154             =back
155              
156             =head2 Other modules of interest
157              
158             =over
159              
160             =item * L
161              
162             =item * L
163              
164             =item * L
165              
166             =item * L
167              
168             =item * L
169              
170             =back
171              
172             =head2 Instantiation
173              
174             Articulate provides a very handy way of creating (or B) objects through your config. The following config, for instance, assignes to the providers attribute (on some other object), an arrayref of four objects, the first created without no arguments, two created with arguments, and a final one created without arguments but using an unusual constructor.
175              
176             providers:
177             - MyProvider::Simple
178             - class: MyProvider::Congfigurable
179             args:
180             verbose: 1
181             - MyProvider::Congfigurable:
182             lax: 1
183             verbose: 1
184             - class: MyProvider::Idiosyncratic
185             constuctor: tada
186              
187             For more details, see L.
188              
189             =head2 Delegation
190              
191             A key part of the flexibility of Articulate is that objects often B functions to other objects (the B)
192              
193             Typically, one class delegates to a series of providers, which are each passed the same arguments in turn. L is a good example of this. Sometimes the response from one provider will halt the delegation - see L for an example of this.
194              
195             Occasionally, only one provider is possible, for instance L. In this case there is a substitution rather than a delegation.
196              
197             =cut
198              
199             =head1 METHOD
200              
201             =head3 enable
202              
203             Sets up the routes. This does not happen at construction so you can control the point at which routes are declared.
204              
205             =head1 ATTRIBUTES
206              
207             =head3 enabled
208              
209             Please do not set this directly, use C instead.
210              
211             =head3 routes
212              
213             The packages which provide routes for Articulate. See L and L for more details.
214              
215             =head3 components
216              
217             The different working pieces of the Articulate app. Components all have access to each other indirectly and they provide features across Articulate; see L for more details.
218              
219             =cut
220              
221             sub enable {
222 0     0 1   my $self = shift;
223 0           foreach my $route (@{ $self->routes }){
  0            
224 0           $route->app($self);
225 0           $route->enable;
226             }
227 0           $self->enabled(1);
228             }
229              
230             has enabled =>
231             is => 'rw',
232             default => sub { 0 };
233              
234             has routes => (
235             is => 'rw',
236             default => sub { [] },
237             coerce => sub { Module::Load::load('Articulate::Syntax'); Articulate::Syntax::instantiate_array ( @_ ) },
238             trigger => sub {
239             my $self = shift;
240             my $orig = shift;
241             $_->app($self) foreach @$orig;
242             },
243             );
244              
245             has components => (
246             is => 'rw',
247             default => sub { {} },
248             coerce => sub {
249             my $orig = shift;
250             Module::Load::load('Articulate::Syntax');
251             Articulate::Syntax::instantiate_selection ( $orig );
252              
253             },
254             trigger => sub {
255             my $self = shift;
256             my $orig = shift;
257             $orig->{$_}->app($self) foreach keys %$orig;
258             },
259             );
260              
261             =head1 BUGS
262              
263             Bugs should be reported to the L. Pull Requests welcome!
264              
265             =head1 COPYRIGHT
266              
267             Articulate is Copyright 2014-2015 Daniel Perrett. You are free to use it subject to the same terms as perl: see the LICENSE file included in this distribution for what this means.
268              
269             Currently Articulate is bundled with versions of other software whose license information you can access from the LICENSE file.
270              
271             =cut
272              
273             1;