Comparing web.py's Templator and Jinja2: strengths and weaknesses - python

I'm adding a simple web interface to an already existing piece of software; web.py fits the job just right and that's what I'm using. Now I'm researching what templating engine to use and came down to two alternatives: either using web.py's own Templator or using Jinja2.
I already have both working in the app and I'm writing some very simple templates in both to explore them. I must say I find Templator easier to read, that's probably due to me being a programmer and not a web designer (who would probably find Jinja easier?).
While I'm only generating (non compliant ;) ugly HTML pages now, I'll also use the templating engine to generate emails and good old plain text files.
Both softwares are "fast enough" for any practical purpose, I'd like to ask people who used extensively one or the other or both what are their strengths and weaknesses in the areas of ease of use, code cleanliness, flexibility, and so on.

Taking a quick look at Templator (which I have never used) and comparing it to Jinja2 (which I have used somewhat extensively), I'd say that the two are pretty similar ... but Templator is closer akin to Mako than to Jinja.
Mako and Jinja both support:
Template Inheritance (You can have a layout that all your pages inherit from)
Whitespace control
While Mako and Templator both support:
Embedding "safe" Python in your templates.
All three support:
Adding to the template context (functions, objects, variables, the works)
Defining functions to encapsulate re-usable pieces of functionality in your templates (Jinja calls them "macros".)
Conditionals and loops
Setting and getting local variables.
Expression evaluation
Caching the compiled bytecode to speed up future execution.
Templator supports on weird thing that I don't believe either Jinja or Mako does:
Setting attributes on the compiled template object from within the template code. (Speaking frankly, actually making use of that feature seems like the wrong thing to do. Any flags that your template could determine need to be set from what has been passed in by the context should already be set by your application code.)
Jinja takes the template code and compiles them to Python bytecode, but it does that for everything, rather than passing through strings to the Python interpreter to use safe_eval. By doing so Jinja2 is theoretically immune to certain types of attacks on the template level (But when you have hostile input from your templates you generally have a much bigger problem).
As for the rest of it, it's all pretty much up to your preference for syntax.

What was hard for me in Templetor is template inheritance. Instead of simple concept of blocks which is present e.g. in Jinja2, you have to select the base template once in the app code, then do the weird attribute setting in the actual template while accessing it in the base template. Still you have problems if you need more than one “big” block like the page body.
Real blocks are much more elegant, and the flexibility of Templetor's “real” Python is not really necessary, while it probably can be unsafe.

Related

Django. Check in template or use an extra field?

I have some text fields in my Django model that are filled by a script, with values in English (the list of values is known).
But the app is actually made for Russian clients only. I'd like to translate those fields into Russian, and here comes a little question. These values are taken from an API response, which means I should check the value to translate it. What's faster: to check and translate fields in template or to make extra fields and translate strings in the Python script?
The problem is overhead of compiling Templates when rendering. So the more complicated the template gets (method calls etc), the performance tends to get slow (like py files are converted to pyc). Django has template caching but that also is limited (I don't know how much). I have faced performance issue because of lot of logic in templates. Plus its always good to have a dumb client (template). I will prefer the Python approach because of the idea to keep client thin and not because of the performance gap. Plus if tomorrow you need to add one more language then changing templates is always going to be difficult then server.

What is the best way of including common content (for example header script) in django / python web app

In php files, this task may be a simple include of another file but I wondered if it was similar practice in Django? like described here: https://docs.djangoproject.com/en/dev/ref/templates/builtins/?from=olddocs#include
Short answer: No, Python doesn't perform that way.
Here's a long one:
A little bit about difference between PHP and Python web development
First of all, include and require are parts of PHP language itself. It means that before processing source code PHP interpreter includes source code from files given as arguments to those functions and then makes interpreting. That's the inheritance of the main purpose of PHP design (HTML, or, generally, text preprocessing).
Web development in Python is a bit different. Language itself was designed as general purpose programming language, so it doesn't assume text-processing by default. Code is just executed. That's why web development is usually done using frameworks (or wsgi modules if you prefer doing everything from scratch.
All that above means that all text manipulations (all output you generate, you generally do manually by creating result text string (or strings list when used with buffering) and giving the output result yourself.
Template languages
That's kinda messy point from which template languages were born, becoming essential part of every (or almost every) web application written in Python (you can assume something simalar to Smarty in PHP world). There are a lot of them: jinja, jinja2, mako, chameleon ... and many others. All of them are different but serve the same purpose (easyfying text generation via providing templates with placeholders for data of basic representation logic).
And here comes the main feature of Python web frameworks: application logic and representation are strictly splitted.
Here we came to the substance of your question:
As all of those template libraries providing text templating facilities are different, there's no common way to make PHP-like includes that we can say they are general for Python. Each of those tools provide different ways and philosophy of handling, in particular, includes, mainly divided into two mainstream ways:
macros- and slots-based (Chameleon)
template inheritance-based (Jinja2, Django template language)
All you need is to take one that best fits your needs (whether you like/unlike their syntax, some of them are faster, some are more readable, and so on..) and work with it combining with other tools that provide logic for your application.
Getting closer: About Django
It's common to use include template tag when you want to include some re-used part of application (e.g. pagination widget), for which you've adapted your view context.
But when you have common header for all pages, or another common part, it's better to use inheritance, that's achieved in two steps:
Basic template is created (containing general header and footer)
Specific templates are created via template inheritance feature, in particular, extends template tag in Django
Python is not PHP!
Django doesn't allow you to write arbitrary scripts(code) in templates. You should do all the computations/business tasks in views.py (controller) and pass results into template. In template usually you iterate over your result set and display data. In django 1.4 a new assignment tag was added , so you can do
{% get_movie_tickets_for_theater movie theater as tickets %}
but your get_movie_tickets_for_theater will be defined in templatetags python file.

Django i18n: is there a gettext alternative?

I'm looking for a way to translate my Django project. Built in mechanism provided with Django is great, but has several weak points which made me go looking for an alternative.
Project owner must be able to edit every translation including English (original translation). With gettext it is possible to edit translations with tools like Pootle, but the original strings stay hardcoded inside file sources or templates. There is no way that product owner can change them.
Possible solution is to make gettext translate some unique identifiers, and just translate them to all languages including English, like this:
_('form_sumbit_button')
But this makes tools like pootle almost impossible to use for translators.
Question: are there any tools for Django project translation that could fit my needs?
If you use some message IDs, they would either be incomprehensible ("message_2215") or you'd be forced to synchronise the message IDs to the actual messages ("Please press any key" = "please_press_any_key" => "Any key to continue" = "any_key_to_continue"). Either way, real strings are better for the programmers and for the tools.
However, if you employ a separate proof-reader for your strings, you can do the following:
Create an English "translation" file (yes, this works)
Let your proof-reader "translate" from English to English using Pootle or any other tool
Make sure your programmers keep that translation file untranslated by updating the strings in code.
(optional) Create a way to deploy translations independently of your main code so you can fix a typo quickly.
You may be able to use Pootle with the _("message_id") approach, depending on how easy Pootle is to customise (I don't know the internals so I can't say, but IIUC it uses Django where template changes are usually straightforward).
For example, Pootle's translation screens have "Original" and "Translation" sections; you could perhaps adapt the templates to show, under the "Original" section, a "Reference" section which displays some canonical translation using a specific reference language (e.g. English).
Or you may be able to use Pootle's alternative source language functionality, without needing to customise Pootle. You could store the canonical versions of the translations using an unused language code (or a made-up one).
Using identifiers is definitely possible with Gettext and there are tools which support this. However it might be unusual for some translators as they are used to downloading only .po file for offline translation, what does not work with monolingual translations.
For example Weblate supports monolingual Gettext files just fine (I'm author of this tool): https://docs.weblate.org/en/latest/formats.html#monolingual-gettext

Embedding Python code as a preprocessor PHP style

I'm going back over an old project where I added preprocessor functionality to Essence' and I realised that my previous solution of writing a domain specific language and associated lexer/parser was overkill.
Instead I just need to be able to embed dynamic language code into the file, isolate it at runtime, eval and insert the results. In other words very similar to the PHP model of inserting dynamic code into HTML. I'd rather not use PHP as Python is much easier to distribute as part of a larger project (IronPython or Jython)
So the question goes, how best to implement something like the following:
<code>Python goes here</code>
Lots of essence <code>Python</code> prime code goes here
I don't want to have to alter the structure of the Essence' file (if I remove all the code blocks everything left should be able to be syntactically correct. It needs to be able to insert text in place of a code block like PHP.
Finally security wise I'm not bothered about code injection, as it would be the user themselves choosing the file to execute although if there were security benefits to one model over another with no extra costs that would obviously be good.
Cheers in advance
Your best bet is to use one of the already made (and battle tested) Templating Engines. The two big ones that I've used are Mako, and Cheetah. They allow you to embed code right in the page, and are mostly used as the View in an MVC architecture.
If you feel that using one of those engines is overkill for your project, here is a small tutorial on how to implement basic templates yourself. Keep in mind that the example will need to be modified to suit your particular project/needs.

Python templates for web designers

What are some good templating engines for web designers? I definitely have my preferences as to what I'd prefer to work with as a programmer. But web designers seem to have a different way of thinking about things and thus may prefer a different system.
So:
Web designers: what templating engine do you prefer to work with?
programmers: what templating engines have you worked with that made working with web designers easy?
I had good votes when answering this same question's duplicate.
My answer was:
Jinja2.
Nice syntax, good customization possibilities.
Integrates well. Can be sandboxed, so you don't have to trust completely your template authors. (Mako can't).
It is also pretty fast, with the bonus of compiling your template to bytecode and cache it, as in the demonstration below:
>>> import jinja2
>>> print jinja2.Environment().compile('{% for row in data %}{{ row.name | upper }}{% endfor %}', raw=True)
from __future__ import division
from jinja2.runtime import LoopContext, Context, TemplateReference, Macro, Markup, TemplateRuntimeError, missing, concat, escape, markup_join, unicode_join
name = None
def root(context, environment=environment):
l_data = context.resolve('data')
t_1 = environment.filters['upper']
if 0: yield None
for l_row in l_data:
if 0: yield None
yield unicode(t_1(environment.getattr(l_row, 'name')))
blocks = {}
debug_info = '1=9'
This code has been generated on the fly by Jinja2. Of course the compiler optmizes it further (e.g. removing if 0: yield None)
Django's templating engine is quite decent. It's pretty robust while not stepping on too many toes. If you're working with Python I would recommend it. I don't know how to divorce it from Django, but I doubt it would be very difficult seeing as Django is quite modular.
EDIT: Apparently the mini-guide to using Django's templating engine standalone was sitting in front of me already, thanks insin.
Look at Mako.
Here's how I cope with web designers.
Ask them to mock up the page. In HTML.
Use the HTML as the basis for the template, replacing the mocked-up content with ${...} replacements.
Fold in loops to handle repeats.
The use of if-statements requires negotiation, since the mock-up is one version of the page, and there are usually some explanations for conditional presentation of some material.
I personally found Cheetah templates to be very designer-friendly. What needed some time was the idea of templates subclassing, and this was something hard to get at the beginning. But a designer creates a full template, duplicating his code... Then you can go clean things up a bit.
To add to #Jaime Soriano's comment, Genshi is the template engine used in Trac post- 0.11. It's can be used as a generic templating solution, but has a focus on HTML/XHTML. It has automatic escaping for reducing XSS vulnerabilities.
Mi vote goes to Clearsilver, it is the template engine used in Trac before 0.11, it's also used in pages like Google Groups or Orkut. The main benefits of this template engine is that it's very fast and language-independent.
I've played both roles and at heart I prefer more of a programmer's templating language. However, I freelance for a few graphic designers doing the "heavy lifting" backed and db programming and can tell you that I've had the best luck with XML templating languages (SimpleTAL, Genshi, etc).
When I'm trying to be web designer friendly I look for something that can be loaded into Dreamweaver and see results. This allows me to provide all the hooks in a template and let the designer tweak it without worrying about breaking what I've already written. It allows us to share the code and work better together where we're both comfortable with the format.
If the designer codes without a WYSIWYG editor, I think you're options are less limited and you could go with your own personal favorite.

Categories

Resources