Demo

Let’s try diecutter!

Online demo

There is an online server hosting diecutter’s demo:

In sourcecode

The demo/ directory in diecutter’s sourcecode [1] contains:

  • templates in templates/ folder.
  • some HTML-based client, specialized for the sphinx-docs template, as sphinx-docs.html file.
  • presets (input data) in presets/ folder.

Feel free to use it as a sandbox.

Note

the online demo uses templates from the source code!

Local demo server

System requirements:

  • Python [2] version 2.6 or 2.7, available as python command.

    Note

    You may use Virtualenv [3] to make sure the active python is the right one.

  • make and wget to use the provided Makefile.

Execute:

git clone git@github.com:novagile/diecutter.git
cd diecutter/
make develop
make serve

The last command runs diecutter service on localhost, port 8106. Check it at http://localhost:8106/

Tip

If you cannot execute the Makefile, read it and adapt the few commands it contains to your needs.

Examples

The following examples use the Local demo server. But you should be able to execute most of them on the online demo too.

The following examples are doctested [4], using Python’s WebTest [5] to run a diecutter server. Adapt the following setup to your needs:

>>> diecutter_url = diecutter_server.application_url

In the following examples, we use Python’s requests [6] as HTTP client.

>>> import requests

greetings.txt

Let’s work on file resource greetings.txt.

>>> greetings_url = diecutter_url + 'greetings.txt'

GET raw content of a template:

>>> response = requests.get(greetings_url)
>>> print response.content
{{ greetings|default('Hello') }} {{ name }}!

POST data to the template and retrieve generated content:

>>> response = requests.post(greetings_url, {'name': u'world'})
>>> print response.content
Hello world!

>>> response = requests.post(greetings_url, {'greetings': u'Greetings',
...                                          'name': u'professor Falken'})
>>> print response.content
Greetings professor Falken!

See Files for details about working with file resources.

django_admin.py startproject

Let’s work on directory resource +django_project+/.

>>> django_project_url = diecutter_url + '+django_project+'

It’s a directory. GET lists the templates it contains:

>>> response = requests.get(django_project_url)
>>> print response.content
+django_project+/manage.py
+django_project+/+django_project+/__init__.py
+django_project+/+django_project+/settings.py
+django_project+/+django_project+/urls.py
+django_project+/+django_project+/wsgi.py

Every template in a directory can be handled as a single file. But let’s focus on the directory feature...

POST returns an archive, with TAR.GZ format by default:

>>> django_project_url = diecutter_url + '+django_project+'

>>> from StringIO import StringIO
>>> import tarfile
>>> response = requests.post(django_project_url,
...                          {'django_project': u'demo'})
>>> response.headers['Content-Type']
'application/gzip; charset=UTF-8'
>>> archive = tarfile.open(fileobj=StringIO(response.content), mode='r|gz')
>>> print '\n'.join(archive.getnames())
demo/manage.py
demo/demo/__init__.py
demo/demo/settings.py
demo/demo/urls.py
demo/demo/wsgi.py
>>> archive.close()

Without trailing slash, directory name is used as a prefix for filenames. Let’s try the same requests with a trailing slash:

>>> django_project_url = diecutter_url + '+django_project+/'

>>> response = requests.get(django_project_url)
>>> print response.content
manage.py
+django_project+/__init__.py
+django_project+/settings.py
+django_project+/urls.py
+django_project+/wsgi.py

>>> response = requests.post(django_project_url,
...                          {'django_project': u'demo'})
>>> archive = tarfile.open(fileobj=StringIO(response.content), mode='r|gz')
>>> print '\n'.join(archive.getnames())
manage.py
demo/__init__.py
demo/settings.py
demo/urls.py
demo/wsgi.py
>>> archive.close()

You can get the content as a ZIP archive instead with the “accept” header:

>>> from zipfile import ZipFile
>>> response = requests.post(django_project_url,
...                          {'django_project': u'demo'},
...                          headers={'accept': 'application/zip'})
>>> print response.headers['Content-Type']
application/zip; charset=UTF-8
>>> archive = ZipFile(StringIO(response.content))
>>> print '\n'.join(archive.namelist())
manage.py
demo/__init__.py
demo/settings.py
demo/urls.py
demo/wsgi.py
>>> archive.close()

Tip

You can see all supported “accept” headers by requesting an unknown mime type:

>>> response = requests.post(django_project_url,
...                          {'django_project': u'demo'},
...                          headers={'accept': 'fake/mime-type'})
>>> response.status_code
406
>>> print response.content
406 Not Acceptable

The server could not comply with the request since it is either malformed or otherwise incorrect.


Supported mime types: */*, application/gzip, application/x-gzip, application/zip

See Directories for details about directory resources.

Dynamic tree template

Let’s work on directory resource dynamic-tree/.

>>> dynamic_tree_url = diecutter_url + 'dynamic-tree/'

It’s a directory. GET lists the templates it contains:

>>> response = requests.get(dynamic_tree_url)
>>> print response.content
.diecutter-tree
greeter.txt

greeter.txt is the same as greetings.txt example above:

>>> response = requests.get(dynamic_tree_url + 'greeter.txt')
>>> print response.content
{{ greeter|default('Hello') }} {{ name|default('world') }}!

diecutter-tree is a normal template, with a special name:

>>> response = requests.get(dynamic_tree_url + '.diecutter-tree')
>>> print response.content
[
  {% for greeter in greeting_list|default(['hello', 'goodbye']) %}
    {
      "template": "greeter.txt",
      "filename": "{{ greeter }}.txt",
      "context": {"greeter": "{{ greeter }}"}
    }{% if not loop.last %},{% endif %}
  {% endfor %}
]

It renders a list of templates, in JSON:

>>> response = requests.post(dynamic_tree_url + '.diecutter-tree',
...                          {'greeting_list': [u'bonjour', u'bonsoir']})
>>> print response.content
[

    {
      "template": "greeter.txt",
      "filename": "bonjour.txt",
      "context": {"greeter": "bonjour"}
    },

    {
      "template": "greeter.txt",
      "filename": "bonsoir.txt",
      "context": {"greeter": "bonsoir"}
    }

]

And guess what, this list of templates is used to render the directory resource:

>>> response = requests.post(dynamic_tree_url,
...                          {'name': u'Remy',
...                           'greeting_list': [u'bonjour', u'bonsoir']})
>>> archive = tarfile.open(fileobj=StringIO(response.content), mode='r:gz')
>>> print '\n'.join(archive.getnames())
bonjour.txt
bonsoir.txt
>>> print archive.extractfile('bonjour.txt').read()
bonjour Remy!
>>> print archive.extractfile('bonsoir.txt').read()
bonsoir Remy!
>>> archive.close()

Here, the greeter.txt template has been rendered several times, with different context data.

See Dynamic directory trees templates for details about dynamic tree templates.

References

[1]https://github.com/novagile/diecutter/
[2]http://python.org
[3]http://virtualenv.org
[4]http://sphinx-doc.org/ext/doctest.html
[5]https://pypi.python.org/pypi/WebTest
[6]https://pypi.python.org/pypi/requests