Can Raku replace HTML?

In my last post, I listed three recent posts that got me thinking about Raku and HTML. I wondered if two of these could be used together to streamline the composition of web sites.

Act #1 – LPQ

Is drawn from a great idea of gfldex – Low Profile Quoting. Here’s my interpretation:

method init-qform() {
    my $css = q:to/END/;
    #demoFont {
    font-size: 16px;
    color: #ff0000;
    }
    END
        
    my $size = <40>;
    my $pattern = <[a-zA-Z0-9 ]+>;
        
    my $html = §<html>(§<head>(§<title>()),
        §<style>(:type<text/css>, $css),
        §<body>(
            §<form>(:action<.action>, :method<post>,
                §<p>('Your Name (required)'),
                §<input>(:type<text>, :required, :name<cf-name>, 
                                      :value<.cf-name>, :$size, :$pattern,),

                §<p>('Your Email (required)'),    #email type validates input
                §<input>(:type<email>, :required, :name<cf-email>, 
                                       :value<.cf-email>, :$size,),
 
                §<p>('Your Subject (required)'),
                §<input>(:type<text>, :required, :name<cf-subject>, 
                                      :value<.cf-subject>, :$size, :$pattern,),

                §<p>(:id<demoFont>, 'Your Message (required)'),
                §<p>(§<textarea>(:rows<10>, :cols<35>, :required, 
                                      :name<cf-message>, '<.cf-message>', ),),

                §<input>(:type<submit>, :name<cf-submitted>, :value<Send>,),
            )
        )
    );
    spurt "templates/qform.crotmp", pretty-print-html($html);
}

In the words of the originator “While casting my Raku spells I once again had felt the urge for a simply but convenient way to inline fragments of html in code. The language leans itself to the task with colon pairs and slurpy arrays.

The full code is available at https://github.com/p6steve/CroTemplateTest for your perusal. Here we have configured Raku with a §<html> shortcut that replaces the usual HTML <open attr=”value”>payload</close> tags. (The syntax magic is that ‘§’ is defined as a Class with Associative accessor.)

So what can this do for me?

  • express HTML components within a richer logical context
  • reduces the impedance of forced separation of component logic
  • tags are now function calls – so no more open/close boilerplate
  • the smooth Raku attribute syntax … :name<value> is used
  • variables ($size, $pattern) help you to DRY
  • it works with css

Act #2 – Cro

BUT – how can Act #1 co-exist with the Cro::WebApp::Template concepts? Sharp eyed readers may have noticed that the HTML above has a couple of examples of that already:

  • :value<.cf-email> … places $context.cf-email variable in attribute
  • ‘<.cf-message>’, … places $context.cf-message variable in payload

I thoroughly recommend the curious reader to review the Raku Cro services documentation

So the above init-qform method generates this .crotmp code:

<!DOCTYPE html>
<html>
<head>
<title>
</title>
</head>
<style type="text/css">#demoFont {
font-size: 16px;
color: #ff0000;
}
</style>
<body>
<form action="<.action>" method="post">
<p>Your Name (required)</p>
<input type="text" size="40" required pattern="[a-zA-Z0-9 ]+" value="<.cf-name>" name="cf-name" />
<p>Your Email (required)</p>
<input size="40" required value="<.cf-email>" type="email" name="cf-email" />
<p>Your Subject (required)</p>
<input value="<.cf-subject>" required name="cf-subject" type="text" pattern="[a-zA-Z0-9 ]+" size="40" />
<p id="demoFont">Your Message (required)</p>
<p>
<textarea name="cf-message" rows="10" required cols="35">
<.cf-message>
</textarea>
</p>
<input name="cf-submitted" type="submit" value="Send" />
</form>
</body>
</html>

Then we can set up a context:

class Context {
    has $.action = 'mailto:you@p6steve.com';
    has $.cf-name = 'p6steve';
    has $.cf-email = 'me@p6steve.com';
    has $.cf-subject = 'Raku does HTML';
    has $.cf-message = 'Describe some of your feelings about this...';
}

And apply the context to process the template in a Cro::Routes files;

use Cro::HTTP::Router;
use Cro::WebApp::Template;
use Cro::TemplateTest::Workshop;

my Workshop $ws = Workshop.new;

sub routes() is export {
    route {
        get -> 'qform' {
            my $context = $ws.context;
            template 'templates/qform.crotmp', $context;
        }
    }
}

Best of Both

This post illustrates how Raku can combine detailed syntax control to smoothly embed HTML within code logic. This helps to refactor awkward syntax islands so that the underlying problem-solution logic can be encapsulated and clearly expressed, It demonstrated the practical combination of the Cro template language with innate Raku power-of-expression to drive more comprehensible, consistent and maintainable code.

Comments and feedback very welcome…

~p6steve

4 Comments

Leave a Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s