;ò ò%úEc@s3dZdkZdkZdklZlZlZlZlZdk Z dk Z y dk Z Wn"e j odk Z e Z nXdZdZdZdZeideefƒZeidƒZhd d <d d <d d <dd <dd >> template = Template("../templates/log.ezt") or by calling the parse() method of a template instance directly with a EZT template string: >>> template = Template() >>> template.parse(''' ... [title_string] ...

[title_string]

... [for a_sequence]

[a_sequence]

... [end]
... The [person] is [if-any state]in[else]out[end]. ... ... ... ''') The application should build a dictionary 'data' and pass it together with the output fileobject to the templates generate method: >>> data = {'title_string' : "A Dummy Page", ... 'a_sequence' : ['list item 1', 'list item 2', 'another element'], ... 'person': "doctor", ... 'state' : None } >>> import sys >>> template.generate(sys.stdout, data) A Dummy Page

A Dummy Page

list item 1

list item 2

another element


The doctor is out. Template syntax error reporting should be improved. Currently it is very sparse (template line numbers would be nice): >>> Template().parse("[if-any where] foo [else] bar [end unexpected args]") Traceback (innermost last): File "", line 1, in ? File "ezt.py", line 220, in parse self.program = self._parse(text) File "ezt.py", line 275, in _parse raise ArgCountSyntaxError(str(args[1:])) ArgCountSyntaxError: ['unexpected', 'args'] >>> Template().parse("[if unmatched_end]foo[end]") Traceback (innermost last): File "", line 1, in ? File "ezt.py", line 206, in parse self.program = self._parse(text) File "ezt.py", line 266, in _parse raise UnmatchedEndError() UnmatchedEndError Directives ========== Several directives allow the use of dotted qualified names refering to objects or attributes of objects contained in the data dictionary given to the .generate() method. Qualified names --------------- Qualified names have two basic forms: a variable reference, or a string constant. References are a name from the data dictionary with optional dotted attributes (where each intermediary is an object with attributes, of course). Examples: [varname] [ob.attr] ["string"] Simple directives ----------------- [QUAL_NAME] This directive is simply replaced by the value of the qualified name. If the value is a number it's converted to a string before being outputted. If it is None, nothing is outputted. If it is a python file object (i.e. any object with a "read" method), it's contents are outputted. If it is a callback function (any callable python object is assumed to be a callback function), it is invoked and passed an EZT Context object as an argument. [QUAL_NAME QUAL_NAME ...] If the first value is a callback function, it is invoked with an EZT Context object as a first argument, and the rest of the values as additional arguments. Otherwise, the first value defines a substitution format, specifying constant text and indices of the additional arguments. The arguments are substituted and the result is inserted into the output stream. Example: ["abc %0 def %1 ghi %0" foo bar.baz] Note that the first value can be any type of qualified name -- a string constant or a variable reference. Use %% to substitute a percent sign. Argument indices are 0-based. [include "filename"] or [include QUAL_NAME] This directive is replaced by content of the named include file. Note that a string constant is more efficient -- the target file is compiled inline. In the variable form, the target file is compiled and executed at runtime. Block directives ---------------- [for QUAL_NAME] ... [end] The text within the [for ...] directive and the corresponding [end] is repeated for each element in the sequence referred to by the qualified name in the for directive. Within the for block this identifiers now refers to the actual item indexed by this loop iteration. [if-any QUAL_NAME [QUAL_NAME2 ...]] ... [else] ... [end] Test if any QUAL_NAME value is not None or an empty string or list. The [else] clause is optional. CAUTION: Numeric values are converted to string, so if QUAL_NAME refers to a numeric value 0, the then-clause is substituted! [if-index INDEX_FROM_FOR odd] ... [else] ... [end] [if-index INDEX_FROM_FOR even] ... [else] ... [end] [if-index INDEX_FROM_FOR first] ... [else] ... [end] [if-index INDEX_FROM_FOR last] ... [else] ... [end] [if-index INDEX_FROM_FOR NUMBER] ... [else] ... [end] These five directives work similar to [if-any], but are only useful within a [for ...]-block (see above). The odd/even directives are for example useful to choose different background colors for adjacent rows in a table. Similar the first/last directives might be used to remove certain parts (for example "Diff to previous" doesn't make sense, if there is no previous). [is QUAL_NAME STRING] ... [else] ... [end] [is QUAL_NAME QUAL_NAME] ... [else] ... [end] The [is ...] directive is similar to the other conditional directives above. But it allows to compare two value references or a value reference with some constant string. [define VARIABLE] ... [end] The [define ...] directive allows you to create and modify template variables from within the template itself. Essentially, any data between inside the [define ...] and its matching [end] will be expanded using the other template parsing and output generation rules, and then stored as a string value assigned to the variable VARIABLE. The new (or changed) variable is then available for use with other mechanisms such as [is ...] or [if-any ...], as long as they appear later in the template. [format STRING] ... [end] The format directive controls how the values substituted into templates are escaped before they are put into the output stream. It has no effect on the literal text of the templates, only the output from [QUAL_NAME ...] directives. STRING can be one of "raw" "html" or "xml". The "raw" mode leaves the output unaltered. The "html" and "xml" modes escape special characters using entity escapes (like " and >) [format CALLBACK] Python applications using EZT can provide custom formatters as callback variables. "[format CALLBACK][QUAL_NAME][end]" is in most cases equivalent to "[CALLBACK QUAL_NAME]" N(s StringTypesIntTypes FloatTypesLongTypes TupleTypesrawshtmlsxmls(?:"(?:[^\\"]|\\.)*"|[-\w.]+)s&\[(%s(?: +%s)*)\]|(\[\[\])|\[#[^\]]*\]s"(?:[^\\"]|\\.)*"|[-\w.]+sif-indexisforisissdefinesformats [ ]* \s*s\s\s+s %(%|[0-9]+)sTemplatecBs°tZeded„Zed„Zed„Zd„Zefed„Zd„Z d„Z d „Z d „Z d „Z d „Zd „Zd„Zd„Zd„Zd„ZRS(NicCs(||_|o|i||ƒndS(N(scompress_whitespacesselfsfnames parse_files base_format(sselfsfnamescompress_whitespaces base_format((s lib/ezt.pys__init__!s cCs|it|ƒ|ƒdS(sHfname -> a string object with pathname of file containg an EZT template.N(sselfsparses _FileReadersfnames base_format(sselfsfnames base_format((s lib/ezt.pys parse_file'scCs=t|tƒ ot|ƒ}n|i|d|ƒ|_dS(sÿParse the template specified by text_or_reader. The argument should be a string containing the template, or it should specify a subclass of ezt.Reader which can read templates. The base format for printing values is given by base_format. s base_formatN(s isinstancestext_or_readersReaders _TextReadersselfs_parses base_formatsprogram(sselfstext_or_readers base_format((s lib/ezt.pysparse,scCsŠt|dƒptt|dtƒƒo#dfd„ƒY}||ƒ}nt|ƒ}||_h|_ h|_ |i |i |ƒdS(Ns __getitem__skeyss_data_obcBstZd„ZRS(NcCst|ƒi|ƒdS(N(svarssselfsupdatesd(sselfsd((s lib/ezt.pys__init__>s(s__name__s __module__s__init__(((s lib/ezt.pys_data_ob=s(shasattrsdatascallablesgetattrsNones_data_obsContextsfpsctxs for_iteratorssdefinessselfs_executesprogram(sselfsfpsdatasctxs_data_ob((s lib/ezt.pysgenerate9s)    cCs§ti|iƒ}g}g}| o g}n|o|i |i t |fƒnx3t t|ƒƒD]}||}|d}|djoH|o=|io"tidtid|ƒƒ}n|i |ƒq‡qh|djo|o|i dƒq‡qh|o€ti|ƒ} | d}|djo^t| ƒdjott| dƒƒ‚n|d d}||}||3||d d string object containing the template. This is a private helper function doing the real work for method parse. It returns the parsed template as a 'program'. This program is a sequence made out of strings or (function, argument) 2-tuples. Note: comment directives [# ...] are automatically dropped by _re_parse. iis s is[selseiiÿÿÿÿsendsformats_cmd_s-s_sforsdefinesissincludes"sif-anyN(7s _re_parsessplitsreaderstextspartssprogramsstacks for_namess base_formatsappendsselfs _cmd_formats _printerssrangeslensispieceswhichscompress_whitespaces_re_whitespacessubs _re_newlines_re_argssfindallsargsscmdsArgCountSyntaxErrorsstrsidxs true_sectionspops IndexErrorsUnmatchedEndErrors else_sections_cmd_end_formatsNonesgetattrsresfuncs _block_cmdss_block_cmd_specss _prepare_refs file_argssprintersgetsUnknownFormatConstantErrorsinclude_filenamesf_argssargsextends_parses read_others _cmd_includes _cmd_printsUnclosedBlocksError(sselfsreaders for_namess file_argss base_formatsprintersargsprogramswhichsinclude_filenamesf_argssargssfuncs else_sectionsstacksidxsiscmdspartss true_sectionspiece((s lib/ezt.pys_parseHs®     "       "      '  0  # cCsNxG|D]?}t|tƒo|ii|ƒq|d|d|ƒqWdS(sËThis private helper function takes a 'program' sequence as created by the method '_parse' and executes it step by step. strings are written to the file object 'fp' and functions are called. iiN(sprogramssteps isinstances StringTypesctxsfpswrite(sselfsprogramsctxsstep((s lib/ezt.pys_execute¾s cCs@t|d|ƒ}t|d„|dƒ}t|||ƒdS(NicCs t||ƒS(N(s _get_valuesvalrefsctx(svalrefsctx((s lib/ezt.pysËsi(s _get_valuesvalrefssctxsvaluesmapsargss _write_value(sselfsvalrefssctxsargssvalue((s lib/ezt.pys _cmd_printÉscCs:t|ƒtjot||ƒ}n|ii|ƒdS(N(stypesprinters TupleTypes _get_valuesctxsprinterssappend(sselfsprintersctx((s lib/ezt.pys _cmd_formatÎscCs|iiƒdS(N(sctxsprintersspop(sselfsvalrefsctx((s lib/ezt.pys_cmd_end_formatÓscCsA|\}}t||ƒ}|i|i|i|ƒƒ|ƒdS(N( svalrefsreaders _get_valuesctxsfnamesselfs_executes_parses read_other(sselfs.2sctxsvalrefsreadersfname((s lib/ezt.pys _cmd_includeÖs cCs[|\}}}d}x)|D]!}t||ƒo d}PqqW|i ||||ƒdS(sDIf any value is a non-empty string or non-empty list, then T else F.iiN( sargssvalrefss t_sections f_sectionsvaluesvalrefs _get_valuesctxsselfs_do_if(sselfsargssctxsvalrefssvalues t_sectionsvalrefs f_section((s lib/ezt.pys _cmd_if_anyÜs cCsÚ|\\}}}}|i|d}|djo|iddj}nw|djo|iddj}nS|djo|idj}n3|djo|i ƒ}n|it |ƒj}|i ||||ƒdS(Nisevenisoddisfirstslast( sargssvalrefsvalues t_sections f_sectionsctxs for_iteratorssiteratorsindexsis_lastsintsselfs_do_if(sselfsargssctxsiteratorsvalues t_sectionsvalrefs f_section((s lib/ezt.pys _cmd_if_indexæs    cCse|\\}}}}t||ƒ}ti t||ƒƒti |ƒj}|i ||||ƒdS(N( sargssleft_refs right_refs t_sections f_sections _get_valuesctxsvaluesstringslowersselfs_do_if(sselfsargssctxs right_refsleft_refsvalues t_sections f_section((s lib/ezt.pys_cmd_isõs'cCsY|tjo|}t}n|o |}n|}|tj o|i||ƒndS(N(s t_sectionsNones f_sectionsvaluessectionsselfs_executesctx(sselfsvalues t_sections f_sectionsctxssection((s lib/ezt.pys_do_ifûs    c CsŽ|\\}}}t||ƒ}t|tƒo t ƒ‚n|d}t |ƒ|i |<}x|D]}|i||ƒqfW|i |=dS(Ni(sargssvalrefsunusedssections _get_valuesctxslists isinstances StringTypesNeedSequenceErrorsrefnames_iters for_iteratorssiteratorsselfs_execute( sselfsargssctxsiteratorslistsrefnamesunusedsvalrefssection((s lib/ezt.pys_cmd_fors  cCsn|\\}}}|i}tiƒ|_|t j o|i ||ƒn|ii ƒ|i |<||_dS(N(sargssnamesunusedssectionsctxsfpsorigfps cStringIOsStringIOsNonesselfs_executesgetvaluesdefines(sselfsargssctxsnamesunusedsorigfpssection((s lib/ezt.pys _cmd_defines  (s__name__s __module__sNones FORMAT_RAWs__init__s parse_filesparsesgenerates_parses_executes _cmd_prints _cmd_formats_cmd_end_formats _cmd_includes _cmd_if_anys _cmd_if_indexs_cmd_iss_do_ifs_cmd_fors _cmd_define(((s lib/ezt.pysTemplates   v       cCs|odSntSdS(sBReturn a value suitable for [if-any bool_var] usage in a template.syesN(svaluesNone(svalue((s lib/ezt.pysbooleansc CsŠ|ddjot|dd!tfSnti|dƒ}|d}|d}|d djo³yt|dƒ}Wnt j oqX|t |ƒjor||\}}}|tjot|tfSn||d*| o||gfSn|dti|dƒ}qn|o_x\tt |ƒddƒD]>} ti|| dƒ} | |jo|| || fSq3q3Wn|||fSdS( särefname -> a string containing a dotted identifier. example:"foo.bar.bang" for_names -> a list of active for sequences. Returns a `value reference', a 3-tuple made out of (refname, start, rest), for fast access later. is"iiÿÿÿÿs.isargN(srefnamesNonesstringssplitspartssstartsrestsintsidxs ValueErrorslens file_argss orig_refnames more_restsjoins for_namessrangesisname( srefnames for_namess file_argss more_restsidxsrestsstartspartss orig_refnamesisname((s lib/ezt.pys _prepare_ref!s4    " cCsE|\}}}|tjo|Sn|ii|ƒo|i|i}nZ|i i|ƒo|i |}n6t |i |ƒot |i |ƒ}n t |ƒ‚xC|D];}yt ||ƒ}Wq«tj ot |ƒ‚q«Xq«Wt|tƒpt|tƒp t|tƒot|ƒSn|tjodSn|SdS(s(refname, start, rest) -> a prepared `value reference' (see above). ctx -> an execution context instance. Does a name space lookup within the template name space. Active for blocks take precedence over data dictionary members with the same name. sN(srefnamesstartsrestsNonesctxs for_iteratorsshas_keys last_itemsobsdefinesshasattrsdatasgetattrsUnknownReferencesattrsAttributeErrors isinstancesIntTypesLongTypes FloatTypesstr(s.0sctxsrefnamesstartsrestsattrsob((s lib/ezt.pys _get_valueQs*  0 c CsVt|ƒo"t||gt|ƒƒdSn|iiƒ}zt |dƒo<xéno-|i dƒ}| oPn|||ƒq[Wn±|oœt i |ƒ}x—tt|ƒƒD]r}||}|ddjo |djo7t|ƒ}|t|ƒjo||}qd}n|||ƒq¶Wn|||ƒWd|ii|ƒXdS(Nsreadii@is%s(scallablesvaluesapplysctxslistsargssprintersspopsprintershasattrsreadschunks _re_substssplitspartssrangeslensispiecesintsidxsappend( svaluesargssctxsprintersidxsischunkspartsspiece((s lib/ezt.pys _write_valueys4    sContextcBs#tZdZd„Zfd„ZRS(s%A container for the execution contextcCs||_g|_dS(N(sfpsselfsprinters(sselfsfp((s lib/ezt.pys__init__¢s cCst|||ƒdS(N(s _write_valuesvaluesargssself(sselfsvaluesargs((s lib/ezt.pyswrite¥s(s__name__s __module__s__doc__s__init__swrite(((s lib/ezt.pysContext s  sReadercBstZdZRS(s9Abstract class which allows EZT to detect Reader objects.(s__name__s __module__s__doc__(((s lib/ezt.pysReader¨s s _FileReadercBs tZdZd„Zd„ZRS(s$Reads templates from the filesystem.cCs1t|dƒiƒ|_tii|ƒ|_dS(Nsrb( sopensfnamesreadsselfstextsosspathsdirnames_dir(sselfsfname((s lib/ezt.pys__init__­scCs ttii|i|ƒƒSdS(N(s _FileReadersosspathsjoinsselfs_dirsrelative(sselfsrelative((s lib/ezt.pys read_other°s(s__name__s __module__s__doc__s__init__s read_other(((s lib/ezt.pys _FileReader«s  s _TextReadercBs tZdZd„Zd„ZRS(s&'Reads' a template from provided text.cCs ||_dS(N(stextsself(sselfstext((s lib/ezt.pys__init__µscCs tƒ‚dS(N(sBaseUnavailableError(sselfsrelative((s lib/ezt.pys read_other·s(s__name__s __module__s__doc__s__init__s read_other(((s lib/ezt.pys _TextReader³s  s _IteratorcBs2tZdZd„Zd„Zd„Zd„ZRS(sSpecialized iterator for EZT that counts items and can look ahead Implements standard iterator interface and provides an is_last() method and two public members: index - integer index of the current item last_item - last item returned by next()cCst|ƒ|_dS(N(siterssequencesselfs_iter(sselfssequence((s lib/ezt.pys__init__ÃscCspt|dƒo|i|_|`n|iiƒ|_t|dƒo|id|_n d|_|iSdS(Ns _next_itemsindexii(shasattrsselfs _next_items last_items_itersnextsindex(sself((s lib/ezt.pysnextÆs   cCsMt|dƒ o4y|iiƒ|_WqEtj o dSqEXndSdS(s;Return true if the current item is the last in the sequences _next_itemiiN(shasattrsselfs_itersnexts _next_items StopIteration(sself((s lib/ezt.pysis_lastÔs cCs|SdS(N(sself(sself((s lib/ezt.pys__iter__ßs(s__name__s __module__s__doc__s__init__snextsis_lasts__iter__(((s lib/ezt.pys _Iteratorºs    s _OldIteratorcBs)tZdZd„Zd„Zd„ZRS(sˆAlternate implemention of _Iterator for old Pythons without iterators This class implements the sequence protocol, instead of the iterator interface, so it's really not an iterator at all. But it can be used in python "for" loops as a drop-in replacement for _Iterator. It also provides the is_last() method and "last_item" and "index" members described in the _Iterator docstring.cCs ||_dS(N(ssequencesselfs_seq(sselfssequence((s lib/ezt.pys__init__ëscCs$|i||_||_|iSdS(N(sselfs_seqsindexs last_item(sselfsindex((s lib/ezt.pys __getitem__îs cCs|idt|iƒjSdS(Ni(sselfsindexslens_seq(sself((s lib/ezt.pysis_lastós(s__name__s __module__s__doc__s__init__s __getitem__sis_last(((s lib/ezt.pys _OldIteratorâs   s EZTExceptioncBstZdZRS(s#Parent class of all EZT exceptions.(s__name__s __module__s__doc__(((s lib/ezt.pys EZTExceptionýs sArgCountSyntaxErrorcBstZdZRS(s6A bracket directive got the wrong number of arguments.(s__name__s __module__s__doc__(((s lib/ezt.pysArgCountSyntaxErrors sUnknownReferencecBstZdZRS(sGThe template references an object not contained in the data dictionary.(s__name__s __module__s__doc__(((s lib/ezt.pysUnknownReferences sNeedSequenceErrorcBstZdZRS(sGThe object dereferenced by the template is no sequence (tuple or list).(s__name__s __module__s__doc__(((s lib/ezt.pysNeedSequenceErrors sUnclosedBlocksErrorcBstZdZRS(s)This error may be simply a missing [end].(s__name__s __module__s__doc__(((s lib/ezt.pysUnclosedBlocksError s sUnmatchedEndErrorcBstZdZRS(s6This error may be caused by a misspelled if directive.(s__name__s __module__s__doc__(((s lib/ezt.pysUnmatchedEndError s sBaseUnavailableErrorcBstZdZRS(s6Base location is unavailable, which disables includes.(s__name__s __module__s__doc__(((s lib/ezt.pysBaseUnavailableErrors sUnknownFormatConstantErrorcBstZdZRS(s)The format specifier is an unknown value.(s__name__s __module__s__doc__(((s lib/ezt.pysUnknownFormatConstantErrors cCs|ii|ƒdS(N(sctxsfpswritess(sctxss((s lib/ezt.pys _raw_printerscCs|iiti|ƒƒdS(N(sctxsfpswritescgisescapess(sctxss((s lib/ezt.pys _html_printerscCstidƒddtdgjpt‚tidƒddtddtdgjpt‚tidƒddtddtdgjpt‚tidƒd dtd dtd gjpt‚tid ƒdd tdgjpt‚tid ƒdd tdgjpt‚dS(Ns[a]ss[a] [b]s s[b]s [a c] [b]s[a c]s x [a] y [b] zsx s y s zs [a "b" c "d"]s["a \"b[foo]" c.d f](s _re_parsessplitsNonesAssertionError(((s lib/ezt.pys test_parse"s )222)cCs5dk}dk}d|j}|i|d|ƒSdS(Ns-vsverbose(sdoctestseztsargvsverbosestestmod(sargvseztsdoctestsverbose((s lib/ezt.pys_test/s s__main__i(;s__doc__sstringsrestypess StringTypesIntTypes FloatTypesLongTypes TupleTypesosscgis cStringIOs ImportErrorsStringIOs FORMAT_RAWs FORMAT_HTMLs FORMAT_XMLs_itemscompiles _re_parses_re_argss_block_cmd_specsskeyss _block_cmdss _re_newlines_re_whitespaces _re_substsTemplatesbooleans _prepare_refs _get_values _write_valuesContextsReaders _FileReaders _TextReaders _Iterators _OldIteratorsiters NameErrors_iters Exceptions EZTExceptionsArgCountSyntaxErrorsUnknownReferencesNeedSequenceErrorsUnclosedBlocksErrorsUnmatchedEndErrorsBaseUnavailableErrorsUnknownFormatConstantErrors _raw_printers _html_printers _printerss test_parses_tests__name__ssyssexitsargv(0s cStringIOs _re_newlinesIntTypes_testsBaseUnavailableErrorsNeedSequenceErrorsbooleansUnknownReferencesTemplatesReaders _IteratorsArgCountSyntaxErrors_iters StringTypes_block_cmd_specss FloatTypes _TextReaders EZTExceptions_re_whitespacesresUnclosedBlocksErrorsUnmatchedEndErrors _re_parses_itemscgis _get_valuesstringsUnknownFormatConstantErrors _prepare_refssyssContexts TupleTypes_re_argss _printerss _re_substs FORMAT_HTMLsLongTypes FORMAT_RAWsStringIOs _raw_printers FORMAT_XMLs _OldIterators _html_printers test_parses _block_cmdss _write_values _FileReadersos((s lib/ezt.pys?Ésj  %     3 û  0 ( '(   !