Monday, December 18, 2006

Cleaned up embedded.factor

Matthew Willis reported a bug against the embedded.factor templating library in the Factor HTTP server, which I now fixed.

Recall that embedded.factor evaluates Factor code between <% and %>, and outputs the rest as text.

I wanted to post the code because I also cleaned it up and now it looks really nice. Factor is all about writing simple code to get useful things done, and I don't think many languages manage to implement a web templating solution with less complexity than Factor:
! Copyright (C) 2005 Alex Chapman
! Copyright (C) 2006 Slava Pestov
! See http://factorcode.org/license.txt for BSD license.
IN: embedded
USING: sequences kernel parser namespaces io html errors ;

: process-html ( parse-tree string -- parse-tree )
dup empty? [ drop ] [ parsed \ write-html parsed ] if ;

: process-embedded ( parse-tree string -- string parse-tree )
"<%" split1 >r process-html r> "%>" split1 >r (parse) r> ;

: (parse-embedded) ( parse-tree string -- parse-tree )
dup empty?
[ drop ] [ process-embedded (parse-embedded) ] if ;

: parse-embedded ( string -- quot )
[ f swap (parse-embedded) >quotation ] with-parser ;

: eval-embedded ( string -- ) parse-embedded call ;

: run-embedded-file ( filename -- )
[
[
file-vocabs
dup file set ! so that reload works properly
dup <file-reader> contents eval-embedded
] with-scope
] assert-depth drop ;

: embedded-convert ( infile outfile -- )
<file-writer> [ run-embedded-file ] with-stream ;

Bear in mind that this implementation properly supports mixing combinators with templating, so for example you can write the following in the middle of your template:
<% 10 [ %> <p>Hello</p> <% ] times %>

And as a final note, I'm aware that mixing markup and logic is a bad thing. However Factor encourages factoring problems into many small words, so the template should not be doing any heavy processing, and instead only calling a handful of words here and there, to achieve the same effect (but less complexity and more elegance) than JSP taglibs and such.

No comments: