Mojolicious::Plugin::Yancy - Embed a simple admin CMS into your Mojolicious application
version 1.010
use Mojolicious::Lite; plugin Yancy => { backend => 'pg://postgres@/mydb', collections => { ... }, }; ## With custom auth routine use Mojo::Base 'Mojolicious'; sub startup { my ( $app ) = @_; my $auth_route = $app->routes->under( '/yancy', sub { my ( $c ) = @_; # ... Validate user return 1; } ); $app->plugin( 'Yancy', { backend => 'pg://postgres@/mydb', collections => { ... }, route => $auth_route, }); }
This plugin allows you to add a simple content management system (CMS) to administrate content on your Mojolicious site. This includes a JavaScript web application to edit the content and a REST API to help quickly build your own application.
For getting started with a configuration for Yancy, see Yancy::Help::Config.
Additional configuration keys accepted by the plugin are:
In addition to specifying the backend as a single URL (see "Database Backend"), you can specify it as a hashref of class => $db. This allows you to share database connections.
class => $db
use Mojolicious::Lite; use Mojo::Pg; helper pg => sub { state $pg = Mojo::Pg->new( 'postgres:///myapp' ) }; plugin Yancy => { backend => { Pg => app->pg } };
A base route to add Yancy to. This allows you to customize the URL and add authentication or authorization. Defaults to allowing access to the Yancy web application under /yancy, and the REST API under /yancy/api.
/yancy
/yancy/api
The URL to use for the "Back to Application" link. Defaults to /.
/
A hash of name => subref pairs of filters to make available. See "yancy.filter.add" for how to create a filter subroutine.
name => subref
This plugin adds some helpers for use in routes, templates, and plugins.
my $config = $c->yancy->config;
The current configuration for Yancy. Through this, you can edit the collections configuration as needed.
collections
my $be = $c->yancy->backend;
Get the currently-configured Yancy backend object. See Yancy::Backend for the methods you can call on a backend object and their purpose.
Get the root route where the Yancy CMS will appear. Useful for adding authentication or authorization checks:
my $route = $c->yancy->route; my @need_auth = @{ $route->children }; my $auth_route = $route->under( sub { # ... Check auth return 1; } ); $auth_route->add_child( $_ ) for @need_auth;
Add a Yancy plugin. Yancy plugins are Mojolicious plugins that require Yancy features and are found in the Yancy::Plugin namespace.
use Mojolicious::Lite; plugin 'Yancy'; app->yancy->plugin( 'Auth::Basic', { collection => 'users' } );
You can also add the Yancy::Plugin namespace into the default plugin lookup locations. This allows you to treat them like any other Mojolicious plugin.
# Lite app use Mojolicious::Lite; plugin 'Yancy', ...; unshift @{ app->plugins->namespaces }, 'Yancy::Plugin'; plugin 'Auth::Basic', ...; # Full app use Mojolicious; sub startup { my ( $app ) = @_; $app->plugin( 'Yancy', ... ); unshift @{ $app->plugins->namespaces }, 'Yancy::Plugin'; $app->plugin( 'Auth::Basic', ... ); }
Yancy does not do this for you to avoid namespace collisions.
my @items = $c->yancy->list( $collection, \%param, \%opt );
Get a list of items from the backend. $collection is a collection name. \%param is a SQL::Abstract where clause structure. Some basic examples:
$collection
\%param
# All people named exactly 'Turanga Leela' $c->yancy->list( people => { name => 'Turanga Leela' } ); # All people with "Wong" in their name $c->yancy->list( people => { name => { like => '%Wong%' } } );
\%opt is a hash of options with the following keys:
\%opt
limit - The number of items to return
offset - The number of items to skip before returning items
See the backend documentation for more information about the list method's arguments. This helper only returns the list of items, not the total count of items or any other value.
my $item = $c->yancy->get( $collection, $id );
Get an item from the backend. $collection is the collection name. $id is the ID of the item to get. See "get" in Yancy::Backend.
$id
$c->yancy->set( $collection, $id, $item_data, %opt );
Update an item in the backend. $collection is the collection name. $id is the ID of the item to update. $item_data is a hash of data to update. See "set" in Yancy::Backend. %opt is a list of options with the following keys:
$item_data
%opt
properties - An arrayref of properties to validate, for partial updates
This helper will validate the data against the configuration and run any filters as needed. If validation fails, this helper will throw an exception with an array reference of JSON::Validator::Error objects. See the validate helper and the filter apply helper. To bypass filters and validation, use the backend object directly via the backend helper.
# A route to update a comment put '/comment/:id' => sub { eval { $c->yancy->set( "comment", $c->stash( 'id' ), $c->req->json ) }; if ( $@ ) { return $c->render( status => 400, errors => $@ ); } return $c->render( status => 200, text => 'Success!' ); };
my $item = $c->yancy->create( $collection, $item_data );
Create a new item. $collection is the collection name. $item_data is a hash of data for the new item. See "create" in Yancy::Backend.
# A route to create a comment post '/comment' => sub { eval { $c->yancy->create( "comment", $c->req->json ) }; if ( $@ ) { return $c->render( status => 400, errors => $@ ); } return $c->render( status => 200, text => 'Success!' ); };
$c->yancy->delete( $collection, $id );
Delete an item from the backend. $collection is the collection name. $id is the ID of the item to delete. See "delete" in Yancy::Backend.
my @errors = $c->yancy->validate( $collection, $item, %opt );
Validate the given $item data against the configuration for the $collection. If there are any errors, they are returned as an array of JSON::Validator::Error objects. %opt is a list of options with the following keys:
$item
See "validate" in JSON::Validator for more details.
my $filter_sub = sub { my ( $field_name, $field_value, $field_conf ) = @_; ... } $c->yancy->filter->add( $name => $filter_sub );
Create a new filter. $name is the name of the filter to give in the field's configuration. $subref is a subroutine reference that accepts three arguments:
$name
$subref
$field_name - The name of the field being filtered
$field_value - The value to filter
$field_conf - The full configuration for the field
For example, here is a filter that will run a password through a one-way hash digest:
use Digest; my $digest = sub { my ( $field_name, $field_value, $field_conf ) = @_; my $type = $field_conf->{ 'x-digest' }{ type }; Digest->new( $type )->add( $field_value )->b64digest; }; $c->yancy->filter->add( 'digest' => $digest );
And you configure this on a field using x-filter and x-digest:
x-filter
x-digest
# mysite.conf { collections => { users => { properties => { username => { type => 'string' }, password => { type => 'string', format => 'password', 'x-filter' => [ 'digest' ], # The name of the filter 'x-digest' => { # Filter configuration type => 'SHA-1', }, }, }, }, }, }
my $filtered_data = $c->yancy->filter->apply( $collection, $item_data );
Run the configured filters on the given $item_data. $collection is a collection name. Returns the hash of $filtered_data.
$filtered_data
my $schema = $c->yancy->schema( $collection ); my $schema = $c->yancy->schema( $collection => $field );
Get the JSON schema for the given $collection, or the $field inside the given $collection. Returns a hashref of configuration.
$field
my $openapi = $c->yancy->openapi;
Get the Mojolicious::Plugin::OpenAPI object containing the OpenAPI interface for this Yancy API.
This plugin uses the following templates. To override these templates with your own theme, provide a template with the same name. Remember to add your template paths to the beginning of the list of paths to be sure your templates are found first:
# Mojolicious::Lite unshift @{ app->renderer->paths }, 'template/directory'; unshift @{ app->renderer->classes }, __PACKAGE__; # Mojolicious sub startup { my ( $app ) = @_; unshift @{ $app->renderer->paths }, 'template/directory'; unshift @{ $app->renderer->classes }, __PACKAGE__; }
This layout template surrounds all other Yancy templates. Like all Mojolicious layout templates, a replacement should use the content helper to display the page content. Additionally, a replacement should use content_for 'head' to add content to the head element.
content
content_for 'head'
head
This is the main Yancy web application. You should not override this. If you need to, consider filing a bug report or feature request.
Doug Bell <preaction@cpan.org>
This software is copyright (c) 2018 by Doug Bell.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.
To install Yancy, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Yancy
CPAN shell
perl -MCPAN -e shell install Yancy
For more information on module installation, please visit the detailed CPAN module installation guide.