Permalink
Newer
Older
100644 409 lines (341 sloc) 19.4 KB
tavis_rudd
Jun 13, 2001
1
Cheetah TODO list
2
-----------------
3
* If you are working on a task please put your initials at the end of the
4
description
tavis_rudd
Jul 13, 2001
5
* When a task is completed please remember to note it in the CHANGES file
6
* Unresolved bugs are listed in the BUGS file. Resolved bugs are be listed
7
in the CHANGES file if the bug is considered significant enough and it
8
affected a released version of Cheetah.
9
11
Requirements for 1.0
12
=========================================================================
tavis_rudd
Jan 3, 2005
13
FIXED
14
- "cheetah test" problem: Python 2.3(b1) causes 16 failures in
15
SyntaxAndOutput.py because the result of boolean expressions is now True and
16
False instead of 1 and 0 (or 'True' and 'False' instead of '1' and '0' when
17
used as placeholders). The same thing happens with $True and $False. Add a
18
preprocessing step to convert output to '1' and '0' before comparing to the
tavis_rudd
Jan 3, 2005
19
control string.
20
21
- "cheetah test" problem: subcommands fail mysteriously on Windows. Rewrite
22
to avoid using subcommands. Instead, set sys.argv and call the appropriate
23
main() for each test.
24
tavis_rudd
Jan 3, 2005
25
FIXED IN BOTH THE PY AND C VERSIONS
26
- Simplify NameMapper.py while maintaining new behavior (ignore dictionary
27
attributes/methods when searching for match of first chunk in searchList
28
lookup). Modify _namemapper.c to conform. Make valueForKey error
29
messages more meaningful: for $placeholder.html it raises "NotFound: html";
30
it should raise "NotFound: 'html' in $placeholder.html". Consider passing
31
the entire unparsed placeholder tag to all NameMapper functions for use in
32
a potential error message, the same way we're passing it to the output
33
filter. Also consider passing it to the errorCatcher. (TR)
34
35
- One-line #if broken. It's recognized only if 'else' is present, otherwise
36
it miscompiles as an unclosed and incorrect multi-line #if. The presence
37
of 'else' should trigger the one-line #if.
38
39
- Documentation: document #encoding. Explain problems with one-line #if and
40
"cheetah test" if they haven't been fixed yet.
41
42
- There's a kludge in CheetahWrapper.py to abort with a helpful error message
43
if the user runs 'cheetah test' but doesn't have write permission in the
44
current directory. The tests should instead put their temporary files
45
under the system tmp directory.
46
47
- update User's Guide about changes to SkeletonPage (no more #settings,
48
etc) (TR)
50
- Decide on Cheetah's 1.0 license and update the Users' Guide. Cheetah
51
will remain open source, and derived works (open or closed source) will be
52
allowed. The issue is how to make the second part more explicit. (TR)
54
- Add an example in the distribution of a simplified SkeletonPage
55
that used #block but does not have fancy esoteric methods like
56
style stuff. (MO)
58
- Eliminate obsolete #settings directive from
59
examples/webware_examples/cheetahSite/siteTemplate.tmpl (TR)
61
- Recognize the exception value as a local variable inside the
62
'#except Exception, ex' clause. Currently $ex raises NotFound.
64
- Reset the current filter to the default (or to the constructor's filter
65
if specified) at the beginning of each fill. Currently, filter changes
66
leak from one fill to the next.
68
- Webware example template has obsolete #settings directive. Replace
69
with #attr for each variable.
70
71
Other TODO Items
tavis_rudd
Jun 13, 2001
72
================================================================================
74
- CheetahWrapper stuff: (MO)
75
* "cheetah compile --shbang '#!/usr/bin/python2.2'"
76
* "cheetah preview [options] [FILES]" print template-specific portion of main
77
method(s) to stdout, with line numbers based on the .py template module.
78
Make a Template method to do the same thing, a la .generatedModuleCode().
79
* Refactor, make compile/fill/code routines callbacks using a bundle arg.
80
* If an input file ends in a dot, intelligently add the input extension if
81
not found.
83
- ##null: throw this comment away, do not place it in the compiled template
84
module in any manner. Useful for obsolete text, unfinished text, or notes
85
to yourself. Do for single- and multi-line comments.
86
87
- Split out the code needed to run the generated
88
python into a base class of Template, and derive the compiled Python class
89
from that? This would allow precompiled templates to be loaded much more
90
quickly.
91
92
- A further 'nice to have' optimisation would be to be able to specify at
93
compile time that you are not using filters, Webware transactions etc, and
94
not generate code that uses them. This would remove the need to import
95
DummyTransaction and the Filters module. It would also simplify the code
96
and function calls in the compiled template module.
97
98
- Debugging tools. See section below.
100
- Add --error option to compiled templates and "cheetah fill". It would
101
activate the Echo error catcher for debugging. (Maybe --list-errors to
102
suppress output and instead list the not found placeholders? Less
103
important.)
104
105
- Provide a utility to list the names of all placeholders in the template.
106
Requested by Tracy Ruggles on Feb 21, 2003.
107
108
- implement some better error handling for misformed #for, #if, #try directives,
109
etc. At the moment these errors are not caught until Python executes the
tavis_rudd
Jan 3, 2005
110
code. @@TR: not a high priority as the python barfs suffice.
tavis_rudd
Jan 3, 2005
112
FIXED
113
- create better error message for bad code such as:
114
##cache
115
This is a cached region. $voom
116
#end cache
tavis_rudd
Jan 3, 2005
117
119
- create a better error message for invalid syntax when a $var inside a
120
directive is enclosed in ${} or $(). E.g.:
121
#include raw source=${x}
122
123
- Delete whitespace before a comment on the same line. The methods are
124
Parser.eatComment() and Parser.eatMultiLineComment(). It's already
125
working if the line contains 'STUFF#slurp ## comment'. Need to make
126
it work for 'STUFF ## comment' (but retain the EOL newline).
127
128
- 'errorCatcher None' to stop catching errors in the middle of a template.
129
130
- Utils.WebInputMixin: factor out Cheetah-specific code so it can be used in
131
non-Cheetah applications. Don't modify the searchList: have a Template
132
wrapper method do that. Consider turning it into a function that does not
133
require 'self'. Consider making Webware-specific code into plugins so that,
134
e.g., other cookie-handling methods can be grafted in. Maybe use callback
135
classes like the planned rewrite for CheetahWrapper. Low priority. (MO)
136
137
- Look through Zope Page Templates (TAL) for ideas to borrow.
138
http://www.zope.org/Documentation/Books/ZopeBook/current/AppendixC.stx
139
http://www.owlfish.com/software/simpleTAL/index.html
140
141
Debugging Tools (Dump Tools)
142
============================
143
It would be nice to provide debugging tools for users who can't figure
144
out why a certain placeholder value isn't found or is being overridden.
145
My idea is to define $dumpSearchList() and $dumpSearchListFlat() in
146
Template, which would print a stanza in the output showing all searchList
147
variables and their values. $dumpSearchList would group by searchList
148
element; $dumpSearchListFlat would combine all into a single
149
alphabetical listing.
150
I made an experimental version but it printed only instance variables,
151
not methods and not inherited attributes. Also, it wouldn't print right
152
using the usual pattern of write-to-custom-StringIO-object-and-return-
153
the-.getvalue() and I couldn't figure out why.
154
The stanza should be set apart by a row of stars with the words
155
"BEGIN/END SEARCH LIST DUMP". Then for $dumpSearchList, precede each
156
group with "*** searchList[i], type <element type>, 142 variables ***".
157
Because some elements like 'self' may have hundreds of inherited
158
methods that would create a forest-through-trees situation for the user,
159
we may need an option to supress the variable listing for elements with
160
> 20 variables (just print the summary line instead). ?
161
The final version should be in Template so it has implicit
162
access to the searchList and perhaps later to other variables (locals,
163
globals, "#set global"s, builtins) too. This is such a central
164
debugging tool that you should not have to monopolize an #extends
165
(the template's only #extends) to use it. You could import it, however,
166
if you pass in the searchList explicitly as an argument. In that case,
167
perhaps we can base it on a generic module for dumping variables/values.
168
Note that we cannot simply depend on str() and pprint, because
169
we need to show instances as dictionaries. Likewise, dir() and vars()
170
may get us part of the distance, but only if they show methods and
171
inherited attributes too.
172
These functions should print only top-level variables, not
173
the subelements of collections. I.e, if the first searchList element
174
is a dictionary, show its keys/values, but do not expand any
175
subvalues if they are dictionaries too, unless the display tool happens
176
to default to that.
177
178
179
Rewrite the caching framework
180
=============================
181
- add #cache varyBy= (tied to Tavis' proposed caching framework for Webware)
182
183
- #cache test= with a one-variable test produces invalid Python (an empty
184
if-block). Example in Cheetah Developers' Guide, section
185
"#cache with test: expression and method conditions".
186
187
- #cache id= seems to be ignoring the ID and generating a random numeric
188
ID instead. Is it working? Do cache IDs have to be numeric?
189
190
- Other ideas in Tavis' head.
191
192
- Have an option to refresh the cache whenever an external
193
file is updated. This would allow a data structure to be kept in
194
sync whenever its text configuration file is changed.
195
hierro
Jun 23, 2002
196
#entry $func($arg1, $arg2="default", $**kw)
197
===============================================================================
hierro
Jun 23, 2002
198
Make a wrapper function in the .py template module that builds a searchList
199
from its positional arguments, then instantiates and fills a template and
200
returns the result. The preceding example would create a function thus:
201
def func(arg1, arg2="default", searchList=None, **kw):
202
"""Function docstring."""
203
sl = {'arg1': arg1, 'arg2': arg2}
204
if searchList is None:
205
searchList = [sl]
206
elif type(searchList) == types.ListType:
207
searchList.insert(0, sl)
208
else:
209
raise TypeError("arg 'searchList'")
210
t = TheTemplate(searchList=searchList, **kw)
211
return str(t)
hierro
Jun 23, 2002
212
##doc-entry: and #*doc-entry: comments are appended to the function docstring.
213
Finally, make this function accessible directly from the shell.
214
If there are any non-option arguments on the command line, call the function
215
instead of filling the template the normal way.
216
This would perhaps make more sense as arguments to .respond(). But
hierro
Jun 23, 2002
217
.respond() has that pesky 'trans' argument that mustn't be interfered with,
218
and other programs may assume .respond() takes only one argument. Also,
219
when called via str(), str() cannot take arguments.
220
221
#indent
222
========================================================================
223
The current indenter (which exists but is undocumented) is a kludge that has an
224
indentation object, with implicit placeholder calls added at each line to
225
generate the indentation, and #silent calls to adjust the object. It should be
226
reimplemented to generate code to call the indentation object directly. Also,
227
the user interface should be cleaned up, the implementation and Users' Guide
228
synchronized, and test cases built.
229
230
The desired implementation revolves around self._indenter, which knows the
231
current indentation level (a non-negative integer), chars (the string output
232
per level, default four spaces), and stack (the previous indentation levels).
233
The .indent() method returns the indentation string currently appropriate.
234
The desired interface for phase 1 (subject to change):
235
#indent strip ; strip leading whitespace from input lines
236
#indent add ; add indentation to output lines as appropriate
237
#indent on ; do both
238
#indent off ; do neither
239
#indent reset ; set level to 0 and clear stack
240
#indent ++ ; increment level
241
#indent -- ; decrement level
242
#indent pop [EXPR] ; revert to Nth previous level (default 1)
243
; if pop past end of stack, set level to 0 and
244
; clear stack. All +/-/= operations push the old level
245
; onto the stack.
246
#indent debug ; dump level, chars and stack to template output
247
248
Possible extensions:
249
#indent =EXPR ; set level to N (likely to be added to phase 1)
250
#indent +EXPR ; add N to level (not very necessary)
251
#indent -EXPR ; subtract N from level (not very necessary)
252
#indent balance BOOL ; require all indent changes in a #def/#block to be
253
; popped before exiting the method. (difficult to
254
; implement)
255
#indent implicitPop BOOL ; automatically pop indent changes within a
256
; #def/block when that method exits. (difficult to
257
; implement)
258
#indent ?? ; a 3-way switch that combines unbalanced, balanced and
259
; implicit pop. (difficult to implement)
260
#indent ?? ; smart stripping: strip input indentation according to
261
; nested directive level; e.g.,
262
; 01: #if foo=1
263
; 02: public int foo()
264
; 03: {
265
; 04: return FOO;
266
; 05: }
267
; 06: #end if
268
; With smart stripping, line 4 would be indented and the
269
; others not. With "on" or "strip" stripping, all lines
270
; 2-5 would be unindented. With "off" stripping,
271
; lines 2-5 would not be stripped.
272
273
There should be one indentation object per Template instance, shared by
274
methods and include files.
275
276
277
Upload File
278
========================================================================
tavis_rudd
Jan 3, 2005
279
@@TR: This is way outside Cheetah's scope!
280
281
A mixin method in Cheetah.Utils (for Template) that handles file uploads --
282
these are too complicated for .webInput(). The method should do a "safe"
283
file upload; e.g., http://us3.php.net/manual/en/features.file-upload.php ,
284
within the limitations of Python's cgi module. The user has the choice of
285
three destinations for the file contents: (A) copied to a local
286
path you specify, (B) placed in a namespace variable like .cgiImport()
287
does, or (C) returned. (B) parallels .webInput, but (A) will certainly be
288
desirable situations where we just want to save the file, not read it into
289
memory. Reject files larger than a user-specified size or not in a list of
290
user-approved MIME types. Define appropriate exceptions for typical
291
file-upload errors. Method name .webUploadFileAsString?
292
One situation to support is when form has a text(area) field
293
related to a file-upload control on the same form, and the user has the choice
294
of typing into the field or uploading a text file. We need a method that
295
updates the text field's value if there is an uploaded file, but not if there
296
isn't. This may be handled by the regular method(s) or may require a separate
297
method.
298
299
RPM Building
300
============
301
From: John Landahl <john@landahl.org>
302
To: cheetahtemplate-discuss@lists.sourceforge.net
303
Subject: [Cheetahtemplate-discuss] Building Cheetah RPMs
304
Date: Wed, 05 Nov 2003 01:27:24 -0800
305
306
If anyone is interested in building Cheetah RPMs, simply add the following
307
lines to a file called MANIFEST.in in the Cheetah directory and you'll be
308
able to use the "bdist_rpm" option to setup.py (i.e. "python setup.py
309
bdist_rpm"):
310
311
include SetupTools.py
312
include SetupConfig.py
313
include bin/*
314
315
Also, I've found that using /usr/lib/site-python for add-on Python
316
packages is much more convenient than the default of
317
/usr/lib/pythonX/site-packages, especially when jumping back and forth
318
between 2.2 and 2.3. If you'd like Cheetah in /usr/lib/site-python,
319
createa a setup.cfg with the following contents:
320
321
[install]
322
install-lib = /usr/lib/site-python
323
324
Of course if you do have version specific libraries they should stay in
325
/usr/lib/pythonX/site-packages, but Cheetah seems happy in both 2.2 and
326
2.3 and so is a good candidate for /usr/lib/site-python.
327
328
329
User-defined directives
330
=======================================================================
331
IF we decide to support user-defined directives someday, consider Spyce's
332
interface. Spyce uses a base class which provides generic services to
333
custom "active tags".
334
http://spyce.sourceforge.net/doc-tag.html
335
http://spyce.sourceforge.net/doc-tag_new.html
336
337
tavis_rudd
Jun 13, 2001
338
Test Suite
339
================================================================================
tavis_rudd
Jan 3, 2005
340
- test cases for the SkeletonPage framework @@TR: I have no interest in this as
341
I plan on removing SkeletonPage.
tavis_rudd
Nov 5, 2001
342
- add cases that test the cheetah-compile script
343
- add cases that test the integration with WebKit. Since these must be called
344
from a running WebKit server, make a servlet that runs the tests and outputs
345
diagnostics to the browser.
tavis_rudd
Jun 13, 2001
346
347
Website
348
================================================================================
349
- automate the documentation update
tavis_rudd
Jun 13, 2001
350
- See if we can get WebKit working on Sourceforge...
351
352
Examples
353
================================================================================
354
- create some non-html code generation examples
tavis_rudd
Nov 5, 2001
355
- SQL
356
- LaTeX
357
- form email
358
- Template definitions in a database. .py template modules in a
359
database? Caching template classes and/or instances extracted from
360
a database.
361
- Pickled templates?
362
363
364
CheetahX: pie-in-the-sky
365
========================================================================
366
These ideas are being considered for Cheetah 2.0.
367
368
- There are five distinct objects in Cheetah which should have a clearer
369
separation.
370
371
1. TEMPLATE DEFINITION: a string.
372
2. TEMPLATE METHOD: the method that implements the desired template
373
(which may be the Main Method or a #def/#block method). This is
374
inside the generated class, which is inside the generated module.
375
3. DATA: the searchList, local variables, current filter, etc. Everything
376
that changes at runtime.
377
4. INFRASTRUCTURE: the internal code used by Cheetah to fill and maintain the
378
template.
379
5. SERVICES: convenience methods from the infrastructure exposed to user.
380
381
Cheetah combines 2-5 into a single Template subclass. CheetahX proposes to
382
keep these distinct, with defined containment and interfaces between them.
383
384
- The TEMPLATE METHOD might instantiate an INFRASTRUCTURE object for each
385
fill. The constructor arguments would be everything necessary to access
386
the DATA. Perhaps the TEMPLATE METHOD can pass its own code block, making
387
its own locals/globals accessible directly. This would be a bit
388
unorthodox, but less so than the current practice of switching the
389
template instance's class on the fly.
390
391
- For SERVICES, add a custom object to the searchList that knows how to
392
access the protected INFRASTRUCTURE data.
393
394
- Push more work into INFRASTRUCTURE, to insulate the TEMPLATE METHOD from
395
implementation changes. For instance, replace every placeholder lookup
396
with a simple INFRASTRUCTURE method call, and let the infrastructure
397
do all the processing. (It can use the code block mentioned above to
398
access the searchList and current filter.) For local variable
399
lookups, you can call another method and pass the value directly.
400
For caching, I guess you pass in the cache time (or a special constant)
401
as a separate argument, and let the INFRASTRUCTURE maintain the cache.
402
403
- Tavis wants to rewrite the cache infrastructure and fully implement it.
404
405
- The Template class needs to be split up into stuff nececssary to fill
406
a template (the INFRASTRUCTURE), and stuff necessary to comple a template
407
(which is not necessary for using precompiled templates, and slows down
408
Cheetah's import time).