root/livinglogic.python.xist/docs/UL4.rst @ 3441:4c509ec872cb

Revision 3441:4c509ec872cb, 16.3 KB (checked in by Walter Doerwald <walter@…>, 11 years ago)

Add support for list and dict constants.

Line 
1:mod:`ll.ul4c` provides templating for XML/HTML as well as any other text-based
2format. A template defines placeholders for data output and basic logic (like
3loops and conditional blocks), that define how the final rendered output will
4look.
5
6:mod:`ll.ul4c` compiles a template to a bytecode format, which makes it possible
7to implement renderers for these templates in multiple programming languages.
8
9
10Embedding
11=========
12
13In the template source any text surrounded by ``<?`` and ``?>`` is a "template
14tag". The first word inside the tag is the tag type. It defines what the tag
15does. For example ``<?print foo?>`` is a print tag (it prints the value of the
16variable ``foo``). A complete example template looks like this::
17
18    <?if data?>
19    <ul>
20    <?for item in data?>
21    <li><?print xmlescape(item)?></li>
22    <?end for?>
23    </ul>
24    <?end if?>
25
26(For text formats where the delimiters ``<?`` and ``?>`` collide with elements
27that are used often or where using these delimiters is inconvenient it's
28possible to specify a different delimiter pair when compiling the template.)
29
30A complete Python program that compiles a template and renders it might look
31like this::
32
33    from ll import ul4c
34
35    code = u'''<?if data?>
36    <ul>
37    <?for item in data?>
38    <li><?print xmlescape(item)?></li>
39    <?end for?>
40    </ul>
41    <?end if?>'''
42
43    tmpl = ul4c.compile(code)
44
45    print tmpl.renders([u"Python", u"Java", u"PHP"])
46
47The method :meth:`Template.renders` gets passed the data object (which is
48available in the template code under the name ``data``) and returns the rendered
49string.
50
51
52Data objects
53============
54
55The template requires a data object for rendering the final output.
56What :mod:`ll.ul4c` supports in this data object is very similar to what JSON_
57supports.
58
59    .. _JSON: http://www.json.org/
60
61Supported types are:
62
63    *   strings
64    *   integers
65    *   floats
66    *   date objects
67    *   The "null" value (``None``)
68    *   boolean values (``True`` and ``False``)
69    *   lists
70    *   dictionaries
71
72Note that depending on the implementation language of the renderer additional
73types might be supported, e.g. a Python renderer will probably support tuples
74and lists and anything supporting :meth:`__getitem__` (or :meth:`__iter__` when
75the list is used in a loop) for lists, Java might support anything implementing
76the ``List`` interface (or the ``Collection`` interface if the list is used in a
77loop).
78
79The data object itself will be available inside the template code under the name
80``data``.
81
82Constants of these types can be created for all types. Most constants look
83similar to the related Python constant.
84
85
86The "null" constant
87-------------------
88
89The "null" constant can be referred to via ``None``.
90
91
92Boolean constants
93-----------------
94
95The boolean constants can be referred to via ``True`` and ``False``.
96
97
98Integer constants
99-----------------
100
101Integer constants can be written in decimal, hexadecimal, octal and binary:
102``42``, ``0x2a``, ``0o52`` and ``0b101010`` all refer to the integer value 42.
103
104
105Float constants
106---------------
107
108Float constants must contain a decimal point or an exponential specifier,
109e.g. ``42.``, ``4e23``.
110
111
112String constants
113----------------
114
115Strings are delimited with single or double quotes and support all escape
116sequences that Python supports (except ``\N{}``). Strings constants are always
117unicode objects, so ``\uXXXX`` escaping is possible. Examples:
118
119    * ``"abc"`` and ``'abc'``;
120
121    *   ``"'"`` and ``'\''`` are single quotes;
122
123    *   ``'"'`` and ``"\""`` are double quotes;
124
125    *   ``"\n"`` is a line feed and ``"\t"`` is a tab;
126
127    *   ``"\x61"`` and ``"\u0061"`` are lowercase "a"s;
128
129
130Date constants
131--------------
132
133Date constants can be created like this:
134
135    *   ``2008-12-24T``
136
137    *   ``2008-12-24T12:34``
138
139    *   ``2008-12-24T12:34:56``
140
141    *   ``2008-12-24T12:34:56.987654``
142
143
144List constants
145--------------
146
147Lists can be created like this:
148
149    *   ``[]``
150
151    *   ``[1, 2, 3]``
152
153    *   ``[None, 42, "foo", [False, True]]``
154
155
156Dictionary constants
157--------------------
158
159Dictionaries can be created like this:
160
161    *   ``{}``
162
163    *   ``{1: 2, 3: 4}``
164
165    *   ``{"foo": 17, "bar": 23}``
166
167
168
169
170Template code
171=============
172
173The template code tries to mimic Python syntax as far as possible, but is
174limited to what is required for templates and does not allow executing arbitrary
175Python statements.
176
177:mod:`ll.ul4c` supports the following tag types:
178
179
180``print``
181---------
182
183The ``print`` tag outputs the value of a variable or any other expression. If
184the expression doesn't evaluate to a string it will be converted to a string
185first. The format of the string depends on the renderer, but should follow
186Python's ``unicode()`` output as much as possible (except that for ``None`` no
187output may be produced)::
188
189    <h1><?print person.lastname?>, <?print person.firstname?></h1>
190
191
192``for``
193-------
194
195The ``for`` tag can be used to loop over the items in a list, the characters in
196a string or the keys in a dictionary. The end of the loop body must be marked
197with an ``<?end for?>`` tag::
198
199    <ul>
200    <?for person in data.persons?>
201    <li><?print person.lastname?>, <?person.firstname?></li>
202    <?end for?>
203    </ul>
204
205In ``for`` loops tuple unpacking is supported for tuples of length 1 and 2, so
206you can do the following::
207
208    <?for (key, value) in data.items?>
209
210if ``items`` is an iterable containing lists with two elements.
211
212
213``if``
214------
215
216The ``if`` tag can be used to output a part of the template only when a
217condition is true. The end of the ``if`` block must be marked with an
218``<?end if?>`` tag. The truth value of an object is the same as in Python:
219
220    *   ``None`` is false.
221    *   The integer ``0`` and the float value ``0.0`` are false.
222    *   Empty strings, lists and dictionaries are false.
223    *   ``False`` is false.
224    *   Anything else is true.
225
226For example we can output the person list only if there are any persons::
227
228    <?if data.persons?>
229    <ul>
230    <?for person in data.persons?>
231    <li><?print person.lastname?>, <?person.firstname?></li>
232    <?end for?>
233    </ul>
234    <?end if?>
235
236``elif`` and ``else`` are supported too::
237
238    <?if data.persons?>
239    <ul>
240    <?for person in data.persons?>
241    <li><?print person.lastname?>, <?person.firstname?></li>
242    <?end for?>
243    </ul>
244    <?else?>
245    <p>No persons found!</p>
246    <?end if?>
247
248or::
249
250    <?if len(data.persons)==0?>
251    No persons found!
252    <?elif len(data.persons)==1?>
253    One person found!
254    <?else?>
255    <?print len(data.persons)?> persons found!
256    <?end if?>
257
258
259``code``
260--------
261
262The ``code`` tag can be used to define or modify variables. Apart from the
263assigment operator ``=``, the following augmented assignment operators are
264supported:
265
266    *   ``+=`` (adds a value to the variable)
267    *   ``-=`` (subtracts a value from the variable)
268    *   ``*=`` (multiplies the variable by a value)
269    *   ``/=`` (divides the variable by a value)
270    *   ``//=`` (divides the variable by a value, rounding down to the next
271        smallest integer)
272    *   ``&=`` (Does a modulo operation and replaces the variable value with the
273        result)
274
275For example the following template will output ``40``::
276
277    <?code x = 17?>
278    <?code x += 23?>
279    <?print x?>
280
281
282``render``
283----------
284
285The render tag allows one template to call other templates. The following Python
286code demonstrates this::
287
288    from ll import ul4c
289
290    # Template 1
291    source1 = u"""\
292    <?if data?>\
293    <ul>
294    <?for item in data?><?render itemtmpl(item)?><?end for?>\
295    </ul>
296    <?end if?>\
297    """
298
299    tmpl1 = ul4c.compile(source1)
300
301    # Template 2
302    source2 = u"<li><?print xmlescape(data)?></li>\n"
303
304    tmpl2 = ul4c.compile(source2)
305
306    # Data object for the outer template
307    data = [u"Python", u"Java", u"PHP"]
308
309    # Dictionary of subtemplates for the outer template
310    templates = dict(itemtmpl=tmpl2)
311
312    print tmpl1.renders(data, templates)
313
314This will output::
315
316    <ul>
317    <li>Python</li>
318    <li>Java</li>
319    <li>PHP</li>
320    </ul>
321
322I.e. a dictionary of templates can be passed to the :meth:`renders` method as
323a additional argument. The keys in this dictionary are the names of the
324templates, which can be used in the ``<?render?>`` tag.
325``<?render itemtmpl(item)?>`` renders the ``itemtmpl`` template and passed the
326``item`` variable as the data object. All templates available in the outer
327template will be available in the inner template too.
328
329
330Expressions
331-----------
332
333:mod:`ll.ul4c` supports many of the operators supported by Python. Getitem style
334element access is available, i.e. in the expression ``a[b]`` the following type
335combinations are supported:
336
337    *   string, integer: Returns the ``b``\th character from the string ``a``.
338        Note that negative ``b`` values are supported and are relative to the end,
339        so ``a[-1]`` is the last character.
340
341    *   list, integer: Returns the ``b``\th list entry of the list ``a``. Negative
342        ``b`` values are supported too.
343
344    *   dict, string: Return the value from the dictionary ``a`` corresponding to
345        the key ``b``. (Note that some implementations might support keys other
346        than strings too.)
347
348Slices are also supported (for list and string objects). As in Python one or
349both of the indexes may be missing to start at the first or end at the last
350character/item. Negative indexes are relative to the end. Indexes that are out
351of bounds are simply clipped:
352
353    *   ``<?print "Hello, World!"[7:-1]?>`` prints ``World``.
354
355    *   ``<?print "Hello, World!"[:-8]?>`` prints ``Hello``.
356
357The following binary operators are supported: ``+``, ``-``, ``*``, ``/`` (floor
358division), ``//`` (truncating division) and ``&`` (modulo).
359
360The usual boolean operators ``not``, ``and`` and ``or`` are supported. However
361``and`` and ``or`` don't short-circuit (but they always return one of the
362operands). For example, the following code will output the ``data.title``
363object if it's true, else ``data.id`` will be output::
364
365    <?print xmlescape(data.title or data.id)?>
366
367The two comparison operators ``==`` and ``!=`` are supported.
368
369Containment test via the ``in`` operator can be done, in the expression
370``a in b`` the following type combinations are supported:
371
372    *   string, string: Checks whether ``a`` is a substring of ``b``.
373    *   any object, list: Checks whether the object ``a`` is in the list ``b``
374        (comparison is done by value not by identity)
375    *   string, dict: Checks whether the key ``a`` is in the dictionary ``b``.
376        (Note that some implementations might support keys other than strings too.)
377
378The inverted containment test (via ``not in``) is available too.
379
380Attribute access in the template code maps the dictionary style getitem access
381in the data object::
382
383    from ll import ul4c
384    tmpl = ul4c.compile("<?print data.foo?>")
385    print tmpl.renders(dict(foo="bar"))
386
387However getitem style access in the template is still possible::
388
389    from ll import ul4c
390    tmpl = ul4c.compile("<?print data['foo']?>")
391    print tmpl.renders(dict(foo="bar"))
392
393
394Functions
395---------
396
397:mod:`ll.ul4c` supports a number of functions.
398
399
400``now``
401:::::::
402
403``now()`` returns the current date and time as a data object.
404
405
406``isnone``
407::::::::::
408
409``isnone(foo)`` returns ``True`` if ``foo`` is ``None``, else ``False`` is
410returned::
411
412    data is <?if isnone(data)?>None<?else?>something else<?end if?>!
413
414
415``isbool``
416::::::::::
417
418``isbool(foo)`` returns ``True`` if ``foo`` is ``True`` or ``False``, else
419``False`` is returned.
420
421
422``isint``
423:::::::::
424
425``isint(foo)`` returns ``True`` if ``foo`` is an integer object, else ``False``
426is returned.
427
428
429``isfloat``
430:::::::::::
431
432``isfloat(foo)`` returns ``True`` if ``foo`` is a float object, else ``False``
433is returned.
434
435
436``isstr``
437:::::::::
438
439``isstr(foo)`` returns ``True`` if ``foo`` is a string object, else ``False``
440is returned.
441
442
443``isdate``
444::::::::::
445
446``isdate(foo)`` returns ``True`` if ``foo`` is a date object, else ``False``
447is returned.
448
449
450``islist``
451::::::::::
452
453``islist(foo)`` returns ``True`` if ``foo`` is a list object, else ``False``
454is returned.
455
456
457``isdict``
458::::::::::::
459
460``isdict(foo)`` returns ``True`` if ``foo`` is a dictionary object, else
461``False`` is returned.
462
463
464``bool``
465::::::::
466
467``bool(foo)`` converts ``foo`` to an boolean. I.e. ``True`` or ``False`` is
468returned according to the truth value of ``foo``.
469
470
471``int``
472:::::::
473
474``int(foo)`` converts ``foo`` to an integer. ``foo`` can be a string, a float,
475a boolean or an integer.
476
477
478``str``
479:::::::
480
481``str(foo)`` converts ``foo`` to a string. If ``foo`` is ``None`` the result
482will be the empty string. For lists and dictionaries the exact format is
483undefined, but should follow Python's repr format.
484
485
486``repr``
487::::::::
488
489``repr(foo)`` converts ``foo`` to a string representation that is useful for
490debugging proposes. The output is a constant expression that could be used to
491recreate the object (except for list and dict, where ``repr`` follows the format
492of Python's :func:`repr` function).
493
494
495``len``
496:::::::
497
498``len(foo)`` returns the length of a string, or the number of items in a list
499or dictionary.
500
501
502``enumerate``
503:::::::::::::
504
505Enumerates the items of the argument (which must be iterable, i.e. a string,
506a list or dictionary). For example the following code::
507
508    <?for (i, c) in enumerate("foo")?><?print i?>=<?print c?>;<?end for?>
509
510prints::
511
512    0=f;1=o;2=o
513   
514
515``xmlescape``
516:::::::::::::
517
518``xmlescape`` takes a string as an argument. It returns a new string where the
519characters ``&``, ``<``, ``>``, ``'`` and ``"`` are replaced with the
520appropriate XML entity references. For example::
521
522    <?print xmlescape("<'foo' & 'bar'>")?>
523
524prints::
525
526    ``&lt;&#39;foo&#39; &amp; ;&#39;bar&#39&gt;``
527
528If the argument is not a string, it will be converted to a string first.
529
530
531``sorted``
532::::::::::
533
534``sorted`` returns a sorted list with the items from it's argument. For example::
535
536    <?for c in sorted('bar')?><?print c?><?end for?>
537
538prints::
539
540    abr
541
542Supported arguments are iterable objects, i.e. strings, lists and dictionaries.
543
544
545``chr``
546:::::::
547
548``chr(x)`` returns a one-character string with a character with the codepoint
549``x``. ``x`` must be an integer.
550
551
552``ord``
553:::::::
554
555The argument for ``ord`` must be a one-character string. ``ord`` returns the
556codepoint of that character as an integer.
557
558
559``hex``
560:::::::
561
562Return the hexadecimal representation of the integer argument (with a leading
563``0x``). For example ``<?print hex(42)?>`` outputs ``0x2a``.
564
565
566``oct``
567:::::::
568
569Return the octal representation of the integer argument (with a leading ``0o``).
570For example ``<?print oct(42)?>`` outputs ``0o52``.
571
572
573``bin``
574:::::::
575
576Return the binary representation of the integer argument (with a leading ``0b``).
577For example ``<?print bin(42)?>`` outputs ``0b101010``.
578
579
580``range``
581::::::::::
582
583``range`` returns an object that can be iterated and will produce consecutive
584integers up to the specified argument. With two arguments the first is the start
585value and the second is the stop value. With three arguments the third one is
586the step size (which can be negative).
587
588
589Methods
590-------
591
592Objects in :mod:`ll.ul4c` support some methods too (depending on the type of the
593object).
594
595
596``upper``
597:::::::::
598
599The ``upper`` method of strings returns an uppercase version of the string for
600which it's called::
601
602    <?print 'foo'.upper()?>
603
604prints::
605
606    FOO
607
608
609``lower``
610:::::::::
611
612The ``lower`` method of strings returns an lowercase version of the string for
613which it's called.
614
615
616``startswith``
617::::::::::::::
618
619``x.startswith(y)`` returns ``True`` if the string ``x`` starts with the string
620``y`` and ``False`` otherwise.
621
622
623``endswith``
624::::::::::::::
625
626``x.endswith(y)`` returns ``True`` if the string ``x`` ends with the string
627``y`` and ``False`` otherwise.
628
629
630``strip``
631:::::::::
632
633The string method ``strip`` returns a copy of the string with leading and
634trailing whitespace removed. If an argument ``chars`` is given and not ``None``,
635characters in ``chars`` will be removed instead.
636
637
638``lstrip``
639::::::::::
640
641The string method ``lstrip`` returns a copy of the string with leading
642whitespace removed. If an argument ``chars`` is given and not ``None``,
643characters in ``chars`` will be removed instead.
644
645
646``rstrip``
647::::::::::
648
649The string method ``rstrip`` returns a copy of the string with trailing
650whitespace removed. If an argument ``chars`` is given and not ``None``,
651characters in ``chars`` will be removed instead.
652
653
654``split``
655:::::::::
656The string method ``split`` splits the string into separate "words" and returns
657the resulting list. Without any arguments, the string is split on whitespace
658characters. With one argument the argument specifies the soprator to use. The
659second optional argument specifies the maximum number of splits to do.
660
661
662``rsplit``
663::::::::::
664The string method ``rsplit`` works like ``split``, except that splitting start
665from the end (which is only relevant when the maximum number of splits is
666given).
667
668
669``find``
670::::::::
671
672This string method search for a substring of the object for which it's called
673and returns the position of the first appearance of the substring or -1 if
674the string can't be found. For example ``"foobar".find("foo")`` returns 3.
675The optional second and third argument specify the start and end position for
676the search.
Note: See TracBrowser for help on using the browser.