Mojolicious::Plugin::Moai - Mojolicious UI components using modern UI libraries
version 0.011
use Mojolicious::Lite; plugin Moai => [ 'Bootstrap4', { version => '4.4.1' } ]; app->start; __DATA__ @@ list.html.ep %= include 'moai/lib' %= include 'moai/table', items => \@items, columns => [qw( id name )] %= include 'moai/pager', current_page => 1, total_pages => 5
This plugin provides some common UI components using a couple different popular UI libraries.
These components are designed to integrate seamlessly with Yancy, Mojolicious::Plugin::DBIC, and Mojolicious::Plugin::SQL.
The Test::Mojo::Role::Moai library is provided to help test the Moai components. It also works without Moai, allowing you to test any website.
These libraries are not included and the desired version should be added to your layout templates. To add your library using a CDN, see "moai/lib", below.
http://getbootstrap.com
http://bulma.io
Add the Moai plugin to your Mojolicious application and specify which UI library and version of that library you want to use.
use Mojolicious::Lite; plugin Moai => [ 'Bootstrap4', { version => '4.4.1', } ];
Now you can add widgets. You will likely first want to add the moai/lib widget to your layout template to get the UI library.
moai/lib
@@ layouts/default.html.ep <!DOCTYPE html> <head> %= include 'moai/lib' </head> <body><%= content %></body>
Widgets are snippets that you can include in your templates using the include helper.
<%= include 'moai/grid', content => begin %> <%= include 'moai/grid/col', size => 9, content => begin %> This column takes up 9/12 width <% end %> <%= include 'moai/grid/col', content => begin %> This column will fill the remaining space <% end %> <% end %>
The moai/grid and moai/grid/col templates provide the library's grid system. moai/grid starts a grid row, and moai/grid/col is a column in that row. For libraries like Bootstrap which have an additional "container" element, that element is already included in the moai/grid template.
moai/grid
moai/grid/col
<%= include 'moai/pager', current_page => param( 'page' ), total_pages => $total_pages, %>
A pagination control. Will display previous and next buttons along with individual page buttons.
Also comes in a mini variant in moai/pager/mini that has just previous/next buttons.
mini
moai/pager/mini
The current page number. Defaults to the value of the page parameter.
page
The total number of pages. Required.
The name of the parameter to use for the current page. Defaults to page.
An ID to add to the pager
<%= include 'moai/table', items => [ { id => 1, name => 'Doug' }, ], columns => [ { key => 'id', title => 'ID' }, { key => 'name', title => 'Name' }, ], %>
A table of items.
The items to display in the table. An arrayref of hashrefs.
The columns to display, in order. An arrayref of hashrefs with the following keys:
The hash key in the item to use.
The text to display in the column heading
Add a link to the given named route. The route will be filled in by the current item, like url_for $link_to => $item.
url_for $link_to => $item
An ID to add to the table.
A hashref of additional classes to add to certain elements:
col - Add these classes to every cell in the column
col
table
thead
wrapper - Add a wrapper element with these classes
wrapper
A horizontal navigation bar.
An arrayref of menu items. Menu items are arrayrefs with two elements: label, and route name.
$app->routes->get( '/' )->name( 'index' ); $app->routes->get( '/blog' )->name( 'blog' ); $app->routes->get( '/about' )->name( 'about' ); <%= include 'moai/menu/navbar', menu => [ [ Home => 'index' ], [ Blog => 'blog' ], [ 'About Us' => 'about' ], ], %>
A menu item for the "brand" section. An arrayref with two elements: a label, and a route name.
<%= include 'moai/menu/navbar', brand => [ 'Zooniverse' => 'main' ], %>
Position the navbar. Can be either fixed-top to affix the navbar to the top of the viewport or fixed-bottom for the bottom of the viewport. If not set, the navbar will be a static element at the current location.
fixed-top
fixed-bottom
navbar - Add these classes to the <nav> element
navbar
<nav>
%= include 'moai/lib', version => '4.1.0';
Add the required stylesheet and JavaScript links for the current library using a CDN. The stylesheets and JavaScript can be added separately using moai/lib/stylesheet and moai/lib/javascript respectively.
moai/lib/stylesheet
moai/lib/javascript
The specific version of the library to use. Defaults to the version specified in the plugin (if any). Required.
version
Layouts wrap your templates in a common framing. See the Mojolicious docs for more information on Layouts.
To get started using a Moai layout, extend a Moai layout template to fill in the missing parts.
use Mojolicious::Lite; plugin Moai => [ 'Bootstrap4', { version => '4.4.1' } ]; get '/' => 'index'; __END__ @@ index.html.ep % layout 'site'; <h1>Welcome!</h1> @@ layouts/site.html.ep % extends 'layouts/moai/default'; %# Add a main nav with links to our products, a history, and contact page % content_for navbar => begin <%= include 'moai/navbar', position => 'fixed-top', brand => [ 'My Site' => 'index' ], menu => [ [ 'Products' => 'products' ], [ 'About Us' => 'history' ], [ 'Contact Us' => 'contact' ], ], %> % end
These layouts are included with Moai.
The default layout is a general-purpose layout for almost any use. Other layouts can extend this one to provide more-specific features.
This content goes inside the <head> .. </head> element, just before the closing </head>.
<head> .. </head>
</head>
This section is the very top of the page and contains the navbar and an optional hero element.
This section is a placeholder for a "moai/menu/navbar" widget (though you can put anything here if you'd like).
This content section is a placeholder for whatever header element the current page requires.
This section contains a grid container with a single row and two columns: the main section and the sidebar section.
main
sidebar
This section contains the <main> element and the main content of the page from the default buffer of the Mojolicious content helper.
<main>
content
This section is a placeholder for whatever sidebar content the current page requires.
This section is a placeholder for whatever footer content the current page requires.
The CDN links should have full security hashes.
Accessibility testing should be automated and applied to all supported libraries.
This library should use Mojolicious's variant feature to provide translations for every widget in every library.
variant
There should be widgets for...
other menus (vertical lists, dropdown buttons)
dropdown menus
forms and other items in the navbar (move the Form plugin from Yancy?)
switched panels (tabs, accordion, slider)
alerts (error, warning, info)
menus (dropdown button, menu bar)
popups (modal dialogs, tooltips, notifications)
There should be support for...
Bootstrap 3
Material
Moai should support the same features for each library, allowing easy switching between them.
Some examples of progressive enhancement:
The table widget could have sortable columns
The table widget could use AJAX to to filter and paginate
The pager widget could use AJAX to update a linked element
The switched panel widgets could load their content lazily
Built-in selection of CDN-based themes for each library
A default color scheme (light / dark) that responds to a user's light/dark preferences (MacOS "dark mode"). The default should be settable from the main config, and overridable for individual elements.
A standard way of adding extra classes to individual tags inside components. In addition to a string, we should also support a subref so that loops can apply classes to certain elements based on input criteria.
Each supported library should come with a single page that demonstrates the various widgets and provides copy/paste code snippets to achieve that widget.
It would be amazing if there was a way to make one template apply to all supported libraries.
We cannot, should not, must not make every little thing customizable or else our templates will be so complex as to be unmaintainable and unusable. We should instead make content sections that can be extended, like the moai/table template could have a thead section, a tbody section, and a tbody.tr section.
moai/table
tbody
tbody.tr
A rule of thumb for adding a feature should be if it can be configured simply by a single string. The more complex the configuration needs to be, the more likely it should be customized using Mojolicious's template extends
extends
Test::Mojo::Role::Moai, Mojolicious::Guides::Rendering
Doug Bell <preaction@cpan.org>
Mohammad S Anwar <mohammad.anwar@yahoo.com>
This software is copyright (c) 2019 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 Mojolicious::Plugin::Moai, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Mojolicious::Plugin::Moai
CPAN shell
perl -MCPAN -e shell install Mojolicious::Plugin::Moai
For more information on module installation, please visit the detailed CPAN module installation guide.