NAME
Yancy::Controller::Yancy - Basic controller for displaying content
VERSION
version 1.023
SYNOPSIS
use Mojolicious::Lite;
plugin Yancy => {
collections => {
blog => {
properties => {
id => { type => 'integer' },
title => { type => 'string' },
html => { type => 'string' },
},
},
},
};
app->routes->get( '/' )->to(
'yancy#list',
collection => 'blog',
template => 'index',
);
__DATA__
@@ index.html.ep
% for my $item ( @{ stash 'items' } ) {
<h1><%= $item->{title} %></h1>
<%== $item->{html} %>
% }
DESCRIPTION
This controller contains basic route handlers for displaying content configured in Yancy collections. These route handlers reduce the amount of code you need to write to display or modify your content.
Route handlers use the Mojolicious stash
for configuration. These values can be set at route creation, or by an under
route handler.
Using these route handlers also gives you a built-in JSON API for your website. Any user agent that requests JSON will get JSON instead of HTML. For full details on how JSON clients are detected, see "Content negotiation" in Mojolicious::Guides::Rendering.
METHODS
list
$routes->get( '/' )->to(
'yancy#list',
collection => $collection_name,
template => $template_name,
);
This method is used to list content.
This method uses the following stash values for configuration:
- collection
-
The collection to use. Required.
- template
-
The name of the template to use. See "Renderer" in Mojolicious::Guides::Rendering for how template names are resolved.
- limit
-
The number of items to show on the page. Defaults to
10
. - page
-
The page number to show. Defaults to
1
. The page number will be used to calculate theoffset
parameter to "list" in Yancy::Backend. - filter
-
A hash reference of field/value pairs to filter the contents of the list.
The following stash values are set by this method:
- items
-
An array reference of items to display.
- total_pages
-
The number of pages of items. Can be used for pagination.
get
$routes->get( '/:id' )->to(
'yancy#get',
collection => $collection_name,
template => $template_name,
);
This method is used to show a single item.
This method uses the following stash values for configuration:
- collection
-
The collection to use. Required.
- id
-
The ID of the item from the collection. Required. Usually part of the route path as a placeholder.
- template
-
The name of the template to use. See "Renderer" in Mojolicious::Guides::Rendering for how template names are resolved.
The following stash values are set by this method:
- item
-
The item that is being displayed.
set
$routes->any( [ 'GET', 'POST' ] => '/:id/edit' )->to(
'yancy#set',
collection => $collection_name,
template => $template_name,
);
$routes->any( [ 'GET', 'POST' ] => '/create' )->to(
'yancy#set',
collection => $collection_name,
template => $template_name,
forward_to => $route_name,
);
This route creates a new item or updates an existing item in a collection. If the user is making a GET
request, they will simply be shown the template. If the user is making a POST
or PUT
request, the form parameters will be read, the data will be validated against the collection configuration, and the user will either be shown the form again with the result of the form submission (success or failure) or the user will be forwarded to another place.
This method uses the following stash values for configuration:
- collection
-
The collection to use. Required.
- id
-
The ID of the item from the collection. Optional: If not specified, a new item will be created. Usually part of the route path as a placeholder.
- template
-
The name of the template to use. See "Renderer" in Mojolicious::Guides::Rendering for how template names are resolved.
- forward_to
-
The name of a route to forward the user to on success. Optional. Any route placeholders that match item field names will be filled in.
$routes->get( '/:id/:slug' )->name( 'blog.view' ); $routes->post( '/create' )->to( 'yancy#set', collection => 'blog', template => 'blog_edit.html.ep', forward_to => 'blog.view', ); # { id => 1, slug => 'first-post' } # forward_to => '/1/first-post'
Forwarding will not happen for JSON requests.
- properties
-
Restrict this route to only setting the given properties. An array reference of properties to allow. Trying to set additional properties will result in an error.
NOTE: Unless restricted to certain properties using this configuration, this method accepts all valid data configured for the collection. The data being submitted can be more than just the fields you make available in the form. If you do not want certain data to be written through this form, you can prevent it by using this.
The following stash values are set by this method:
- item
-
The item that is being edited, if the
id
is given. Otherwise, the item that was created. - errors
-
An array of hash references of errors that occurred during data validation. Each hash reference is either a JSON::Validator::Error object or a hash reference with a
message
field. See the yancy.validate helper docs and "validate" in JSON::Validator for more details.
Each field in the item is also set as a param using "param" in Mojolicious::Controller so that tag helpers like text_field
will be pre-filled with the values. See Mojolicious::Plugin::TagHelpers for more information. This also means that fields can be pre-filled with initial data or new data by using GET query parameters.
This method is protected by Mojolicious's Cross-Site Request Forgery (CSRF) protection. CSRF protection prevents other sites from tricking your users into doing something on your site that they didn't intend, such as editing or deleting content. You must add a <%= csrf_field %>
to your form in order to delete an item successfully. See "Cross-site request forgery" in Mojolicious::Guides::Rendering.
Displaying a form could be done as a separate route using the yancy#get
method, but with more code:
$routes->get( '/:id/edit' )->to(
'yancy#get',
collection => $collection_name,
template => $template_name,
);
$routes->post( '/:id/edit' )->to(
'yancy#set',
collection => $collection_name,
template => $template_name,
);
delete
$routes->any( [ 'GET', 'POST' ], '/delete/:id' )->to(
'yancy#delete',
collection => $collection_name,
template => $template_name,
forward_to => $route_name,
);
This route deletes an item from a collection. If the user is making a GET
request, they will simply be shown the template (which can be used to confirm the delete). If the user is making a POST
or DELETE
request, the item will be deleted and the user will either be shown the form again with the result of the form submission (success or failure) or the user will be forwarded to another place.
This method uses the following stash values for configuration:
- collection
-
The collection to use. Required.
- id
-
The ID of the item from the collection. Required. Usually part of the route path as a placeholder.
- template
-
The name of the template to use. See "Renderer" in Mojolicious::Guides::Rendering for how template names are resolved.
- forward_to
-
The name of a route to forward the user to on success. Optional. Forwarding will not happen for JSON requests.
The following stash values are set by this method:
- item
-
The item that will be deleted. If displaying the form again after the item is deleted, this will be
undef
.
This method is protected by Mojolicious's Cross-Site Request Forgery (CSRF) protection. CSRF protection prevents other sites from tricking your users into doing something on your site that they didn't intend, such as editing or deleting content. You must add a <%= csrf_field %>
to your form in order to delete an item successfully. See "Cross-site request forgery" in Mojolicious::Guides::Rendering.
EXTENDING
Here are some tips for inheriting from this controller to add functionality.
- set
-
When setting field values to add to the updated/created item, use
$c->req->param
not$c->param
. The underlying code uses$c->req->param
to get all of the params, which will not be updated if you use$c->param
.
DIAGNOSTICS
- Page not found
-
If you get a
404 Not Found
response or Mojolicious's "Page not found... yet!" page, it could be from one of a few reasons:- No route with the given path was found
-
Check to make sure that your routes match the URL.
- Configured template not found
-
Make sure the template is configured and named correctly and the correct format and renderer are being used.
The Mojolicious debug log will have more information. Make sure you are logging at
debug
level by running indevelopment
mode (the default), or setting theMOJO_LOG_LEVEL
environment variable todebug
. See MODE in the Mojolicious tutorial for more information.
SEE ALSO
AUTHOR
Doug Bell <preaction@cpan.org>
COPYRIGHT AND LICENSE
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.