NAME
Yancy::Controller::Yancy::MultiTenant - A controller to show a user only their content
VERSION
version 1.075
SYNOPSIS
use Mojolicious::Lite;
plugin Yancy => {
schema => {
blog => {
properties => {
id => { type => 'integer' },
user_id => { type => 'integer' },
title => { type => 'string' },
html => { type => 'string' },
},
},
},
};
app->routes->get( '/user/:user_id' )->to(
'yancy-multi_tenant#list',
schema => 'blog',
template => 'index'
);
__DATA__
@@ index.html.ep
% for my $item ( @{ stash 'items' } ) {
<h1><%= $item->{title} %></h1>
<%== $item->{html} %>
% }
DESCRIPTION
This module contains routes to manage content owned by users. When paired with an authentication plugin like Yancy::Plugin::Auth::Basic, each user is allowed to manage their own content.
This controller extends Yancy::Controller::Yancy to add filtering content by a user's ID.
METHODS
list
$routes->get( '/:user_id' )->to(
'yancy-multi_tenant#list',
schema => $schema_name,
template => $template_name,
);
This method is used to list content owned by the given user (specified in the user_id
stash value).
Input Stash
This method extends "list" in Yancy::Controller::Yancy and adds the following configuration and stash values:
- user_id
-
The ID of the user whose content should be listed. Required. Should match a value in the
user_id_field
. - user_id_field
-
The field in the item that holds the user ID. Defaults to
user_id
.
get
$routes->get( '/:user_id/:id' )->to(
'yancy-multi_tenant#get',
schema => $schema_name,
template => $template_name,
);
This method is used to show a single item owned by a user (given by the user_id
stash value).
Input Stash
This method extends "get" in Yancy::Controller::Yancy and adds the following configuration and stash values:
- user_id
-
The ID of the user whose content should be listed. Required. Should match a value in the
user_id_field
. - user_id_field
-
The field in the item that holds the user ID. Defaults to
user_id
.
set
$routes->any( [ 'GET', 'POST' ] => '/:id/edit' )->to(
'yancy#set',
schema => $schema_name,
template => $template_name,
);
$routes->any( [ 'GET', 'POST' ] => '/create' )->to(
'yancy#set',
schema => $schema_name,
template => $template_name,
forward_to => $route_name,
);
This route creates a new item or updates an existing item in a schema. 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 schema 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 does not authenticate users. User authentication and authorization should be performed by an auth plugin like Yancy::Plugin::Auth::Basic.
Input Stash
This method extends "set" in Yancy::Controller::Yancy and adds the following configuration and stash values:
- user_id
-
The ID of the user whose content is being edited. Required. Will be set in the
user_id_field
. - user_id_field
-
The field in the item that holds the user ID. Defaults to
user_id
. This field will be filled in with theuser_id
stash value.
delete
$routes->any( [ 'GET', 'POST' ], '/delete/:id' )->to(
'yancy#delete',
schema => $schema_name,
template => $template_name,
forward_to => $route_name,
);
This route deletes an item from a schema. 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 does not authenticate users. User authentication and authorization should be performed by an auth plugin like Yancy::Plugin::Auth::Basic.
Input Stash
This method extends "delete" in Yancy::Controller::Yancy and adds the following configuration and stash values:
- user_id
-
The ID of the user whose content is being edited. Required. Will be set in the
user_id_field
. - user_id_field
-
The field in the item that holds the user ID. Defaults to
user_id
. This field will be filled in with theuser_id
stash value.
EXAMPLES
To use this controller when the URL displays a username and the content uses an internal ID, you can use an under
route to map the username in the path to the ID:
my $user_route = app->routes->under( '/:username', sub {
my ( $c ) = @_;
my $username = $c->stash( 'username' );
my @users = $c->yancy->list( user => { username => $username } );
if ( my $user = $users[0] ) {
$c->stash( user_id => $user->{id} );
return 1;
}
return $c->reply->not_found;
} );
# /:username - List blog posts
$user_route->get( '' )->to(
'yancy-multi_tenant#list',
schema => 'blog',
template => 'blog_list',
);
# /:username/:id/:slug - Get a single blog post
$user_route->get( '/:id/:slug' )->to(
'yancy-multi_tenant#get',
schema => 'blog',
template => 'blog_view',
);
To build a website where content is only for the current logged-in user, combine this controller with an auth plugin like Yancy::Plugin::Auth::Basic. Use an under
route to set the user_id
from the current user.
app->yancy->plugin( 'Auth::Basic', {
route => any( '' ), # All routes require login
schema => 'user',
username_field => 'username',
password_digest => { type => 'SHA-1' },
} );
my $user_route = app->yancy->auth->route->under( '/', sub {
my ( $c ) = @_;
my $user = $c->yancy->auth->current_user;
$c->stash( user_id => $user->{id} );
return 1;
} );
# / - List todo items
$user_route->get( '' )->to(
'yancy-multi_tenant#list',
schema => 'todo_item',
template => 'todo_list',
);
SEE ALSO
Yancy::Controller::Yancy, Mojolicious::Controller, Yancy
AUTHOR
Doug Bell <preaction@cpan.org>
COPYRIGHT AND LICENSE
This software is copyright (c) 2021 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.