# Intro to Mojolicious ## Starting from scratch: Mojolicious::Lite - Everything in one file (if you want) - Great for big or small projects (can be [grown](https://docs.mojolicious.org/Mojolicious/Guides/Growing#Inflating-templates) into full-blown Mojolicious app later) - You should probably use Perl 5.26+ ## Learning the basics ### Routes # The main landing page; index.html get '/' => sub { my ($c) = @_; my $count = format_number time; # Grab epoch and add commas my $fortune = `/usr/games/fortune` || `fortune` || "huh??\n"; $c->stash( count => $count, fortune => $fortune ); $c->render(); } => 'index'; - Route name can be derived from path (specified as 'index 'here) - `stash()` is used to pass variables from controller to view (i.e. our templates) #### Minimal routes get '/about'; - This would render a template named `about.html.ep` ### Placeholders get '/:route'; - I wanted to (mostly) adhere to the D.R.Y. (don't repeat yourself) principle - Got 500s rather than 404s for requesting routes with no templates (bad) #### Restrictive placeholder # Default route get '/:route' => [route => [qw{die me news portal}]] => sub { my ($c) = @_; $c->render(template => $c->stash('route')); }; - Now renders a 404 for routes with no templates (success) - The requested route is available via `stash()` ### Sessions my ($c) = @_; my $sessionLife = 604800; if ($c->cookie('banner') eq 'seen') { # Set session for a week $c->session(expiration => $sessionLife, banner => 'seen'); # Kill plain-text cookie $c->cookie(banner => 'seen', {expires => 1}); } # Pass in the expiration for plain-text cookie $c->stash(sessionLife => $sessionLife); - `session()` is the way to go for [session cookie](https://docs.mojolicious.org/Mojolicious/Controller#session) - `cookie()` can access plain-text [cookies](https://docs.mojolicious.org/Mojolicious/Controller#cookie) - We should generate a secret passphrase; can be set with `app->secrets()` or the [Config plugin](https://docs.mojolicious.org/Mojolicious/Plugin/Config) to make our life easier. Speaking of plugins... ### Plugins plugin 'Config'; # CGI scripts plugin CGI => ['/cgi-bin/guest.cgi' => './cgi-bin/guest_mm.cgi']; plugin CGI => ['/cgi-bin/whoami.cgi' => './cgi-bin/whoami.cgi' ]; - Extensions that help with code sharing and organization - I'm using [Mojolicious::Plugins::CGI](https://metacpan.org/pod/Mojolicious::Plugin::CGI) to keep my CGI scripts kickin' - There's all kinds on [CPAN](https://metacpan.org/search?q=Mojolicious+Plugin) - No need to `use` these in Mojolicious::Lite, `plugin` keyword takes care of that for us #### Config plugin - Good for keeping [secrets](https://mojolicious.io/blog/2017/12/16/day-16-the-secret-life-of-sessions/) (amongst other things) - [Whoopsie](https://codeberg.org/swaggboi/www2.0/commit/f2c8b04d88604cd418d64e5f2e3d0c9bb6824b8f), had to rotate this one out ### Under # Handle the session under sub { my ($c) = @_; my $sessionLife = 604800; if ($c->cookie('banner') eq 'seen') { # Set session for a week $c->session(expiration => $sessionLife, banner => 'seen'); # Kill plain-text cookie $c->cookie(banner => 'seen', {expires => 1}); } # Pass in the expiration for plain-text cookie $c->stash(sessionLife => $sessionLife); 1; }; - Great for code shared between multiple routes - Give it a path; defaults to `/` - Must return true in order for routes "under" its path to be evaluated #### Another good use for `under` # /foo under '/foo'; # /foo/bar get '/bar' => {text => 'foo bar'}; # /foo/baz get '/baz' => {text => 'foo baz'}; # / (reset) under '/' => {msg => 'whatever'}; # /bar get '/bar' => {inline => '<%= $msg %> works'}; - Used here as a prefix for multiple routes (borrowed example from [docs](https://docs.mojolicious.org/Mojolicious/Guides/Tutorial#Under)) ### Templates % title 'Swagg::Net ULA Tool'; % layout 'swagg-iframe'; <% if ($ula6) { %>

Your IPv6 ULA prefix is <%= $ula6 %>.

<% } else { %>
MAC address:


<% } %> - HTML with [embedded Perl](https://docs.mojolicious.org/Mojolicious/Guides/Rendering#Embedded-Perl) (code and variables) - I decided to generally keep as much as HTML/CSS as possible for now - `title` specifies the `` element in the `layout`; speaking of [layouts](https://docs.mojolicious.org/Mojolicious/Guides/Tutorial#Layouts)... ### Layouts <!DOCTYPE HTML> <html lang="en"> <head> <meta charset="UTF-8"> <title><%= title %> <%= content %> - Much easier for maintaining hyperlinks, page navigation, etc - Still embedded Perl here! #### Layout + sessions = my banner <% unless (session('banner') eq 'seen') { %>
Notice: This site uses MIDI technology instead of tracking cookies. a compact disc playing music

<% } %> - Was using all JS (jquery) for this - This saves bandwidth in comparison ### TODO - [cpanfile](https://github.com/mojolicious/mojo/wiki/Installation-of-cpan-modules-by-cpanm-and-cpanfile) should lighten up the `Dockerfile` some - [AssetPack plugin](https://metacpan.org/pod/Mojolicious::Plugin::AssetPack) looks interesting - Use [Hypnotoad](https://docs.mojolicious.org/Mojo/Server/Hypnotoad) in prod - Implement Perl module as "model"; get rid of much of the controller code (replaced with subroutines from module) - Implement DB for stuff like visitor counter and guestbook (will need our model/Perl module) ### Goodbye # Delete whole session by setting an expiration date in the past $c->session(expires => 1);