Migrating to Jinja2

184 views
Skip to first unread message

Christian Boos

unread,
Feb 4, 2016, 8:14:52 PM2/4/16
to trac...@googlegroups.com
Hello,

Inspired by some recent discussion seen on Trac-Users ("Genshi
question"), I decided to revisit this old topic and the last 2 weeks I
tried to get a feel of what it would take to migrate our template engine
from Genshi to Jinja2.

The results are very encouraging, as we can expect a 5x to 10x speedup.
I posted some numbers there:

http://trac.edgewall.org/wiki/TracDev/Proposals/Jinja

But the gain in speed and memory usage is only one thing (though a major
one), other aspects are important as well, like the ease of developing
the templates, the support for all the features we got used to (i18n in
particular). Without getting yet in the details, my initial experience
also makes me very optimistic for these points.

I've pushed the current rough state of my experiment in the jinja2
branch on t.e.o. It's nowhere near finished, but I hope it's in a state
which can be interesting for others to play with or simply look at, to
make up their mind.

I started by migrating an "easy" template, the search page, then
followed with the report view (#11185 in mind) and then with the browser
and the changeset views. Oh yes, I actually started with Kajiki, not
Jinja2, While the speed of the former was more than adequate (seems to
beat Jinja2 by a narrow margin), it's nowhere near as mature as Jinja2
is, and the error reporting is very lacking. This, plus other glitches
(see the commit messages for 7acf61b and 7d4b6f8), and the fact that
despite the surface similarity with Genshi you needed to adopt the
Jinja2 approach anyway (extends and blocks), meant that it was worth
going with the real thing.

And I actually like going away from an all-XML template markup, the
templates are much more readable this way, I think, at least with the
Jinja2 notation I picked: use line statements for the most part and
block statements only exceptionally. I also kept the familiar ${}
notation for the embedded expressions.

To somewhat compensate for the loss of the well-formedness guarantee
that Genshi provided for the template and the generated content, I
developed a little tool (contrib/jinjachecker.py) that will separate the
Jinja2 markup from the HTML content, and verify both separately (proper
nesting for the Jinja2 control structures, validation of the HTML using
lxml).

As for the next steps, besides starting to get feedback, document the
migration process and advocate that move, I'll continue with a few more
modules to be sure that all the remaining aspects get covered (the form
token handling, the late scripts and such little details). Ideally, I
hope that this could be the big thing for 1.3dev with in sight an
all-Jinja2 Trac 1.4 ;-)

Feedback welcomed!

-- Christian

Tim Graham

unread,
Feb 5, 2016, 10:44:53 AM2/5/16
to Trac Development
From a familiarity standpoint, I know that Django developers would appreciate this change as Jinja2 is similar to the Django Template Language and we recently added native support for Jinja2 in Django.

RjOllos

unread,
Feb 17, 2016, 12:38:44 AM2/17/16
to Trac Development
Hi Christian,

The results look very encouraging. I like the move to a more popular templating library, which I hope will help at least a little in attracting new contributors.

Once I finish up a few more tasks I plan to spend some time studying your code, and will try converting a template or two. If I can manage that, then the tasks should be more than doable for everyone else involved ;)

I gather from your comment in #11988 that adopting a better functional testing framework might happen concurrently. It seems like a good idea to put some regression tests in place as we port the templates.

- Ryan


 

Christian Boos

unread,
Feb 23, 2016, 3:07:58 PM2/23/16
to trac...@googlegroups.com
Hello,

I wanted to share some updates.

On 2/17/2016 6:38 AM, RjOllos wrote:
>
> Hi Christian,
>
> The results look very encouraging. I like the move to a more popular
> templating library, which I hope will help at least a little in
> attracting new contributors.

I also hope that getting back in touch with decent performance will
bring renewed interest.

>
> Once I finish up a few more tasks I plan to spend some time studying
> your code, and will try converting a template or two. If I can manage
> that, then the tasks should be more than doable for everyone else
> involved ;)

As you've probably seen, the Jinja2 related documentation improved lately:

- https://trac.edgewall.org/wiki/TracDev/Proposals/Jinja features a
presentation of the page architecture, as well as some detailed
conversion examples
- https://trac.edgewall.org/wiki/TracDev/PortingFromGenshiToJinja is a
migration guide, targeted at plugin developers but it will also help us
for the core Trac templates

Speaking about the work in progress:
- I'm roughly half-way through the list of templates, and I'll continue
in that order: wiki, revisionlog, roadmap, milestone, reports and admin
templates; the admin templates can follow the same model as the prefs
templates (well, I did migrate one admin panel already, so there's a
pattern to follow); if you want to help, start somewhere near the end of
that list ;-)
- we will also need to port the templates in the t.e.o plugins, mostly
the SpamFilter plugin
- fixing the tests is also a big task
- we need to integrate Genshi's HTMLSanitizer and redo it without "streams"
- and finally, we'll be able to remove the last remnants of Genshi

I've given some thoughts about maintaining a Genshi-compatibility layer,
but finally decided against it:
- making the tag builder replacement API compatible with Genshi would
imply to reimplement it fully, instead of simplifying it
- keeping the base Genshi infrastructure would hinder the evolution of
the layout/theme templates, and chrome component, as everything would
have to be done twice there
- there wouldn't anyway be a sensible way to support plugins relying on
the ITemplateStreamFilter for modifying other pages, if those pages are
produced by Jinja2 templates (parsing them back into a stream and
filtering them again would be a performance killer)

The goal is really to simplify the Trac code base, and getting rid of
the Genshi dependency will help us doing that. See for example the huge
simplification that happened with the mimeview/pygments renderer (1) (if
there was anyone feeling easy with having complex things like
_group_lines in our code base, well, that wasn't me ;-) ).


So overall I think we're a little more than half-way through, and if I
can maintain the current velocity, it sounds possible to make the switch
on trunk soon after the 1.2 release. That will give a clear signal to
the plugin developers, as well as giving them enough time to adapt
before 1.4. I should also evaluate how my branch plays with Jun's py3k
compat branch.


> I gather from your comment in #11988 that adopting a better functional
> testing framework might happen concurrently. It seems like a good idea
> to put some regression tests in place as we port the templates.

Fixing all the current tests is already a challenge, as lots of the
generated content is slightly different (tag builder API, `escape`d
strings, template generated content). But yes, ideally I'd like to give
a go to Selenium. I'm especially interested in finding a way to make the
functional tests run faster (create an env once, play the tests, remove
the env).

-- Christian

(1) -
https://trac.edgewall.org/changeset/6df5e586b8c5a7eaa1426a685913d116758bb28a/cboos.git/

Dirk Stöcker

unread,
Feb 26, 2016, 5:18:15 PM2/26/16
to trac...@googlegroups.com
On Tue, 23 Feb 2016, Christian Boos wrote:

> I've given some thoughts about maintaining a Genshi-compatibility layer,
> but finally decided against it:

Do I understand that correctly? You want to replace the template engine
with an incompatible new one and instead of operating these two in
parallel for at least one majore release, you want to drop the old one
immediatelly?

> That will give a clear signal to the plugin developers, as well as
> giving them enough time to adapt before 1.4.

Yes - it gives a clear signal: That you don't care about other peoples work.

Usually plugins are developed to solve a certain problem, not to rewrite
the same code again and again when someone decides that a fancy new
library is again better than the last one. Genshi also was so much better
than the previous one.

Compatibility is not a nuisance, it's required for acceptance.

Ciao
--
http://www.dstoecker.eu/ (PGP key available)

RjOllos

unread,
Feb 26, 2016, 7:01:39 PM2/26/16
to Trac Development


On Friday, February 26, 2016 at 2:18:15 PM UTC-8, Dirk Stöcker wrote:
On Tue, 23 Feb 2016, Christian Boos wrote:

> I've given some thoughts about maintaining a Genshi-compatibility layer,
> but finally decided against it:

Do I understand that correctly? You want to replace the template engine
with an incompatible new one and instead of operating these two in
parallel for at least one majore release, you want to drop the old one
immediatelly?

> That will give a clear signal to the plugin developers, as well as
> giving them enough time to adapt before 1.4.

Yes - it gives a clear signal: That you don't care about other peoples work.

As usual your tone is quite unpleasant. People are more likely to care about your opinion if you learn to phrase your points better.

Usually plugins are developed to solve a certain problem, not to rewrite
the same code again and again when someone decides that a fancy new
library is again better than the last one. Genshi also was so much better
than the previous one.

The migration to Jinja2 solves two real problems:
 - Performance
 - Genshi is no longer producing releases

Additionally Jinja2 is much more widely adopted. It's not simply "deciding a fancy new library is again better than the last one". You should take a look at the performance numbers Christian has produced and the detailed migration notes he has already prepared. This migration solves several real problems and the amount of effort he has put into documentation demonstrates that he clearly does care about helping users migrate.

Compatibility is not a nuisance, it's required for acceptance.

Sometimes the ideal solution is not always practical. There will likely be more than a year of pre-releases over which time plugins can be made compatible. Maybe that's not a perfect solution, but a year is quite a bit of time to plan your transition.

- Ryan

Olemis Lang

unread,
Feb 26, 2016, 7:18:29 PM2/26/16
to trac...@googlegroups.com
On 2/26/16, RjOllos <rjo...@gmail.com> wrote:
> On Friday, February 26, 2016 at 2:18:15 PM UTC-8, Dirk Stöcker wrote:
>> On Tue, 23 Feb 2016, Christian Boos wrote:
>
[...]
>
> Usually plugins are developed to solve a certain problem, not to rewrite
>> the same code again and again when someone decides that a fancy new
>> library is again better than the last one. Genshi also was so much better
>>
>> than the previous one.
>>
>
> The migration to Jinja2 solves two real problems:
> - Performance
> - Genshi is no longer producing releases
>

... but not limited to that . I could come up with three or four
similar advantages .

> Additionally Jinja2 is much more widely adopted. It's not simply "deciding
> a fancy new library is again better than the last one". You should take a
> look at the performance numbers Christian has produced and the detailed
> migration notes he has already prepared. This migration solves several real
> problems and the amount of effort he has put into documentation
> demonstrates that he clearly does care about helping users migrate.
>

+1

[...]

--
Regards,

Olemis - @olemislc

Apache™ Bloodhound contributor
http://issues.apache.org/bloodhound
http://blood-hound.net

Brython committer
http://brython.info
http://github.com/brython-dev/brython

Blog ES: http://simelo-es.blogspot.com/
Blog EN: http://simelo-en.blogspot.com/

Featured article:

Christian Boos

unread,
Feb 27, 2016, 9:25:10 AM2/27/16
to trac...@googlegroups.com
Hello,

On 2/27/2016 1:01 AM, RjOllos wrote:
>
> On Friday, February 26, 2016 at 2:18:15 PM UTC-8, Dirk Stöcker wrote:
>
> On Tue, 23 Feb 2016, Christian Boos wrote:
>
> > I've given some thoughts about maintaining a Genshi-compatibility
> layer,
> > but finally decided against it:
>
> Do I understand that correctly? You want to replace the template engine
> with an incompatible new one and instead of operating these two in
> parallel for at least one majore release, you want to drop the old one
> immediatelly?
>
> > That will give a clear signal to the plugin developers, as well as
> > giving them enough time to adapt before 1.4.
>
> Yes - it gives a clear signal: That you don't care about other
> peoples work.
>
>
> As usual your tone is quite unpleasant. People are more likely to care
> about your opinion if you learn to phrase your points better.

Ah, glad to see it's not just me reading it that way ;-) Yes, please
everyone, it would be great to keep a conversation tone where everyone
feels welcome to share her opinion. Nothing has been "voted" upon yet,
so I'm sure we can reach a consensus in what's the best outcome for the
project, its maintainers, plugin developers and users.

So yes, I want to switch to the Jinja2 template engine, this point seems
already consensual, and it's been already the consensus 6 years ago in
the first discussion on the topic (1). What has changed is that now we
have a working branch which is going to be completed (2), and as things
get more concrete we're also presented with a few development choices,
with pros and cons.

Dirk proposes to keep Genshi in parallel for "at least one major
release" (1.3.x - 1.4.x). It's true that we did that when we switched
from ClearSilver to Genshi. For that period, we had to keep telling
people: "yeah, we know we have this and that issue with ClearSilver,
please ask the plugin maintainer to switch to Genshi" and likewise with
ClearSilver related bugs. Do we really want to do the same with Genshi
again? Also, we would have to explain what still works and what no
longer works, as 100% backward compatibility is not possible
(ITemplateStreamFilter will no longer be supported). Having both
template engines coexist is not impossible of course, as this is how
things currently work in the branch, but this mixed situation has to be
compared with the clarity of a clear-cut transition.

Again, I'm not "viscerally" opposed to the idea, but I have to be
convinced that it really makes a difference. I know that for plugins
like the SpamFilter plugin, this would be "great", the Genshi templates
would still work, no changes required, and the plugin can just be used
unmodified. But what happens when 1.5.1 comes around? Same discussion?
We're not going to maintain forever a template engine we don't use in
core and know is problematic, so the necessity to migrate will come
sooner or later. The question is, does it really make such a big
difference if we announce it now, and have people do the migration early
during the 1.3.x time frame, or if we say you'll have till 1.5.x do to it?

>
> Usually plugins are developed to solve a certain problem, not to
> rewrite
> the same code again and again when someone decides that a fancy new
> library is again better than the last one. Genshi also was so much
> better
> than the previous one.
>
>
> The migration to Jinja2 solves two real problems:
> - Performance
> - Genshi is no longer producing releases
>
> Additionally Jinja2 is much more widely adopted. It's not simply
> "deciding a fancy new library is again better than the last one". You
> should take a look at the performance numbers Christian has produced and
> the detailed migration notes he has already prepared. This migration
> solves several real problems and the amount of effort he has put into
> documentation demonstrates that he clearly does care about helping users
> migrate.
>

Yes, I think so far no one really spoke against the migration and we all
see the benefits. I do what I can to prepare for a smooth transition. I
even found yesterday that making the tag builder API replacement in
trac.util.html compatible again with the Genshi templates was not as
problematic as I initially thought. So now on the branch the remaining
Genshi templates work again.

I will continue to refactor trac.web.chrome to more cleanly separate the
Genshi legacy support from the new code. An intermediate goal will be to
make Genshi an *optional* package, i.e. Trac should be able to work
fully without Genshi installed.

> Compatibility is not a nuisance, it's required for acceptance.
>
>
> Sometimes the ideal solution is not always practical. There will likely
> be more than a year of pre-releases over which time plugins can be made
> compatible. Maybe that's not a perfect solution, but a year is quite a
> bit of time to plan your transition.

I hope that after a few more exchanges we will be able to figure out the
right approach, a clear severance between Trac and Genshi, or a
middle-of-the-road approach, with Genshi templates still supported for a
while in a "low profile" maintenance mode (i.e. if something's broken,
tell people to migrate away from Genshi), and what's the appropriate
time frame for either.


But compatibility *will* be challenged, that's what happens with live
software projects and I do hope we still count Trac as a live software
project ;-) Genshi vs. Jinja2 is by far not the only compatibility
concern for plugins in future versions. With Trac 1.3.x, I also support
the proposal (made initially by Ryan? or me?) that we drop Python 2.6
compatibility and focus on Python 2.7. If we can merge in support for
Python 3.5, all the better. We'll also pick at some point jQuery 3.0.
And switch from XHTML to HTML5 (also more or less part of the jinja2
branch, btw). And yes, our data model still sucks and is eventually
going to change radically one day. I can already here the "you're going
to break *all* plugins with such a change!" criticisms. Well, yes, but
we can keep that one for a future discussion ;-)

-- Christian

(1) - http://groups.google.com/group/trac-dev/msg/fc8d8c0447140110

(2) current output of python contrib/jinjastats.py:

58.54% converted to Jinja2 (5067 Jinja2 lines corresponding to 3861
Genshi lines on a total of 6596 Genshi lines)

Yes, it looks like the way I write Jinja2 templates results in templates
being 30% more verbose than their Genshi counterparts, but I think we
also gain in clarity (and also I stick now to < 80 chars per line most
of the time).

Eduard-Cristian Stefan

unread,
Feb 27, 2016, 3:13:22 PM2/27/16
to Trac Development
Hi,

I would migrate my plugins (if any) for as little as a 2x speed improvement :D

And it would be nice to avoid a py2-py3-like transition, and move to jinja as soon as possible.

Just my two cents.

Have a nice week-end,
  Eduard

Eduard-Cristian Stefan

unread,
Feb 27, 2016, 4:05:16 PM2/27/16
to Trac Development
Hi cboos,

Could you do me a favor?

Starting from the links in this thread, please try to find a public git repo
that I would be able to fork and contribute.

which requires some credentials.

Happy migration,
  Eduard

Ed - 0x1b, Inc.

unread,
Feb 27, 2016, 8:04:07 PM2/27/16
to trac...@googlegroups.com
+1 quick clean cut for 1.4 - just from the perspective of change
management, clarity is good.
If needed could 1.3 go into something of a LTS stability extended
availability state?
Version 1.4 is looking to have a "its all new" theme - if your going
to be taking Trac on a shakedown cruise, might as well swap out the
templating engine too -smoke test!

I, for one, welcome our new Jinja2 overlords....
Thx - Ed
> --
> You received this message because you are subscribed to the Google Groups
> "Trac Development" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to trac-dev+u...@googlegroups.com.
> To post to this group, send email to trac...@googlegroups.com.
> Visit this group at https://groups.google.com/group/trac-dev.
> For more options, visit https://groups.google.com/d/optout.

Christian Boos

unread,
Feb 28, 2016, 10:02:23 AM2/28/16
to trac...@googlegroups.com
Hello,
Strange, it should be possible to clone it without having to give any
credentials. But you're right, currently it's like that, we will have to
fix it.

Anyway, you may find it easier to fork from the equivalent branch on
github:

https://github.com/cboos/trac/tree/jinja2

I push primarily on t.e.o, so the github branch will be from time to
time a bit lagging behind.

-- Christian

Jun Omae

unread,
Feb 28, 2016, 10:06:48 AM2/28/16
to trac...@googlegroups.com
On Mon, Feb 29, 2016 at 12:02 AM, Christian Boos <christi...@free.fr> wrote:
> On 2/27/2016 10:05 PM, Eduard-Cristian Stefan wrote:
>> Starting from the links in this thread, please try to find a public git repo
>> that I would be able to fork and contribute.
>>
>> So far I have found https://svn.edgewall.org/git/trac/devs/cboos,
>> which requires some credentials.
>
> Strange, it should be possible to clone it without having to give any
> credentials. But you're right, currently it's like that, we will have to
> fix it.

No credentials are required by
http://svn.edgewall.org/git/trac/devs/cboos rather than https.

--
Jun Omae <jun...@gmail.com> (大前 潤)

Christian Boos

unread,
Feb 28, 2016, 10:20:02 AM2/28/16
to trac...@googlegroups.com
Oh, I thought we had an "everything's HTTPS" policy now.

What's the plan for git access? Looking back at previous discussions, I
see that we didn't even finalize the decision for svn yet.

-- Christian

Thomas Moschny

unread,
Feb 28, 2016, 12:31:01 PM2/28/16
to trac...@googlegroups.com
Hello,

2016-02-27 15:25 GMT+01:00 Christian Boos <christi...@free.fr>:
> Also, we would have to explain what still works and what no
> longer works, as 100% backward compatibility is not possible
> (ITemplateStreamFilter will no longer be supported).

maybe I missed that part if it was already explained: Will there be
some sort of replacement for the ITemplateStreamFilter mechanism, i.e.
will plugins have a way of modifiying existing pages?

Regards,

--
Thomas Moschny <thomas....@gmail.com>

Christian Boos

unread,
Feb 28, 2016, 1:21:54 PM2/28/16
to trac...@googlegroups.com
Hello,

On 2/28/2016 6:30 PM, Thomas Moschny wrote:
> Hello,
>
> 2016-02-27 15:25 GMT+01:00 Christian Boos <christi...@free.fr>:
>> Also, we would have to explain what still works and what no
>> longer works, as 100% backward compatibility is not possible
>> (ITemplateStreamFilter will no longer be supported).
>
> maybe I missed that part if it was already explained: Will there be
> some sort of replacement for the ITemplateStreamFilter mechanism, i.e.
> will plugins have a way of modifiying existing pages?
>

You're right, I wasn't that clear yet about the alternative. I think
that the best way to modify existing pages would be to delegate this to
the client, using JavaScript. The advantage of this approach is that
it's fully backward-compatible, i.e. it would work for Trac < 1.3 as well.

See
https://trac.edgewall.org/wiki/TracDev/PortingFromGenshiToJinja#ReplacingITemplateStreamFilter
for details.

Yes, this will make Trac increasingly dependent on having JavaScript
enabled, but it is a trend I want to encourage anyway, as it facilitates
the development of new features. In the past, for every bit of
functionality added by JavaScript, we added a fallback method that would
also make it work *without* JavaScript. But in recent years, we're
getting away from that approach, for example the batch ticket
modification feature is not available without JavaScript.

I'm also willing to evaluate the "performance killer" part of my
argument against supporting ITemplateStreamFilter, maybe it's not so
terrible after all, and maybe I can come up with a way to support
ITemplateStreamFilter even for the pages generated by Jinja2. But at
best that's going to be an interim solution for the "grace" period
during which we would support both engines, so the earlier you consider
migrating, the better. Probably there are issues I don't see yet that
will require us to add more extension mechanisms.

-- Christian

RjOllos

unread,
Feb 29, 2016, 9:08:19 PM2/29/16
to Trac Development, tr...@0x1b.com


On Saturday, February 27, 2016 at 5:04:07 PM UTC-8, Ed - 0x1b, Inc. wrote:
+1 quick clean cut for 1.4 - just from the perspective of change
management, clarity is good.
If needed could 1.3 go into something of a LTS stability extended
availability state?

 Previously it was suggested making 1.2 our next LTS release (1).

Also, Christian raised the point about dropping Python 2.6 support and going with Python 2.7+ in 1.3 development. That was discussed in (2).

RjOllos

unread,
Feb 29, 2016, 9:12:22 PM2/29/16
to Trac Development
I think we should aim for HTTPS-only. I didn't feel like I should moved forward on Lynx #37 without additional input. But if we all agree then I'm happy to make the final configuration changes to the web server.

- Ryan 

RjOllos

unread,
Feb 29, 2016, 9:13:53 PM2/29/16
to Trac Development


On Saturday, February 27, 2016 at 6:25:10 AM UTC-8, cboos wrote:
Hello,

On 2/27/2016 1:01 AM, RjOllos wrote:
>
> On Friday, February 26, 2016 at 2:18:15 PM UTC-8, Dirk Stöcker wrote:
>
>     On Tue, 23 Feb 2016, Christian Boos wrote:
>
>     > I've given some thoughts about maintaining a Genshi-compatibility
>     layer,
>     > but finally decided against it:
>
>     Do I understand that correctly? You want to replace the template engine
>     with an incompatible new one and instead of operating these two in
>     parallel for at least one majore release, you want to drop the old one
>     immediatelly?
>
>     > That will give a clear signal to the plugin developers, as well as
>     > giving them enough time to adapt before 1.4.
>
>     Yes - it gives a clear signal: That you don't care about other
>     peoples work.
>
>
> As usual your tone is quite unpleasant. People are more likely to care
> about your opinion if you learn to phrase your points better.

Ah, glad to see it's not just me reading it that way ;-) Yes, please
everyone, it would be great to keep a conversation tone where everyone
feels welcome to share her opinion.

Well put, and with that in mind I later realized that I could have said in a nicer way what I felt needed to be said, which I'll aim to do in the future.

- Ryan
Reply all
Reply to author
Forward
0 new messages