mò DµMc@s dZdkZdkZdkZdkZdefd„ƒYZdefd„ƒYZdefd„ƒYZdefd „ƒYZ d efd „ƒYZ d e ƒhd dfd„Z d„Z deeehhd dfd„ZedjodkZeiƒndS(s¢ This file is part of the web2py Web Framework (Copyrighted, 2007-2011). License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html) Author: Thadeus Burgess Contributors: - Thank you to Massimo Di Pierro for creating the original gluon/template.py - Thank you to Jonathan Lundell for extensively testing the regex on Jython. - Thank you to Limodou (creater of uliweb) who inspired the block-element support for web2py. NtNodecBs&tZdZeed„Zd„ZRS(s Basic Container Object cCs||_||_dS(N(tvaluetselft pre_extend(RRR((t8/home/camdpams_www/Products_Activation/gluon/template.pyt__init__s cCs t|iƒS(N(tstrRR(R((Rt__str__s(t__name__t __module__t__doc__tNonetFalseRR(((RRs t SuperNodecBs)tZded„Zd„Zd„ZRS(NtcCs||_d|_||_dS(N(tnameRR RR(RRR((RR#s  cCs6|iot|iƒSntd|idƒ‚dS(Ns Undefined parent block ``%s``. sbYou must define a block before referencing it. Make sure you have not left out an ``{{end}}`` tag.(RRRt SyntaxErrorR(R((RR(s cCsd|i|ifS(Ns%s->%s(RRR(R((Rt__repr__/s(RR R RRR(((RR "s t BlockNodecBsMtZdZded d„Zd„Zd„Zd„Zd„Zd „Z RS( sä Block Container. This Node can contain other Nodes and will render in a hierarchical order of when nodes were added. ie:: {{ block test }} This is default block test {{ end }} Rs{{s}}cCs1g|_||_||_|\|_|_dS(s+ name - Name of this Node. N(RtnodesRRt delimiterstlefttright(RRRR((RR?s    cCspd|i|i|ifg}x$|iD]}|it|ƒƒq)W|id|i|ifƒdi |ƒS(Ns %sblock %s%ss%send%sR( RRRRtlinesRtnodetappendRtjoin(RRR((RRHs  cCsNg}x8|iD]-}t|tƒp|it|ƒƒqqWdi|ƒS(sH Get this BlockNodes content, not including child Nodes RN( RRRRt isinstanceRRRR(RRR((RROs cCsHt|tƒpt|tƒo|ii|ƒntd|ƒ‚dS(s} Add an element to the nodes. Keyword Arguments - node -- Node object or string to append. s>Invalid type; must be instance of ``str`` or ``BlockNode``. %sN(RRRRRRRt TypeError(RR((RRYs cCs;t|tƒo|ii|iƒntd|ƒ‚dS(s£ Extend the list of nodes with another BlockNode class. Keyword Arguments - other -- BlockNode or Content object to extend from. s3Invalid type; must be instance of ``BlockNode``. %sN(RtotherRRRtextendR(RR((RRfscCs•g}x|iD]t}t|tƒoK|i|jo!|i||ii |ƒƒq„|i|i |ƒƒq|it |ƒƒqWdi |ƒS(s Merges all nodes into a single string. blocks -- Dictionary of blocks that are extending from this template. RN( RRRRRRRtblocksRtoutputRR(RRRR((RR ss !(s{{s}}( RR R R RRRRRR (((RR2s   tContentcBsYtZdZded„Zd„Zdd„Zdd„Zd„Zd„Z d „Z RS( sm Parent Container -- Used as the root level BlockNode. Contains functions that operate as such. t ContentBlockcCs(||_g|_h|_||_dS(sS Keyword Arguments name -- Unique name for this BlockNode N(RRRRR(RRR((RR’s    cCs¡g}x‹|iD]€}t|tƒoW|i|ijo'|i|i|ii |iƒƒq|i|i |iƒƒq|it |ƒƒqWdi |ƒS(NR( RRRRRRRRRR RR(RRR((RRs 'icCsGt|tƒpt|tƒo|ii||ƒn tdƒ‚dS(s* Inserts object at index. s6Invalid type, must be instance of ``str`` or ``Node``.N( RRRRRRtinserttindexR(RRR$((Rt_insert°s cCsYt|ttfƒo/|iƒx2|D]}|i||ƒq'Wn|i||ƒdS(sj Inserts object at index. You may pass a list of objects and have them inserted. N( RRtlistttupletreversetitemRR%R$(RRR$R)((RR#¹s cCslt|tƒpt|tƒo8|ii|ƒt|tƒo||i|i Invalid type, must be instance of ``str`` or ``BlockNode``. %sN( RRRRRRRRRRR(RR((RRÇs  cCsNt|tƒo*|ii|iƒ|ii|iƒntd|ƒ‚dS(sN Extends the objects list of nodes with another objects nodes s3Invalid type; must be instance of ``BlockNode``. %sN( RRRRRRRtupdateR(RR((RRÒs cCs g|_dS(N(RR(R((Rt clear_contentÜs( RR R R RRR%R#RRR+(((RR!Œs    tTemplateParsercBsétZeideiƒZeideiƒZeideiƒZeideiƒZeideiƒZ de ƒddhdgd „Z d „Z d „Z d„Zd„Zddd„Zd„Zd„Zd„Zd„ZRS(Ns (\{\{.*?\}\})s(""".*?""")|(\'\'\'.*?\'\'\')s*^(elif |else:|except:|except |finally:).*$s%^(return|continue|break|raise)( .*)?$s ^pass( .*)?$tParserContainersviews/sresponse.writes{{s}}c Csü||_||_||_t|tƒo ||_n h|_||_||_||_ |djoFt i |dƒt i |dƒf} t i d| t iƒ|_ntd|ƒ|_|ig|_g|_||_h|_|i|ƒdS( s text -- text to parse context -- context to parse in path -- folder path to templates writer -- string of writer class to use lexers -- dict of custom lexers to use. delimiters -- for example ('{{','}}') _super_nodes -- a list of nodes to check for inclusion this should only be set by "self.extend" It contains a list of SuperNodes from a child template that need to be handled. s{{s}}iis (%s.*?%s)RN(s{{s}}(RRttexttwriterRtlexerstdicttpathtcontextRtretescapetescaped_delimiterstcompiletDOTALLtr_tagR!tcontenttstackt super_nodest _super_nodestchild_super_nodesRtparse( RR.RR3R2R/R0RR=R6((RRîs&         &    cCs|it|iƒƒS(sz Return the parsed template with correct indentation. Used to make it easier to port to python3. N(RtreindentRR:(R((Rt to_string7scCs |iƒS(s0Make sure str works exactly the same as python 3N(RRA(R((RR?scCs |iƒS(s0Make sure str works exactly the same as python 3N(RRA(R((Rt __unicode__Csc Csk|idƒ}g}d}d}xò|D]ê}|iƒ}|pq(nt i i |ƒo||d}nt |dƒ}|i dd||ƒd}t ii |ƒo|d8}nt ii |ƒod}|d8}n|idƒo|idƒ o|d7}q(q(Wdi|ƒ}|djo|id|ƒn"|djo|id |ƒn|S( s? Reindents a string of unindented python code. s iit it:t#smissing "pass" in viewstoo many "pass" in viewN(R.tsplitRt new_linestcredittktraw_linetstriptlineR,tre_blocktmatchtmaxRtre_passt re_unblocktendswitht startswithRtnew_textRt _raise_error( RR.RGRTRRHRJRLRI((RR@Gs8  !  RcCsB|oti|i||ƒ‚nti|i|i|ƒ‚dS(sR Raise an error using itself as the filename and textual content. N(R.t restrictedtRestrictedErrorRRtmessage(RRXR.((RRU•scCsœ|iƒp|idƒnt||iƒ}tii|i|ƒ}y)t |dƒ}|i ƒ}|iƒWn$tj o|id|ƒnX|S(s~ Attempt to open ``filename`` and retrieve its text. This will use self.path to search for the file. sInvalid template filenametrbs#Unable to open included view file: N(tfilenameRKRRUtevalR3tosR2RtfilepathtopentfileobjtreadR.tclosetIOError(RRZR]R_R.((Rt_get_file_textžs  c Cs_|i|ƒ}t|d|d|id|id|id|iƒ}|i t |i ƒƒdS(s, Include ``filename`` here. RR3R2R/RN( RRcRZR.R,R3R2R/RttR:RR(RR:RZR.Rd((Rtinclude¼s   cCsz|i|ƒ}g}|i|iƒ|i|iƒt|d|d|id|i d|i d|i d|ƒ}t dd|d|i ƒ}g}x‘|iiD]ƒ}t|t ƒo!|i|iijoq q×nt|tƒo/|io|i|ƒq n|i|ƒq |i|ƒq Wg|i_||iid|<|ii|ƒ|ii|iƒ|i|_dS( s£ Extend ``filename``. Anything not declared in a block defined by the parent will be placed in the parent templates ``{{include}}`` block. RR3R2R/RR=t __include__N(RRcRZR.R<RR>R,R3R2R/RRdRtbuftpreR:RRRRRRRRR#(RRZR<RhRR.RdRg((RRËs<          c Cs|t}d} t}|ii|ƒ}xÇt t |ƒƒD]³}||}|o•t |iƒdjo|idƒn|id}|o*|}|dd!iƒ}|pq7nd„} titi| |ƒ}|idƒod|diƒ}}nN|id dƒ}t |ƒdjo|d}d }n|d}|d}||ijo-|i|d |d |d |d|iƒqß|djo0d|i|f}|i t!|d|ƒƒqß|djoV|idƒ oEt"d|iƒd|d|i#ƒ} |i | ƒ|ii | ƒqß|djo2|idƒ o!||i%|i<|ii&ƒqß|djoa|idƒ oP|o |}n |i}t(d|d|ƒ} |i)i | ƒ|i | ƒqß|djob|idƒ oQ|o|i*||ƒq¯t"dd|id|d|i#ƒ}|i |ƒqß|djo!|idƒ o|} t}qß|o8|o1|idƒ} t}d}xãt t | ƒƒD]Ï}| |iƒ| |<|t | |ƒ7}| |idƒol| |i0dƒo/t}d|i| |diƒf| |tremove(RR.RRvRR€RtR‚RƒRRRlR„RRLRgRRzRIRyRR}Ro((RR? s¾  5              ))!  (s{{s}}(RR R4R7R8R9R|RMRQRPR1RRARRBR@R RURcReRR?(((RR,ßs   !I    N   Asviews/s{{s}}c Cs«t|tƒogy8ttii||ƒdƒ}|iƒ}|i ƒWqƒt j ot i |ddƒ‚qƒXn |iƒ}tt|d|d|d|d|ƒƒS( sº filename can be a view filename in the views folder or an input stream path is the path of a views folder context is a dictionary of symbols used to render the template RYRsUnable to find the fileR3R2R0RN(RRZRR^R\R2RtfpR`R.RaRbRVRWR,R3R0R(RZR2R3R0RR†R.((Rtparse_templates   cCstt|ƒƒS(sM Returns the indented python code of text. Useful for unit testing. N(RR,R.(R.((Rt get_parsed6ss hello worldc Bsdk}| o| o| o ed‚ne} |p>|oe|dƒ}e} qy|oe i |ƒ}qyn|i ƒ|d>> render() 'hello world' >>> render(content='abc') 'abc' >>> render(content='abc\'') "abc'" >>> render(content='a"\'bc') 'a"\'bc' >>> render(content='a\nbc') 'a\nbc' >>> render(content='a"bcd"e') 'a"bcd"e' >>> render(content="'''a\nc'''") "'''a\nc'''" >>> render(content="'''a\'c'''") "'''a'c'''" >>> render(content='{{for i in range(a):}}{{=i}}
{{pass}}', context=dict(a=5)) '0
1
2
3
4
' >>> render(content='{%for i in range(a):%}{%=i%}
{%pass%}', context=dict(a=5),delimiters=('{%','%}')) '0
1
2
3
4
' >>> render(content="{{='''hello\nworld'''}}") 'hello\nworld' >>> render(content='{{for i in range(3):\n=i\npass}}') '012' Ns,Must specify a stream or filename or contentRYtresponseR3R2R0R(tglobalsR:tstreamRZRR t close_streamR^Rut cStringIOtStringIOtResponseR3RR,R`R2R0Rtcodet ExceptionRatbodytgetvalue( R:R‹RZR2R3R0RRRŠRŒ((Rtrender?s(!   0 t__main__(R R\R4RRVtobjectRR RR!R,R1R‡RˆR R”Rtdoctestttestmod( RRR”R,RVR!R4R—R R‡RR\Rˆ((Rt?s"     ZSÿÿ? $D