| 1 | = `jinjachecker` |
| 2 | |
| 3 | Jinja2 is very helpful when it detects any kind of error, as you always end up with a meaningful backtrace. Nevertheless, it can be tedious to get the nesting of control structures right. |
| 4 | |
| 5 | To help with that problem, we wrote the [source:cboos.git/contrib/jinjachecker.py contrib/jinjachecker.py] tool. |
| 6 | |
| 7 | {{{ |
| 8 | python contrib/jinjachecker.py trac/wiki/templates/jwiki_view.html |
| 9 | }}} |
| 10 | |
| 11 | It first analyzes the Jinja2 control structures, and tries to provide some helpful diagnostics in case of nesting or stylistic errors. |
| 12 | It also adds curly braces to the statements, so if you have an editor which can do matching of brace pairs, you can quickly spot the origin o a nesting problem. |
| 13 | |
| 14 | Finally, while the indentation of the statements is free in Jinja2 templates, being consistent with it also helps to ensure a proper nesting. |
| 15 | {{{ |
| 16 | # -- Jinja2 check for 'trac/wiki/templates/jwiki_view.html' |
| 17 | 12 EXTENDS "jlayout.html" |
| 18 | 18 {BLOCK title |
| 19 | 19 {IF title: |
| 20 | 21 }IF |
| 21 | 22 }BLOCK title |
| 22 | 25 {BLOCK head |
| 23 | 26 SET modify_perm = 'WIKI_MODIFY' in perm(page.resource) |
| 24 | 27 SET is_not_latest = page.exists and page.version != latest_version |
| 25 | 31 {IF version or page.author == 'trac': |
| 26 | 33 }IF |
| 27 | 34 {IF modify_perm: |
| 28 | 40 }IF |
| 29 | 52 }BLOCK head |
| 30 | 56 {BLOCK content |
| 31 | 57 SET modify_perm = 'WIKI_MODIFY' in perm(page.resource) |
| 32 | 58 SET create_perm = 'WIKI_CREATE' in perm(page.resource) |
| 33 | 59 SET admin_perm = 'WIKI_ADMIN' in perm(page.resource) |
| 34 | 60 SET is_not_latest = page.exists and page.version != latest_version |
| 35 | 63 {IF version: |
| 36 | 67 {WITH |
| 37 | 68 SET version = page.version |
| 38 | 69 SET author = authorinfo(page.author) |
| 39 | 70 SET date = pretty_dateinfo(page.time) |
| 40 | 71 SET hef = href.wiki(page.name, action='diff', version=page.version) |
| 41 | 72 {TRANS version, author, date, href |
| 42 | 77 }TRANS |
| 43 | 78 }WITH |
| 44 | 84 }IF |
| 45 | 87 {IF page.exists: |
| 46 | 91 SET last_modification = (page.comment and |
| 47 | 97 {IF not version: |
| 48 | 100 {WITH |
| 49 | 101 SET href = href.wiki(page.name, action='diff', |
| 50 | 103 SET date = pretty_dateinfo(page.time) |
| 51 | 104 {TRANS href, last_modification, date |
| 52 | 109 }TRANS |
| 53 | 110 }WITH |
| 54 | 116 }IF |
| 55 | 117 ELSE: |
| 56 | 119 {TRANS name = name_of(page.resource) |
| 57 | 124 }TRANS |
| 58 | 126 }IF |
| 59 | 129 {WITH |
| 60 | 130 SET alist = attachments |
| 61 | 131 SET compact = True |
| 62 | 132 SET foldable = True |
| 63 | 133 INCLUDE "jlist_of_attachments.html" |
| 64 | 134 }WITH |
| 65 | 136 {WITH |
| 66 | 137 SET delete_perm = 'WIKI_DELETE' in perm(page.resource) |
| 67 | 138 SET rename_perm = 'WIKI_RENAME' in perm(page.resource) |
| 68 | 139 {IF modify_perm or create_perm or delete_perm: |
| 69 | 141 {IF modify_perm or create_perm: |
| 70 | 145 {IF is_not_latest and modify_perm: |
| 71 | 148 ELIF page.exists and modify_perm: |
| 72 | 151 ELIF not page.exists and create_perm: |
| 73 | 154 {IF templates: |
| 74 | 161 {FOR t in sorted(templates): |
| 75 | 165 }FOR |
| 76 | 168 }IF |
| 77 | 169 }IF |
| 78 | 173 {IF page.exists: |
| 79 | 174 {WITH alist = attachments |
| 80 | 175 INCLUDE "jattach_file_form.html" |
| 81 | 176 }WITH |
| 82 | 177 }IF |
| 83 | 178 }IF |
| 84 | 180 {IF page.exists and rename_perm: |
| 85 | 187 }IF |
| 86 | 188 {IF page.exists and delete_perm: |
| 87 | 193 {IF page.version == latest_version: |
| 88 | 195 }IF |
| 89 | 199 }IF |
| 90 | 201 }IF |
| 91 | 202 }WITH |
| 92 | 204 {IF not page.exists and higher: |
| 93 | 208 {FOR markup in higher: |
| 94 | 210 }FOR |
| 95 | 213 }IF |
| 96 | 215 {IF not page.exists and related: |
| 97 | 219 {FOR markup in related: |
| 98 | 221 }FOR |
| 99 | 224 }IF |
| 100 | 230 }BLOCK content |
| 101 | # -- Jinja2 OK |
| 102 | }}} |
| 103 | |
| 104 | As a second step, jinjachecker removes the Jinja2 markup and performs a validation of the document, using lxml. |
| 105 | {{{ |
| 106 | # -- HTML check for 'trac/wiki/templates/jwiki_view.html' |
| 107 | 1 |
| 108 | ... |
| 109 | 13 |
| 110 | 14 <!DOCTYPE html> |
| 111 | 15 <html> |
| 112 | 16 <head> |
| 113 | 17 <title> |
| 114 | 18 |
| 115 | 19 |
| 116 | 20 ${title} ${ super() } |
| 117 | 21 |
| 118 | 22 |
| 119 | 23 </title> |
| 120 | 24 |
| 121 | 25 |
| 122 | 26 |
| 123 | 27 |
| 124 | 28 |
| 125 | 29 ${ super() } |
| 126 | 30 |
| 127 | ... |
| 128 | 52 |
| 129 | 53 </head> |
| 130 | 54 |
| 131 | 55 <body> |
| 132 | 56 |
| 133 | 57 |
| 134 | 58 |
| 135 | 59 |
| 136 | 60 |
| 137 | 61 <div id="content" class="${classes('wiki', create=not page.exists)}"> |
| 138 | 62 |
| 139 | ... |
| 140 | 213 |
| 141 | 214 |
| 142 | 215 </div> |
| 143 | 216 |
| 144 | 217 ${ super() } |
| 145 | 218 |
| 146 | 219 |
| 147 | 220 </body> |
| 148 | 221 </html> |
| 149 | # -- HTML OK |
| 150 | }}} |