root/livinglogic.python.xist/docs/UL4.rst @ 5351:c8084839327f

Revision 5351:c8084839327f, 33.3 KB (checked in by Walter Doerwald <walter@…>, 7 years ago)

<?return?> tags in UL4 templates simply end the template rendering.

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 an internal format, which makes it
7possible to implement renderers for these templates in multiple programming
8languages.
9
10Apart from this Python implementaion there are implementations for Java_ (both a
11compiler and renderer), Javascript_ (renderer only) and PHP_ (renderer only).
12
13.. _Java: http://hg.livinglogic.de/LivingLogic.Java.ul4/
14.. _Javascript: http://hg.livinglogic.de/LivingLogic.Javascript.ul4/
15.. _PHP: http://hg.livinglogic.de/LivingLogic.PHP.ul4/
16
17
18Embedding
19=========
20
21In the template source any text surrounded by ``<?`` and ``?>`` is a "template
22tag". The first word inside the tag is the tag type. It defines what the tag
23does. For example ``<?print foo?>`` is a print tag (it prints the value of the
24variable ``foo``). A complete example template looks like this::
25
26    <?if data?>
27    <ul>
28    <?for item in data?>
29    <li><?print xmlescape(item)?></li>
30    <?end for?>
31    </ul>
32    <?end if?>
33
34(For text formats where the delimiters ``<?`` and ``?>`` collide with elements
35that are used often or where using these delimiters is inconvenient it's
36possible to specify a different delimiter pair when compiling the template.)
37
38A complete Python program that compiles a template and renders it might look
39like this::
40
41    from ll import ul4c
42
43    code = '''
44        <?if data?>
45            <ul>
46                <?for item in data?>
47                    <li><?print item?></li>
48                <?end for?>
49            </ul>
50        <?end if?>
51    '''
52
53    template = ul4c.Template(code)
54
55    print(template.renders(data=["Python", "Java", "Javascript", "PHP"]))
56
57The variables that should be available to the template code can be passed to the
58method :meth:`Template.renders` as keyword arguments. :meth:`renders` returns
59the final rendered output as a string. Alternatively the method :meth:`render`
60can be used, which is a generator and returns the output piecewise.
61
62
63Supported data types
64====================
65
66The following object types can be passed as variables to be used by the template
67code:
68
69*   strings
70*   integers
71*   floats
72*   date objects
73*   color objects
74*   The "null" value (``None``)
75*   boolean values (``True`` and ``False``)
76*   the ``Undefined`` variable
77*   lists
78*   dictionaries
79*   UL4 templates
80
81This is similar to what JSON_ supports (except for date objects, color objects,
82UL4 templates).
83
84    .. _JSON: http://www.json.org/
85
86Note that depending on the implementation language of the renderer additional
87types might be supported, e.g. a Python renderer will probably support tuples
88and lists and anything supporting :meth:`__getitem__` (or :meth:`__iter__` when
89the list is used in a loop) for lists, Java might support anything implementing
90the ``List`` interface (or the ``Collection`` interface if the list is used in a
91loop).
92
93Objects of these types can either be passed to the template in the call to the
94render function, or the template can create objects of thoses types itself. The
95syntax for creating such a constant is very similar to Python's syntax.
96
97
98The "null" constant
99-------------------
100
101The "null" constant can be referred to via ``None``.
102
103
104Boolean constants
105-----------------
106
107The boolean constants can be referred to via ``True`` and ``False``.
108
109
110Integer constants
111-----------------
112
113Integer constants can be written in decimal, hexadecimal, octal and binary:
114``42``, ``0x2a``, ``0o52`` and ``0b101010`` all refer to the integer value 42.
115
116
117Float constants
118---------------
119
120Float constants must contain a decimal point or an exponential specifier,
121e.g. ``42.``, ``4e23``.
122
123
124String constants
125----------------
126
127Strings are delimited with single or double quotes and support all escape
128sequences that Python supports (except ``\N{}``). Strings constants are always
129unicode objects, so ``\uXXXX`` escaping is possible. Examples:
130
131* ``"abc"`` and ``'abc'``;
132
133*   ``"'"`` and ``'\''`` are single quotes;
134
135*   ``'"'`` and ``"\""`` are double quotes;
136
137*   ``"\n"`` is a line feed and ``"\t"`` is a tab;
138
139*   ``"\x61"`` and ``"\u0061"`` are lowercase "a"s;
140
141
142Date constants
143--------------
144
145Date objects have a date and time including microseconds. Date constants can be
146created like this:
147
148*   ``@(2008-12-24)``
149
150*   ``@(2008-12-24T12:34)``
151
152*   ``@(2008-12-24T12:34:56)``
153
154*   ``@(2008-12-24T12:34:56.987654)``
155
156
157Color constants
158---------------
159
160Color values are 8 bit red, green, blue and alpha values. Color constants can
161be created like this:
162
163*   ``#fff``
164
165*   ``#fff8``
166
167*   ``#0063a8``
168
169*   ``#0063a880``
170
171The variants with 3 or 6 hex digits will create a color object with an alpha
172value of 255.
173
174
175Lists
176-----
177
178Lists can be created like this:
179
180*   ``[]``
181
182*   ``[1, 2, 3]``
183
184*   ``[None, 42, "foo", [False, True]]``
185
186It is also possible to create a list with a list comprehension::
187
188    ["(" + c.upper() + ")" for c in "hurz" if c < "u"]
189
190This will create the list::
191
192    ["(H)", "(R)"]
193
194The ``if`` condition is optional, i.e.::
195
196    ["(" + c.upper() + ")" for c in "hurz"]
197
198will create the list::
199
200    ["(H)", "(U)", "(R)", "(Z)"]
201
202
203Dictionaries
204------------
205
206Dictionaries can be created like this:
207
208*   ``{}``
209
210*   ``{1: 2, 3: 4}``
211
212*   ``{"foo": 17, "bar": 23}``
213
214It is also possible to create a dictionary with a dictionary comprehension::
215
216    { c.upper() : "(" + c + ")" for c in "hurz" if c < "u"}
217
218This will create the dictionary::
219
220    { "H": "(h)", "R": "(r)"}
221
222The ``if`` condition is optional, i.e.::
223
224    { c.upper() : "(" + c + ")" for c in "hurz"}
225
226will create the dictionary::
227
228    { "H": "(h)", "R": "(r)", "U": "(u)", "Z": "(z)"}
229
230
231The ``Undefined`` object
232------------------------
233
234The object ``Undefined`` will be returned when a non-existant variable, a
235non-existant dictionary entry or an index that is out of range for a list/string
236is accessed.
237
238
239Template code
240=============
241
242The template code tries to mimic Python syntax as far as possible, but is
243limited to what is required for templates and does not allow executing arbitrary
244Python statements. In some spots it also borrows Javascript semantics.
245
246:mod:`ll.ul4c` supports the following tag types:
247
248
249``print``
250---------
251
252The ``print`` tag outputs the value of a variable or any other expression. If
253the expression doesn't evaluate to a string it will be converted to a string
254first. The format of the string depends on the renderer, but should follow
255Python's ``str()`` output as much as possible (except that for ``None`` no
256output may be produced)::
257
258    <h1><?print person.lastname?>, <?print person.firstname?></h1>
259
260
261``printx``
262----------
263
264The ``printx`` tag outputs the value of a variable or any other expression and
265escapes the characters ``<``, ``>``, ``&``, ``'`` and ``"`` with the appropriate
266character or entity references for XML or HTML output.
267
268
269``for``
270-------
271
272The ``for`` tag can be used to loop over the items in a list, the characters in
273a string or the keys in a dictionary. The end of the loop body must be marked
274with an ``<?end for?>`` tag::
275
276    <ul>
277    <?for person in data.persons?>
278    <li><?print person.lastname?>, <?person.firstname?></li>
279    <?end for?>
280    </ul>
281
282In ``for`` loops variable unpacking is supported, so you can do the following::
283
284    <?for (key, value) in dict.items()?>
285
286if ``dict`` is a dictionary.
287
288This unpacking can be arbitrarily nested, i.e. the following is possible too::
289
290    <?for (i, (key, value)) in enumerate(dict.items())?>
291
292
293``break``
294---------
295
296The ``break`` tag can be used to break out of the innermost running loop.
297
298
299``continue``
300------------
301
302The ``continue`` tag can be used to skip the rest of the loop body of the
303innermost running loop.
304
305
306``if``
307------
308
309The ``if`` tag can be used to output a part of the template only when a
310condition is true. The end of the ``if`` block must be marked with an
311``<?end if?>`` tag. The truth value of an object is mostly the same as in Python:
312
313*   ``None`` is false.
314*   The integer ``0`` and the float value ``0.0`` are false.
315*   Empty strings, lists and dictionaries are false.
316*   ``timedelta`` and ``monthdelta`` objects for an empty timespan (i.e.
317    ``timedelta(0, 0, 0)`` and ``monthdelta(0)``) are false.
318*   ``False`` is false.
319*   ``Undefined`` is false.
320*   Anything else is true.
321
322For example we can output the person list only if there are any persons::
323
324    <?if persons?>
325    <ul>
326    <?for person in persons?>
327    <li><?print person.lastname?>, <?person.firstname?></li>
328    <?end for?>
329    </ul>
330    <?end if?>
331
332``elif`` and ``else`` are supported too::
333
334    <?if persons?>
335    <ul>
336    <?for person in persons?>
337    <li><?print person.lastname?>, <?person.firstname?></li>
338    <?end for?>
339    </ul>
340    <?else?>
341    <p>No persons found!</p>
342    <?end if?>
343
344or::
345
346    <?if len(persons)==0?>
347    No persons found!
348    <?elif len(persons)==1?>
349    One person found!
350    <?else?>
351    <?print len(persons)?> persons found!
352    <?end if?>
353
354
355``code``
356--------
357
358The ``code`` tag can contain statements that define or modify variables or
359expressions which will be evaluated for their side effects. Apart from the
360assigment operator ``=``, the following augmented assignment operators are
361supported:
362
363*   ``+=`` (adds a value to the variable)
364*   ``-=`` (subtracts a value from the variable)
365*   ``*=`` (multiplies the variable by a value)
366*   ``/=`` (divides the variable by a value)
367*   ``//=`` (divides the variable by a value, rounding down to the next
368    smallest integer)
369*   ``&=`` (Does a modulo operation and replaces the variable value with the
370    result)
371
372For example the following template will output ``40``::
373
374    <?code x = 17?>
375    <?code x += 23?>
376    <?print x?>
377
378
379``def``
380-------
381
382The ```def`` tag defined a new template as a variable. Usage looks like this::
383
384    <?def quote?>"<?print text?>"<?end def?>
385
386This defines a local variable ``quote`` that is a template object. This template
387can be called like any other template, that has been passed to the outermost
388template::
389
390    <?code quote.render(text="foo")?>
391
392(Here an ``<?code?>`` tag is used. The expression in the ``<?code?>`` tag is
393evaluated for the side effect of generating output)
394
395
396``note``
397--------
398
399A ``note`` tag is a comment, i.e. the content of the tag will be completely ignored.
400
401
402Nested scopes
403-------------
404
405UL4 templates support lexical scopes. This means that a template that is defined
406(via ``<?def?>``) inside another template has access to the local variables
407of the outer template. The inner template sees that state of the variables at
408the point in time when the ``<?def?>`` tag was executed. The following example
409will output ``1``::
410
411    <?code i = 1?>
412    <?def x?>
413        <?print i?>
414    <?end def?>
415    <?code i = 2?>
416    <?render x.render()?>
417
418
419Expressions
420-----------
421
422:mod:`ll.ul4c` supports many of the operators supported by Python. Getitem style
423element access is available, i.e. in the expression ``a[b]`` the following type
424combinations are supported:
425
426*   string, integer: Returns the ``b``\th character from the string ``a``.
427    Note that negative ``b`` values are supported and are relative to the end,
428    so ``a[-1]`` is the last character.
429
430*   list, integer: Returns the ``b``\th list entry of the list ``a``. Negative
431    ``b`` values are supported too.
432
433*   dict, string: Return the value from the dictionary ``a`` corresponding to
434    the key ``b``. Note that some implementations might support keys other
435    than strings too. (The Python and Java renderer do for example.)
436
437If the specified key doesn't exist or the index is out of range for the string
438or list, the special object ``Undefined`` is returned.
439
440Slices are also supported (for list and string objects). As in Python one or
441both of the indexes may be missing to start at the first or end after the last
442character/item. Negative indexes are relative to the end. Indexes that are out
443of bounds are simply clipped:
444
445*   ``<?print "Hello, World!"[7:-1]?>`` prints ``World``.
446
447*   ``<?print "Hello, World!"[:-8]?>`` prints ``Hello``.
448
449The following binary operators are supported: ``+``, ``-``, ``*``, ``/`` (true
450division), ``//`` (truncating division) and ``&`` (modulo).
451
452The usual boolean operators ``not``, ``and`` and ``or`` are supported. ``and``
453and ``or`` work like in Python, i.e. they short-circuit, i.e. if they result is
454clear from the first operand the seconds won't be evaluated, Furthermore they
455always return one of the operands). For example, the following code will output
456the ``data.title`` object if it's true, else ``data.id`` will be output::
457
458    <?print xmlescape(data.title or data.id)?>
459
460The comparison operators ``==``, ``!=``, ``<``, ``<=``, ``>`` and ``>=`` are
461supported.
462
463Containment test via the ``in`` operator can be done, in the expression
464``a in b`` the following type combinations are supported:
465
466*   string, string: Checks whether ``a`` is a substring of ``b``.
467*   any object, list: Checks whether the object ``a`` is in the list ``b``
468    (comparison is done by value not by identity)
469*   string, dict: Checks whether the key ``a`` is in the dictionary ``b``.
470    (Note that some implementations might support keys other than strings too.
471    E.g. Python and Java do, Javascript doesn't.)
472
473The inverted containment test (via ``not in``) is available too.
474
475Attribute access in the template code maps to dictionary style getitem access
476in the data object::
477
478    from ll import ul4c
479    tmpl = ul4c.Template("<?print data.foo?>")
480    print(tmpl.renders(data=dict(foo="bar")))
481
482However getitem style access in the template is still possible::
483
484    from ll import ul4c
485    tmpl = ul4c.Template("<?print data['foo']?>")
486    print(tmpl.renders(data=dict(foo="bar")))
487
488UL4 also supports generator expressions::
489
490    <?print ", ".join("(" + c + ")" for c in "gurk")?>
491
492will output::
493
494    (g), (u), (r), (k)
495
496Outside of function/method arguments brackets are required around generator
497expressions::
498
499    <?code ge = ("(" + c + ")" for c in "gurk")?>
500    <?print ", ".join(ge)?>
501
502
503Functions
504---------
505
506:mod:`ll.ul4c` supports a number of functions.
507
508
509``now``
510"""""""
511
512``now()`` returns the current date and time as a date object.
513
514
515``utcnow``
516""""""""""
517
518``utcnow()`` returns the current date and time as a date object in UTC.
519
520
521``date``
522""""""""
523
524``date()`` creates a date object from the parameter passed in. ``date()``
525supports from three parameters (year, month, day) upto seven parameters
526(year, month, day, hour, minute, second, microsecond).
527
528
529``timedelta``
530"""""""""""""
531
532``timedelta`` returns an object that represents a timespan. ``timedelta``
533allows from zero to three arguments specifying the numbers of days, seconds and
534microseconds. Passing negative values or values that are out of bounds (e.g.
53524*60*60+1 seconds) is allowed. Arguments default to 0, i.e. ``timedelta()``
536returns the timespan for "0 days, 0 seconds, 0 microseconds". In a boolean
537context this object is treated as false (i.e. ``bool(timedelta()))`` returns
538``False``). The following arithmetic operations are supported::
539
540*   ``date`` + ``timedelta``
541*   ``date`` - ``timedelta``
542*   ``timedelta`` + ``timedelta``
543*   ``timedelta`` - ``timedelta``
544*   ``number`` * ``timedelta``
545*   ``timedelta`` * ``number``
546*   ``timedelta`` / ``number``
547*   ``timedelta`` // ``int``
548
549
550``monthdelta``
551""""""""""""""
552
553``monthdelta`` returns an object that represents a timespan of a number of
554months. ``monthdelta`` allows zero or one arguments. With zero arguments
555``monthdelta`` returns the timespan for "0 months". In a boolean context this
556object is treated as false (i.e. ``bool(monthdelta()))`` or
557``bool(monthdelta(0)))`` return ``False``). The following arithmetic operations
558are supported::
559
560*   ``date`` + ``monthdelta``
561*   ``date`` - ``monthdelta``
562*   ``monthdelta`` + ``monthdelta``
563*   ``monthdelta`` - ``monthdelta``
564*   ``int`` * ``monthdelta``
565*   ``monthdelta`` // ``int``
566
567For operation involving ``date`` objects, if the resulting day falls out of the
568range of valid days for the target month, the last day for the target month
569will be used instead, i.e. ``<?print @(2000-01-31) + monthdelta(1)?>`` prints
570``2000-02-29 00:00:00``.
571
572
573``random``
574""""""""""
575
576``random()`` returns a random float value between 0 (included) and 1 (excluded).
577
578
579``randrange``
580"""""""""""""
581
582``randrange(start, stop, step)`` returns a random integer value between ``start``
583(included) and ``stop`` (excluded). ``step`` specifies the step size (i.e.
584when ``r`` is the random value, ``(r-start) % step`` will always be ``0``.
585``step`` and ``start`` can be ommitted.
586
587
588``randchoice``
589""""""""""""""
590
591``randchoice(seq)`` returns a random item from the sequence ``seq``.
592
593
594``isundefined``
595"""""""""""""""
596
597``isundefined(foo)`` returns ``True`` if ``foo`` is ``Undefined``, else
598``False`` is returned::
599
600    data is <?if isundefined(data)?>undefined<?else?>defined<?end if?>!
601
602
603``isdefined``
604"""""""""""""
605
606``isdefined(foo)`` returns ``False`` if ``foo`` is ``Undefined``, else
607``True`` is returned::
608
609    data is <?if isdefined(data)?>defined<?else?>undefined<?end if?>!
610
611
612``isnone``
613""""""""""
614
615``isnone(foo)`` returns ``True`` if ``foo`` is ``None``, else ``False`` is
616returned::
617
618    data is <?if isnone(data)?>None<?else?>something else<?end if?>!
619
620
621``isbool``
622""""""""""
623
624``isbool(foo)`` returns ``True`` if ``foo`` is ``True`` or ``False``, else
625``False`` is returned.
626
627
628``isint``
629"""""""""
630
631``isint(foo)`` returns ``True`` if ``foo`` is an integer object, else ``False``
632is returned.
633
634
635``isfloat``
636"""""""""""
637
638``isfloat(foo)`` returns ``True`` if ``foo`` is a float object, else ``False``
639is returned.
640
641
642``isstr``
643"""""""""
644
645``isstr(foo)`` returns ``True`` if ``foo`` is a string object, else ``False``
646is returned.
647
648
649``isdate``
650""""""""""
651
652``isdate(foo)`` returns ``True`` if ``foo`` is a date object, else ``False``
653is returned.
654
655
656``istimedelta``
657"""""""""""""""
658
659``istimedelta(foo)`` returns ``True`` if ``foo`` is a timedelta object, else
660``False`` is returned.
661
662
663``ismonthdelta``
664""""""""""""""""
665
666``ismonthdelta(foo)`` returns ``True`` if ``foo`` is a monthdelta object, else
667``False`` is returned.
668
669
670``islist``
671""""""""""
672
673``islist(foo)`` returns ``True`` if ``foo`` is a list object, else ``False``
674is returned.
675
676
677``isdict``
678""""""""""
679
680``isdict(foo)`` returns ``True`` if ``foo`` is a dictionary object, else
681``False`` is returned.
682
683
684``iscolor``
685"""""""""""
686
687``iscolor(foo)`` returns ``True`` if ``foo`` is a color object, else ``False``
688is returned.
689
690
691``istemplate``
692""""""""""""""
693
694``istemplate(foo)`` returns ``True`` if ``foo`` is a template object, else
695``False`` is returned.
696
697
698``bool``
699""""""""
700
701``bool(foo)`` converts ``foo`` to an boolean. I.e. ``True`` or ``False`` is
702returned according to the truth value of ``foo``. Calling ``bool`` without
703arguments returns ``False``.
704
705
706``int``
707"""""""
708
709``int(foo)`` converts ``foo`` to an integer. ``foo`` can be a string, a float,
710a boolean or an integer. ``int`` can also be called with two arguments. In this
711case the first argument must be a string and the second is the number base for
712the conversion. Calling ``int`` without arguments returns ``0``.
713
714
715``float``
716"""""""""
717
718``float(foo)`` converts ``foo`` to a float. ``foo`` can be a string, a float,
719a boolean or an integer. Calling ``float`` without arguments returns ``0.0``.
720
721
722``str``
723"""""""
724
725``str(foo)`` converts ``foo`` to a string. If ``foo`` is ``None`` or ``Undefined``
726the result will be the empty string. For lists and dictionaries the exact format
727is undefined, but should follow Python's repr format. For color objects the
728result is a CSS expression (e.g. ``"#fff"``). Calling ``str`` without arguments
729returns the empty string.
730
731
732``repr``
733""""""""
734
735``repr(foo)`` converts ``foo`` to a string representation that is useful for
736debugging proposes. The output looks that the UL constant that could be used to
737recreate the object.
738
739
740``asjson``
741""""""""""
742
743``asjson(foo)`` returns a JSON representation of the object ``foo``.
744(Date objects, color objects and templates are not supported by JSON, but
745``asjson`` will output the appropriate Javascript code for those objects)
746
747
748``fromjson``
749""""""""""""
750
751``fromjson(foo)`` decodes the JSON string ``foo`` and returns the resulting
752object. (Date objects, color objects and templates are not supported by
753``fromjson``).
754
755
756``asul4on``
757"""""""""""
758
759``asul4on(foo)`` returns the UL4ON representation of the object ``foo``.
760
761
762``fromul4on``
763"""""""""""""
764
765``fromul4on(foo)`` decodes the UL4ON string ``foo`` and returns the resulting
766object.
767
768
769``len``
770"""""""
771
772``len(foo)`` returns the length of a string, or the number of items in a list
773or dictionary.
774
775
776``any``
777"""""""
778
779``any(foo)`` returns ``True`` if any of the items in the iterable ``foo`` is
780true. Otherwise ``False`` is returns. If ``foo`` is empty ``False`` is returned.
781
782
783``all``
784"""""""
785
786``all(foo)`` returns ``True`` if all of the items in the iterable ``foo`` are
787true. Otherwise ``False`` is returns. If ``foo`` is empty ``True`` is returned.
788
789
790``enumerate``
791"""""""""""""
792
793Enumerates the items of the argument (which must be iterable, i.e. a string,
794a list or dictionary) and for each item in the original iterable returns a two
795item list containing the item position and the item itself. For example the
796following code::
797
798    <?for (i, c) in enumerate("foo")?>
799        (<?print c?>=<?print i?>)
800    <?end for?>
801
802prints::
803
804    (f=0)(o=1)(o=2)
805
806
807``isfirstlast``
808"""""""""""""""
809
810Iterates through items of the argument (which must be iterable, i.e. a string,
811a list or dictionary) and gives information about whether the item is the first
812and/or last in the iterable. For example the following code::
813
814    <?for (first, last, c) in isfirstlast("foo")?>
815        <?if first?>[<?end if?>
816        (<?print c?>)
817        <?if last?>]<?end if?>
818    <?end for?>
819
820prints::
821
822    [(f)(o)(o)]
823
824
825``isfirst``
826"""""""""""
827
828Iterates through items of the argument (which must be iterable, i.e. a string,
829a list or dictionary) and gives information about whether the item is the first
830in the iterable. For example the following code::
831
832    <?for (first, c) in isfirst("foo")?>
833        <?if first?>[<?end if?>
834        (<?print c?>)
835    <?end for?>
836
837prints::
838
839    [(f)(o)(o)
840
841
842``islast``
843""""""""""
844
845Iterates through items of the argument (which must be iterable, i.e. a string,
846a list or dictionary) and gives information about whether the item is the last
847in the iterable. For example the following code::
848
849    <?for (last, c) in islast("foo")?>
850        (<?print c?>)
851        <?if last?>]<?end if?>
852    <?end for?>
853
854prints::
855
856    (f)(o)(o)]
857
858
859``enumfl``
860""""""""""
861
862This function is a combination of ``enumerate`` and ``isfirstlast``. It iterates
863through items of the argument (which must be iterable, i.e. a string, a list
864or dictionary) and gives information about whether the item is the first
865and/or last in the iterable and its position. For example the following code::
866
867    <?for (index, first, last, c) in enumfl("foo")?>
868        <?if first?>[<?end if?>
869        (<?print c?>=<?print index?>)
870        <?if last?>]<?end if?>
871    <?end for?>
872
873prints::
874
875    [(f=0)(o=1)(o=2)]
876
877
878``xmlescape``
879"""""""""""""
880
881``xmlescape`` takes a string as an argument. It returns a new string where the
882characters ``&``, ``<``, ``>``, ``'`` and ``"`` have been replaced with the
883appropriate XML entity or character reference. For example::
884
885    <?print xmlescape("<'foo' & 'bar'>")?>
886
887prints::
888
889    ``&lt;&#39;foo&#39; &amp; ;&#39;bar&#39&gt;``
890
891If the argument is not a string, it will be converted to a string first.
892
893``<?printx foo?>`` is a shortcut for ``<?print xmlescape(foo)?>``.
894
895
896``min``
897"""""""
898
899``min`` returns the minimum value of its two or more arguments. If it's called
900with one argument, this argument must be iterable and ``min`` returns the
901minimum value of this argument.
902
903
904``max``
905"""""""
906
907``max`` returns the maximum value of its two or more arguments. If it's called
908with one argument, this argument must be iterable and ``max`` returns the
909maximum value of this argument.
910
911
912``sorted``
913""""""""""
914
915``sorted`` returns a sorted list with the items from its argument. For example::
916
917    <?for c in sorted('abracadabra')?><?print c?><?end for?>
918
919prints::
920
921    aaaaabbcdrr
922
923Supported arguments are iterable objects, i.e. strings, lists, dictionaries
924and colors.
925
926
927``chr``
928"""""""
929
930``chr(x)`` returns a one-character string containing the character with the
931codepoint ``x``. ``x`` must be an integer. For example ``<?print chr(0x61)?>``
932outputs ``a``.
933
934
935``ord``
936"""""""
937
938The argument for ``ord`` must be a one-character string. ``ord`` returns the
939codepoint of that character as an integer. For example ``<?print ord('a')?>``
940outputs ``97``.
941
942
943``hex``
944"""""""
945
946Return the hexadecimal representation of the integer argument (with a leading
947``0x``). For example ``<?print hex(42)?>`` outputs ``0x2a``.
948
949
950``oct``
951"""""""
952
953Return the octal representation of the integer argument (with a leading ``0o``).
954For example ``<?print oct(42)?>`` outputs ``0o52``.
955
956
957``bin``
958"""""""
959
960Return the binary representation of the integer argument (with a leading ``0b``).
961For example ``<?print bin(42)?>`` outputs ``0b101010``.
962
963
964``range``
965""""""""""
966
967``range`` returns an object that can be iterated and will produce consecutive
968integers up to the specified argument. With two arguments the first is the start
969value and the second is the stop value. With three arguments the third one is
970the step size (which can be negative). For example the following template::
971
972    <?for i in range(4, 10, 2)?>(<?print i?>)<?end for?>
973
974outputs::
975
976    (4)(6)(8)
977
978
979``type``
980""""""""
981
982``type`` returns the type of the object as a string. Possible return values are
983``"undefined"``, ``"none"``, ``"bool"``, ``"int"``, ``"float"``, ``"str"``,
984``"list"``, ``"dict"``, ``"date"``, ``"color"``, ``"template"`` and
985``"function"``. (If the type isn't recognized ``None`` is returned.)
986
987
988``rgb``
989"""""""
990
991``rgb`` returns a color object. It can be called with
992
993*   three arguments, the red, green and blue values. The alpha value will be
994    set to 255;
995*   four arguments, the red, green, blue and alpha values.
996
997
998``random``
999""""""""""
1000
1001``random`` returns a random floating point number between 0 and 1.
1002
1003
1004``randchoice``
1005""""""""""""""
1006
1007``randchoice`` returns a random item from its argument (which must be list or
1008string)
1009
1010
1011``randchoice``
1012""""""""""""""
1013
1014``random`` returns a random item from its argument (which must be list or string).
1015
1016
1017Methods
1018-------
1019
1020Objects in :mod:`ll.ul4c` support some methods too (depending on the type of the
1021object).
1022
1023
1024``upper``
1025"""""""""
1026
1027The ``upper`` method of strings returns an uppercase version of the string for
1028which it's called::
1029
1030    <?print 'foo'.upper()?>
1031
1032prints::
1033
1034    FOO
1035
1036
1037``lower``
1038"""""""""
1039
1040The ``lower`` method of strings returns an lowercase version of the string for
1041which it's called.
1042
1043
1044``capitalize``
1045""""""""""""""
1046
1047The ``capitalize`` method of strings returns a copy of the string for with its
1048first letter capitalized.
1049
1050
1051``startswith``
1052""""""""""""""
1053
1054``x.startswith(y)`` returns ``True`` if the string ``x`` starts with the string
1055``y`` and ``False`` otherwise.
1056
1057
1058``endswith``
1059""""""""""""""
1060
1061``x.endswith(y)`` returns ``True`` if the string ``x`` ends with the string
1062``y`` and ``False`` otherwise.
1063
1064
1065``strip``
1066"""""""""
1067
1068The string method ``strip`` returns a copy of the string with leading and
1069trailing whitespace removed. If an argument ``chars`` is given and not ``None``,
1070characters in ``chars`` will be removed instead.
1071
1072
1073``lstrip``
1074""""""""""
1075
1076The string method ``lstrip`` returns a copy of the string with leading
1077whitespace removed. If an argument ``chars`` is given and not ``None``,
1078characters in ``chars`` will be removed instead.
1079
1080
1081``rstrip``
1082""""""""""
1083
1084The string method ``rstrip`` returns a copy of the string with trailing
1085whitespace removed. If an argument ``chars`` is given and not ``None``,
1086characters in ``chars`` will be removed instead.
1087
1088
1089``split``
1090"""""""""
1091The string method ``split`` splits the string into separate "words" and returns
1092the resulting list. Without any arguments, the string is split on whitespace
1093characters. With one argument the argument specifies the separator to use. The
1094second optional argument specifies the maximum number of splits to do.
1095
1096
1097``rsplit``
1098""""""""""
1099The string method ``rsplit`` works like ``split``, except that splitting starts
1100from the end (which is only relevant when the maximum number of splits is
1101given).
1102
1103
1104``find``
1105""""""""
1106
1107This method searches for a substring of the string or an item in a list
1108and returns the position of the first appearance of the substring/item or -1 if
1109the string/item can't be found. For example ``"foobar".find("bar")`` returns 3.
1110The optional second and third argument specify the start and end position for
1111the search.
1112
1113
1114``rfind``
1115"""""""""
1116
1117This method works like ``find`` but searches from the end.
1118
1119
1120``replace``
1121"""""""""""
1122
1123The string method ``replace`` has two arguments. It returns a new string where
1124each occurrence of the first argument is replaced by the second argument, i.e.
1125``"abracadabra".replace("ab", "ba")`` returns ``"baracadbara"``
1126
1127
1128``get``
1129"""""""
1130
1131``get`` is a dictionary method. ``d.get(k, v)`` returns ``d[k]`` if the key
1132``k`` is in ``d``, else ``v`` is returned. If ``v`` is not given, it defaults
1133to ``None``.
1134
1135
1136``join``
1137""""""""
1138
1139``join`` is a string method. It returns a concatentation of the strings in the
1140argument sequence with the string itself as the separator, i.e.::
1141
1142    <?print "+".join("1234")?>
1143
1144outputs::
1145
1146    1+2+3+4
1147
1148
1149``renders``
1150"""""""""""
1151
1152The ``renders`` method of template objects renders the template and returns the
1153output as a string. The parameter can be passed via keyword argument or via the
1154``**`` syntax::
1155
1156    <?code output = template.renders(a=17, b=23)?>
1157    <?code data = {'a': 17, 'b': 23)?>
1158    <?code output = template.renders(**data)?>
1159
1160
1161``isoformat``
1162"""""""""""""
1163
1164``isoformat`` is a date method. It returns the date object in ISO 8601 format,
1165i.e.::
1166
1167    <?print now().isoformat()?>
1168
1169might output::
1170
1171    2010-02-22T18:30:29.569639
1172
1173
1174``mimeformat``
1175""""""""""""""
1176
1177``mimeformat`` is a date method. It returns the date object in MIME format
1178(assuming the date object is in UTC), i.e.::
1179
1180    <?print utcnow().mimeformat()?>
1181
1182might output::
1183
1184    Mon, 22 Feb 2010 17:38:40 GMT
1185
1186
1187``day``, ``month``, ``year``, ``hour``, ``minute``, ``second``, ``microsecond``, ``weekday``
1188""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
1189
1190Those methods are date methods. They return a specific attribute of a date
1191object. For example the following reproduces the ``mimeformat`` output from
1192above (except for the linefeeds of course)::
1193
1194    <?code weekdays = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']?>
1195    <?code months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']?>
1196    <?code t = @(2010-02-22T17:38:40.123456)?>
1197    <?print weekdays[t.weekday()]?>,
1198    <?print format(t.day(), '02')?>
1199    <?print months[t.month()-1]?>
1200    <?print format(t.year(), '04')?>
1201    <?print format(t.hour(), '02')?>:
1202    <?print format(t.minute(), '02')?>:
1203    <?print format(t.second(), '02')?>.
1204    <?print format(t.microsecond(), '06')?> GMT
1205
1206
1207``week``
1208""""""""
1209
1210``week`` is a date method. This method returns the week number of the year.
1211It supports one argument: the weekday number that should be considered the start
1212day of the week (0 for Monday, ... 6 for Sunday). All days in a new year
1213preceding the first week start day are considered to be in week 0. The week
1214start day defaults to 0 (Monday).
1215
1216
1217``yearday``
1218"""""""""""
1219
1220``yearday`` is a date method. It returns the number of days since the beginning
1221of the year, so::
1222
1223    <?print @(2010-01-01).yearday()?>
1224
1225prints ``1`` and::
1226
1227    <?print @(2010-12-31).yearday()?>
1228
1229prints ``365``.
1230
1231
1232``append``
1233""""""""""
1234
1235``append`` is a list method. It adds its arguments to the end of the list for
1236which it is called::
1237
1238    <?code v = [1, 2]?>
1239    <?code v.append(3, 4)?>
1240    <?print v?>
1241
1242prints ``[1, 2, 3, 4]``.
1243
1244
1245``insert``
1246""""""""""
1247
1248``insert`` is a list method. Its first argument in the insert position, the
1249remaining arguments are the intems that will be inserted at that position, so::
1250
1251    <?code v = [1, 4]?>
1252    <?code v.insert(1, 2, 3)?>
1253    <?print v?>
1254
1255prints ``[1, 2, 3, 4]``.
1256
1257
1258``pop``
1259"""""""
1260
1261``pop`` is a list method. It removes the last item of the list and returns it.
1262If an index is passed the item at that position is removed and returned.
1263A negative index is treated as relative to the end of the list.
1264
1265
1266``update``
1267""""""""""
1268
1269``update`` is a dictionary method. It supports an arbitrary number of positional
1270and keyword arguments. Each positional argument may be a dictionary, all the
1271items in the dictionary will be copied to the target dictionary. A positional
1272argument may also be an iterable of (key, value) pairs. These will also be copied
1273to the target dictionary. After each positional argument is copied over in a last
1274step the keyword arguments will be copied to the target dictionary.
1275
1276
1277Templates as functions
1278======================
1279
1280UL4 templates can be used as functions too. Calling a template as a function
1281will ignore any output from the template. The return value will be the value of
1282the first ``<?return?>`` tag::
1283
1284    from ll import ul4c
1285
1286    code = '''
1287        <?for item in data?>
1288            <?if "i" in item?>
1289                <?return item?>
1290            <?end if?>
1291        <?end for?>
1292    '''
1293
1294    function = ul4c.Function(code)
1295
1296    output = function(data=["Python", "Java", "Javascript", "PHP"]))
1297
1298With this, ``output`` will be the string ``"Javascript"``.
1299
1300When no ``<?return?>`` tag is encountered, ``None`` will be returned.
1301
1302When a ``<?return?>`` tag is encountered when the template is used as a template,
1303output will simply stop.
1304
1305
1306Delimiters
1307==========
1308
1309It is possible to specify alternative delimiters from the template tags::
1310
1311    >>> from ll import ul4c
1312    >>> t = ul4c.Template(
1313    ...     "{{for i in range(10)}}{{print i}};{{end for}}",
1314    ...     startdelim="{{",
1315    ...     enddelim="}}"
1316    ... )
1317    >>> t.renders()
1318    '0;1;2;3;4;5;6;7;8;9;'
1319
1320
1321Whitespace
1322==========
1323
1324Normally the literal text between template tags will be output as it is. However
1325it is possible to specify that linefeeds and the following indentation should be
1326ignored. This is done with the parameter ``keepws``::
1327
1328    >>> from ll import ul4c
1329    >>> t = ul4c.Template("""
1330    ...     <?for i in range(10)?>
1331    ...         <?print i?>
1332    ...         ;
1333    ...     <?end for?>
1334    ... """, keepws=False)
1335    >>> t.renders()
1336    '0;1;2;3;4;5;6;7;8;9;'
1337
1338Using ``keepws=True`` (the default) the output would include all the line feeds
1339and whitespace::
1340
1341    '\n\t\n\t\t0\n\t\t;\n\t\n\t\t1\n\t\t;\n\t\n\t\t2...
Note: See TracBrowser for help on using the browser.