рд╣рдо рдкрд╛рдпрдерди рдореЗрдВ рдЕрдкрдирд╛ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдЗрдВрдЬрди рд▓рд┐рдЦрддреЗ рд╣реИрдВ

рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЖрдк рдореЗрдВ рд╕реЗ рдХрдИ рдиреЗ рд╕реЛрдЪрд╛ рдерд╛ рдХрд┐ рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрдВрдЬрди рдХреА рд╡реНрдпрд╡рд╕реНрдерд╛ рдХреИрд╕реЗ рдХреА рдЬрд╛рддреА рд╣реИ, рдЗрд╕рдХреА рдЖрдВрддрд░рд┐рдХ рд╕рдВрд░рдЪрдирд╛ рдХреНрдпрд╛ рд╣реИ рдФрд░ HTML рдХреЛрдб рдХреЗ рдЯреБрдХрдбрд╝реЛрдВ рдореЗрдВ рд░реВрдкрд╛рдВрддрд░рдг рдХреИрд╕реЗ рд╣реЛрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЖрдкрдХреЛ рдЗрд╕рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреА рдХрд┐рд╕реА рднреА рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдирд╣реАрдВ рдкрддрд╛ рдерд╛ред рдЗрд╕рд▓рд┐рдП, рдЪрд▓реЛ рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрдВрдЬрди рдХреЗ рдПрдХ рд╕рд░рд▓реАрдХреГрдд рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ "рд╣реБрдб рдХреЗ рддрд╣рдд" рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред

рдкрд╣рд▓реЗ рдЖрдкрдХреЛ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рд╣рдорд╛рд░рд╛ рдЗрдВрдЬрди рдХрд╛рдо рдХрд░реЗрдЧрд╛ред рджреВрд╕рд░реЗ рд╢рдмреНрджреЛрдВ рдореЗрдВ, рднрд╛рд╖рд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░рддреА рд╣реИ рдХрд┐ рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрдВрдЬрди рдЙрдиреНрд╣реЗрдВ рд╕рдордЭреЗрдЧрд╛ рдФрд░ рдЙрдирдХреЗ рдЕрдиреБрд╕рд╛рд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд░реЗрдЧрд╛ред

рднрд╛рд╖рд╛ рд╡рд╛рдХреНрдп рд░рдЪрдирд╛


рдпрджреНрдпрдкрд┐ рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ рднрд╛рд╖рд╛ рдмрд╣реБрдд рд╕рд░рд▓ рд╣реЛ рдЬрд╛рдПрдЧреА, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдо рдЪрд░ рдФрд░ рдмреНрд▓реЙрдХ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░реЗрдВрдЧреЗ, рдЬреЛ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрд╛рдИ рджреЗрдЧрд╛:

<!тАФ-     `{{`  `}}` --> <div>{{my_var}}</div> <!тАФ-    `{%`  `%}` --> {% each items %} <div>{{it}}</div> {% end %} 


рдЕрдзрд┐рдХрд╛рдВрд╢ рдмреНрд▓реЙрдХреЛрдВ рдХреЛ рдмрдВрдж рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдЬреИрд╕рд╛ рдХрд┐ рдКрдкрд░ рджрд┐рдП рдЧрдП рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рд╣реИ, рдФрд░ рдЕрдВрдд рдЯреИрдЧ рдХреЗ рд╕рд╛рде рд╕рдорд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реИ ред
рд╣рдорд╛рд░рд╛ рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрдВрдЬрди рднреА рдЫреЛрд░реЛрдВ рдФрд░ рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░реЗрдЧрд╛ред рдмреНрд▓реЙрдХреЛрдВ рдХреЗ рдЕрдВрджрд░ рдХреЙрд▓ рдХреЗ рд▓рд┐рдП рд╕рдорд░реНрдерди рдЬреЛрдбрд╝рдирд╛ рди рднреВрд▓реЗрдВ - рдпрд╣ рдПрдХ рдХрд╛рдлреА рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдЪреАрдЬ рд╣реЛрдЧреА рдЬреЛ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реЛ рд╕рдХрддреА рд╣реИред

рдЪрдХреНрд░

рдЙрдирдХреА рдорджрдж рд╕реЗ, рд╣рдо рд╕рдВрдЧреНрд░рд╣ рдХреЛ рдмрд╛рдпрдкрд╛рд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдПрдХ рддрддреНрд╡ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рдпрд╣ рдЖрд╡рд╢реНрдпрдХ рд╕рдВрдЪрд╛рд▓рди рдХрд░реЗрдЧрд╛:

 {% each people %} <div>{{it.name}}</div> {% end %} {% each [1, 2, 3] %} <div>{{it}}</div> {% end %} {% each records %} <div>{{..name}}</div> {% end %} 


рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рд▓реЛрдЧ рдПрдХ рд╕рдВрдЧреНрд░рд╣ рд╣реИрдВ рдФрд░ рдпрд╣ рдЗрд╕рдореЗрдВ рд╕реЗ рдПрдХ рддрддреНрд╡ рдХреЛ рд╕рдВрджрд░реНрднрд┐рдд рдХрд░рддрд╛ рд╣реИред рдПрдХ рдмрд┐рдВрджреБ, рдПрдХ рд╡рд┐рднрд╛рдЬрдХ рдХреЗ рд░реВрдк рдореЗрдВ, рдЖрдкрдХреЛ рдЖрд╡рд╢реНрдпрдХ рдЬрд╛рдирдХрд╛рд░реА рдирд┐рдХрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рдХреНрд╖реЗрддреНрд░реЛрдВ рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред ".." рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдорд╛рддрд╛-рдкрд┐рддрд╛ рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рд╕реНрдерд┐рдд рдирд╛рдореЛрдВ рддрдХ рдкрд╣реБрдВрдЪ рдкреНрд░рджрд╛рди рдХрд░реЗрдЧрд╛ред

рд╕реНрдерд┐рддрд┐

рдкрд░рд┐рдЪрдп рджреЗрдиреЗ рдХреА рдЬрд░реВрд░рдд рдирд╣реАрдВред рд╣рдорд╛рд░рд╛ рдЗрдВрдЬрди рд╕рдорд░реНрдерди рдХрд░реЗрдЧрд╛ рдпрджрд┐ ... рдФрд░ рднреА , рд╕рд╛рде рд╣реА рд╕рд╛рде рдСрдкрд░реЗрдЯрд░реЛрдВ: ==, <=,> =, =, =,>, <! ред

 {% if num > 5 %} <div> 5</div> {% else %} <div>   5</div> {% end %} 


рдлрдВрдХреНрд╢рди рдХреЙрд▓

рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЗ рдЕрдВрджрд░ рдХреЙрд▓ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рдирд╛рдо рдФрд░ рд╕реНрдерд┐рддреАрдп рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рдорд░реНрдерди рди рднреВрд▓реЗрдВред рдмреНрд▓реЙрдХ рдЬреЛ рдХреЙрд▓ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдмрдВрдж рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред

 <!тАФ-   ... --> <div class='date'>{% call prettify date_created %}</div> <!-- ...   --> <div>{% call log 'here' verbosity='debug' %}</div> 


рд╕реИрджреНрдзрд╛рдВрддрд┐рдХ рднрд╛рдЧ


рдЗрдВрдЬрди рдХреЗ рд╡рд┐рд╡рд░рдг рдореЗрдВ рджреЗрд░реА рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдЬреЛ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдХреЛ рдкреНрд░рд╕реНрддреБрдд рдХрд░реЗрдЧрд╛, рдЖрдкрдХреЛ рдЗрд╕ рдмрд╛рдд рдХрд╛ рдЕрдВрджрд╛рдЬрд╛ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдХреЛ рдореЗрдореЛрд░реА рдореЗрдВ рдХреИрд╕реЗ рдкреНрд░рд╕реНрддреБрдд рдХрд┐рдпрд╛ рдЬрд╛рдПред

рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╕рд╛рд░ рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рдкреЗрдбрд╝ (рдЗрд╕рдХреЗ рдмрд╛рдж рдПрдПрд╕рдбреА), рдЬреЛ рдбреЗрдЯрд╛ рдХреА рдкреНрд░рд╕реНрддреБрддрд┐ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдЖрд╡рд╢реНрдпрдХ рд╣реИрдВ, рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдПрдПрд╕рдбреА рд╕реНрд░реЛрдд рдХреЛрдб рдХреЗ рд╢рд╛рдмреНрджрд┐рдХ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд╛ рдкрд░рд┐рдгрд╛рдо рд╣реИред рд╕реНрд░реЛрдд рдХреЛрдб рдкрд░ рдЗрд╕ рд╕рдВрд░рдЪрдирд╛ рдХреЗ рдХрдИ рдлрд╛рдпрджреЗ рд╣реИрдВ, рдЬрд┐рдирдореЗрдВ рд╕реЗ рдПрдХ рдЕрдирд╛рд╡рд╢реНрдпрдХ рдкрд╛рда рддрддреНрд╡реЛрдВ рдХрд╛ рдЙрдиреНрдореВрд▓рди рд╣реИ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╕реАрдорд╛рдВрдХрдХ)ред

рд╣рдо рдбреЗрдЯрд╛ рдкрд╛рд░реНрд╕рд┐рдВрдЧ рдХрд░реЗрдВрдЧреЗ рдФрд░ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░реЗрдВрдЧреЗ, рдЙрдкрдпреБрдХреНрдд рдкреЗрдбрд╝ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░реЗрдВрдЧреЗ, рдЬреЛ рдХреБрдЫ рд╕рдВрдХрд▓рд┐рдд рдЯреЗрдореНрдкрд▓реЗрдЯ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░реЗрдЧрд╛ред рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдХрд╛ рдкреНрд░рддрд┐рдкрд╛рджрди рдПрдХ рд╕рд░рд▓ рдЯреНрд░реА рдЯреНрд░реИрд╡рд░реНрд╕рд▓ рд╣реЛрдЧрд╛, рдЬрд┐рд╕рдореЗрдВ рдПрдЪрдЯреАрдПрдордПрд▓ рдХреЛрдб рдХреЗ рдЯреБрдХрдбрд╝реЛрдВ рдореЗрдВ рдмрдиреЗ рдкреЗрдбрд╝ рддрддреНрд╡ рд╡рд╛рдкрд╕ рдЖ рдЬрд╛рдПрдВрдЧреЗред

рд╕рд┐рдВрдЯреЗрдХреНрд╕ рдкрд░рд┐рднрд╛рд╖рд╛;


рд╣рдорд╛рд░реЗ рдХрдард┐рди рд╡реНрдпрд╡рд╕рд╛рдп рдореЗрдВ рдкрд╣рд▓рд╛ рдХрджрдо рд╕рд╛рдордЧреНрд░реА рдХреЛ рдЯреБрдХрдбрд╝реЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдкреНрд░рддреНрдпреЗрдХ рд╕реНрдирд┐рдкреЗрдЯ рдПрдХ HTML рдЯреИрдЧ рд╣реИред рдирд┐рдпрдорд┐рдд рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐, рд╕рд╛рде рд╣реА рд╡рд┐рднрд╛рдЬрди () рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рд╕рд╛рдордЧреНрд░реА рдХреЛ рдЕрд▓рдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред

 VAR_TOKEN_START = '{{' VAR_TOKEN_END = '}}' BLOCK_TOKEN_START = '{%' BLOCK_TOKEN_END = '%}' TOK_REGEX = re.compile(r"(%s.*?%s|%s.*?%s)" % ( VAR_TOKEN_START, VAR_TOKEN_END, BLOCK_TOKEN_START, BLOCK_TOKEN_END )) 


рддреЛ, рдЪрд▓рд┐рдП TOK_REGEX рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рддреЗ рд╣реИрдВред рдЗрд╕ рдирд┐рдпрдорд┐рдд рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдореЗрдВ, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рдЪрд░ рдпрд╛ рдмреНрд▓реЙрдХ рдХреЗ рдмреАрдЪ рдПрдХ рд╡рд┐рдХрд▓реНрдк рд╣реИред рдпрд╣ рдХреБрдЫ рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИ - рд╣рдо рд╕рд╛рдордЧреНрд░реА рдХреЛ рдЪрд░ рдпрд╛ рдмреНрд▓реЙрдХ рдореЗрдВ рдЕрд▓рдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рдкрд╣рд▓реЗ рд╕реЗ рд╕рд╣рдордд рдХрд┐рдП рдЧрдП рдЯреИрдЧ рдХреЗ рд░реВрдк рдореЗрдВ рдЖрд╡рд░рдг рд╣рдореЗрдВ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдЯреБрдХрдбрд╝реЛрдВ рдХреА рдкрд╣рдЪрд╛рди рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░реЗрдЧрд╛ред рд╕рдВрдХреЗрдд? рдирд┐рдпрдорд┐рдд рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЗ рдЕрдВрджрд░ рд╕рдВрдХреЗрдд рдПрдХ рд▓рд╛рд▓рдЪреА рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдирд╣реАрдВ рд╣реИред рдпрд╣ рдЖрд╡рд╢реНрдпрдХ рд╣реИ рддрд╛рдХрд┐ рдирд┐рдпрдорд┐рдд рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ "рдЖрд▓рд╕реА" рд╣реЛ рдФрд░ рдкрд╣рд▓реЗ рдореИрдЪ рдореЗрдВ рд░реБрдХ рдЬрд╛рдП, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЬрдм рдЖрдкрдХреЛ рдмреНрд▓реЙрдХ рдХреЗ рдЕрдВрджрд░ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдЪрд░ рдирд┐рдХрд╛рд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛред рд╡реИрд╕реЗ, рдпрд╣рд╛рдВ рдЖрдк рдирд┐рдпрдорд┐рдд рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдХреЗ рд▓рд╛рд▓рдЪ рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рддрд░реАрдХреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкрдврд╝ рд╕рдХрддреЗ рд╣реИрдВред

рдпрд╣рд╛рдБ рдПрдХ рд╕рд░рд▓ рдЙрджрд╛рд╣рд░рдг рд╣реИ рдЬреЛ рджрд░реНрд╢рд╛рддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдирд┐рдпрдорд┐рдд рдХрд╛рдо рдХреИрд╕реЗ рдХрд░рддрд╛ рд╣реИ:
 >>> TOK_REGEX.split('{% each vars %}<i>{{it}}</i>{% endeach %}') ['{% each vars %}', '<i>', '{{it}}', '</i>', '{% endeach %}'] 


рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдкреНрд░рддреНрдпреЗрдХ рд╕рдВрд╕рд╛рдзрд┐рдд рдЯреБрдХрдбрд╝реЗ рдХрд╛ рдЕрдкрдирд╛ рдкреНрд░рдХрд╛рд░ рд╣реЛрдЧрд╛, рдЬрд┐рд╕реЗ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдФрд░ рд╕рдВрдХрд▓рди рдХреЗ рджреМрд░рд╛рди рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрд╛ рдЬрд╛рдПрдЧрд╛ред рдЯреБрдХрдбрд╝реЛрдВ рдХреЛ рдЪрд╛рд░ рдкреНрд░рдХрд╛рд░реЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛:

 VAR_FRAGMENT = 0 OPEN_BLOCK_FRAGMENT = 1 CLOSE_BLOCK_FRAGMENT = 2 TEXT_FRAGMENT = 3 


рдПрдПрд╕рдбреА рдЧрдарди


рд╣рдорд╛рд░реЗ рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрдВрдЬрди рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдЕрдВрд╢реЛрдВ рд╡рд╛рд▓реЗ HTML рдкреГрд╖реНрда рдХреЗ рд╕реНрд░реЛрдд рдкрд╛рда рдХреЗ рдирд┐рдпрдорд┐рдд рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреЗ рдмрд╛рдж, рд╣рдорд╛рд░реА "рднрд╛рд╖рд╛" рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рддрддреНрд╡реЛрдВ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдПрдХ рдкреЗрдбрд╝ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рдиреЛрдб рд╡рд░реНрдЧ рд╣реЛрдЧрд╛, рдЬреЛ рдкреЗрдбрд╝ рдХреА рдЬрдбрд╝ рд╣реИ рдФрд░ рдЗрд╕рдореЗрдВ рдмрд╛рд▓ рдиреЛрдбреНрд╕ рд╣реЛрддреЗ рд╣реИрдВ, рдЬреЛ рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рдиреЛрдб рдХреЗ рд▓рд┐рдП рдЙрдкрд╡рд░реНрдЧ рд╣реИрдВред рдЙрдкрд╡рд░реНрдЧреЛрдВ рдореЗрдВ process_fragment () рдФрд░ рд░реЗрдВрдбрд░ () рд╡рд┐рдзрд┐рдпрд╛рдБ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдП:
- рдкреНрд░рдХреНрд░рд┐рдпрд╛_рдлреНрд░реИрдЧрдореЗрдВрдЯ () рдХрд╛ рдЙрдкрдпреЛрдЧ рдиреЛрдб рдСрдмреНрдЬреЗрдХреНрдЯ рдХреА рд╕рд╛рдордЧреНрд░реА рдФрд░ рдЖрд╡рд╢реНрдпрдХ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
- рд╕рдВрдмрдВрдзрд┐рдд рдХреЛрдб рдХреЛ HTML рдХреЛрдб рдореЗрдВ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рд░реЗрдВрдбрд░ () рдХреА рдЬрд░реВрд░рдд рд╣реЛрддреА рд╣реИ

рдпрд╣ рдХрдВрдкрд╛рдЗрд▓рд░ рдСрдкрд░реЗрд╢рди рдХреЗ рджреМрд░рд╛рди рдХрд╣реЗ рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ enter_scope () рдФрд░ exit_scope () рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡реИрдХрд▓реНрдкрд┐рдХ рд╣реИред рдкрд╣рд▓рд╛ рдлрд╝рдВрдХреНрд╢рди, enter_scope () рдХрд╣рд▓рд╛рддрд╛ рд╣реИ, рдЬрдм рдиреЛрдб рдПрдХ рдирдпрд╛ рдХреНрд╖реЗрддреНрд░ рдмрдирд╛рддрд╛ рд╣реИ (рдмрд╛рдж рдореЗрдВ рдЙрд╕ рдкрд░ рдЕрдзрд┐рдХ), рдФрд░ рдмрд╛рд╣рд░ рдирд┐рдХрд▓реЗрдВ_scope () рд╡рд░реНрддрдорд╛рди рдХреНрд╖реЗрддреНрд░ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЫреЛрдбрд╝ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрдм рдХреНрд╖реЗрддреНрд░ рдХрд╛ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдкреВрд░рд╛ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред

рдЖрдзрд╛рд░ рд╡рд░реНрдЧ рдиреЛрдб :
 class _Node(object): def __init__(self, fragment=None): self.children = [] self.creates_scope = False self.process_fragment(fragment) def process_fragment(self, fragment): pass def enter_scope(self): pass def render(self, context): pass def exit_scope(self): pass def render_children(self, context, children=None): if children is None: children = self.children def render_child(child): child_html = child.render(context) return '' if not child_html else str(child_html) return ''.join(map(render_child, children)) 


рдФрд░ рдпрд╣рд╛рдБ рдЪрд░ рдЙрдкрд╡рд░реНрдЧ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╣реИ:
 class _Variable(_Node): def process_fragment(self, fragment): self.name = fragment def render(self, context): return resolve_in_context(self.name, context) 


рдиреЛрдб рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╕рдордп, рдкрд╛рда рдХреЗ рдПрдХ рдЯреБрдХрдбрд╝реЗ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдЬреЛ рд╣рдореЗрдВ рдЗрд╕ рдЯреБрдХрдбрд╝реЗ рдХрд╛ рдкреНрд░рдХрд╛рд░ рдмрддрд╛рдПрдЧрд╛ (рдпрд╛рдиреА рдпрд╣ рдПрдХ рдЪрд░, рдмреНрд░реИрдХреЗрдЯ, рдЖрджрд┐ рд╣реИ)
рдкрд╛рда рдФрд░ рдЪрд░ рдХреЛ рдЙрдирдХреЗ рд╕рдВрдмрдВрдзрд┐рдд рдЙрдкрд╡рд░реНрдЧреЛрдВ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
рдпрджрд┐ рдпреЗ рд▓реВрдк рд╣реИрдВ, рддреЛ рдЙрдирдХреЗ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рдереЛрдбрд╝рд╛ рдЕрдзрд┐рдХ рд╕рдордп рд▓рдЧреЗрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдХрдИ рдЖрджреЗрд╢реЛрдВ рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдпрд╣ рдХрдорд╛рдВрдб рдХрд╛ рдПрдХ рдмреНрд▓реЙрдХ рд╣реИ, рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИ: рдЖрдкрдХреЛ рдмрд╕ "{%" рдФрд░ "%}" рдореЗрдВ рд╕рдВрд▓рдЧреНрди рдкрд╛рда рдХреЗ рдПрдХ рдЯреБрдХрдбрд╝реЗ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдпрд╣рд╛рдБ рдПрдХ рд╕рд░рд▓ рдЙрджрд╛рд╣рд░рдг рд╣реИ:
 {% each items %} 

рдЬрд╣рд╛рдВ рдкреНрд░рддреНрдпреЗрдХ рдХрдорд╛рдВрдб рдХрд╛ рдЗрдЪреНрдЫрд┐рдд рдмреНрд▓реЙрдХ рд╣реИ

рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд┐рдВрджреБ рдпрд╣ рд╣реИ рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдиреЛрдб рдПрдХ рдХреНрд╖реЗрддреНрд░ рдмрдирд╛рддрд╛ рд╣реИред рд╕рдВрдХрд▓рди рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рджреМрд░рд╛рди, рд╣рдо рдЗрд╕ рдХреНрд╖реЗрддреНрд░ рдХреЗ рднреАрддрд░ рдЬреЛрдбрд╝реЗ рдЧрдП рд╡рд░реНрддрдорд╛рди рдХреНрд╖реЗрддреНрд░ рдФрд░ рдиреЛрдбреНрд╕ рдХреЛ рдЯреНрд░реИрдХ рдХрд░рддреЗ рд╣реИрдВред рдпрджрд┐ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреЗ рджреМрд░рд╛рди рдПрдХ рдмрдВрдж рдмреНрд░реИрдХреЗрдЯ рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░рдирд╛ рдкрдбрд╝рддрд╛ рд╣реИ, рддреЛ рд╡рд░реНрддрдорд╛рди рдХреНрд╖реЗрддреНрд░ рдХрд╛ рдЧрдарди рдкреВрд░рд╛ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдЕрдЧрд▓реЗ рдХреЗ рд▓рд┐рдП рд╕рдВрдХреНрд░рдордг рд╣реЛрддрд╛ рд╣реИред

 def compile(self): root = _Root() scope_stack = [root] for fragment in self.each_fragment(): if not scope_stack: raise TemplateError('nesting issues') parent_scope = scope_stack[-1] if fragment.type == CLOSE_BLOCK_FRAGMENT: parent_scope.exit_scope() scope_stack.pop() continue new_node = self.create_node(fragment) if new_node: parent_scope.children.append(new_node) if new_node.creates_scope: scope_stack.append(new_node) new_node.enter_scope() return root 


рдкреНрд░рддрд┐рдкрд╛рджрди


рдПрд╕рдбреАрдП рдХреЛ HTML рдореЗрдВ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдВрддрд┐рдо рдЪрд░рдг рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдкреЗрдбрд╝ рдХреЗ рд╕рднреА рдиреЛрдбреНрд╕ рдкрд░ рдЬрд╛рддреЗ рд╣реИрдВ рдФрд░ рд░реЗрдВрдбрд░ () рд╡рд┐рдзрд┐ рдХрд╣рддреЗ рд╣реИрдВред рд░реЗрдВрдбрд░рд┐рдВрдЧ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ, рдпрд╣ рдзреНрдпрд╛рди рд░рдЦрдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ рдХрд┐ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдХреНрдпрд╛ рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реИ: рд╢рд╛рдмреНрджрд┐рдХ рдпрд╛ рдЪрд░ рдирд╛рдо рдХрд╛ рд╕рдВрджрд░реНрднред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, ast.literal_eval () рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ, рдЬреЛ рд╕реБрд░рдХреНрд╖рд┐рдд рд░реВрдк рд╕реЗ рдЖрдкрдХреЛ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ:

 def eval_expression(expr): try: return 'literal', ast.literal_eval(expr) except ValueError, SyntaxError: return 'name', expr 


рдпрджрд┐ рд╣рдо рдПрдХ рдЪрд░ рдирд╛рдо рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рдХрд╛рдо рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рддреЛ рд╣рдо рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдЗрд╕рдХреЗ рд╕рд╛рде рдХреНрдпрд╛ рд╕рдВрдХреЗрдд рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ: "ред" рдпрд╛ "..":
 def resolve(name, context): if name.startswith('..'): context = context.get('..', {}) name = name[2:] try: for tok in name.split('.'): context = context[tok] return context except KeyError: raise TemplateContextError(name) 


рдирд┐рд╖реНрдХрд░реНрд╖


рдпрд╣ рд▓реЗрдЦ рдПрдХ рдЕрдиреБрд╡рд╛рдж рд╣реИ рдЬреЛ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рд╡рд┐рдЪрд╛рд░ рджреЗрддрд╛ рд╣реИ рдХрд┐ рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрдВрдЬрди рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВред рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рд╕рдмрд╕реЗ рд╕рд░рд▓ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЙрджрд╛рд╣рд░рдг рд╣реИ, рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрдВрдЬрди рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХреЗ рд▓рд┐рдП рдЖрдзрд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рдкреВрд░реНрдг рд╕реНрд░реЛрдд рдХреЛрдб, рд╕рд╛рде рд╣реА рдЙрдкрдпреЛрдЧ рдХреЗ рдЙрджрд╛рд╣рд░рдг рдпрд╣рд╛рдВ рджреЗрдЦреЗ рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВред

Source: https://habr.com/ru/post/In180935/


All Articles