")
def default(path=None):
gp = request.args.to_dict()
pp = request.form.to_dict()
html = zml.render('page.zml', path=path, getparams=gp, postparams=pp)
return html
if __name__ == "__main__":
app.run(debug=True)
Nominatim
^^^^^^^^^
This example shows the usage of the REST API of Nominatim.
The API keys are imported from a separate file.
You have to rename the file "keys.zml.default" to "keys.zml" and change the API key.
Get your API key from
https://developer.mapquest.com/plan_purchase/free/business_edition/business_edition_free
::
%import keys
%import components
%inherit base
@db:
host: 'open.mapquestapi.com'
#places: @db/nominatim/v1/search?format=json&q=Cologne&key={appkey}
*content:
%for p in places:
p: {p.display_name}
The rendered result showing the nominatim results for the term 'Cologne':
::
zml
Köln, Regierungsbezirk Köln, Nordrhein-Westfalen, 50667-51149, Deutschland
Köln, Regierungsbezirk Köln, Nordrhein-Westfalen, Deutschland
Cologne, BS, LOM, Italia
Cologne, BS, LOM, Italia
Cologne, Auch, Gers, Midi-Pyrénées, France métropolitaine, 32430, France
La Cologne, Tincourt-Boucly, Péronne, Somme, Picardie, France métropolitaine, 80240, France
La Cologne, Doingt, Péronne, Somme, Picardie, France métropolitaine, 80200, France
La Cologne, Péronne, Somme, Picardie, France métropolitaine, France
La Cologne, Cartigny, Péronne, Somme, Picardie, France métropolitaine, 80200, France
La Cologne, Péronne, Somme, Picardie, France métropolitaine, France
Wikipedia
^^^^^^^^^
There is a wikipedia rest example in the examples folder:
::
%import components
%inherit base
@db:
host: 'en.wikipedia.org'
#pages: @db/w/api.php?action=query&list=search&format=json&srsearch=rest
*content:
%for p in pages.query.search:
p: {p.title}
The rendered result:
::
zml
Representational state transfer
Rest
ReStructuredText
Rest (music)
Shady Rest, California
Travelers Rest
Rest area
Pilgrim's Rest, Arkansas
Note value
Pilgrim's Rest
Routes
^^^^^^
Routes are defined by using ~ as a prefix.
The routes will be used by a dispatcher and linkto components.
::
%import components
%inherit base
~routes:
list: '/blog/posts'
show: '/blog/post/{id}'
edit: '/blog/post/{id}/edit'
*content:
ul:
li:
base-linkto action='list': List
li:
base-linkto action='show' id=1: Details
li:
base-linkto action='edit' id=1: Edit
The rendered result:
::
zml
The linkto-component of the base namespace is simply defined:
::
%namespace base=doonx.org/base
*linkto:
a href=_path(action, _params):
{_children[0]}
The _path function is a core function of the zml implementation.
It will return an url path by interpolating the parameters into the route path definition.
The routevars wrapped by moustaches in the route-section (~) with the corresponding action name will be replaced by the values of the second function parameter of the _path function.
The _params context property contains all parameters of a component.
F.e. the following line will use the linkto-component with the parameters action and id.
The component can access the parameters by using the _params context property. The linkto-component will forward the _params property as a parameter of the _path function.
::
base-linkto action='edit' id=1
Slots
^^^^^
Slots are defined with a | (pronounced "pipe") prefix.:
::
html:
head:
title: zml
body:
nav: {nav}
main: |main
footer: |footer
The dispatcher maps the URLs to views, which are defined with a * (star).
The mapping is defined in the ~ routes section.
::
%import components
%inherit base
~main:
index: '/'
list: 'blog/posts'
show: 'blog/post/{id}'
edit: 'blog/post/{id}/edit'
~footer:
userfooter: '/'
devfooter: 'develop/'
*nav:
ul.mainmenu:
li:
base-linkto action='list': 'List'
li:
base-linkto action='show' id=1: 'Show item with id 1'
li:
base-linkto action='edit' id=1: 'Edit item with id 1'
li:
base-linkto action='devfooter' router='footer': 'A developer sub section with a different footer'
*index:
p: 'index view'
div: x: {_request.get.x}
*list:
p: 'posts view'
*show:
p: 'show view of id {id}'
*edit:
p: 'edit view of id {id}'
*userfooter:
ul.footernav:
li: 'user footer item 1'
li: 'user footer item 2'
li: 'user footer item 3'
*devfooter:
ul.footernav:
li: 'dev footer item 1'
li: 'dev footer item 2'
li: 'dev footer item 3'
Open http://127.0.0.1:5000/ in your browser.
The rendered result depends on the url you enter:
http://localhost:5000/blog/posts
shows the posts view.
http://localhost:5000/blog/1
shows the detail view.
http://localhost:5000/blog/post/1/edit
shows the edit view.
Views
^^^^^
Views are defined with a * glyph:
The dispatcher maps the URLs to views, which are defined with a * (star).
The mapping is defined in the ~ routes section.
The dispatcher uses the route variables defined with moustaches f.e. {id} in the routes.
See ~ section of the main router:
::
%import components
%inherit base
~main:
index: '/'
list: 'blog/posts'
show: 'blog/post/{id}'
edit: 'blog/post/{id}/edit'
~footer:
userfooter: '/'
devfooter: 'develop/'
*nav:
ul.mainmenu:
li:
base-linkto action='list': 'List'
li:
base-linkto action='show' id=1: 'Show item with id 1'
'li:
base-linkto action='edit' id=1: 'Edit item with id 1'
li:
base-linkto action='devfooter' router='footer': 'A developer sub section with a different footer'
*index:
p: 'index view'
div: x: {_request.get.x}
*list:
p: 'posts view'
*show:
p: 'show view of id {id}'
*edit:
p: 'edit view of id {id}'
*userfooter:
ul.footernav:
li: 'user footer item 1'
li: 'user footer item 2'
li: 'user footer item 3'
*devfooter:
ul.footernav:
li: 'dev footer item 1'
li: 'dev footer item 2'
li: 'dev footer item 3'
Open http://127.0.0.1:5000/ in your browser.
The rendered result depends on the url you enter:
http://localhost:5000/blog/posts
shows the posts view.
http://localhost:5000/blog/1
shows the detail view.
http://localhost:5000/blog/post/1/edit
shows the edit view.
RESTful resources
^^^^^^^^^^^^^^^^^
RESTful resource are defined by using & as a prefix.
The resources can be used to load data into data sections.
In the following example the resource named 'db' is configured with a wikipedia api hostname. The ZML implementation loads the JSON data from the path
/w/api.php?action=query&list=search&format=json&srsearch=rest.
The JSON will be converted and is accessible by using the 'pages' context variable.
::
%import components
%inherit base
@db:
host: 'en.wikipedia.org'
#pages: @db/w/api.php?action=query&list=search&format=json&srsearch=rest
*content:
%for p in pages.query.search:
p: {p.title}
The rendered result showing the wikipedia pages for the term 'rest':
::
zml
Representational state transfer
Rest
ReStructuredText
Rest (music)
Shady Rest, California
Rest area
Travelers Rest
Pilgrim's Rest, Arkansas
Note value
Pilgrim's Rest
In the following example the resource named 'db' is configured with hostname, port, username and password. The ZML implementation loads the JSON data from the path
http://localhost:5984/blog/_design/app/_view/posts.
The JSON will be converted and is accessible by using the 'posts' context variable.
::
@db:
host: 'localhost'
port: 5984
username: 'zml'
password: 'secret'
#posts: @db/blog/_design/app/_view/posts
*content:
%for post in posts.rows:
p: {post.value.title}
The rendered result f.e. loading data for 3 blog posts from a couchdb:
::
zml
First blog post title
Second post
Third post
Translations
^^^^^^^^^^^^
Add translations with the !-glyph followed by the two-letter code of the language.
::
%import components
%inherit base
!en:
labels:
title: 'Title'
date: 'Date'
bodytext: 'Bodytext'
buttons:
save: 'Save'
!de:
labels:
title: 'Titel'
date: 'Datum'
bodytext: 'Haupttext'
buttons:
save: 'Speichern'
*content:
form:
div.formrow:
label: !labels.title
input type='text' name='title'
div.formrow:
label: !labels.bodytext
textarea name='bodytext'
button type='submit': !buttons.save
Models
^^^^^^
Add models to your app by using the +-glyph followed by the model descriptor.
The base-form viewhelper expands the model to a form. The different model properties will be rendered with suitable form fields.
::
%import components
%inherit base
!en:
labels:
title: 'Title'
date: 'Date'
bodytext: 'Bodytext'
buttons:
save: 'Save'
!de:
labels:
title: 'Titel'
date: 'Datum'
bodytext: 'Haupttext'
buttons:
save: 'Speichern'
+post:
title:
&label: !labels.title
&type: 'str'
date:
&label: !labels.date
&type: 'datetime'
bodytext:
&label: !labels.bodytext
&type: 'str'
*content:
base-form model='post'