Testing Mojolicious locally

Tags:

So you have coded your newest web system in Mojolicious and would like to test it in an environment where it "thinks" it's running on the actual webserver, even though it's still running on your machine.

Add your www.example.com entry to point to 127.0.0.1 in /etc/hosts and then redirect your localhost's port 80 to port 3000:

sudo iptables -t nat -I OUTPUT -p tcp     -d 127.0.0.1 --dport 80     -j REDIRECT --to-ports 3000

No need to run as root!

Zero to Mojolicious, Part 2: Content-Wrapping Filter Templates

Tags:

In the previous installment, we built a basic site with Zurb Foundation.

We were able to split the main HTML wrapper into a layout file, but our index.html that we passed to the render function had to have the whole rest of the row and column divisions. We really want to just have our "content" consist only of the body of each page, and let the template system take care of the row/column site structure and any navigation or sidebars.

Doing this highlighted how different Mojolicious is from using something like PHP, or even Ruby on Rails. In using, or trying to use those, I spent more time getting frustrated at PHP's inconsistencies (how many different kinds of 'equal' are there?) or ripping apart Rails (there is One True way to speak to a database, and your existing schema ain't it) and being frustrated at Ruby's zaniness (zero is true!) than I did actually getting anything done.

Glen Hinkle (tempire) comments on this in a post to the Mojolicious group [groups.google.com, 11 November 2011]:

This is a matter of the tools built on top of the platform, rather than the platform itself. Ruby's Rails distributes these sort of tools and touts them as the hotness, but in practicality, they don't provide much value…

Let's say you have a tool that creates your CRUD interface and boilerplate. It looks great, because look at all the work it saved you from doing! In reality, it's saved you nothing. When you customize your app, you're going to have to re-organize and/or re- write every piece of code/HTML. Guaranteed. These tools are a red herring - they're simply not going to save you any time at all.

For example: You create a resource. Oh, but you need to verify the data. Except, how you verify depends on the nature of your data. That's ok, you can just take out the boilerplate and put your own code in. Except, it ties in with the way it stores data in the database. That's ok, you can replace that with your own code. Except, that ties in with the way you've chosen to display your data. That's ok, you can replace the templates with your own code. Except, you need to show your templates in a specific way so that it makes sense. That's ok, you can replace...

In the end, boilerplate templates limit you more than save you time…

Attempt to create boilerplate on any platform, and you'll see how useless it is after the 3rd web app, wherein maintaining the boilerplate was more effort than creating the app itself. If it's not, you don't actually want a custom web app, you want a CMS.

Once I realized that Mojo is just Perl inside, and all the idioms are just old-fashioned syntactic sugar, everything started to become clear.

The very first thing we need to do to work in the "Foundation style" is to build a hierarchy of nested sub-templates. Specifically, we want rows and columns in a master template and then use the standard [content](http://mojolicio.us/perldoc/Mojolicious/Plugin/DefaultHelpers#content) mechanism to drop text into the body.

With Mojolicious now, in an ep (Encapsulated Perl) file, you can specify:

% layout 'template_name'

and that layout can then say:

% extends 'subtemplate_name'

but be careful: the latter does not let you nest; the 'extending' template's content is discarded. (Unless, that is, there has been no content yet defined: an unlikely situation.)

So let's take the "Lite app" from Part I and add the lines shown in bold here:

#!/usr/bin/env perl
use Mojolicious::Lite;

get '/' => sub {
 my $c = shift;
 $c->render('index',
 msg => 'Welcome to the Mojolicious real-time web framework!');
};

app->start;
__DATA__

@@ index.html.ep
<strong>% layout 'site_design';</strong>
% title 'Welcome';
<div class="row">
 <h2><%= $msg %></h2>
 <div class="small-2 columns">2 columns</div>
 <div class="small-10 columns">10 columns</div>
</div>
<div class="row">
 <div class="small-3 columns">3 columns</div>
 <div class="small-9 columns">9 columns</div>
</div>

<strong>@@ layouts/site_design.html.ep</strong>
<strong>% extends 'layouts/zurb';</strong>

<strong>This text does not appear.</strong>

@@ layouts/zurb.html.ep
<!DOCTYPE html>
<html lang="en">
 <head>
 <meta charset="utf-8">
 <!-- Zurb Foundation stuff -->
 <meta name="viewport" content=
 "width=device-width, initial-scale=1.0">
 <link rel="stylesheet" href="/css/normalize.css">
 <link rel="stylesheet" href="/css/foundation.min.css">
 <script src="/js/vendor/modernizr.js"></script>
 <!-- end Zurb -->
 <title><%= title %></title>
 </head>
 <body>
 <script src="/js/vendor/jquery.js"></script>
 <script src="/js/foundation.min.js"></script>
 <script>
 $(document).foundation();
 </script>
<%= content %>
 </body>
</html>

Now the index HTML calls for the site_design template, which in turn extends our Zurb Foundation template. The wrinkle is: In order to nest templates, we must do this a bit differently.

As of Mojolicions 6.01, the built-in content helper functions are:

content
stash
content_for
content_with

The first lets us define the content stash (but, if that contains anything at all, the function has no effect); the second function returns the value of any stash including content; content_with replaces the content (which we will use to wrap the content); and content_for appends to the content stash.

NOTE: An earlier version of this article led to the addition of content_with in Mojolicious core. (See

[

this commit ](https://github.com/kraih/mojo/commit/275f0e75bf350d40542a67e5a9eaef84eaa08236) .)

Let's take a bit of a sidetrack for a little understanding of what is really going on. According to "Rendering" in the Mojolicious Guides,

The renderer is a tiny black box turning stash data into actual responses utilizing multiple template systems and data encoding modules.

Well that's all wonderful, but what does the black box do exactly? In Mojolicious/Renderer.pm in your Perl installation, you can see the loop in the render function, just below the comment:

`

sub render … # Extends `

The extends loop there descends through the template definition, which has the effect of rendering each of the include, extends, and layout calls. Again, do realize that in your template,

% layout 'site_design';

is a simple Perl function call, not some kind of magic. Understand too that the layout's processing is deferred until after the remainder of the containing template.

Back to the story. We write our index.html to declare what we want in each of the containers: header, footer, sidebar, and then the content, leaving the details of the rows and columns to our nested site layout template, as follows (new parts in bold):

#!/usr/bin/env perl
use Mojolicious::Lite;

get '/' => sub {
  my $c = shift;
  $c->render('index',
         msg => 'Welcome to the Mojolicious real-time web framework!');
};

app->helper(content_with => sub {
  my ($c, $name, $content) = @_;
  return unless defined $content;
  my $hash = $c->stash->{'mojo.content'} ||= {};
  return $hash->{$name} = 
    ref $content eq 'CODE' ? $content->() : $content;
});

app->start;
__DATA__

@@ index.html.ep
% layout 'site_design';
% title 'Welcome';
<strong>% content header => begin
<h2><%= $msg %></h2>
% end
% content footer => begin
<h5>Copyright ⓒ <%= ((localtime())[5]+1900) %></h5>
% end
% content sidebar => begin
<ul>
  <li>Sidebar item 1</li>
  <li>Sidebar item 2</li>
</ul>
% end

This plain text is the content − the body of the page.
</strong>
<strong>@@ layouts/site_design.html.ep
% extends 'layouts/zurb';

% content_with content => begin
<div class="row">
  <div class="large-12 columns"><%= content 'header' %></div>
</div>
<div class="row">
  <div class="small-3 columns"><%= content 'sidebar' %></div>
  <div class="small-9 columns"><%= content %></div>
</div>
<div class="row">
  <div class="large-12 columns"><%= content 'footer' %></div>
</div>
% end</strong>

@@ layouts/zurb.html.ep
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <!-- Zurb Foundation stuff -->
    <meta name="viewport" content=
       "width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="/css/normalize.css">
    <link rel="stylesheet" href="/css/foundation.min.css">
    <script src="/js/vendor/modernizr.js"></script>
    <!-- end Zurb -->
    <title><%= title %></title>
  </head>
  <body>
    <script src="/js/vendor/jquery.js"></script>
    <script src="/js/foundation.min.js"></script>
    <script>
      $(document).foundation();
    </script>
<%= content %>
  </body>
</html>

Note the little trick for displaying the current year: We use the list-returning version of localtime() but only want the year element (the number of years since 1900) and print all four digits.:

<h5>Copyright ⓒ <%= ((localtime())[5]+1900) %></h5>

Thanks to everyone on #mojo IRC, particularly jberger.

Next time, we will start adding database functionality. Meantime, have fun with easy Foundation enabled Mojo sites!

Mojolicious and DBI handles

Tags:

From http://toroid.org/ams/etc/mojolicious-db-handles we find this bit of code:

sub startup {
  my $app = shift;

  my ($user, $pass);
  # read $user and $pass from config file
  (ref $app)->attr(db => sub {
    DBI->connect("dbi:Mysql:database=$db",
                 $user, $pass)
    }
  );
}

The concept is that Morbo, or Starman, or whatever PSGI server is running your program, can use any kind of forking, but each instance of your program will execute the startup code and create its own database handle.

Some of the code is not too obvious:

And here's how you get the data back out:

  $app->get('/test')->to(cb =>
               sub{ 
               my $self = shift;
               $Data::Dumper::Indent = 1;
               $self->render( 'text' => "TEST: ATTR of foo" . $self->app->foo .
                    "\n<pre>\n" . Dumper($self) . "</pre>" );
               });

It's really a better idea to use DBIx::Connector anyway, but the startup attribute trick might come in handy elsewhere. One note on DBIX::Connector − Under the heading, Execution Methods we see the code:

  <span class="sh_variable">$conn</span><span class="sh_symbol">-></span><span class="sh_function">run</span><span class="sh_symbol">(</span><span class="sh_keyword">sub</span> <span class="sh_cbracket">{</span> <span class="sh_variable">$_</span><span class="sh_symbol">-></span><span class="sh_keyword">do</span><span class="sh_symbol">(</span><span class="sh_variable">$query</span><span class="sh_symbol">)</span> <span class="sh_cbracket">}</span><span class="sh_symbol">);</span>

It is not documented, but by reading the source (let's hear it for free software!) what happens is that $_ is set, via the «local» keyword, to temporarily be the database handle (dbh) of the connection within execution of the code reference.

Thanks to mst and others on #perl for the assistance.

Zero to Mojolicious with Zurb Foundation in Five Minutes

Tags:

A short tutorial.

Let's run through creating a Perl web application with Mojolicious and styling by Zurb Foundation. We will create this first as a full "application" and then as a "Lite" version.

Installing (Perlbrew and) Mojolicious

While perlbrew is not strictly required, the latest versions of Perl have a number of features and optomizations that help Mojolicious. There are two ways to install all this: Globally for all users (I recommend this if you are administering the entire server, and want to keep just one set of software) or in your home directory (best if you share a server).

  1. *Installing in your home directory *Following the instructions here [perlbrew.pl], install Perlbrew into your home directory: something like this:

    \curl -L http://install.perlbrew.pl | bash
    nice perlbrew -j 5 install perl-5.20.2
    

    Note the 'nice' (to reduce impact on a running system) and the "-j 5" (to use up to five concurrent compilation threads) − although on an active server, you might want to just use the default single thread. Observe the final output of perlbrew: You will almost certainly have to edit ~/.bash_profile as it suggests, logout, and then log back in to enable the perlbrew command.

    Now permanently switch to the new Perl, and install Mojolicious:

    perlbrew switch perl-5.20.2
    sudo sh -c "curl get.mojolicio.us | sh"  
    
  2. *Installing globally *Assuming a brand new machine (possibly a Linode virtual machine), first we install the latest Mojolicious under /local/bin ... if you don't do this as root this way, I recommend you probably get a cpanminus version somewhere in your user home directory.

    sudo sh -c "curl get.mojolicio.us | sh"  
    

Creating a Mojo "app"

OK now we can go into a working directory somewhere and type:

mojo generate app Test

which will create an entire tree of default files under the subdirectory 'test' for a program called 'Test.'

At this point you should be able to start your example program:

cd Test
morbo script/test

and view the default text at http://localhost:3000

Adding Zurb Foundation to your "app"

Next we get the latest Foundation distribution from their website. At the time of writing, this gave me foundation-5.3.1.zip. Create a subdirectory called foundation under the public directory and unzip into there. This will create subdirectories css and js among a few others.

wget <em>latest_foundation_link_from_above
</em>cd public
mkdir foundation
cd foundation
unzip ../../foundation*.zip
cd ..          <em># back to Mojo project's public</em>

We are going to leave those files in a pristine tree so we can replace them later, and create symbolics links to them. Note the slightly curious use of relative paths in the symbolic links below. The multiple ../ are needed because symlinks are relative to the destination file, not the directory where our shell happens to be when they are created. Also, if only the destination directory and not a filename is given, the destination filename is copied from the source (linked-to) file.

# Assuming the latest Foundation framework code
# is downloaded into the 'foundation' directory,
# and that we are currently in the 'public'
# directory in your generated mojo application,
# here we make symlinks from our document root
# into there, only for the files we actually use.
mkdir css
mkdir -p js/vendor
ln -s ../foundation/css/normalize.css css/
ln -s ../foundation/css/foundation.min.css css/
ln -s ../foundation/js/foundation.min.js js/
ln -s ../../foundation/js/vendor/jquery.js js/vendor/
ln -s ../../foundation/js/vendor/modernizr.js js/vendor/

It is worth a reminder that the syntax here is:

<tt>ln -s</tt> <em><small>{source (real file)} {destination (new link name)}</small></em>

Building the HTML for Foundation

Starting with the basic HTML from here:

http://foundation.zurb.com/docs/css.html

We copy some of the code from the original default.html.ep and create the new templates/layouts/zurbish.html.ep as follows:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <!-- Zurb Foundation stuff -->
    <meta name="viewport" content=
       "width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="css/normalize.css">
    <link rel="stylesheet" href="css/foundation.min.css">
    <script src="js/vendor/modernizr.js"></script>
    <!-- end Zurb -->
    <title><%= title %></title>
  </head>
  <body>
    <script src="js/vendor/jquery.js"></script>
    <script src="js/foundation.min.js"></script>
    <script>
      $(document).foundation();
    </script>
<%= content %>
  </body>
</html>

Then in templates/example/welcome.html.ep we change the content to be as follows:

% layout 'zurbish';
% title 'Welcome';
<h2><%= $msg %></h2>
This page was generated from the template "templates/example/welcome.html.ep"
and the layout "templates/layouts/zurbish.html.ep",
<a href="<%== url_for %>">click here</a> to reload the page or
<a href="/index.html">here</a> to move forward to a static page.
<div class="row">
  <div class="small-2 columns">2 columns</div>
  <div class="small-10 columns">10 columns</div>
</div>
<div class="row">
  <div class="small-3 columns">3 columns</div>
  <div class="small-9 columns">9 columns</div>
</div>

Now, http://localhost:3000 should give you the example text in a very, very basic Foundation based layout. From here, you might want to follow one of the excellent Mojolicious tutorials out there. Here is Zurb's official guide to the Grid, for example.

Also useful is this from "Zurb U" which explains the small/medium/large grids. The one-line gist is:

If you don't specify small-# to a column, Foundation will assume you mean "go full-width on small screens."

As a "Lite App"

For simplicity, here is basically the same program as a single file, in the form of a boilerplate Mojolicious "Lite app":

#!/usr/bin/env perl
use Mojolicious::Lite;

get '/' => sub {
  my $c = shift;
  $c->render('index',
         msg => 'Welcome to the Mojolicious real-time web framework!');
};

app->start;
__DATA__

@@ index.html.ep
% layout 'zurb';
% title 'Welcome';
<div class="row">
  <h2><%= $msg %></h2>
  <div class="small-2 columns">2 columns</div>
  <div class="small-10 columns">10 columns</div>
</div>
<div class="row">
  <div class="small-3 columns">3 columns</div>
  <div class="small-9 columns">9 columns</div>
</div>

@@ layouts/zurb.html.ep
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <!-- Zurb Foundation stuff -->
    <meta name="viewport" content=
       "width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="css/normalize.css">
    <link rel="stylesheet" href="css/foundation.min.css">
    <script src="js/vendor/modernizr.js"></script>
    <!-- end Zurb -->
    <title><%= title %></title>
  </head>
  <body>
    <script src="js/vendor/jquery.js"></script>
    <script src="js/foundation.min.js"></script>
    <script>
      $(document).foundation();
    </script>
<%= content %>
  </body>
</html>

If you save the above as example.pl for example, then the command

morbo example.pl

should permit you to view the generated one-page site at http://localhost:3000

Next steps

In the next installment, we will see how to better use Mojo's template system with Foundation.

Additional Resources

Perl Catalyst on a base Debian system

Tags:

This turns out to be amazingly easy, at least with Debian 7.3.

First, instead of MySQL, I followed instructions at the MariaDB site: Setting Up MariaDB Repositories. Then:

$ sudo apt-get install libcatalyst-modules-perl

which installed over 200 modules, but what do you know:

$ catalyst.pl Foo

creates a Foo Catalyst application under the current directory. Everything *Just Works. *Thanks to Debian and the folks who bring you Catalyst.

Further reading:

UPDATE (April 2014): Catalyst seems a bit heavy for most of my needs. I'm exploring mojolicious.