Editing Myghty with TextMate 2
TextMate is a rather slick little text editor, with a bunch of cool automation stuff thats great for programmers. You’ve probably already seen it if you’ve watched any of those demo movies for some of the latest web frameworks.
Anyways, as I mainly use Myghty, I needed a syntax highlighting mode for its format. So I made a Myghty bundle for TextMate. This should also be useful for those using Mason as only a few minor adjustments regarding the underlying language highlighter need to be tweaked (Change source.python -> source.perl). This also has a few automation snippets to speed things up.
To install:- Unzip
- Drag into
~/Library/Application Support/TextMate/Bundles/ - Restart TextMate (Not absolutely sure this is needed though)
Enjoy!
Hooked on Myghty 1
I’ve been programming web sites for many years, and have yet to come across a templating language as appealing as Mason / Myghty. To avoid confusion I’m going to talk about Myghty, but since its a direct port of Mason (plus some MVC stuff) all of my comments apply to Mason as well (unless otherwise noted). So if you find yourself stuck using Perl (or you prefer Perl) and something here sounds appealing, by all means use Mason as I did.
Despite Myghty only having come into existence approximately 14 months ago, the code-base is stable, very quick, and has been running in production environments for over 8 months. This is mainly because it started as a very direct port of Mason to Python, it then grew a few additional features that made it great for MVC use. The methodologies present in Mason (thus Myghty as well) are known to scale to very large and complex sites, as this list of Mason-powered sites shows. But it’s the little things added up that really make Myghty my template language of choice.
This is a rather lengthy post as I highlight and explain some core concepts of Myghty, please bear with me… also, if you’d like to follow along and try the examples out, its really easy to get started using Myghty with Paste.
Syntax
Template languages vary a lot in style, there are the very basic string replacement template languages all the way to more advanced template languages. Myghty definitely weighs in on the latter as it has many of its own concepts with regards to templating that produce a very robust and advanced templating system.
The syntax itself is also very appealing to me, as I’m a fan of templating languages that keep their guts inside < > signs. The only exception to this being if you need a quick line of Python, which is done just by having a % in front of it. Here’s what a loop would look like:
% for person in people:
<b>Hi</b><% person %>
% #end
You’ll notice an additional line is needed to indicate the end of the loop. This is because Python uses white-space to determine blocks and Myghty needs to know when the indentation is over.
Components and Inheritance
In Myghty, each template is more properly referred to as a Component. When a component is directly called as a request (or sub-request), inheritance is applied. This is how a site’s skin is typically applied. Rather than having to specify in your template that it includes or extends some other template, in Myghty your component automatically inherits from an autohandler file above it.
An easier way to think of it is to consider your template directory layout as a Class, and all the templates in it are methods. Every directory inside that root one is another Class, and so on. Theautohandler in this context acts much like your __init__ method. Here’s a little example:
# /autohandler
<html>
<head>
<title>Sitename</title>
</head>
<body>
% m.call_next()
</body>
</html>
# /index.myt
<p>Welcome to your site!</p>
When the autohandler encounters a m.call_next() command it calls the next component in the inheritance chain until eventually it gets down to the original component that was requested. It could end up going through several autohandler files on the way down to your component, each one creating sections of your site appropriate for where the component is located.
This makes life really easy if you need to move content around and have it pick up the proper “skin” for the site. The concept is also rather easy for web designers to grasp, and I’ve had no problem teaching web designers the basics they need to know about Myghty to be quickly adding sections to a website.
Methods
Of course, we have to have a way for our index.myt page to get its own title up to the autohandler which creates that section. This is where Methods become useful. Methods allow you to define (typically small) sections inside your component that can be called almost like functions, even from outside the component the method is in. If you’ve ever had to write a Python function for use in a template that has so much HTML in it you went nuts, methods will make you quite happy (more on that shortly).
/index.myt page filling in the HTML title:
# /autohandler
<html>
<head>
<title><& SELF:title &></title>
</head>
<body>
% m.call_next()
</body>
</html>
<%method title>
Your Site
</%method>
# /index.myt
<p>Welcome to your site!</p>
<%method title>
<& PARENT:title &> - Welcome Page
</%method>
The title this page will have is Your Site - Welcome Page. When calling a method, we use the same syntax as when calling another component (yes, an entire component can be called). The <&&> syntax is used, with a method we also declare the name of it following the :. Using the SELF location tells Myghty to search down the inheritance (including itself), so calling SELF:title searches down the inheritance until it comes across the most deeply nested component containing a method called title. Using PARENT searches the up looking for the first component that contains a method called title.
# /autohandler is the same as above
# /products/autohandler
% m.call_next()
<%method title>
<& PARENT:title &> - Products
</%method>
# /products/sprocket.myt
<p>Buy a sprocket, they're great....</p>
<%method title>
<& PARENT:title &> - Sprocket Details
</%method>
The title will now be Your Site - Products - Sprocket Details if you request the /products/sprocket.myt component. As I mentioned earlier, this makes it very easy to move files around as inheritance fills in so much for you.
Component Calls and Arguments
While I’m just using these methods calls for the title, the contents of a method block can contain Python code and variables as well just as our component can. In keeping with the spirit of explanation by example, here’s how we could put a sidebar in our main autohandler:
# /autohandler
<html>
<head>
<title><& SELF:title &></title>
</head>
<body>
<& /sidebar.myt &>
% m.call_next()
</body>
</html>
# /sidebar.myt
<div class="sidebar">
<ul>List of sidebar stuff</ul>
</div>
If you’ve used Rails, they call the ability to insert other components “rendering a partial”. If you’re other component needs some data that you have in your autohandler, here’s how you can pass variables into a component when you call it:
# /autohandler
<html>
<head>
<title><& SELF:title &></title>
</head>
<body>
<& /sidebar.myt, argument=variable &>
% m.call_next()
</body>
</html>
# /sidebar.myt
<h2><% argument %></h2>
<div class="sidebar">
<ul>List of sidebar stuff</ul>
</div>
<%args>
argument = "Default"
</%args>
The args block designates arguments that can be passed into the component, as well as letting you setup default arguments in case none were passed in.
Init and Python Blocks
As much as we all hate it (in a MVC context), sooner or later you need to have a chunk or two of Python code in your template. In Myghty we have several options for putting Python in our component, the most obvious is to use the% code... syntax but that quickly becomes tiresome if we have 8 lines of Python code. So we can put that in a block like so:
# /somefile.myt
<%python>
x = 10
y = 20
z = []
for a in range(1,100):
z.append(x*y+a)
</%python>
Having python blocks like that is a very common scheme in many Python template languages, but has a side-effect that can become quite irritating. It sticks you with having code through-out your template or having a large block at the top. In Myghty, there’s another block that can be defined only once in a component called an init block. It looks exactly like the above example but instead of <%python> we use <%init>.
This init block can go anywhere in your component, and I usually stick it at the very bottom. This way when designers open the page they aren’t smacked with Python code and they can just ignore the foreign language at the bottom. The init block runs before the rest of your component, so you can stick in variable initialization, import a module if you need one, etc. I’ve found this to be a great way to keep the Python bits that creep into my components out of the way.
Caching
If the rest wasn’t enough to interest you, this section and the next really start to lay on the goods. Myghty lets any component cache itself, you can cache by key as well in case there’s several different versions of a component that you wish to use. Caching a component is very useful and its very easy in Myghty.
# /index.myt
<p>Welcome to your site!</p>
<%method title>
<& PARENT:title &> - Welcome Page
</%method>
<%init>
if m.cache_self():
return
do_really_slow_stuff()
</%init>
Upon the component load, it will check to see if it has a cached version of itself on hand (and cache itself in the process otherwise), then return the output. You can cache individual parts of a component, and even cache function output (if its pickle-able). This ability makes it very easy to design a site, then go through and if sections of it take a long time, put a cache command in the parts of the page that render the slowest.
The caching system can use the file system, memory, or memcached to store data.
Multiple Component Roots
In Myghty, the directory that is searched for components is called the Component Root. An extremely powerful and more advanced function is to use multiple component roots.
Here’s what a standard configuration for Myghty would look like to define a component_root to search:
component_root = "/path/to/your/components"
Most (if not all) template languages let you specify the directory containing your templates. Myghty goes another step furthor and lets you define multiple roots:
component_root = [
{'main':"/web/sites/mysite/htdocs"},
{'components':"/web/sites/mysite/components"},
{'alt':"/usr/local/lib/special-comp"}
]
If you have multiple component roots, and you ask for /lib/view_user.myt, Myghty will search for that under each of those directories you specified to component_root.
This is a very powerful ability as you can add component roots and override other components. I cannot stress enough how useful and vital this feature is for me. It’s exceptionally useful if you want to run multiple sites with different skins, ie, co-branding your site perhaps. All you need to do is setup a new Myghty server, and configure the component roots to the other site and make a new component root for your co-branded site.
Here’s a possible config given our original site is configured as shown above:
component_root = [
{'cobrand':"/web/sites/cobrand/htdocs"},
{'main':"/web/sites/mysite/htdocs"},
{'components':"/web/sites/mysite/components"},
{'alt':"/usr/local/lib/special-comp"}
]
Now I could just create a /autohandler in the new directory, and when Myghty is searching the inheritance chain looking for autohandler’s, it loads /web/sites/cobrand/htdocs/autohandler instead of /web/sites/mysite/htdocs/autohandler. I could also specify a certain component using the key in front, main:/some/component.myt.
Using Myghty in MVC
Myghty has Sessions, Filters, Content Escaping, and some rather advanced functionality for switching buffer spaces on component output that even surpasses Mason. A further extension of the Component concept is the Module Component concept, which allows you to design your web application in the MVC paradigm with a Controller class.
The benefit of using Myghty’s MVC vs using Myghty strictly as a template language within a different MVC web application, is that you gain the ability to easily call Controllers from within a template. While you might wonder at first why you’d want to do this, it can be very useful when using AJAX and a section of a page is going to be filled in by an AJAX request. Calling the Controller for its output from the template lets you easily put in the starting content. There’s other benefits as well, my prior article on Myghty covered the other import reason, which is the Custom Resolvers ability that you wouldn’t have if a different framework is handling the request.
If this has you interested and you’d like to learn Myghty in depth, my suggestion would be to read the Mason Book while keeping the Myghty docs handy to see what the Python implementation looks like. Myghty is a very advanced template framework that handles the VC in MVC, and I’ve yet to find another template language I enjoy as much.
Fast CGI with HTML::Mason 1
I decided the other day for a variety of reasons, to switch from the mod_perl web-app style to using Fast CGI with HTML::Mason. I only found one application out there that uses Mason with Fast CGI, which was the RT Ticket tracking system. However, the way it was setup didn’t match my requirements, nor the way their handler was configured.
After scouring the Internet some more, I hobbled together a working config section for my Apache+mod_fastcgi along with a template for the mason handler. Since I haven’t seen anything going over these basic steps anywhere else, here’s how I did it.
First, the things you should have installed on your system (which I’m assuming is nix):
- HTML::Mason
- CGI::Fast
- Apache w/mod_fastcgi
Fast CGI runs your CGI application for you, and handles connections between your application, and the webserver. To configure your application, you just use one of the Fast CGI development kits for the response event loop within which your application will process requests.
Since we’re using Perl, there’s already a handy module available from CPAN that I chose to use called CGI::Fast. Then we just wrap our Mason call within a CGI::Fast loop to handle requests. This Perl script will be kept running persistently so that you get the advantage of not having to startup the Perl interpreter on every web page request.
Why Fast CGI instead of mod_perl?
- You can use the connection feature of Fast CGI to run your app on a different machine than the webserver
- Your application takes up only as much ram as Perl + your modules
- It’s more portable, you don’t even need to use Apache, any webserver supporting Fast CGI will work
- Less configuration files to maintain
Before showing my standard handler template, you should be aware of how I organize a Mason site using Fast CGI. Here’s what my directory structure looks like under the fictional GroovieWebapp:
- GroovieWebapp/
- site/
- modules/
- libs/
- mdata/
- mason-handler.fcgi
Site is where all of our Mason code (and images, css, etc.) is going to go. Modules is for putting any of your own Perl modules into that you made specifically for this webapp. libs for Mason libs, mdata for your Mason data dir, and finally the handler itself. This structure puts your whole webapp under one directory which is also useful under version control systems like Subversion.
Here’s what my standard handler template looks like (mason-handler.fcgi):
#!/usr/bin/perl
use FindBin qw($Bin);
use lib "$Bin/modules";
use strict;
use HTML::Mason::CGIHandler;
use MIME::Lite; # Need this to e-mail the error
# Enter CGI::Fast mode, which should also work as a vanilla CGI script.
require CGI::Fast;
my $h;
my $show_error = 1; # Should we e-mail the error, or dump to the web?
if ($show_error) {
$h = HTML::Mason::CGIHandler->new
( comp_root => [
[main => "/usr/local/www/GroovieWebapp/site"],
[libs => "/usr/local/www/GroovieWebapp/libs"]
],
data_dir => "/usr/local/www/GroovieWebapp/mdata",
allow_globals => [qw($Schema $Session)]
);
} else {
$h = HTML::Mason::CGIHandler->new
( comp_root => [
[main => "/usr/local/www/GroovieWebapp/site"],
[libs => "/usr/local/www/GroovieWebapp/libs"]
],
data_dir => "/usr/local/www/GroovieWebapp/mdata",
error_format => 'text',
error_mode => 'fatal',
allow_globals => [qw($Schema $Session)]
);
}
# Setup our global vars for the request, preload our modules
{ package HTML::Mason::Commands;
use Apache::Session::File (); # My favorite for session tracking
use CGI::Cookie; # Also for session tracking
use DBI; # It's nice to load and establish our db connection in advance
DBI->install_driver("mysql"); # Put in whatever connection you use, etc.
# This allows our $Schema variable to be accessed from anywhere in our Mason site
our $Schema = DBI->connect_cached("dbi:mysql:DB_NAME","DB_USER", "DB_PASSWORD" );
}
# These two subroutines add Mason functionality that was lost by using CGIHandler instead
# of the ApacheHandler.
sub HTML::Mason::FakeApache::document_root {
my $self = shift;
return $ENV{'DOCUMENT_ROOT'};
}
sub HTML::Mason::FakeApache::param {
my $self = shift;
my $key = shift;
my %args = HTML::Mason::Utils::cgi_request_args($self->query,$self->query->request_method);
my @keys = (keys %args);
if ($key) {
return $args{$key};
} else {
return @keys;
}
}
# For e-mailing the error
sub send_email {
my $error = shift;
my $cgi = shift;
my $site = $cgi->virtual_host();
my $time = localtime;
my $body = "----------------------------------------\n";
$body .= "-------- ERROR OCCURRED\n";
$body .= "----------------------------------------\n";
$body .= "\n\n";
$body .= "WEBSITE INFO\n";
$body .= "Site: $site\n";
$body .= "Full URI Request: ".$ENV{'REQUEST_URI'}."\n";
$body .= "Time: $time\n";
$body .= "\n\n";
$body .= "USER INFO\n";
$body .= "Referrer: ".$cgi->referer()."\n";
$body .= "User-agent: ".$cgi->user_agent()."\n";
$body .= "IP Address: ".$cgi->remote_host()."\n";
$body .= "Cookie info: ".$cgi->raw_cookie()."\n";
$body .= "\n\n";
$body .= "MASON ERROR\n";
$body .= $error;
my $msg = MIME::Lite->new( From => 'YOUR SITE <WHERE@WHEREVER.COM>',
To => 'YOUR_EMAIL_ADDRESS',
Subject => "$site Mason Website Error occured at $time",
Data => $body,
);
$msg->send('smtp','YOUR_SMTP_SERVER');
}
while (my $cgi = new CGI::Fast) {
# the whole point of fastcgi requires the env to get reset here..
# So we must squash it again (This was copied from RT's Fast CGI handler)
$ENV{'PATH'} = '/bin:/usr/bin';
$ENV{'CDPATH'} = '' if defined $ENV{'CDPATH'};
$ENV{'SHELL'} = '/bin/sh' if defined $ENV{'SHELL'};
$ENV{'ENV'} = '' if defined $ENV{'ENV'};
$ENV{'IFS'} = '' if defined $ENV{'IFS'};
# The Mason $r->uri includes the script name unless we do this
$ENV{'SCRIPT_NAME'} = '';
# This deals with someone entering yoursite.com/ to make sure it serves index.html
if ( ( !$h->interp->comp_exists( $cgi->path_info ) )
&& ( $h->interp->comp_exists( $cgi->path_info . "index.html" ) ) ) {
$cgi->path_info( $cgi->path_info . "index.html" );
}
#$cgi->header(-charset=>'utf-8'); # If your site uses utf-8 characters
# Ping our db handle
$HTML::Mason::Commands::Schema->ping;
# Lets try and handle this...
eval {
$h->handle_cgi_object($cgi);
};
# Something happened, if it couldn't find the component, don't fatal
# we'll re-process as a 404
if ($@) {
if ($@ =~ /could not find component/) {
# If you want Mason to handle the error so you can keep your site appearence,
# this will call Mason to display your error page. If the error was in the
# code that is called on every page, this will cause trouble.
$cgi->path_info('/errordocs/404.html');
$h->handle_cgi_object($cgi);
} else {
send_email($@,$cgi);
}
}
}
This template has the option of either showing the Mason debugging output to the screen, or capturing the error, displaying a pretty 404 of your desire, and e-mailing you the error that occured.
Now for the Apache httpd.conf:
# Tell FastCGI to put its temporary files somewhere sane.
FastCgiIpcDir /tmp
# Increases processes if you have heavy loads to deal with
FastCgiServer /usr/local/www/GroovieWebapp/mason-handler.fcgi -idle-timeout 120 -processes 2
<VirtualHost *:80>
ServerAdmin webmaster@YOUR_SERVER
ServerName YOUR_SERVER_NAME
AddHandler fastcgi-script fcgi
ScriptAliasMatch (.*\.html$) /usr/local/www/GroovieWebapp/mason-handler.fcgi$1
ScriptAliasMatch (.*\/$) /usr/local/www/GroovieWebapp/mason-handler.fcgi$1
DocumentRoot /usr/local/www/GroovieWebapp
</VirtualHost>
Restart apache, and check apache’s error_log to see that Fast CGI started up your application properly. Obviously, tailor these samples as needed. Another useful trick when running your webapp this way, is that if you kill the perl processes the apache Fast CGI process manager starts for you, it’ll re-spawn them. I find this a quick way to re-load individual webapps if I made changes to a module they’re using.
Enjoy!*
A Mason component to fill-in error messages
How often have you seen those sites with a form, and after you miss a field, it pops up a little message in red under the text box indicating what went wrong? I’m guessing a lot, and when writing web applications this can be a pain to code in.
Typically in Perl/PHP, you’d add this by going through your form, adding little bits of code under each and every form element to display the error on invalid input. I quickly got tired of this, and decided to simplify the process.
% if ($form_status eq 'errors') {
<&| /lib/error_fill.mas, errors => $errors_hash_ref &>
<p style="color: red; font-weight:bold;">Errors Found: Please correct the fields indicated.
<& /forms/myform.mas, %ARGS &>
</&>
% } else {
<& /forms/myform.mas, %ARGS &>
% }
$errors_hash_ref is a hash ref that is keyed by the form field name, with the value set to the error message you want displayed. Right now, error_fill.mas does not have custom pre/post-fix variables for you to tweak how the error message is inserted. It currently puts a <br> followed by a red span element containing your message.
myform.mas is the form I want to display, I prefer to split sections out in Mason to keep my web application modular and the sections of my pages more reusable.
Here’s error_fill.mas:
<%args>
$errors
</%args>
<%init>
# $errors is a hash reference keyed as:
# 'field name' > 'Error message'
use HTML::Parser;
my $form = $m->content;
my $p = HTML::Parser->new(api_version > 3);
$p->handler(default => sub { print @_ }, "text");
$p->handler(end => sub {
my ($tagname, $text, $attr) = @_;
if (($tagname eq 'select') && (exists $errors->{$attr->{name}})) {
print $text;
print '<span style="color:red;">';
foreach my $err (@{$errors->{$attr->{name}}}) {
print '<br />'.$err;
}
print '</span>';
} else {
print $text;
}
},
"tagname, text, attr");
$p->handler(start => sub {
my ($tagname, $text, $attr) = @_;
if (($tagname eq 'input') && (exists $errors->{$attr->{name}})) {
print $text;
print '<span style="color:red;">';
foreach my $err (@{$errors->{$attr->{name}}}) {
print '<br />'.$err;
}
print '</span>';
} else {
print $text;
}
},
"tagname, text, attr");
$p->parse($form);
</%init>
Hopefully this will help some people out.





