root/livinglogic.python.xist/docs/UL4.rst @ 3701:53324f8b687d

Revision 3701:53324f8b687d, 19.7 KB (checked in by Walter Doerwald <walter@…>, 10 years ago)

Document the new render() method.

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