NAME
Mojolicious::Plugin::ContentManagement - Content management for Mojolicious
VERSION
Version 0.01
SYNOPSIS
use Mojolicious::Lite;
# Change this!
my $admin_route = app->routes->bridge('/admin')->to( cb => sub {
my $self = shift;
my $user = $self->param('user') || 'foo';
my $pass = $self->param('pass') || 'bar';
return 1 if $user eq $pass;
$self->res->code(401);
$self->res->body(<<'EOF');
<!doctype html><html>
<head><title>Authorization required</title></head>
<body><h1>401 Authorization required</h1></body>
EOF
});
plugin content_management => {
source => 'filesystem',
source_conf => { directory => 'content' },
type => 'markdown',
type_conf => { empty_element_suffix => '>' },
forbidden => [ '/foo.html', qr|/bar/\d{4}/baz.html| ],
admin_route => $admin_route,
};
get '/(*everything)' => ( content_management => 1 ) => 'page';
# your webapp stuff goes here,
# avoid routes that aren't matched by the forbidden rules above
__DATA__
@@ page.html.ep
% layout 'default';
%== $content_page->html;
DESCRIPTION
This is a simple but flexible and extendable content management system that seamlessly integrates into your Mojolicious or Mojolicious::Lite app. You can use your own actions to display generated content and create your own bridge or waypoint routes for the optional admin interface.
First, Mojolicious::Plugin::ContentManagement (called MPCM from now on) comes as a Mojolicious plugin that can be used with the standard plugin code:
# Mojolicious
sub startup {
my $self = shift;
$self->plugin( content_management => $conf );
...
}
# Mojolicious::Lite
plugin content_management => $conf;
CONFIGURATION
The $conf
scalar needs to be a hashref with the following keys:
- source
-
The source class used to store and generate content pages. The value of this option is camelized before used to find the right class, for example you write
source => 'filesystem'
and MPCM loads Mojolicious::Plugin::ContentManagement::Source::Filesystem for you.
See Mojolicious::Plugin::ContentManagement::Source for more implementations.
- source_conf
-
A configuration hashref that is passed to your
source
class. See the documentation of your source class for more details. - type
-
The type class. This is a translator for your content pages. The value of this option is camelized before used, like the
source
. See Mojolicious::Plugin::ContentManagement::Type for implementations. - type_conf
-
A configuration hashref that is passed to your
type
class. See the documentation of your source class for more details. - forbidden
-
An arrayref with paths and path regexes which must not be managed by MPCM (because you need them for your own routes and actions).
- admin_route
-
If you want an admin interface for MPCM, you can pass a route object, so MPCM can set up routes to let you list or edit the pages. A typical way to do this is to set up a bridge for the path '/admin' with some kind of authentication and passing this bridge to MPCM:
my $admin_route = $routes->bridge('/admin')->to( cb => sub { my $self = shift; my $user = $self->param('user') || 'foo'; my $pass = $self->param('pass') || 'bar'; return 1 if $user eq $pass; $self->res->code(401); $self->res->body(<<'EOF'); <!doctype html><html> <head><title>Authorization required</title></head> <body><h1>401 Authorization required</h1></body> EOF });
I'm sure you can do that more securely, but I hope it shows what I mean. The
$admin_route
can now be passed to MPCM and it will create things like/admin/edit/foo.html
which are only accessable if the user passes the bridge.
CONTENT HANDLING
You need to set up a controller or something like that which displays the managed content. But how do you dispatch? No problem, this is what the content_management
condition is for:
# Mojolicious::Lite
get '/(*everything)' => ( content_management => 1 ) => sub {
my $self = shift;
# do something with $self->stash('content_page')
}) => 'content';
# Mojolicious
$r->route('/(*everything)')->over( content_management => 1 )
->to('foo#content');
If this matches, you have access to the stash element 'content_page', which is a Mojolicious::Plugin::ContentManagement::Page object. For most cases, this will do it:
get '/(*everything)' => ( content_management => 1 ) => 'page'
__DATA__
@@page.html.ep
% layout 'default';
%== $content_page->html
GENERATING THE ADMIN TEMPLATES
The (optional) admin interface ships with templates. This is how you generate them in your app home dir:
$ mojolicious generate content_management_templates
Change the templates if you want and if you know what you're doing.
BUGS
Please use githubs issue tracker at http://github.com/memowe/mojolicious-plugin-content_management.
If you want to provide patches, feel free to fork and pull request me.
AUTHOR, COPYRIGHT AND LICENSE
Copyright (c) 2010 Mirko Westermeier, <mail at memowe.de>
Released under the MIT license (see MIT-LICENSE) for details.