Pretty good template function
Posted: Wed Apr 11, 2007 12:16 am
It's a first draft, and I'd appreciate any ideas to tighten the code, but here it is:
It reads in the string 'template (which you would most likely get from a template file) and interprets lisp code between {% (do something...) %} tags. It is important to have a space between the tag borders and the command, and also it is important to keep an eye on your parenthesis in the template. Anything outside of the tags gets sent to print. This means that you can have:
This becomes:
...although it is not pretty and indented. Note that I used begin to encapsulate the text, "This is where...," because it gets put into a print expression. If there were no begin statement, it would treat the (print some-value) as the else form to the if statement.
This sort of emulates PHP in that anything between your outer parenthesis will be placed logistically inside of the parenthesis in the eval'd code.
The second argument to render is a context in which variables that will be considered local to the template are defined. This forces the template to explicitly call values from MAIN if it wishes to do so; a sort of chair against the door (not impossible to bypass, but you have to really want to) to keep from accidentally exposing important data from MAIN.
Code: Select all
(context 'TEMPLATE)
(define (render template ctx)
(set 'ctx (eval ctx))
(context ctx)
(set 'expanded-template "")
(set 'blocks (parse template "{|}" 4))
(dolist (block blocks)
(if (not (regex "% .+? %" block 0))
(push (format "(print [text]%s[/text])" (replace "%" block "" 0))
expanded-template -1)
(push (replace "\s*%\s*" block "" 0) expanded-template -1)))
(eval-string expanded-template)
(exit))
(context MAIN)
Code: Select all
{% (if (not (null? some-value)) (begin %}
<p>This is where you print {% (print some-value) %}</p>
{% )) %}
Code: Select all
(if (not (null? some-value))
(begin
(print "<p>This is where you print ")
(print some-value)
(print "</p>")))
This sort of emulates PHP in that anything between your outer parenthesis will be placed logistically inside of the parenthesis in the eval'd code.
The second argument to render is a context in which variables that will be considered local to the template are defined. This forces the template to explicitly call values from MAIN if it wishes to do so; a sort of chair against the door (not impossible to bypass, but you have to really want to) to keep from accidentally exposing important data from MAIN.