Changes between Version 43 and Version 44 of TracDev/PortingFromGenshiToJinja
- Timestamp:
- Jan 30, 2017, 12:07:58 PM (7 years ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
TracDev/PortingFromGenshiToJinja
v43 v44 8 8 }}} 9 9 10 [[PageOutline(2- 4)]]10 [[PageOutline(2-5)]] 11 11 = Porting Templates from Genshi to Jinja2 12 12 … … 506 506 The `html` extractor (i.e. the `trac.dist.extract_html` function) will be applied to all HTML files `**/templates/**.html`, while the `text` extractor (the `trac.dist.extract_text` function). wil be applied on the "text" files `**/templates/**.txt`. 507 507 508 The HTML extractor "auto-detects" in a simple but effective way the presence of Genshi i18n directives, and will use the legacy Genshi extractor in that case. It is therefore safe to use this new way even before the integrality of the templates has been migrated to Jinja2.509 510 Note that as we have a dedicated mapping file anyway, we specify the extractors directly there, so we no longer need sto do that in the setup.py file:508 The HTML extractor "auto-detects" in a simple but effective way the presence of Genshi i18n directives, and will use the legacy Genshi extractor in that case. It is therefore safe to use this new way during the migration process, when there's a mix of Jinja2 and Genshi templates. 509 510 Note that as we have a dedicated mapping file anyway, we specify the extractors directly there, so we no longer need to do that in the setup.py file: 511 511 {{{#!diff 512 512 Index: setup.py … … 630 630 Most of the time, the porting is a straightforward operation. 631 631 632 ==== expand a variable 632 ==== expand a variable (`${var}`) 633 633 - Genshi [[html+genshi(<b>$the_variable</b>)]] 634 634 - Jinja2 [[html+jinja(<b>${the_variable}</b>)]] … … 641 641 }}} 642 642 643 ==== expand a simple computation 643 ==== expand a simple computation (`${Jinja2-expr}`) 644 644 - Genshi [[html+genshi(<b>${the_variable + 1}</b>)]] 645 645 - Jinja2 [[html+jinja(<b>${the_variable + 1}</b>)]] … … 651 651 Another customization we made to Jinja2 is to avoid having a Python `None` value be expanded to the `"None"` string. Instead, we make it produce an empty string, like Genshi did. 652 652 653 ==== include another template 653 ==== include another template (`include`) #include 654 654 - Genshi [[xml(<xi:include href="the_file.html"><xi:fallback/></xi:include>)]] 655 655 - Jinja2 [[xml(# include "the_file.html" ignore missing)]] … … 693 693 694 694 695 ==== simple if...then (no else)#if695 ==== simple conditional (`if` ... `endif`) #if 696 696 - Genshi [[xml(<py:if test="flag"><b>OK</b></py:if>)]] or simply: [[xml(<b py:if="flag">OK</b>)]] 697 697 - Jinja2 … … 704 704 See [http://jinja.pocoo.org/docs/dev/templates/#if if] doc. 705 705 706 ==== if...then...else706 ==== conditional with multiple branches (`if` ... `elif` ... `else` ... `endif`) 707 707 - Genshi 708 708 {{{#!html+genshi … … 716 716 </py:choose> 717 717 }}} 718 or simply:718 or: 719 719 {{{#!html+genshi 720 720 <py:choose> 721 721 <b py:when="flag">OK</b> 722 <b py:when="other_flag">Maybe...</b> 722 723 <i py:otherwise="">!!!</i> 723 724 </py:choose> … … 732 733 # endif 733 734 }}} 735 or: 736 {{{#!html+jinja 737 # if flag: 738 <b>OK</b> 739 # elif other_flag: 740 <b>Maybe...</b> 741 # else: 742 <i>!!!</i> 743 # endif 744 }}} 734 745 735 746 If you really have to, you can also use the block style: … … 739 750 However this goes against readability and processing via the [./Checker jinjachecker] tool, so we really advise that you stick to the use of //[http://jinja.pocoo.org/docs/dev/templates/#line-statements line statements]//. 740 751 741 ==== iterate over a collection 752 ==== iterate over a collection (`for` ... `endfor`) #for 742 753 - Genshi 743 754 {{{#!html+genshi … … 764 775 See [http://jinja.pocoo.org/docs/dev/templates/#for for] doc. 765 776 766 ===== No need for `enumerate`777 ===== no need for `enumerate` 767 778 768 779 - Genshi: … … 787 798 See [http://jinja.pocoo.org/docs/dev/templates/#for loop] doc. 788 799 789 ==== define a macro 800 ==== define a macro (`macro` ... `endmacro`) #macro 790 801 - Genshi 791 802 {{{#!html+genshi … … 802 813 See [http://jinja.pocoo.org/docs/dev/templates/#macros macros] doc. 803 814 804 ==== set a variable 815 ==== set a variable (`set`) 805 816 - Genshi 806 817 {{{#!html+genshi … … 818 829 See [http://jinja.pocoo.org/docs/dev/templates/#tests tests] doc. 819 830 820 ==== set several variables in a scope #with831 ==== set several variables in a scope (`with` ... `endwith`) #with 821 832 822 833 - Genshi … … 848 859 849 860 850 ==== set HTML attributes 861 ==== set HTML attributes (`|htmlattr`) #htmlattr 851 862 In Genshi, an attribute with a `None` value wouldn't be output. However, Jinja2 doesn't know what an attribute is (or anything else about HTML, XML for that matter), so we have to use a special filter, `htmlattr`, to reproduce this behavior: 852 863 … … 868 879 869 880 870 ==== set complex variables 881 ==== set complex variables (`set`) #set 871 882 Note that Jinja2 expressions are a subset of Python expressions, and for the sake of simplicity the generator expressions are not part of that subset. This limitation often requires one to make creative use of [http://jinja.pocoo.org/docs/dev/templates/#filters filters], [http://jinja.pocoo.org/docs/dev/templates/#builtin-filters built-in] or custom (`min`, `max`, `trim`, `flatten`). 872 883 … … 897 908 # endif 898 909 }}} 899 If the repeated content is complex, one can use a //block assignment// ( see below).900 901 ==== i18n 910 If the repeated content is complex, one can use a //block assignment// ([#set_endset see below]). 911 912 ==== i18n (`trans` ... `endtrans`) #trans 902 913 903 914 Genshi had a pretty good notion of what was a piece of translatable text within an HTML template, … … 949 960 950 961 Note that only direct variable expansions are supported in `trans` blocks, nothing more complex. 951 So one way to deal with complex translatable content is to factor out the complex parts in variable blocks. See [http://jinja.pocoo.org/docs/dev/templates/#block-assignments block assignments] doc. 962 963 So one way to deal with complex translatable content is to factor out the complex parts in variable blocks. 964 965 ===== assigning blocks of text to variables (`set` ... `endset`) #set_endset 966 967 This feature is particularly useful in combination with `trans`, when dealing with complex expansions in translatable content. 968 See [http://jinja.pocoo.org/docs/dev/templates/#block-assignments block assignments] doc. 952 969 - Genshi: 953 970 {{{#!html+genshi … … 982 999 }}} 983 1000 984 Note that another tricky case is when you want to use `gettext` and one of the variables is Markup. Using the `|safe` filter is needed, but that's not enough, as currently `gettext()` doesn't support Markup, you need to use `tgettext()` which is available with the `tag_` shortcut: 1001 ===== translation of Markup content `tag_()` 1002 Note that another tricky case is when you want to use `gettext` and one of the variables is Markup. The `_()` and `gettext()` functions don't support Markup, you need to use `tgettext()` which is also available with the `tag_()` shortcut: 985 1003 {{{#!html+jinja 986 1004 <em> … … 990 1008 # endset 991 1009 ${tag_("Set your email in %(preferences_link)s", 992 preferences_link=preferences_link |safe)}1010 preferences_link=preferences_link)} 993 1011 </em> 994 1012 }}} … … 999 1017 - when you need to output a plain "#" character at the beginning of a line, this will be parsed as a line statement; the trick here is to use an empty inline comment as a prefix: `{##}# ...` (see [61e8d9ec/cboos.git]) 1000 1018 - when you need to output indented text, this can be made difficult due to our `lstrip_block` configuration setting; you can work around this by embedding Python strings with the exact whitespace content you need in variable expressions: ` ${"\t "}` (see [0fdef480/cboos.git]) 1001 1002