Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

135 lines (95 sloc) 4.331 kb
= Templates and Scomps =
The templates in Zotonic are based on django templates, using the excellent erlydtl library.
See for the implemented tags and release notes.
== Template Locations ==
The templates are searched for in two different locations:
Templates don't need to have an extension, they are just text files. Templates can also be found in subdirectories, as long as you give the subdirectory name with the template.
== Scomps ==
Scomp is shorthand for screen component. A scomp is a module implementing logic and templates.
Scomps can be included in the template using, for example:
{% @button text="Hello" action={growl text="Hello World" stay="1"} %}
{% @button text=somevar action={growl text="Hello World" stay="1"} %}
This button scomp has two parameters, text and action. The action parameter is a tuple with two additional parameters.
== Implementing Scomps ==
Scomps come in two different variations, caching and non-caching.
You can implement scomps by using the behaviours scomp and caching_scomp.
A scomp has the following four functions:
init(Args) -> {ok, State} | {error, Error}
render(Params, Context, State) -> {ok, NewContext} | {error, Error}
code_change(OldVsn, State, Extra) -> {ok}
terminate(Reason, State) -> ok
State = term()
Params = proplist()
Context = context()
depends(Params, Context) -> {NewParams, MaxAge, Depend} | false
Params = proplist()
MaxAge = integer()
Depend = TermList()
== Templates, Scomps and Request Context State ==
During the evaluation of scomps we are able to:
- wire action
- add script
- add validator
- add variable (accessible only by other scomps)
After rendering a template it is inspected to find all scripts, actions and validators. They are placed as #context records in the resulting iolist, the #contexts should be replaced by the 'render' record-attribute. There will be a special 'script' atom to signify the place where all collected scripts will be inserted. When the script atom is not found, then the result of the template
is a context, unless there are no collected scripts.
Process state diagram, how all processes work together to render a scomp:
Resource Template ScompServer Scomp Page/Session/User
|------------> render(Template,ReqContext)
| ------------------------------- lookup missing var ---------->|
|<------------------------------------- value ------------------|
|------------------> render(Scomp,ReqContext)
|---------> render(ReqContext)
: |
(if cached) |
: |
|<------------ Output ----------|
Filter scripts
|<---- Output ------|
reply user agent
The scripts/actions/validators are similar to the ones defined with Nitrogen, though the record structure is redefined to accomodate easy construction by the Template compiler.
== Things to do ==
1. Change the variable lookup in erlydtl_runtime.erl - Done.
2. Add extra parsing rules to erlydtl_parser.yrl - Done.
3. Build the new LALR parser - Done.
4. Add handling of scomp AST (abstract syntax tree) to erlydtl_compiler.erl - Done.
5. Create the scomp server (no caching for the moment) - Done.
6. Add script filter to z_template - Done.
7. Make test scomps - Done.
== Code generated for the scomp calls ==
{% @button text="Hello" action={growl text="Hello World" stay=1} %}
gives an AST of:
{string_literal,{5,44},"\"Hello World\""}},
Which should be translated to:
case z_scomp:render(button, [{text,"Hello"},
{action, {growl, [{text,"HelloWorld"}, {stay,1}]} }
], Variables)
{ok, Rendered} -> Rendered;
{error, Reason} -> io_lib:format("error: ~p", Reason)
Jump to Line
Something went wrong with that request. Please try again.