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.