Mako-0.9.1/0000755000076500000240000000000012257137143013161 5ustar classicstaff00000000000000Mako-0.9.1/CHANGES0000644000076500000240000010274012257136636014166 0ustar classicstaff000000000000000.9.1 - [bug] Fixed bug in Babel plugin where translator comments would be lost if intervening text nodes were encountered. Fix courtesy Ned Batchelder. [ticket:225] - [bug] Fixed TGPlugin.render method to support unicode template names in Py2K - courtesy Vladimir Magamedov. - [bug] Fixed an AST issue that was preventing correct operation under alpha versions of Python 3.4. Pullreq courtesy Zer0-. - [bug] Changed the format of the "source encoding" header output by the code generator to use the format ``# -*- coding:%s -*-`` instead of ``# -*- encoding:%s -*-``; the former is more common and compatible with emacs. Courtesy Martin Geisler. - [bug] Fixed issue where an old lexer rule prevented a template line which looked like "#*" from being correctly parsed. [ticket:224] 0.9.0 - [bug] The Context.locals_() method becomes a private underscored method, as this method has a specific internal use. The purpose of Context.kwargs has been clarified, in that it only delivers top level keyword arguments originally passed to template.render(). [ticket:219] - [bug] Fixed the babel plugin to properly interpret ${} sections inside of a "call" tag, i.e. <%self:some_tag attr="${_('foo')}"/>. Code that's subject to babel escapes in here needs to be specified as a Python expression, not a literal. This change is backwards incompatible vs. code that is relying upon a _('') translation to be working within a call tag. - [bug] The Babel plugin has been repaired to work on Python 3. [ticket:187] - [bug] Using <%namespace import="*" module="somemodule"/> now skips over module elements that are not explcitly callable, avoiding TypeError when trying to produce partials. [ticket:207] - [bug] Fixed Py3K bug where a "lambda" expression was not interpreted correctly within a template tag; also fixed in Py2.4. [ticket:190] 0.8.1 - [bug] Changed setup.py to skip installing markupsafe if Python version is < 2.6 or is between 3.0 and less than 3.3, as Markupsafe now only supports 2.6->2.X, 3.3->3.X. [ticket:216] - [bug] Fixed regression where "entity" filter wasn't converted for py3k properly (added tests.) [ticket:214] - [bug] Fixed bug where mako-render script wasn't compatible with Py3k. [ticket:212] - [bug] Cleaned up all the various deprecation/ file warnings when running the tests under various Pythons with warnings turned on. [ticket:213] 0.8.0 - [feature] Performance improvement to the "legacy" HTML escape feature, used for XML escaping and when markupsafe isn't present, courtesy George Xie. - [bug] Fixed bug whereby an exception in Python 3 against a module compiled to the filesystem would fail trying to produce a RichTraceback due to the content being in bytes. [ticket:209] - [bug] Change default for compile()->reserved_names from tuple to frozenset, as this is expected to be a set by default. [ticket:208] - [feature] Code has been reworked to support Python 2.4-> Python 3.xx in place. 2to3 no longer needed. - [feature] Added lexer_cls argument to Template, TemplateLookup, allows alternate Lexer classes to be used. - [feature] Added future_imports parameter to Template and TemplateLookup, renders the __future__ header with desired capabilities at the top of the generated template module. Courtesy Ben Trofatter. 0.7.3 - [bug] legacy_html_escape function, used when Markupsafe isn't installed, was using an inline-compiled regexp which causes major slowdowns on Python 3.3; is now precompiled. - [bug] AST supporting now supports tuple-packed function arguments inside pure-python def or lambda expressions. [ticket:201] - [bug] Fixed Py3K bug in the Babel extension. - [bug] Fixed the "filter" attribute of the <%text> tag so that it pulls locally specified identifiers from the context the same way as that of <%block> and <%filter>. - [bug] Fixed bug in plugin loader to correctly raise exception when non-existent plugin is specified. 0.7.2 - [bug] Fixed regression in 0.7.1 where AST parsing for Py2.4 was broken. [ticket:193] 0.7.1 - [feature] Control lines with no bodies will now succeed, as "pass" is added for these when no statements are otherwise present. Courtesy Ben Trofatter [ticket:146] - [bug] Fixed some long-broken scoping behavior involving variables declared in defs and such, which only became apparent when the strict_undefined flag was turned on. [ticket:192] - [bug] Can now use strict_undefined at the same time args passed to def() are used by other elements of the <%def> tag. [ticket:191] 0.7.0 - [feature] Added new "loop" variable to templates, is provided within a % for block to provide info about the loop such as index, first/last, odd/even, etc. A migration path is also provided for legacy templates via the "enable_loop" argument available on Template, TemplateLookup, and <%page>. Thanks to Ben Trofatter for all the work on this [ticket:125] - [feature] Added a real check for "reserved" names, that is names which are never pulled from the context and cannot be passed to the template.render() method. Current names are "context", "loop", "UNDEFINED". - [feature] The html_error_template() will now apply Pygments highlighting to the source code displayed in the traceback, if Pygments if available. Courtesy Ben Trofatter [ticket:95] - [feature] Added support for context managers, i.e. "% with x as e:/ % endwith" support. Courtesy Ben Trofatter [ticket:147] - [feature] Added class-level flag to CacheImpl "pass_context"; when True, the keyword argument 'context' will be passed to get_or_create() containing the Mako Context object. [ticket:185] - [bug] Fixed some Py3K resource warnings due to filehandles being implicitly closed. [ticket:182] - [bug] Fixed endless recursion bug when nesting multiple def-calls with content. Thanks to Jeff Dairiki. [ticket:186] - [feature] Added Jinja2 to the example benchmark suite, courtesy Vincent Férotin 0.6.2 - [bug] The ${{"foo":"bar"}} parsing issue is fixed!! The legendary Eevee has slain the dragon! [ticket:20]. Also fixes quoting issue at [ticket:86]. 0.6.1 - [bug] Added special compatibility for the 0.5.0 Cache() constructor, which was preventing file version checks and not allowing Mako 0.6 to recompile the module files. 0.6.0 - [feature] Template caching has been converted into a plugin system, whereby the usage of Beaker is just the default plugin. Template and TemplateLookup now accept a string "cache_impl" parameter which refers to the name of a cache plugin, defaulting to the name 'beaker'. New plugins can be registered as pkg_resources entrypoints under the group "mako.cache", or registered directly using mako.cache.register_plugin(). The core plugin is the mako.cache.CacheImpl class. - [feature] Added support for Beaker cache regions in templates. Usage of regions should be considered as superseding the very obsolete idea of passing in backend options, timeouts, etc. within templates. - [feature] The 'put' method on Cache is now 'set'. 'put' is there for backwards compatibility. - [feature] The <%def>, <%block> and <%page> tags now accept any argument named "cache_*", and the key minus the "cache_" prefix will be passed as keyword arguments to the CacheImpl methods. - [feature] Template and TemplateLookup now accept an argument cache_args, which refers to a dictionary containing cache parameters. The cache_dir, cache_url, cache_type, cache_timeout arguments are deprecated (will probably never be removed, however) and can be passed now as cache_args={'url':, 'type':'memcached', 'timeout':50, 'dir':'/path/to/some/directory'} - [feature/bug] Can now refer to context variables within extra arguments to <%block>, <%def>, i.e. <%block name="foo" cache_key="${somekey}">. Filters can also be used in this way, i.e. <%def name="foo()" filter="myfilter"> then template.render(myfilter=some_callable) [ticket:180] - [feature] Added "--var name=value" option to the mako-render script, allows passing of kw to the template from the command line. [ticket:178] - [feature] Added module_writer argument to Template, TemplateLookup, allows a callable to be passed which takes over the writing of the template's module source file, so that special environment-specific steps can be taken. [ticket:181] - [bug] The exception message in the html_error_template is now escaped with the HTML filter. [ticket:142] - [bug] Added "white-space:pre" style to html_error_template() for code blocks so that indentation is preserved [ticket:173] - [bug] The "benchmark" example is now Python 3 compatible (even though several of those old template libs aren't available on Py3K, so YMMV) [ticket:175] 0.5 - A Template is explicitly disallowed from having a url that normalizes to relative outside of the root. That is, if the Lookup is based at /home/mytemplates, an include that would place the ultimate template at /home/mytemplates/../some_other_directory, i.e. outside of /home/mytemplates, is disallowed. This usage was never intended despite the lack of an explicit check. The main issue this causes is that module files can be written outside of the module root (or raise an error, if file perms aren't set up), and can also lead to the same template being cached in the lookup under multiple, relative roots. TemplateLookup instead has always supported multiple file roots for this purpose. [ticket:174] 0.4.2 - Fixed bug regarding <%call>/def calls w/ content whereby the identity of the "caller" callable inside the <%def> would be corrupted by the presence of another <%call> in the same block. [ticket:170] - Fixed the babel plugin to accommodate <%block> [ticket:169] 0.4.1 - New tag: <%block>. A variant on <%def> that evaluates its contents in-place. Can be named or anonymous, the named version is intended for inheritance layouts where any given section can be surrounded by the <%block> tag in order for it to become overrideable by inheriting templates, without the need to specify a top-level <%def> plus explicit call. Modified scoping and argument rules as well as a more strictly enforced usage scheme make it ideal for this purpose without at all replacing most other things that defs are still good for. Lots of new docs. [ticket:164] - a slight adjustment to the "highlight" logic for generating template bound stacktraces. Will stick to known template source lines without any extra guessing. [ticket:165] 0.4.0 - A 20% speedup for a basic two-page inheritance setup rendering a table of escaped data (see http://techspot.zzzeek.org/2010/11/19/quick-mako-vs.-jinja-speed-test/). A few configurational changes which affect those in the I-don't-do-unicode camp should be noted below. - The FastEncodingBuffer is now used by default instead of cStringIO or StringIO, regardless of whether output_encoding is set to None or not. FEB is faster than both. Only StringIO allows bytestrings of unknown encoding to pass right through, however - while it is of course not recommended to send bytestrings of unknown encoding to the output stream, this mode of usage can be re-enabled by setting the flag bytestring_passthrough to True. - disable_unicode mode requires that output_encoding be set to None - it also forces the bytestring_passthrough flag to True. - the <%namespace> tag raises an error if the 'template' and 'module' attributes are specified at the same time in one tag. A different class is used for each case which allows a reduction in runtime conditional logic and function call overhead. [ticket:156] - the keys() in the Context, as well as it's internal _data dictionary, now include just what was specified to render() as well as Mako builtins 'caller', 'capture'. The contents of __builtin__ are no longer copied. Thanks to Daniel Lopez for pointing this out. [ticket:159] 0.3.6 - Documentation is on Sphinx. [ticket:126] - Beaker is now part of "extras" in setup.py instead of "install_requires". This to produce a lighter weight install for those who don't use the caching as well as to conform to Pyramid deployment practices. [ticket:154] - The Beaker import (or attempt thereof) is delayed until actually needed; this to remove the performance penalty from startup, particularly for "single execution" environments such as shell scripts. [ticket:153] - Patch to lexer to not generate an empty '' write in the case of backslash-ended lines. [ticket:155] - Fixed missing **extra collection in setup.py which prevented setup.py from running 2to3 on install. [ticket:148] - New flag on Template, TemplateLookup - strict_undefined=True, will cause variables not found in the context to raise a NameError immediately, instead of defaulting to the UNDEFINED value. - The range of Python identifiers that are considered "undefined", meaning they are pulled from the context, has been trimmed back to not include variables declared inside of expressions (i.e. from list comprehensions), as well as in the argument list of lambdas. This to better support the strict_undefined feature. The change should be fully backwards-compatible but involved a little bit of tinkering in the AST code, which hadn't really been touched for a couple of years, just FYI. 0.3.5 - The <%namespace> tag allows expressions for the `file` argument, i.e. with ${}. The `context` variable, if needed, must be referenced explicitly. [ticket:141] - ${} expressions embedded in tags, such as <%foo:bar x="${...}">, now allow multiline Python expressions. - Fixed previously non-covered regular expression, such that using a ${} expression inside of a tag element that doesn't allow them raises a CompileException instead of silently failing. - Added a try/except around "import markupsafe". This to support GAE which can't run markupsafe. [ticket:151] No idea whatsoever if the install_requires in setup.py also breaks GAE, couldn't get an answer on this. 0.3.4 - Now using MarkupSafe for HTML escaping, i.e. in place of cgi.escape(). Faster C-based implementation and also escapes single quotes for additional security. Supports the __html__ attribute for the given expression as well. When using "disable_unicode" mode, a pure Python HTML escaper function is used which also quotes single quotes. Note that Pylons by default doesn't use Mako's filter - check your environment.py file. - Fixed call to "unicode.strip" in exceptions.text_error_template which is not Py3k compatible. [ticket:137] 0.3.3 - Added conditional to RichTraceback such that if no traceback is passed and sys.exc_info() has been reset, the formatter just returns blank for the "traceback" portion. [ticket:135] - Fixed sometimes incorrect usage of exc.__class__.__name__ in html/text error templates when using Python 2.4 [ticket:131] - Fixed broken @property decorator on template.last_modified - Fixed error formatting when a stacktrace line contains no line number, as in when inside an eval/exec-generated function. [ticket:132] - When a .py is being created, the tempfile where the source is stored temporarily is now made in the same directory as that of the .py file. This ensures that the two files share the same filesystem, thus avoiding cross-filesystem synchronization issues. Thanks to Charles Cazabon. 0.3.2 - Calling a def from the top, via template.get_def(...).render() now checks the argument signature the same way as it did in 0.2.5, so that TypeError is not raised. reopen of [ticket:116] 0.3.1 - Fixed incorrect dir name in setup.py [ticket:129] 0.3 - Python 2.3 support is dropped. [ticket:123] - Python 3 support is added ! See README.py3k for installation and testing notes. [ticket:119] - Unit tests now run with nose. [ticket:127] - Source code escaping has been simplified. In particular, module source files are now generated with the Python "magic encoding comment", and source code is passed through mostly unescaped, except for that code which is regenerated from parsed Python source. This fixes usage of unicode in <%namespace:defname> tags. [ticket:99] - RichTraceback(), html_error_template().render(), text_error_template().render() now accept "error" and "traceback" as optional arguments, and these are now actually used. [ticket:122] - The exception output generated when format_exceptions=True will now be as a Python unicode if it occurred during render_unicode(), or an encoded string if during render(). - A percent sign can be emitted as the first non-whitespace character on a line by escaping it as in "%%". [ticket:112] - Template accepts empty control structure, i.e. % if: %endif, etc. [ticket:94] - The <%page args> tag can now be used in a base inheriting template - the full set of render() arguments are passed down through the inherits chain. Undeclared arguments go into **pageargs as usual. [ticket:116] - defs declared within a <%namespace> section, an uncommon feature, have been improved. The defs no longer get doubly-rendered in the body() scope, and now allow local variable assignment without breakage. [ticket:109] - Windows paths are handled correctly if a Template is passed only an absolute filename (i.e. with c: drive etc.) and no URI - the URI is converted to a forward-slash path and module_directory is treated as a windows path. [ticket:128] - TemplateLookup raises TopLevelLookupException for a given path that is a directory, not a filename, instead of passing through to the template to generate IOError. [ticket:73] 0.2.6 - Fix mako function decorators to preserve the original function's name in all cases. Patch from Scott Torborg. - Support the <%namespacename:defname> syntax in the babel extractor. [ticket:118] - Further fixes to unicode handling of .py files with the html_error_template. [ticket:88] 0.2.5 - Added a "decorator" kw argument to <%def>, allows custom decoration functions to wrap rendering callables. Mainly intended for custom caching algorithms, not sure what other uses there may be (but there may be). Examples are in the "filtering" docs. - When Mako creates subdirectories in which to store templates, it uses the more permissive mode of 0775 instead of 0750, helping out with certain multi-process scenarios. Note that the mode is always subject to the restrictions of the existing umask. [ticket:101] - Fixed namespace.__getattr__() to raise AttributeError on attribute not found instead of RuntimeError. [ticket:104] - Added last_modified accessor to Template, returns the time.time() when the module was created. [ticket:97] - Fixed lexing support for whitespace around '=' sign in defs. [ticket:102] - Removed errant "lower()" in the lexer which was causing tags to compile with case-insensitive names, thus messing up custom <%call> names. [ticket:108] - added "mako.__version__" attribute to the base module. [ticket:110] 0.2.4 - Fixed compatibility with Jython 2.5b1. 0.2.3 - the <%namespacename:defname> syntax described at http://techspot.zzzeek.org/?p=28 has now been added as a built in syntax, and is recommended as a more modern syntax versus <%call expr="expression">. The %call tag itself will always remain, with <%namespacename:defname> presenting a more HTML-like alternative to calling defs, both plain and nested. Many examples of the new syntax are in the "Calling a def with embedded content" section of the docs. - added support for Jython 2.5. - cache module now uses Beaker's CacheManager object directly, so that all cache types are included. memcached is available as both "ext:memcached" and "memcached", the latter for backwards compatibility. - added "cache" accessor to Template, Namespace. e.g. ${local.cache.get('somekey')} or template.cache.invalidate_body() - added "cache_enabled=True" flag to Template, TemplateLookup. Setting this to False causes cache operations to "pass through" and execute every time; this flag should be integrated in Pylons with its own cache_enabled configuration setting. - the Cache object now supports invalidate_def(name), invalidate_body(), invalidate_closure(name), invalidate(key), which will remove the given key from the cache, if it exists. The cache arguments (i.e. storage type) are derived from whatever has been already persisted for that template. [ticket:92] - For cache changes to work fully, Beaker 1.1 is required. 1.0.1 and up will work as well with the exception of cache expiry. Note that Beaker 1.1 is **required** for applications which use dynamically generated keys, since previous versions will permanently store state in memory for each individual key, thus consuming all available memory for an arbitrarily large number of distinct keys. - fixed bug whereby an <%included> template with <%page> args named the same as a __builtin__ would not honor the default value specified in <%page> [ticket:93] - fixed the html_error_template not handling tracebacks from normal .py files with a magic encoding comment [ticket:88] - RichTraceback() now accepts an optional traceback object to be used in place of sys.exc_info()[2]. html_error_template() and text_error_template() accept an optional render()-time argument "traceback" which is passed to the RichTraceback object. - added ModuleTemplate class, which allows the construction of a Template given a Python module generated by a previous Template. This allows Python modules alone to be used as templates with no compilation step. Source code and template source are optional but allow error reporting to work correctly. - fixed Python 2.3 compat. in mako.pyparser [ticket:90] - fix Babel 0.9.3 compatibility; stripping comment tags is now optional (and enabled by default). 0.2.2 - cached blocks now use the current context when rendering an expired section, instead of the original context passed in [ticket:87] - fixed a critical issue regarding caching, whereby a cached block would raise an error when called within a cache-refresh operation that was initiated after the initiating template had completed rendering. 0.2.1 - fixed bug where 'output_encoding' parameter would prevent render_unicode() from returning a unicode object. - bumped magic number, which forces template recompile for this version (fixes incompatible compile symbols from 0.1 series). - added a few docs for cache options, specifically those that help with memcached. 0.2.0 - Speed improvements (as though we needed them, but people contributed and there you go): - added "bytestring passthru" mode, via `disable_unicode=True` argument passed to Template or TemplateLookup. All unicode-awareness and filtering is turned off, and template modules are generated with the appropriate magic encoding comment. In this mode, template expressions can only receive raw bytestrings or Unicode objects which represent straight ASCII, and render_unicode() may not be used if multibyte characters are present. When enabled, speed improvement around 10-20%. [ticket:77] (courtesy anonymous guest) - inlined the "write" function of Context into a local template variable. This affords a 12-30% speedup in template render time. (idea courtesy same anonymous guest) [ticket:76] - New Features, API changes: - added "attr" accessor to namespaces. Returns attributes configured as module level attributes, i.e. within <%! %> sections. [ticket:62] i.e.: # somefile.html <%! foo = 27 %> # some other template <%namespace name="myns" file="somefile.html"/> ${myns.attr.foo} The slight backwards incompatibility here is, you can't have namespace defs named "attr" since the "attr" descriptor will occlude it. - cache_key argument can now render arguments passed directly to the %page or %def, i.e. <%def name="foo(x)" cached="True" cache_key="${x}"/> [ticket:78] - some functions on Context are now private: _push_buffer(), _pop_buffer(), caller_stack._push_frame(), caller_stack._pop_frame(). - added a runner script "mako-render" which renders standard input as a template to stdout [ticket:81] [ticket:56] - Bugfixes: - can now use most names from __builtins__ as variable names without explicit declaration (i.e. 'id', 'exception', 'range', etc.) [ticket:83] [ticket:84] - can also use builtin names as local variable names (i.e. dict, locals) (came from fix for [ticket:84]) - fixed bug in python generation when variable names are used with identifiers like "else", "finally", etc. inside them [ticket:68] - fixed codegen bug which occured when using <%page> level caching, combined with an expression-based cache_key, combined with the usage of <%namespace import="*"/> - fixed lexer exceptions not cleaning up temporary files, which could lead to a maximum number of file descriptors used in the process [ticket:69] - fixed issue with inline format_exceptions that was producing blank exception pages when an inheriting template is present [ticket:71] - format_exceptions will apply the encoding options of html_error_template() to the buffered output - rewrote the "whitespace adjuster" function to work with more elaborate combinations of quotes and comments [ticket:75] 0.1.10 - fixed propagation of 'caller' such that nested %def calls within a <%call> tag's argument list propigates 'caller' to the %call function itself (propigates to the inner calls too, this is a slight side effect which previously existed anyway) - fixed bug where local.get_namespace() could put an incorrect "self" in the current context - fixed another namespace bug where the namespace functions did not have access to the correct context containing their 'self' and 'parent' 0.1.9 - filters.Decode filter can also accept a non-basestring object and will call str() + unicode() on it [ticket:47] - comments can be placed at the end of control lines, i.e. if foo: # a comment, [ticket:53], thanks to Paul Colomiets - fixed expressions and page tag arguments and with embedded newlines in CRLF templates, follow up to [ticket:16], thanks Eric Woroshow - added an IOError catch for source file not found in RichTraceback exception reporter [ticket:51] 0.1.8 - variable names declared in render methods by internal codegen prefixed by "__M_" to prevent name collisions with user code - added a Babel (http://babel.edgewall.org/) extractor entry point, allowing extraction of gettext messages directly from mako templates via Babel [ticket:45] - fix to turbogears plugin to work with dot-separated names (i.e. load_template('foo.bar')). also takes file extension as a keyword argument (default is 'mak'). - more tg fix: fixed [ticket:35], allowing string-based templates with tgplugin even if non-compatible args were sent 0.1.7 - one small fix to the unit tests to support python 2.3 - a slight hack to how cache.py detects Beaker's memcached, works around unexplained import behavior observed on some python 2.3 installations 0.1.6 - caching is now supplied directly by Beaker, which has all of MyghtyUtils merged into it now. The latest Beaker (0.7.1) also fixes a bug related to how Mako was using the cache API. - fix to module_directory path generation when the path is "./" [ticket:34] - TGPlugin passes options to string-based templates [ticket:35] - added an explicit stack frame step to template runtime, which allows much simpler and hopefully bug-free tracking of 'caller', fixes #28 - if plain Python defs are used with <%call>, a decorator @runtime.supports_callable exists to ensure that the "caller" stack is properly handled for the def. - fix to RichTraceback and exception reporting to get template source code as a unicode object #37 - html_error_template includes options "full=True", "css=True" which control generation of HTML tags, CSS [ticket:39] - added the 'encoding_errors' parameter to Template/TemplateLookup for specifying the error handler associated with encoding to 'output_encoding' [ticket:40] - the Template returned by html_error_template now defaults to output_encoding=sys.getdefaultencoding(), encoding_errors='htmlentityreplace' [ticket:37] - control lines, i.e. % lines, support backslashes to continue long lines (#32) - fixed codegen bug when defining <%def> within <%call> within <%call> - leading utf-8 BOM in template files is honored according to pep-0263 0.1.5 - AST expression generation - added in just about everything expression-wise from the AST module [ticket:26] - AST parsing, properly detects imports of the form "import foo.bar" [ticket:27] - fix to lexing of <%docs> tag nested in other tags - fix to context-arguments inside of <%include> tag which broke during 0.1.4 [ticket:29] - added "n" filter, disables *all* filters normally applied to an expression via <%page> or default_filters (but not those within the filter) - added buffer_filters argument, defines filters applied to the return value of buffered/cached/filtered %defs, after all filters defined with the %def itself have been applied. allows the creation of default expression filters that let the output of return-valued %defs "opt out" of that filtering via passing special attributes or objects. 0.1.4 - got defs-within-defs to be cacheable - fixes to code parsing/whitespace adjusting where plain python comments may contain quote characters [ticket:23] - fix to variable scoping for identifiers only referenced within functions - added a path normalization step to lookup so URIs like "/foo/bar/../etc/../foo" pre-process the ".." tokens before checking the filesystem - fixed/improved "caller" semantics so that undefined caller is "UNDEFINED", propigates __nonzero__ method so it evaulates to False if not present, True otherwise. this way you can say % if caller:\n ${caller.body()}\n% endif - <%include> has an "args" attribute that can pass arguments to the called template (keyword arguments only, must be declared in that page's <%page> tag.) - <%include> plus arguments is also programmatically available via self.include_file(, **kwargs) - further escaping added for multibyte expressions in %def, %call attributes [ticket:24] 0.1.3 - ***Small Syntax Change*** - the single line comment character is now *two* hash signs, i.e. "## this is a comment". This avoids a common collection with CSS selectors. - the magic "coding" comment (i.e. # coding:utf-8) will still work with either one "#" sign or two for now; two is preferred going forward, i.e. ## coding:. - new multiline comment form: "<%doc> a comment " - UNDEFINED evaluates to False - improvement to scoping of "caller" variable when using <%call> tag - added lexer error for unclosed control-line (%) line - added "preprocessor" argument to Template, TemplateLookup - is a single callable or list of callables which will be applied to the template text before lexing. given the text as an argument, returns the new text. - added mako.ext.preprocessors package, contains one preprocessor so far: 'convert_comments', which will convert single # comments to the new ## format 0.1.2 - fix to parsing of code/expression blocks to insure that non-ascii characters, combined with a template that indicates a non-standard encoding, are expanded into backslash-escaped glyphs before being AST parsed [ticket:11] - all template lexing converts the template to unicode first, to immediately catch any encoding issues and ensure internal unicode representation. - added module_filename argument to Template to allow specification of a specific module file - added modulename_callable to TemplateLookup to allow a function to determine module filenames (takes filename, uri arguments). used for [ticket:14] - added optional input_encoding flag to Template, to allow sending a unicode() object with no magic encoding comment - "expression_filter" argument in <%page> applies only to expressions - added "default_filters" argument to Template, TemplateLookup. applies only to expressions, gets prepended to "expression_filter" arg from <%page>. defaults to ["unicode"], so that all expressions get stringified into u'' by default (this is what Mako already does). By setting to [], expressions are passed through raw. - added "imports" argument to Template, TemplateLookup. so you can predefine a list of import statements at the top of the template. can be used in conjunction with default_filters. - support for CRLF templates...whoops ! welcome to all the windows users. [ticket:16] - small fix to local variable propigation for locals that are conditionally declared - got "top level" def calls to work, i.e. template.get_def("somedef").render() 0.1.1 - buffet plugin supports string-based templates, allows ToscaWidgets to work [ticket:8] - AST parsing fixes: fixed TryExcept identifier parsing - removed textmate tmbundle from contrib and into separate SVN location; windows users cant handle those files, setuptools not very good at "pruning" certain directories - fix so that "cache_timeout" parameter is propigated - fix to expression filters so that string conversion (actually unicode) properly occurs before filtering - better error message when a lookup is attempted with a template that has no lookup - implemented "module" attribute for namespace - fix to code generation to correctly track multiple defs with the same name - "directories" can be passed to TemplateLookup as a scalar in which case it gets converted to a list [ticket:9] 0.1.0 Initial release. Mako-0.9.1/distribute_setup.py0000644000076500000240000003661512257136636017152 0ustar classicstaff00000000000000#!python """Bootstrap distribute installation If you want to use setuptools in your package's setup.py, just include this file in the same directory with it, and add this to the top of your setup.py:: from distribute_setup import use_setuptools use_setuptools() If you want to require a specific version of setuptools, set a download mirror, or use an alternate download directory, you can do so by supplying the appropriate options to ``use_setuptools()``. This file can also be run as a script to install or upgrade setuptools. """ import os import sys import time import fnmatch import tempfile import tarfile from distutils import log try: from site import USER_SITE except ImportError: USER_SITE = None try: import subprocess def _python_cmd(*args): args = (sys.executable,) + args return subprocess.call(args) == 0 except ImportError: # will be used for python 2.3 def _python_cmd(*args): args = (sys.executable,) + args # quoting arguments if windows if sys.platform == 'win32': def quote(arg): if ' ' in arg: return '"%s"' % arg return arg args = [quote(arg) for arg in args] return os.spawnl(os.P_WAIT, sys.executable, *args) == 0 DEFAULT_VERSION = "0.6.13" DEFAULT_URL = "http://pypi.python.org/packages/source/d/distribute/" SETUPTOOLS_FAKED_VERSION = "0.6c11" SETUPTOOLS_PKG_INFO = """\ Metadata-Version: 1.0 Name: setuptools Version: %s Summary: xxxx Home-page: xxx Author: xxx Author-email: xxx License: xxx Description: xxx """ % SETUPTOOLS_FAKED_VERSION def _install(tarball): # extracting the tarball tmpdir = tempfile.mkdtemp() log.warn('Extracting in %s', tmpdir) old_wd = os.getcwd() try: os.chdir(tmpdir) tar = tarfile.open(tarball) _extractall(tar) tar.close() # going in the directory subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0]) os.chdir(subdir) log.warn('Now working in %s', subdir) # installing log.warn('Installing Distribute') if not _python_cmd('setup.py', 'install'): log.warn('Something went wrong during the installation.') log.warn('See the error message above.') finally: os.chdir(old_wd) def _build_egg(egg, tarball, to_dir): # extracting the tarball tmpdir = tempfile.mkdtemp() log.warn('Extracting in %s', tmpdir) old_wd = os.getcwd() try: os.chdir(tmpdir) tar = tarfile.open(tarball) _extractall(tar) tar.close() # going in the directory subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0]) os.chdir(subdir) log.warn('Now working in %s', subdir) # building an egg log.warn('Building a Distribute egg in %s', to_dir) _python_cmd('setup.py', '-q', 'bdist_egg', '--dist-dir', to_dir) finally: os.chdir(old_wd) # returning the result log.warn(egg) if not os.path.exists(egg): raise IOError('Could not build the egg.') def _do_download(version, download_base, to_dir, download_delay): egg = os.path.join(to_dir, 'distribute-%s-py%d.%d.egg' % (version, sys.version_info[0], sys.version_info[1])) if not os.path.exists(egg): tarball = download_setuptools(version, download_base, to_dir, download_delay) _build_egg(egg, tarball, to_dir) sys.path.insert(0, egg) import setuptools setuptools.bootstrap_install_from = egg def use_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, download_delay=15, no_fake=True): # making sure we use the absolute path to_dir = os.path.abspath(to_dir) was_imported = 'pkg_resources' in sys.modules or \ 'setuptools' in sys.modules try: try: import pkg_resources if not hasattr(pkg_resources, '_distribute'): if not no_fake: _fake_setuptools() raise ImportError except ImportError: return _do_download(version, download_base, to_dir, download_delay) try: pkg_resources.require("distribute>="+version) return except pkg_resources.VersionConflict: e = sys.exc_info()[1] if was_imported: sys.stderr.write( "The required version of distribute (>=%s) is not available,\n" "and can't be installed while this script is running. Please\n" "install a more recent version first, using\n" "'easy_install -U distribute'." "\n\n(Currently using %r)\n" % (version, e.args[0])) sys.exit(2) else: del pkg_resources, sys.modules['pkg_resources'] # reload ok return _do_download(version, download_base, to_dir, download_delay) except pkg_resources.DistributionNotFound: return _do_download(version, download_base, to_dir, download_delay) finally: if not no_fake: _create_fake_setuptools_pkg_info(to_dir) def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, delay=15): """Download distribute from a specified location and return its filename `version` should be a valid distribute version number that is available as an egg for download under the `download_base` URL (which should end with a '/'). `to_dir` is the directory where the egg will be downloaded. `delay` is the number of seconds to pause before an actual download attempt. """ # making sure we use the absolute path to_dir = os.path.abspath(to_dir) try: from urllib.request import urlopen except ImportError: from urllib2 import urlopen tgz_name = "distribute-%s.tar.gz" % version url = download_base + tgz_name saveto = os.path.join(to_dir, tgz_name) src = dst = None if not os.path.exists(saveto): # Avoid repeated downloads try: log.warn("Downloading %s", url) src = urlopen(url) # Read/write all in one block, so we don't create a corrupt file # if the download is interrupted. data = src.read() dst = open(saveto, "wb") dst.write(data) finally: if src: src.close() if dst: dst.close() return os.path.realpath(saveto) def _no_sandbox(function): def __no_sandbox(*args, **kw): try: from setuptools.sandbox import DirectorySandbox if not hasattr(DirectorySandbox, '_old'): def violation(*args): pass DirectorySandbox._old = DirectorySandbox._violation DirectorySandbox._violation = violation patched = True else: patched = False except ImportError: patched = False try: return function(*args, **kw) finally: if patched: DirectorySandbox._violation = DirectorySandbox._old del DirectorySandbox._old return __no_sandbox def _patch_file(path, content): """Will backup the file then patch it""" existing_content = open(path).read() if existing_content == content: # already patched log.warn('Already patched.') return False log.warn('Patching...') _rename_path(path) f = open(path, 'w') try: f.write(content) finally: f.close() return True _patch_file = _no_sandbox(_patch_file) def _same_content(path, content): return open(path).read() == content def _rename_path(path): new_name = path + '.OLD.%s' % time.time() log.warn('Renaming %s into %s', path, new_name) os.rename(path, new_name) return new_name def _remove_flat_installation(placeholder): if not os.path.isdir(placeholder): log.warn('Unkown installation at %s', placeholder) return False found = False for file in os.listdir(placeholder): if fnmatch.fnmatch(file, 'setuptools*.egg-info'): found = True break if not found: log.warn('Could not locate setuptools*.egg-info') return log.warn('Removing elements out of the way...') pkg_info = os.path.join(placeholder, file) if os.path.isdir(pkg_info): patched = _patch_egg_dir(pkg_info) else: patched = _patch_file(pkg_info, SETUPTOOLS_PKG_INFO) if not patched: log.warn('%s already patched.', pkg_info) return False # now let's move the files out of the way for element in ('setuptools', 'pkg_resources.py', 'site.py'): element = os.path.join(placeholder, element) if os.path.exists(element): _rename_path(element) else: log.warn('Could not find the %s element of the ' 'Setuptools distribution', element) return True _remove_flat_installation = _no_sandbox(_remove_flat_installation) def _after_install(dist): log.warn('After install bootstrap.') placeholder = dist.get_command_obj('install').install_purelib _create_fake_setuptools_pkg_info(placeholder) def _create_fake_setuptools_pkg_info(placeholder): if not placeholder or not os.path.exists(placeholder): log.warn('Could not find the install location') return pyver = '%s.%s' % (sys.version_info[0], sys.version_info[1]) setuptools_file = 'setuptools-%s-py%s.egg-info' % \ (SETUPTOOLS_FAKED_VERSION, pyver) pkg_info = os.path.join(placeholder, setuptools_file) if os.path.exists(pkg_info): log.warn('%s already exists', pkg_info) return log.warn('Creating %s', pkg_info) f = open(pkg_info, 'w') try: f.write(SETUPTOOLS_PKG_INFO) finally: f.close() pth_file = os.path.join(placeholder, 'setuptools.pth') log.warn('Creating %s', pth_file) f = open(pth_file, 'w') try: f.write(os.path.join(os.curdir, setuptools_file)) finally: f.close() _create_fake_setuptools_pkg_info = _no_sandbox(_create_fake_setuptools_pkg_info) def _patch_egg_dir(path): # let's check if it's already patched pkg_info = os.path.join(path, 'EGG-INFO', 'PKG-INFO') if os.path.exists(pkg_info): if _same_content(pkg_info, SETUPTOOLS_PKG_INFO): log.warn('%s already patched.', pkg_info) return False _rename_path(path) os.mkdir(path) os.mkdir(os.path.join(path, 'EGG-INFO')) pkg_info = os.path.join(path, 'EGG-INFO', 'PKG-INFO') f = open(pkg_info, 'w') try: f.write(SETUPTOOLS_PKG_INFO) finally: f.close() return True _patch_egg_dir = _no_sandbox(_patch_egg_dir) def _before_install(): log.warn('Before install bootstrap.') _fake_setuptools() def _under_prefix(location): if 'install' not in sys.argv: return True args = sys.argv[sys.argv.index('install')+1:] for index, arg in enumerate(args): for option in ('--root', '--prefix'): if arg.startswith('%s=' % option): top_dir = arg.split('root=')[-1] return location.startswith(top_dir) elif arg == option: if len(args) > index: top_dir = args[index+1] return location.startswith(top_dir) if arg == '--user' and USER_SITE is not None: return location.startswith(USER_SITE) return True def _fake_setuptools(): log.warn('Scanning installed packages') try: import pkg_resources except ImportError: # we're cool log.warn('Setuptools or Distribute does not seem to be installed.') return ws = pkg_resources.working_set try: setuptools_dist = ws.find(pkg_resources.Requirement.parse('setuptools', replacement=False)) except TypeError: # old distribute API setuptools_dist = ws.find(pkg_resources.Requirement.parse('setuptools')) if setuptools_dist is None: log.warn('No setuptools distribution found') return # detecting if it was already faked setuptools_location = setuptools_dist.location log.warn('Setuptools installation detected at %s', setuptools_location) # if --root or --preix was provided, and if # setuptools is not located in them, we don't patch it if not _under_prefix(setuptools_location): log.warn('Not patching, --root or --prefix is installing Distribute' ' in another location') return # let's see if its an egg if not setuptools_location.endswith('.egg'): log.warn('Non-egg installation') res = _remove_flat_installation(setuptools_location) if not res: return else: log.warn('Egg installation') pkg_info = os.path.join(setuptools_location, 'EGG-INFO', 'PKG-INFO') if (os.path.exists(pkg_info) and _same_content(pkg_info, SETUPTOOLS_PKG_INFO)): log.warn('Already patched.') return log.warn('Patching...') # let's create a fake egg replacing setuptools one res = _patch_egg_dir(setuptools_location) if not res: return log.warn('Patched done.') _relaunch() def _relaunch(): log.warn('Relaunching...') # we have to relaunch the process # pip marker to avoid a relaunch bug if sys.argv[:3] == ['-c', 'install', '--single-version-externally-managed']: sys.argv[0] = 'setup.py' args = [sys.executable] + sys.argv sys.exit(subprocess.call(args)) def _extractall(self, path=".", members=None): """Extract all members from the archive to the current working directory and set owner, modification time and permissions on directories afterwards. `path' specifies a different directory to extract to. `members' is optional and must be a subset of the list returned by getmembers(). """ import copy import operator from tarfile import ExtractError directories = [] if members is None: members = self for tarinfo in members: if tarinfo.isdir(): # Extract directories with a safe mode. directories.append(tarinfo) tarinfo = copy.copy(tarinfo) tarinfo.mode = 448 # decimal for oct 0700 self.extract(tarinfo, path) # Reverse sort directories. if sys.version_info < (2, 4): def sorter(dir1, dir2): return cmp(dir1.name, dir2.name) directories.sort(sorter) directories.reverse() else: directories.sort(key=operator.attrgetter('name'), reverse=True) # Set correct owner, mtime and filemode on directories. for tarinfo in directories: dirpath = os.path.join(path, tarinfo.name) try: self.chown(tarinfo, dirpath) self.utime(tarinfo, dirpath) self.chmod(tarinfo, dirpath) except ExtractError: e = sys.exc_info()[1] if self.errorlevel > 1: raise else: self._dbg(1, "tarfile: %s" % e) def main(argv, version=DEFAULT_VERSION): """Install or upgrade setuptools and EasyInstall""" tarball = download_setuptools() _install(tarball) if __name__ == '__main__': main(sys.argv[1:]) Mako-0.9.1/doc/0000755000076500000240000000000012257137143013726 5ustar classicstaff00000000000000Mako-0.9.1/doc/_sources/0000755000076500000240000000000012257137143015550 5ustar classicstaff00000000000000Mako-0.9.1/doc/_sources/caching.txt0000644000076500000240000003302012257136636017711 0ustar classicstaff00000000000000.. _caching_toplevel: ======= Caching ======= Any template or component can be cached using the ``cache`` argument to the ``<%page>``, ``<%def>`` or ``<%block>`` directives: .. sourcecode:: mako <%page cached="True"/> template text The above template, after being executed the first time, will store its content within a cache that by default is scoped within memory. Subsequent calls to the template's :meth:`~.Template.render` method will return content directly from the cache. When the :class:`.Template` object itself falls out of scope, its corresponding cache is garbage collected along with the template. By default, caching requires that the `Beaker `_ package be installed on the system, however the mechanism of caching can be customized to use any third party or user defined system -- see :ref:`cache_plugins`. In addition to being available on the ``<%page>`` tag, the caching flag and all its options can be used with the ``<%def>`` tag as well: .. sourcecode:: mako <%def name="mycomp" cached="True" cache_timeout="60"> other text ... and equivalently with the ``<%block>`` tag, anonymous or named: .. sourcecode:: mako <%block cached="True" cache_timeout="60"> other text Cache Arguments =============== Mako has two cache arguments available on tags that are available in all cases. The rest of the arguments available are specific to a backend. The two generic tags arguments are: * ``cached="True"`` - enable caching for this ``<%page>``, ``<%def>``, or ``<%block>``. * ``cache_key`` - the "key" used to uniquely identify this content in the cache. Usually, this key is chosen automatically based on the name of the rendering callable (i.e. ``body`` when used in ``<%page>``, the name of the def when using ``<%def>``, the explicit or internally-generated name when using ``<%block>``). Using the ``cache_key`` parameter, the key can be overridden using a fixed or programmatically generated value. For example, here's a page that caches any page which inherits from it, based on the filename of the calling template: .. sourcecode:: mako <%page cached="True" cache_key="${self.filename}"/> ${next.body()} ## rest of template On a :class:`.Template` or :class:`.TemplateLookup`, the caching can be configured using these arguments: * ``cache_enabled`` - Setting this to ``False`` will disable all caching functionality when the template renders. Defaults to ``True``. e.g.: .. sourcecode:: python lookup = TemplateLookup( directories='/path/to/templates', cache_enabled = False ) * ``cache_impl`` - The string name of the cache backend to use. This defaults to ``'beaker'``, which has historically been the only cache backend supported by Mako. .. versionadded:: 0.6.0 For example, here's how to use the upcoming `dogpile.cache `_ backend: .. sourcecode:: python lookup = TemplateLookup( directories='/path/to/templates', cache_impl = 'dogpile.cache', cache_args = {'regions':my_dogpile_regions} ) * ``cache_args`` - A dictionary of cache parameters that will be consumed by the cache backend. See :ref:`beaker_backend` for examples. .. versionadded:: 0.6.0 Backend-Specific Cache Arguments -------------------------------- The ``<%page>``, ``<%def>``, and ``<%block>`` tags accept any named argument that starts with the prefix ``"cache_"``. Those arguments are then packaged up and passed along to the underlying caching implementation, minus the ``"cache_"`` prefix. The actual arguments understood are determined by the backend. * :ref:`beaker_backend` - Includes arguments understood by Beaker. * :ref:`dogpile.cache_backend` - Includes arguments understood by dogpile.cache. .. _beaker_backend: Using the Beaker Cache Backend ------------------------------ When using Beaker, new implementations will want to make usage of **cache regions** so that cache configurations can be maintained externally to templates. These configurations live under named "regions" that can be referred to within templates themselves. .. versionadded:: 0.6.0 Support for Beaker cache regions. For example, suppose we would like two regions. One is a "short term" region that will store content in a memory-based dictionary, expiring after 60 seconds. The other is a Memcached region, where values should expire in five minutes. To configure our :class:`.TemplateLookup`, first we get a handle to a :class:`beaker.cache.CacheManager`: .. sourcecode:: python from beaker.cache import CacheManager manager = CacheManager(cache_regions={ 'short_term':{ 'type': 'memory', 'expire': 60 }, 'long_term':{ 'type': 'ext:memcached', 'url': '127.0.0.1:11211', 'expire': 300 } }) lookup = TemplateLookup( directories=['/path/to/templates'], module_directory='/path/to/modules', cache_impl='beaker', cache_args={ 'manager':manager } ) Our templates can then opt to cache data in one of either region, using the ``cache_region`` argument. Such as using ``short_term`` at the ``<%page>`` level: .. sourcecode:: mako <%page cached="True" cache_region="short_term"> ## ... Or, ``long_term`` at the ``<%block>`` level: .. sourcecode:: mako <%block name="header" cached="True" cache_region="long_term"> other text The Beaker backend also works without regions. There are a variety of arguments that can be passed to the ``cache_args`` dictionary, which are also allowable in templates via the ``<%page>``, ``<%block>``, and ``<%def>`` tags specific to those sections. The values given override those specified at the :class:`.TemplateLookup` or :class:`.Template` level. With the possible exception of ``cache_timeout``, these arguments are probably better off staying at the template configuration level. Each argument specified as ``cache_XYZ`` in a template tag is specified without the ``cache_`` prefix in the ``cache_args`` dictionary: * ``cache_timeout`` - number of seconds in which to invalidate the cached data. After this timeout, the content is re-generated on the next call. Available as ``timeout`` in the ``cache_args`` dictionary. * ``cache_type`` - type of caching. ``'memory'``, ``'file'``, ``'dbm'``, or ``'ext:memcached'`` (note that the string ``memcached`` is also accepted by the dogpile.cache Mako plugin, though not by Beaker itself). Available as ``type`` in the ``cache_args`` dictionary. * ``cache_url`` - (only used for ``memcached`` but required) a single IP address or a semi-colon separated list of IP address of memcache servers to use. Available as ``url`` in the ``cache_args`` dictionary. * ``cache_dir`` - in the case of the ``'file'`` and ``'dbm'`` cache types, this is the filesystem directory with which to store data files. If this option is not present, the value of ``module_directory`` is used (i.e. the directory where compiled template modules are stored). If neither option is available an exception is thrown. Available as ``dir`` in the ``cache_args`` dictionary. .. _dogpile.cache_backend: Using the dogpile.cache Backend ------------------------------- `dogpile.cache`_ is a new replacement for Beaker. It provides a modernized, slimmed down interface and is generally easier to use than Beaker. As of this writing it has not yet been released. dogpile.cache includes its own Mako cache plugin -- see :mod:`dogpile.cache.plugins.mako_cache` in the dogpile.cache documentation. Programmatic Cache Access ========================= The :class:`.Template`, as well as any template-derived :class:`.Namespace`, has an accessor called ``cache`` which returns the :class:`.Cache` object for that template. This object is a facade on top of the underlying :class:`.CacheImpl` object, and provides some very rudimental capabilities, such as the ability to get and put arbitrary values: .. sourcecode:: mako <% local.cache.set("somekey", type="memory", "somevalue") %> Above, the cache associated with the ``local`` namespace is accessed and a key is placed within a memory cache. More commonly, the ``cache`` object is used to invalidate cached sections programmatically: .. sourcecode:: python template = lookup.get_template('/sometemplate.html') # invalidate the "body" of the template template.cache.invalidate_body() # invalidate an individual def template.cache.invalidate_def('somedef') # invalidate an arbitrary key template.cache.invalidate('somekey') You can access any special method or attribute of the :class:`.CacheImpl` itself using the :attr:`impl <.Cache.impl>` attribute: .. sourcecode:: python template.cache.impl.do_something_special() Note that using implementation-specific methods will mean you can't swap in a different kind of :class:`.CacheImpl` implementation at a later time. .. _cache_plugins: Cache Plugins ============= The mechanism used by caching can be plugged in using a :class:`.CacheImpl` subclass. This class implements the rudimental methods Mako needs to implement the caching API. Mako includes the :class:`.BeakerCacheImpl` class to provide the default implementation. A :class:`.CacheImpl` class is acquired by Mako using a ``pkg_resources`` entrypoint, using the name given as the ``cache_impl`` argument to :class:`.Template` or :class:`.TemplateLookup`. This entry point can be installed via the standard `setuptools`/``setup()`` procedure, underneath the `EntryPoint` group named ``"mako.cache"``. It can also be installed at runtime via a convenience installer :func:`.register_plugin` which accomplishes essentially the same task. An example plugin that implements a local dictionary cache: .. sourcecode:: python from mako.cache import Cacheimpl, register_plugin class SimpleCacheImpl(CacheImpl): def __init__(self, cache): super(SimpleCacheImpl, self).__init__(cache) self._cache = {} def get_or_create(self, key, creation_function, **kw): if key in self._cache: return self._cache[key] else: self._cache[key] = value = creation_function() return value def set(self, key, value, **kwargs): self._cache[key] = value def get(self, key, **kwargs): return self._cache.get(key) def invalidate(self, key, **kwargs): self._cache.pop(key, None) # optional - register the class locally register_plugin("simple", __name__, "SimpleCacheImpl") Enabling the above plugin in a template would look like: .. sourcecode:: python t = Template("mytemplate", file="mytemplate.html", cache_impl='simple') Guidelines for Writing Cache Plugins ------------------------------------ * The :class:`.CacheImpl` is created on a per-:class:`.Template` basis. The class should ensure that only data for the parent :class:`.Template` is persisted or returned by the cache methods. The actual :class:`.Template` is available via the ``self.cache.template`` attribute. The ``self.cache.id`` attribute, which is essentially the unique modulename of the template, is a good value to use in order to represent a unique namespace of keys specific to the template. * Templates only use the :meth:`.CacheImpl.get_or_create()` method in an implicit fashion. The :meth:`.CacheImpl.set`, :meth:`.CacheImpl.get`, and :meth:`.CacheImpl.invalidate` methods are only used in response to direct programmatic access to the corresponding methods on the :class:`.Cache` object. * :class:`.CacheImpl` will be accessed in a multithreaded fashion if the :class:`.Template` itself is used multithreaded. Care should be taken to ensure caching implementations are threadsafe. * A library like `Dogpile `_, which is a minimal locking system derived from Beaker, can be used to help implement the :meth:`.CacheImpl.get_or_create` method in a threadsafe way that can maximize effectiveness across multiple threads as well as processes. :meth:`.CacheImpl.get_or_create` is the key method used by templates. * All arguments passed to ``**kw`` come directly from the parameters inside the ``<%def>``, ``<%block>``, or ``<%page>`` tags directly, minus the ``"cache_"`` prefix, as strings, with the exception of the argument ``cache_timeout``, which is passed to the plugin as the name ``timeout`` with the value converted to an integer. Arguments present in ``cache_args`` on :class:`.Template` or :class:`.TemplateLookup` are passed directly, but are superseded by those present in the most specific template tag. * The directory where :class:`.Template` places module files can be acquired using the accessor ``self.cache.template.module_directory``. This directory can be a good place to throw cache-related work files, underneath a prefix like ``_my_cache_work`` so that name conflicts with generated modules don't occur. API Reference ============= .. autoclass:: mako.cache.Cache :members: :show-inheritance: .. autoclass:: mako.cache.CacheImpl :members: :show-inheritance: .. autofunction:: mako.cache.register_plugin .. autoclass:: mako.ext.beaker_cache.BeakerCacheImpl :members: :show-inheritance: Mako-0.9.1/doc/_sources/defs.txt0000644000076500000240000004245112257136636017246 0ustar classicstaff00000000000000.. _defs_toplevel: =============== Defs and Blocks =============== ``<%def>`` and ``<%block>`` are two tags that both demarcate any block of text and/or code. They both exist within generated Python as a callable function, i.e., a Python ``def``. They differ in their scope and calling semantics. Whereas ``<%def>`` provides a construct that is very much like a named Python ``def``, the ``<%block>`` is more layout oriented. Using Defs ========== The ``<%def>`` tag requires a ``name`` attribute, where the ``name`` references a Python function signature: .. sourcecode:: mako <%def name="hello()"> hello world To invoke the ``<%def>``, it is normally called as an expression: .. sourcecode:: mako the def: ${hello()} If the ``<%def>`` is not nested inside of another ``<%def>``, it's known as a **top level def** and can be accessed anywhere in the template, including above where it was defined. All defs, top level or not, have access to the current contextual namespace in exactly the same way their containing template does. Suppose the template below is executed with the variables ``username`` and ``accountdata`` inside the context: .. sourcecode:: mako Hello there ${username}, how are ya. Lets see what your account says: ${account()} <%def name="account()"> Account for ${username}:
% for row in accountdata: Value: ${row}
% endfor The ``username`` and ``accountdata`` variables are present within the main template body as well as the body of the ``account()`` def. Since defs are just Python functions, you can define and pass arguments to them as well: .. sourcecode:: mako ${account(accountname='john')} <%def name="account(accountname, type='regular')"> account name: ${accountname}, type: ${type} When you declare an argument signature for your def, they are required to follow normal Python conventions (i.e., all arguments are required except keyword arguments with a default value). This is in contrast to using context-level variables, which evaluate to ``UNDEFINED`` if you reference a name that does not exist. Calling Defs from Other Files ----------------------------- Top level ``<%def>``\ s are **exported** by your template's module, and can be called from the outside; including from other templates, as well as normal Python code. Calling a ``<%def>`` from another template is something like using an ``<%include>`` -- except you are calling a specific function within the template, not the whole template. The remote ``<%def>`` call is also a little bit like calling functions from other modules in Python. There is an "import" step to pull the names from another template into your own template; then the function or functions are available. To import another template, use the ``<%namespace>`` tag: .. sourcecode:: mako <%namespace name="mystuff" file="mystuff.html"/> The above tag adds a local variable ``mystuff`` to the current scope. Then, just call the defs off of ``mystuff``: .. sourcecode:: mako ${mystuff.somedef(x=5,y=7)} The ``<%namespace>`` tag also supports some of the other semantics of Python's ``import`` statement, including pulling names into the local variable space, or using ``*`` to represent all names, using the ``import`` attribute: .. sourcecode:: mako <%namespace file="mystuff.html" import="foo, bar"/> This is just a quick intro to the concept of a **namespace**, which is a central Mako concept that has its own chapter in these docs. For more detail and examples, see :ref:`namespaces_toplevel`. Calling Defs Programmatically ----------------------------- You can call defs programmatically from any :class:`.Template` object using the :meth:`~.Template.get_def()` method, which returns a :class:`.DefTemplate` object. This is a :class:`.Template` subclass which the parent :class:`.Template` creates, and is usable like any other template: .. sourcecode:: python from mako.template import Template template = Template(""" <%def name="hi(name)"> hi ${name}! <%def name="bye(name)"> bye ${name}! """) print template.get_def("hi").render(name="ed") print template.get_def("bye").render(name="ed") Defs within Defs ---------------- The def model follows regular Python rules for closures. Declaring ``<%def>`` inside another ``<%def>`` declares it within the parent's **enclosing scope**: .. sourcecode:: mako <%def name="mydef()"> <%def name="subdef()"> a sub def i'm the def, and the subcomponent is ${subdef()} Just like Python, names that exist outside the inner ``<%def>`` exist inside it as well: .. sourcecode:: mako <% x = 12 %> <%def name="outer()"> <% y = 15 %> <%def name="inner()"> inner, x is ${x}, y is ${y} outer, x is ${x}, y is ${y} Assigning to a name inside of a def declares that name as local to the scope of that def (again, like Python itself). This means the following code will raise an error: .. sourcecode:: mako <% x = 10 %> <%def name="somedef()"> ## error ! somedef, x is ${x} <% x = 27 %> ...because the assignment to ``x`` declares ``x`` as local to the scope of ``somedef``, rendering the "outer" version unreachable in the expression that tries to render it. .. _defs_with_content: Calling a Def with Embedded Content and/or Other Defs ----------------------------------------------------- A flip-side to def within def is a def call with content. This is where you call a def, and at the same time declare a block of content (or multiple blocks) that can be used by the def being called. The main point of such a call is to create custom, nestable tags, just like any other template language's custom-tag creation system -- where the external tag controls the execution of the nested tags and can communicate state to them. Only with Mako, you don't have to use any external Python modules, you can define arbitrarily nestable tags right in your templates. To achieve this, the target def is invoked using the form ``<%namepacename:defname>`` instead of the normal ``${}`` syntax. This syntax, introduced in Mako 0.2.3, is functionally equivalent to another tag known as ``%call``, which takes the form ``<%call expr='namespacename.defname(args)'>``. While ``%call`` is available in all versions of Mako, the newer style is probably more familiar looking. The ``namespace`` portion of the call is the name of the **namespace** in which the def is defined -- in the most simple cases, this can be ``local`` or ``self`` to reference the current template's namespace (the difference between ``local`` and ``self`` is one of inheritance -- see :ref:`namespaces_builtin` for details). When the target def is invoked, a variable ``caller`` is placed in its context which contains another namespace containing the body and other defs defined by the caller. The body itself is referenced by the method ``body()``. Below, we build a ``%def`` that operates upon ``caller.body()`` to invoke the body of the custom tag: .. sourcecode:: mako <%def name="buildtable()">
${caller.body()}
<%self:buildtable> I am the table body. This produces the output (whitespace formatted): .. sourcecode:: html
I am the table body.
Using the older ``%call`` syntax looks like: .. sourcecode:: mako <%def name="buildtable()">
${caller.body()}
<%call expr="buildtable()"> I am the table body. The ``body()`` can be executed multiple times or not at all. This means you can use def-call-with-content to build iterators, conditionals, etc: .. sourcecode:: mako <%def name="lister(count)"> % for x in range(count): ${caller.body()} % endfor <%self:lister count="${3}"> hi Produces: .. sourcecode:: html hi hi hi Notice above we pass ``3`` as a Python expression, so that it remains as an integer. A custom "conditional" tag: .. sourcecode:: mako <%def name="conditional(expression)"> % if expression: ${caller.body()} % endif <%self:conditional expression="${4==4}"> i'm the result Produces: .. sourcecode:: html i'm the result But that's not all. The ``body()`` function also can handle arguments, which will augment the local namespace of the body callable. The caller must define the arguments which it expects to receive from its target def using the ``args`` attribute, which is a comma-separated list of argument names. Below, our ``<%def>`` calls the ``body()`` of its caller, passing in an element of data from its argument: .. sourcecode:: mako <%def name="layoutdata(somedata)"> % for item in somedata: % for col in item: % endfor % endfor
${caller.body(col=col)}
<%self:layoutdata somedata="${[[1,2,3],[4,5,6],[7,8,9]]}" args="col">\ Body data: ${col}\ Produces: .. sourcecode:: html
Body data: 1 Body data: 2 Body data: 3
Body data: 4 Body data: 5 Body data: 6
Body data: 7 Body data: 8 Body data: 9
You don't have to stick to calling just the ``body()`` function. The caller can define any number of callables, allowing the ``<%call>`` tag to produce whole layouts: .. sourcecode:: mako <%def name="layout()"> ## a layout def
${caller.header()}
${caller.body()}
## calls the layout def <%self:layout> <%def name="header()"> I am the header <%def name="sidebar()">
  • sidebar 1
  • sidebar 2
this is the body The above layout would produce: .. sourcecode:: html
I am the header
this is the body
The number of things you can do with ``<%call>`` and/or the ``<%namespacename:defname>`` calling syntax is enormous. You can create form widget libraries, such as an enclosing ``
`` tag and nested HTML input elements, or portable wrapping schemes using ``
`` or other elements. You can create tags that interpret rows of data, such as from a database, providing the individual columns of each row to a ``body()`` callable which lays out the row any way it wants. Basically anything you'd do with a "custom tag" or tag library in some other system, Mako provides via ``<%def>`` tags and plain Python callables which are invoked via ``<%namespacename:defname>`` or ``<%call>``. .. _blocks: Using Blocks ============ The ``<%block>`` tag introduces some new twists on the ``<%def>`` tag which make it more closely tailored towards layout. .. versionadded:: 0.4.1 An example of a block: .. sourcecode:: mako <%block> this is a block. In the above example, we define a simple block. The block renders its content in the place that it's defined. Since the block is called for us, it doesn't need a name and the above is referred to as an **anonymous block**. So the output of the above template will be: .. sourcecode:: html this is a block. So in fact the above block has absolutely no effect. Its usefulness comes when we start using modifiers. Such as, we can apply a filter to our block: .. sourcecode:: mako <%block filter="h"> this is some escaped html. or perhaps a caching directive: .. sourcecode:: mako <%block cached="True" cache_timeout="60"> This content will be cached for 60 seconds. Blocks also work in iterations, conditionals, just like defs: .. sourcecode:: mako % if some_condition: <%block>condition is met % endif While the block renders at the point it is defined in the template, the underlying function is present in the generated Python code only once, so there's no issue with placing a block inside of a loop or similar. Anonymous blocks are defined as closures in the local rendering body, so have access to local variable scope: .. sourcecode:: mako % for i in range(1, 4): <%block>i is ${i} % endfor Using Named Blocks ------------------ Possibly the more important area where blocks are useful is when we do actually give them names. Named blocks are tailored to behave somewhat closely to Jinja2's block tag, in that they define an area of a layout which can be overridden by an inheriting template. In sharp contrast to the ``<%def>`` tag, the name given to a block is global for the entire template regardless of how deeply it's nested: .. sourcecode:: mako <%block name="header"> <%block name="title">Title</%block> ${next.body()} The above example has two named blocks "``header``" and "``title``", both of which can be referred to by an inheriting template. A detailed walkthrough of this usage can be found at :ref:`inheritance_toplevel`. Note above that named blocks don't have any argument declaration the way defs do. They still implement themselves as Python functions, however, so they can be invoked additional times beyond their initial definition: .. sourcecode:: mako
<%block name="pagecontrol"> previous page | next page ## some content
${pagecontrol()}
The content referenced by ``pagecontrol`` above will be rendered both above and below the ```` tags. To keep things sane, named blocks have restrictions that defs do not: * The ``<%block>`` declaration cannot have any argument signature. * The name of a ``<%block>`` can only be defined once in a template -- an error is raised if two blocks of the same name occur anywhere in a single template, regardless of nesting. A similar error is raised if a top level def shares the same name as that of a block. * A named ``<%block>`` cannot be defined within a ``<%def>``, or inside the body of a "call", i.e. ``<%call>`` or ``<%namespacename:defname>`` tag. Anonymous blocks can, however. Using Page Arguments in Named Blocks ------------------------------------ A named block is very much like a top level def. It has a similar restriction to these types of defs in that arguments passed to the template via the ``<%page>`` tag aren't automatically available. Using arguments with the ``<%page>`` tag is described in the section :ref:`namespaces_body`, and refers to scenarios such as when the ``body()`` method of a template is called from an inherited template passing arguments, or the template is invoked from an ``<%include>`` tag with arguments. To allow a named block to share the same arguments passed to the page, the ``args`` attribute can be used: .. sourcecode:: mako <%page args="post"/> <%block name="post_prose" args="post"> ${post.content} Where above, if the template is called via a directive like ``<%include file="post.mako" args="post=post" />``, the ``post`` variable is available both in the main body as well as the ``post_prose`` block. Similarly, the ``**pageargs`` variable is present, in named blocks only, for those arguments not explicit in the ``<%page>`` tag: .. sourcecode:: mako <%block name="post_prose"> ${pageargs['post'].content} The ``args`` attribute is only allowed with named blocks. With anonymous blocks, the Python function is always rendered in the same scope as the call itself, so anything available directly outside the anonymous block is available inside as well. Mako-0.9.1/doc/_sources/filtering.txt0000644000076500000240000002442512257136636020311 0ustar classicstaff00000000000000.. _filtering_toplevel: ======================= Filtering and Buffering ======================= Expression Filtering ==================== As described in the chapter :ref:`syntax_toplevel`, the "``|``" operator can be applied to a "``${}``" expression to apply escape filters to the output: .. sourcecode:: mako ${"this is some text" | u} The above expression applies URL escaping to the expression, and produces ``this+is+some+text``. The built-in escape flags are: * ``u`` : URL escaping, provided by ``urllib.quote_plus(string.encode('utf-8'))`` * ``h`` : HTML escaping, provided by ``markupsafe.escape(string)`` .. versionadded:: 0.3.4 Prior versions use ``cgi.escape(string, True)``. * ``x`` : XML escaping * ``trim`` : whitespace trimming, provided by ``string.strip()`` * ``entity`` : produces HTML entity references for applicable strings, derived from ``htmlentitydefs`` * ``unicode`` (``str`` on Python 3): produces a Python unicode string (this function is applied by default) * ``decode.``: decode input into a Python unicode with the specified encoding * ``n`` : disable all default filtering; only filters specified in the local expression tag will be applied. To apply more than one filter, separate them by a comma: .. sourcecode:: mako ${" some value " | h,trim} The above produces ``<tag>some value</tag>``, with no leading or trailing whitespace. The HTML escaping function is applied first, the "trim" function second. Naturally, you can make your own filters too. A filter is just a Python function that accepts a single string argument, and returns the filtered result. The expressions after the ``|`` operator draw upon the local namespace of the template in which they appear, meaning you can define escaping functions locally: .. sourcecode:: mako <%! def myescape(text): return "" + text + "" %> Here's some tagged text: ${"text" | myescape} Or from any Python module: .. sourcecode:: mako <%! import myfilters %> Here's some tagged text: ${"text" | myfilters.tagfilter} A page can apply a default set of filters to all expression tags using the ``expression_filter`` argument to the ``%page`` tag: .. sourcecode:: mako <%page expression_filter="h"/> Escaped text: ${"some html"} Result: .. sourcecode:: html Escaped text: <html>some html</html> .. _filtering_default_filters: The ``default_filters`` Argument -------------------------------- In addition to the ``expression_filter`` argument, the ``default_filters`` argument to both :class:`.Template` and :class:`.TemplateLookup` can specify filtering for all expression tags at the programmatic level. This array-based argument, when given its default argument of ``None``, will be internally set to ``["unicode"]`` (or ``["str"]`` on Python 3), except when ``disable_unicode=True`` is set in which case it defaults to ``["str"]``: .. sourcecode:: python t = TemplateLookup(directories=['/tmp'], default_filters=['unicode']) To replace the usual ``unicode``/``str`` function with a specific encoding, the ``decode`` filter can be substituted: .. sourcecode:: python t = TemplateLookup(directories=['/tmp'], default_filters=['decode.utf8']) To disable ``default_filters`` entirely, set it to an empty list: .. sourcecode:: python t = TemplateLookup(directories=['/tmp'], default_filters=[]) Any string name can be added to ``default_filters`` where it will be added to all expressions as a filter. The filters are applied from left to right, meaning the leftmost filter is applied first. .. sourcecode:: python t = Template(templatetext, default_filters=['unicode', 'myfilter']) To ease the usage of ``default_filters`` with custom filters, you can also add imports (or other code) to all templates using the ``imports`` argument: .. sourcecode:: python t = TemplateLookup(directories=['/tmp'], default_filters=['unicode', 'myfilter'], imports=['from mypackage import myfilter']) The above will generate templates something like this: .. sourcecode:: python # .... from mypackage import myfilter def render_body(context): context.write(myfilter(unicode("some text"))) Turning off Filtering with the ``n`` Filter ------------------------------------------- In all cases the special ``n`` filter, used locally within an expression, will **disable** all filters declared in the ``<%page>`` tag as well as in ``default_filters``. Such as: .. sourcecode:: mako ${'myexpression' | n} will render ``myexpression`` with no filtering of any kind, and: .. sourcecode:: mako ${'myexpression' | n,trim} will render ``myexpression`` using the ``trim`` filter only. Filtering Defs and Blocks ========================= The ``%def`` and ``%block`` tags have an argument called ``filter`` which will apply the given list of filter functions to the output of the ``%def``: .. sourcecode:: mako <%def name="foo()" filter="h, trim"> this is bold When the ``filter`` attribute is applied to a def as above, the def is automatically **buffered** as well. This is described next. Buffering ========= One of Mako's central design goals is speed. To this end, all of the textual content within a template and its various callables is by default piped directly to the single buffer that is stored within the :class:`.Context` object. While this normally is easy to miss, it has certain side effects. The main one is that when you call a def using the normal expression syntax, i.e. ``${somedef()}``, it may appear that the return value of the function is the content it produced, which is then delivered to your template just like any other expression substitution, except that normally, this is not the case; the return value of ``${somedef()}`` is simply the empty string ``''``. By the time you receive this empty string, the output of ``somedef()`` has been sent to the underlying buffer. You may not want this effect, if for example you are doing something like this: .. sourcecode:: mako ${" results " + somedef() + " more results "} If the ``somedef()`` function produced the content "``somedef's results``", the above template would produce this output: .. sourcecode:: html somedef's results results more results This is because ``somedef()`` fully executes before the expression returns the results of its concatenation; the concatenation in turn receives just the empty string as its middle expression. Mako provides two ways to work around this. One is by applying buffering to the ``%def`` itself: .. sourcecode:: mako <%def name="somedef()" buffered="True"> somedef's results The above definition will generate code similar to this: .. sourcecode:: python def somedef(): context.push_buffer() try: context.write("somedef's results") finally: buf = context.pop_buffer() return buf.getvalue() So that the content of ``somedef()`` is sent to a second buffer, which is then popped off the stack and its value returned. The speed hit inherent in buffering the output of a def is also apparent. Note that the ``filter`` argument on ``%def`` also causes the def to be buffered. This is so that the final content of the ``%def`` can be delivered to the escaping function in one batch, which reduces method calls and also produces more deterministic behavior for the filtering function itself, which can possibly be useful for a filtering function that wishes to apply a transformation to the text as a whole. The other way to buffer the output of a def or any Mako callable is by using the built-in ``capture`` function. This function performs an operation similar to the above buffering operation except it is specified by the caller. .. sourcecode:: mako ${" results " + capture(somedef) + " more results "} Note that the first argument to the ``capture`` function is **the function itself**, not the result of calling it. This is because the ``capture`` function takes over the job of actually calling the target function, after setting up a buffered environment. To send arguments to the function, just send them to ``capture`` instead: .. sourcecode:: mako ${capture(somedef, 17, 'hi', use_paging=True)} The above call is equivalent to the unbuffered call: .. sourcecode:: mako ${somedef(17, 'hi', use_paging=True)} Decorating ========== .. versionadded:: 0.2.5 Somewhat like a filter for a ``%def`` but more flexible, the ``decorator`` argument to ``%def`` allows the creation of a function that will work in a similar manner to a Python decorator. The function can control whether or not the function executes. The original intent of this function is to allow the creation of custom cache logic, but there may be other uses as well. ``decorator`` is intended to be used with a regular Python function, such as one defined in a library module. Here we'll illustrate the python function defined in the template for simplicities' sake: .. sourcecode:: mako <%! def bar(fn): def decorate(context, *args, **kw): context.write("BAR") fn(*args, **kw) context.write("BAR") return '' return decorate %> <%def name="foo()" decorator="bar"> this is foo ${foo()} The above template will return, with more whitespace than this, ``"BAR this is foo BAR"``. The function is the render callable itself (or possibly a wrapper around it), and by default will write to the context. To capture its output, use the :func:`.capture` callable in the ``mako.runtime`` module (available in templates as just ``runtime``): .. sourcecode:: mako <%! def bar(fn): def decorate(context, *args, **kw): return "BAR" + runtime.capture(context, fn, *args, **kw) + "BAR" return decorate %> <%def name="foo()" decorator="bar"> this is foo ${foo()} The decorator can be used with top-level defs as well as nested defs, and blocks too. Note that when calling a top-level def from the :class:`.Template` API, i.e. ``template.get_def('somedef').render()``, the decorator has to write the output to the ``context``, i.e. as in the first example. The return value gets discarded. Mako-0.9.1/doc/_sources/index.txt0000644000076500000240000000037612257136636017434 0ustar classicstaff00000000000000Table of Contents ================= .. toctree:: :maxdepth: 2 usage syntax defs runtime namespaces inheritance filtering unicode caching Indices and Tables ------------------ * :ref:`genindex` * :ref:`search` Mako-0.9.1/doc/_sources/inheritance.txt0000644000076500000240000004003012257136636020605 0ustar classicstaff00000000000000.. _inheritance_toplevel: =========== Inheritance =========== .. note:: Most of the inheritance examples here take advantage of a feature that's new in Mako as of version 0.4.1 called the "block". This tag is very similar to the "def" tag but is more streamlined for usage with inheritance. Note that all of the examples here which use blocks can also use defs instead. Contrasting usages will be illustrated. Using template inheritance, two or more templates can organize themselves into an **inheritance chain**, where content and functions from all involved templates can be intermixed. The general paradigm of template inheritance is this: if a template ``A`` inherits from template ``B``, then template ``A`` agrees to send the executional control to template ``B`` at runtime (``A`` is called the **inheriting** template). Template ``B``, the **inherited** template, then makes decisions as to what resources from ``A`` shall be executed. In practice, it looks like this. Here's a hypothetical inheriting template, ``index.html``: .. sourcecode:: mako ## index.html <%inherit file="base.html"/> <%block name="header"> this is some header content this is the body content. And ``base.html``, the inherited template: .. sourcecode:: mako ## base.html
<%block name="header"/>
${self.body()} Here is a breakdown of the execution: #. When ``index.html`` is rendered, control immediately passes to ``base.html``. #. ``base.html`` then renders the top part of an HTML document, then invokes the ``<%block name="header">`` block. It invokes the underlying ``header()`` function off of a built-in namespace called ``self`` (this namespace was first introduced in the :doc:`Namespaces chapter ` in :ref:`namespace_self`). Since ``index.html`` is the topmost template and also defines a block called ``header``, it's this ``header`` block that ultimately gets executed -- instead of the one that's present in ``base.html``. #. Control comes back to ``base.html``. Some more HTML is rendered. #. ``base.html`` executes ``self.body()``. The ``body()`` function on all template-based namespaces refers to the main body of the template, therefore the main body of ``index.html`` is rendered. #. When ``<%block name="header">`` is encountered in ``index.html`` during the ``self.body()`` call, a conditional is checked -- does the current inherited template, i.e. ``base.html``, also define this block? If yes, the ``<%block>`` is **not** executed here -- the inheritance mechanism knows that the parent template is responsible for rendering this block (and in fact it already has). In other words a block only renders in its *basemost scope*. #. Control comes back to ``base.html``. More HTML is rendered, then the ``<%block name="footer">`` expression is invoked. #. The ``footer`` block is only defined in ``base.html``, so being the topmost definition of ``footer``, it's the one that executes. If ``index.html`` also specified ``footer``, then its version would **override** that of the base. #. ``base.html`` finishes up rendering its HTML and the template is complete, producing: .. sourcecode:: html
this is some header content
this is the body content. ...and that is template inheritance in a nutshell. The main idea is that the methods that you call upon ``self`` always correspond to the topmost definition of that method. Very much the way ``self`` works in a Python class, even though Mako is not actually using Python class inheritance to implement this functionality. (Mako doesn't take the "inheritance" metaphor too seriously; while useful to setup some commonly recognized semantics, a textual template is not very much like an object-oriented class construct in practice). Nesting Blocks ============== The named blocks defined in an inherited template can also be nested within other blocks. The name given to each block is globally accessible via any inheriting template. We can add a new block ``title`` to our ``header`` block: .. sourcecode:: mako ## base.html
<%block name="header">

<%block name="title"/>

${self.body()} The inheriting template can name either or both of ``header`` and ``title``, separately or nested themselves: .. sourcecode:: mako ## index.html <%inherit file="base.html"/> <%block name="header"> this is some header content ${parent.header()} <%block name="title"> this is the title this is the body content. Note when we overrode ``header``, we added an extra call ``${parent.header()}`` in order to invoke the parent's ``header`` block in addition to our own. That's described in more detail below, in :ref:`parent_namespace`. Rendering a Named Block Multiple Times ====================================== Recall from the section :ref:`blocks` that a named block is just like a ``<%def>``, with some different usage rules. We can call one of our named sections distinctly, for example a section that is used more than once, such as the title of a page: .. sourcecode:: mako ${self.title()} <%block name="header">

<%block name="title"/>

${self.body()} Where above an inheriting template can define ``<%block name="title">`` just once, and it will be used in the base template both in the ```` section as well as the ``<h2>``. But what about Defs? ==================== The previous example used the ``<%block>`` tag to produce areas of content to be overridden. Before Mako 0.4.1, there wasn't any such tag -- instead there was only the ``<%def>`` tag. As it turns out, named blocks and defs are largely interchangeable. The def simply doesn't call itself automatically, and has more open-ended naming and scoping rules that are more flexible and similar to Python itself, but less suited towards layout. The first example from this chapter using defs would look like: .. sourcecode:: mako ## index.html <%inherit file="base.html"/> <%def name="header()"> this is some header content </%def> this is the body content. And ``base.html``, the inherited template: .. sourcecode:: mako ## base.html <html> <body> <div class="header"> ${self.header()} </div> ${self.body()} <div class="footer"> ${self.footer()} </div> </body> </html> <%def name="header()"/> <%def name="footer()"> this is the footer </%def> Above, we illustrate that defs differ from blocks in that their definition and invocation are defined in two separate places, instead of at once. You can *almost* do exactly what a block does if you put the two together: .. sourcecode:: mako <div class="header"> <%def name="header()"></%def>${self.header()} </div> The ``<%block>`` is obviously more streamlined than the ``<%def>`` for this kind of usage. In addition, the above "inline" approach with ``<%def>`` does not work with nesting: .. sourcecode:: mako <head> <%def name="header()"> <title> ## this won't work ! <%def name="title()">default title</%def>${self.title()} ${self.header()} Where above, the ``title()`` def, because it's a def within a def, is not part of the template's exported namespace and will not be part of ``self``. If the inherited template did define its own ``title`` def at the top level, it would be called, but the "default title" above is not present at all on ``self`` no matter what. For this to work as expected you'd instead need to say: .. sourcecode:: mako <%def name="header()"> ${self.title()} ${self.header()} <%def name="title()"/> That is, ``title`` is defined outside of any other defs so that it is in the ``self`` namespace. It works, but the definition needs to be potentially far away from the point of render. A named block is always placed in the ``self`` namespace, regardless of nesting, so this restriction is lifted: .. sourcecode:: mako ## base.html <%block name="header"> <%block name="title"/> The above template defines ``title`` inside of ``header``, and an inheriting template can define one or both in **any** configuration, nested inside each other or not, in order for them to be used: .. sourcecode:: mako ## index.html <%inherit file="base.html"/> <%block name="title"> the title <%block name="header"> the header So while the ``<%block>`` tag lifts the restriction of nested blocks not being available externally, in order to achieve this it *adds* the restriction that all block names in a single template need to be globally unique within the template, and additionally that a ``<%block>`` can't be defined inside of a ``<%def>``. It's a more restricted tag suited towards a more specific use case than ``<%def>``. Using the ``next`` Namespace to Produce Content Wrapping ======================================================== Sometimes you have an inheritance chain that spans more than two templates. Or maybe you don't, but you'd like to build your system such that extra inherited templates can be inserted in the middle of a chain where they would be smoothly integrated. If each template wants to define its layout just within its main body, you can't just call ``self.body()`` to get at the inheriting template's body, since that is only the topmost body. To get at the body of the *next* template, you call upon the namespace ``next``, which is the namespace of the template **immediately following** the current template. Lets change the line in ``base.html`` which calls upon ``self.body()`` to instead call upon ``next.body()``: .. sourcecode:: mako ## base.html
<%block name="header"/>
${next.body()} Lets also add an intermediate template called ``layout.html``, which inherits from ``base.html``: .. sourcecode:: mako ## layout.html <%inherit file="base.html"/>
    <%block name="toolbar">
  • selection 1
  • selection 2
  • selection 3
${next.body()}
And finally change ``index.html`` to inherit from ``layout.html`` instead: .. sourcecode:: mako ## index.html <%inherit file="layout.html"/> ## .. rest of template In this setup, each call to ``next.body()`` will render the body of the next template in the inheritance chain (which can be written as ``base.html -> layout.html -> index.html``). Control is still first passed to the bottommost template ``base.html``, and ``self`` still references the topmost definition of any particular def. The output we get would be: .. sourcecode:: html
this is some header content
  • selection 1
  • selection 2
  • selection 3
this is the body content.
So above, we have the ````, ```` and ``header``/``footer`` layout of ``base.html``, we have the ``
    `` and ``mainlayout`` section of ``layout.html``, and the main body of ``index.html`` as well as its overridden ``header`` def. The ``layout.html`` template is inserted into the middle of the chain without ``base.html`` having to change anything. Without the ``next`` namespace, only the main body of ``index.html`` could be used; there would be no way to call ``layout.html``'s body content. .. _parent_namespace: Using the ``parent`` Namespace to Augment Defs ============================================== Lets now look at the other inheritance-specific namespace, the opposite of ``next`` called ``parent``. ``parent`` is the namespace of the template **immediately preceding** the current template. What's useful about this namespace is that defs or blocks can call upon their overridden versions. This is not as hard as it sounds and is very much like using the ``super`` keyword in Python. Lets modify ``index.html`` to augment the list of selections provided by the ``toolbar`` function in ``layout.html``: .. sourcecode:: mako ## index.html <%inherit file="layout.html"/> <%block name="header"> this is some header content <%block name="toolbar"> ## call the parent's toolbar first ${parent.toolbar()}
  • selection 4
  • selection 5
  • this is the body content. Above, we implemented a ``toolbar()`` function, which is meant to override the definition of ``toolbar`` within the inherited template ``layout.html``. However, since we want the content from that of ``layout.html`` as well, we call it via the ``parent`` namespace whenever we want it's content, in this case before we add our own selections. So the output for the whole thing is now: .. sourcecode:: html
    this is some header content
    • selection 1
    • selection 2
    • selection 3
    • selection 4
    • selection 5
    this is the body content.
    and you're now a template inheritance ninja! .. _inheritance_attr: Inheritable Attributes ====================== The :attr:`attr <.Namespace.attr>` accessor of the :class:`.Namespace` object allows access to module level variables declared in a template. By accessing ``self.attr``, you can access regular attributes from the inheritance chain as declared in ``<%! %>`` sections. Such as: .. sourcecode:: mako <%! class_ = "grey" %>
    ${self.body()}
    If an inheriting template overrides ``class_`` to be ``"white"``, as in: .. sourcecode:: mako <%! class_ = "white" %> <%inherit file="parent.html"/> This is the body you'll get output like: .. sourcecode:: html
    This is the body
    .. seealso:: :ref:`namespace_attr_for_includes` - a more sophisticated example using :attr:`.Namespace.attr`. Mako-0.9.1/doc/_sources/namespaces.txt0000644000076500000240000003435612257136636020451 0ustar classicstaff00000000000000.. _namespaces_toplevel: ========== Namespaces ========== Namespaces are used to organize groups of defs into categories, and also to "import" defs from other files. If the file ``components.html`` defines these two defs: .. sourcecode:: mako ## components.html <%def name="comp1()"> this is comp1 <%def name="comp2(x)"> this is comp2, x is ${x} you can make another file, for example ``index.html``, that pulls those two defs into a namespace called ``comp``: .. sourcecode:: mako ## index.html <%namespace name="comp" file="components.html"/> Here's comp1: ${comp.comp1()} Here's comp2: ${comp.comp2(x=5)} The ``comp`` variable above is an instance of :class:`.Namespace`, a **proxy object** which delivers method calls to the underlying template callable using the current context. ``<%namespace>`` also provides an ``import`` attribute which can be used to pull the names into the local namespace, removing the need to call it via the "``.``" operator. When ``import`` is used, the ``name`` attribute is optional. .. sourcecode:: mako <%namespace file="components.html" import="comp1, comp2"/> Heres comp1: ${comp1()} Heres comp2: ${comp2(x=5)} ``import`` also supports the "``*``" operator: .. sourcecode:: mako <%namespace file="components.html" import="*"/> Heres comp1: ${comp1()} Heres comp2: ${comp2(x=5)} The names imported by the ``import`` attribute take precedence over any names that exist within the current context. .. note:: In current versions of Mako, usage of ``import='*'`` is known to decrease performance of the template. This will be fixed in a future release. The ``file`` argument allows expressions -- if looking for context variables, the ``context`` must be named explicitly: .. sourcecode:: mako <%namespace name="dyn" file="${context['namespace_name']}"/> Ways to Call Namespaces ======================= There are essentially four ways to call a function from a namespace. The "expression" format, as described previously. Namespaces are just Python objects with functions on them, and can be used in expressions like any other function: .. sourcecode:: mako ${mynamespace.somefunction('some arg1', 'some arg2', arg3='some arg3', arg4='some arg4')} Synonymous with the "expression" format is the "custom tag" format, when a "closed" tag is used. This format, introduced in Mako 0.2.3, allows the usage of a "custom" Mako tag, with the function arguments passed in using named attributes: .. sourcecode:: mako <%mynamespace:somefunction arg1="some arg1" arg2="some arg2" arg3="some arg3" arg4="some arg4"/> When using tags, the values of the arguments are taken as literal strings by default. To embed Python expressions as arguments, use the embedded expression format: .. sourcecode:: mako <%mynamespace:somefunction arg1="${someobject.format()}" arg2="${somedef(5, 12)}"/> The "custom tag" format is intended mainly for namespace functions which recognize body content, which in Mako is known as a "def with embedded content": .. sourcecode:: mako <%mynamespace:somefunction arg1="some argument" args="x, y"> Some record: ${x}, ${y} The "classic" way to call defs with embedded content is the ``<%call>`` tag: .. sourcecode:: mako <%call expr="mynamespace.somefunction(arg1='some argument')" args="x, y"> Some record: ${x}, ${y} For information on how to construct defs that embed content from the caller, see :ref:`defs_with_content`. .. _namespaces_python_modules: Namespaces from Regular Python Modules ====================================== Namespaces can also import regular Python functions from modules. These callables need to take at least one argument, ``context``, an instance of :class:`.Context`. A module file ``some/module.py`` might contain the callable: .. sourcecode:: python def my_tag(context): context.write("hello world") return '' A template can use this module via: .. sourcecode:: mako <%namespace name="hw" module="some.module"/> ${hw.my_tag()} Note that the ``context`` argument is not needed in the call; the :class:`.Namespace` tag creates a locally-scoped callable which takes care of it. The ``return ''`` is so that the def does not dump a ``None`` into the output stream -- the return value of any def is rendered after the def completes, in addition to whatever was passed to :meth:`.Context.write` within its body. If your def is to be called in an "embedded content" context, that is as described in :ref:`defs_with_content`, you should use the :func:`.supports_caller` decorator, which will ensure that Mako will ensure the correct "caller" variable is available when your def is called, supporting embedded content: .. sourcecode:: python from mako.runtime import supports_caller @supports_caller def my_tag(context): context.write("
    ") context['caller'].body() context.write("
    ") return '' Capturing of output is available as well, using the outside-of-templates version of the :func:`.capture` function, which accepts the "context" as its first argument: .. sourcecode:: python from mako.runtime import supports_caller, capture @supports_caller def my_tag(context): return "
    %s
    " % \ capture(context, context['caller'].body, x="foo", y="bar") Declaring Defs in Namespaces ============================ The ``<%namespace>`` tag supports the definition of ``<%def>``\ s directly inside the tag. These defs become part of the namespace like any other function, and will override the definitions pulled in from a remote template or module: .. sourcecode:: mako ## define a namespace <%namespace name="stuff"> <%def name="comp1()"> comp1 ## then call it ${stuff.comp1()} .. _namespaces_body: The ``body()`` Method ===================== Every namespace that is generated from a template contains a method called ``body()``. This method corresponds to the main body of the template, and plays its most important roles when using inheritance relationships as well as def-calls-with-content. Since the ``body()`` method is available from a namespace just like all the other defs defined in a template, what happens if you send arguments to it? By default, the ``body()`` method accepts no positional arguments, and for usefulness in inheritance scenarios will by default dump all keyword arguments into a dictionary called ``pageargs``. But if you actually want to get at the keyword arguments, Mako recommends you define your own argument signature explicitly. You do this via using the ``<%page>`` tag: .. sourcecode:: mako <%page args="x, y, someval=8, scope='foo', **kwargs"/> A template which defines the above signature requires that the variables ``x`` and ``y`` are defined, defines default values for ``someval`` and ``scope``, and sets up ``**kwargs`` to receive all other keyword arguments. If ``**kwargs`` or similar is not present, the argument ``**pageargs`` gets tacked on by Mako. When the template is called as a top-level template (i.e. via :meth:`~.Template.render`) or via the ``<%include>`` tag, the values for these arguments will be pulled from the ``Context``. In all other cases, i.e. via calling the ``body()`` method, the arguments are taken as ordinary arguments from the method call. So above, the body might be called as: .. sourcecode:: mako ${self.body(5, y=10, someval=15, delta=7)} The :class:`.Context` object also supplies a :attr:`~.Context.kwargs` accessor, for cases when you'd like to pass along the top level context arguments to a ``body()`` callable: .. sourcecode:: mako ${next.body(**context.kwargs)} The usefulness of calls like the above become more apparent when one works with inheriting templates. For more information on this, as well as the meanings of the names ``self`` and ``next``, see :ref:`inheritance_toplevel`. .. _namespaces_builtin: Built-in Namespaces =================== The namespace is so great that Mako gives your template one (or two) for free. The names of these namespaces are ``local`` and ``self``. Other built-in namespaces include ``parent`` and ``next``, which are optional and are described in :ref:`inheritance_toplevel`. .. _namespace_local: ``local`` --------- The ``local`` namespace is basically the namespace for the currently executing template. This means that all of the top level defs defined in your template, as well as your template's ``body()`` function, are also available off of the ``local`` namespace. The ``local`` namespace is also where properties like ``uri``, ``filename``, and ``module`` and the ``get_namespace`` method can be particularly useful. .. _namespace_self: ``self`` -------- The ``self`` namespace, in the case of a template that does not use inheritance, is synonymous with ``local``. If inheritance is used, then ``self`` references the topmost template in the inheritance chain, where it is most useful for providing the ultimate form of various "method" calls which may have been overridden at various points in an inheritance chain. See :ref:`inheritance_toplevel`. Inheritable Namespaces ====================== The ``<%namespace>`` tag includes an optional attribute ``inheritable="True"``, which will cause the namespace to be attached to the ``self`` namespace. Since ``self`` is globally available throughout an inheritance chain (described in the next section), all the templates in an inheritance chain can get at the namespace imported in a super-template via ``self``. .. sourcecode:: mako ## base.html <%namespace name="foo" file="foo.html" inheritable="True"/> ${next.body()} ## somefile.html <%inherit file="base.html"/> ${self.foo.bar()} This allows a super-template to load a whole bunch of namespaces that its inheriting templates can get to, without them having to explicitly load those namespaces themselves. The ``import="*"`` part of the ``<%namespace>`` tag doesn't yet interact with the ``inheritable`` flag, so currently you have to use the explicit namespace name off of ``self``, followed by the desired function name. But more on this in a future release. Namespace API Usage Example - Static Dependencies ================================================== The ``<%namespace>`` tag at runtime produces an instance of :class:`.Namespace`. Programmatic access of :class:`.Namespace` can be used to build various kinds of scaffolding in templates and between templates. A common request is the ability for a particular template to declare "static includes" - meaning, the usage of a particular set of defs requires that certain Javascript/CSS files are present. Using :class:`.Namespace` as the object that holds together the various templates present, we can build a variety of such schemes. In particular, the :class:`.Context` has a ``namespaces`` attribute, which is a dictionary of all :class:`.Namespace` objects declared. Iterating the values of this dictionary will provide a :class:`.Namespace` object for each time the ``<%namespace>`` tag was used, anywhere within the inheritance chain. .. _namespace_attr_for_includes: Version One - Use :attr:`.Namespace.attr` ----------------------------------------- The :attr:`.Namespace.attr` attribute allows us to locate any variables declared in the ``<%! %>`` of a template. .. sourcecode:: mako ## base.mako ## base-most template, renders layout etc. ## traverse through all namespaces present, ## look for an attribute named 'includes' % for ns in context.namespaces.values(): % for incl in getattr(ns.attr, 'includes', []): ${incl} % endfor % endfor ${next.body()} ## library.mako ## library functions. <%! includes = [ '', '' ] %> <%def name="mytag()"> ${caller.body()} ## index.mako ## calling template. <%inherit file="base.mako"/> <%namespace name="foo" file="library.mako"/> <%foo:mytag> a form Above, the file ``library.mako`` declares an attribute ``includes`` inside its global ``<%! %>`` section. ``index.mako`` includes this template using the ``<%namespace>`` tag. The base template ``base.mako``, which is the inherited parent of ``index.mako`` and is reponsible for layout, then locates this attribute and iterates through its contents to produce the includes that are specific to ``library.mako``. Version Two - Use a specific named def ----------------------------------------- In this version, we put the includes into a ``<%def>`` that follows a naming convention. .. sourcecode:: mako ## base.mako ## base-most template, renders layout etc. ## traverse through all namespaces present, ## look for a %def named 'includes' % for ns in context.namespaces.values(): % if hasattr(ns, 'includes'): ${ns.includes()} % endif % endfor ${next.body()} ## library.mako ## library functions. <%def name="includes()"> <%def name="mytag()">
    ${caller.body()} ## index.mako ## calling template. <%inherit file="base.mako"/> <%namespace name="foo" file="library.mako"/> <%foo:mytag> a form In this version, ``library.mako`` declares a ``<%def>`` named ``includes``. The example works identically to the previous one, except that ``base.mako`` looks for defs named ``include`` on each namespace it examines. API Reference ============= .. autoclass:: mako.runtime.Namespace :show-inheritance: :members: .. autoclass:: mako.runtime.TemplateNamespace :show-inheritance: :members: .. autoclass:: mako.runtime.ModuleNamespace :show-inheritance: :members: .. autofunction:: mako.runtime.supports_caller .. autofunction:: mako.runtime.capture Mako-0.9.1/doc/_sources/runtime.txt0000644000076500000240000003741112257136636020010 0ustar classicstaff00000000000000.. _runtime_toplevel: ============================ The Mako Runtime Environment ============================ This section describes a little bit about the objects and built-in functions that are available in templates. .. _context: Context ======= The :class:`.Context` is the central object that is created when a template is first executed, and is responsible for handling all communication with the outside world. Within the template environment, it is available via the :ref:`reserved name ` ``context``. The :class:`.Context` includes two major components, one of which is the output buffer, which is a file-like object such as Python's ``StringIO`` or similar, and the other a dictionary of variables that can be freely referenced within a template; this dictionary is a combination of the arguments sent to the :meth:`~.Template.render` function and some built-in variables provided by Mako's runtime environment. The Buffer ---------- The buffer is stored within the :class:`.Context`, and writing to it is achieved by calling the :meth:`~.Context.write` method -- in a template this looks like ``context.write('some string')``. You usually don't need to care about this, as all text within a template, as well as all expressions provided by ``${}``, automatically send everything to this method. The cases you might want to be aware of its existence are if you are dealing with various filtering/buffering scenarios, which are described in :ref:`filtering_toplevel`, or if you want to programmatically send content to the output stream, such as within a ``<% %>`` block. .. sourcecode:: mako <% context.write("some programmatic text") %> The actual buffer may or may not be the original buffer sent to the :class:`.Context` object, as various filtering/caching scenarios may "push" a new buffer onto the context's underlying buffer stack. For this reason, just stick with ``context.write()`` and content will always go to the topmost buffer. .. _context_vars: Context Variables ----------------- When your template is compiled into a Python module, the body content is enclosed within a Python function called ``render_body``. Other top-level defs defined in the template are defined within their own function bodies which are named after the def's name with the prefix ``render_`` (i.e. ``render_mydef``). One of the first things that happens within these functions is that all variable names that are referenced within the function which are not defined in some other way (i.e. such as via assignment, module level imports, etc.) are pulled from the :class:`.Context` object's dictionary of variables. This is how you're able to freely reference variable names in a template which automatically correspond to what was passed into the current :class:`.Context`. * **What happens if I reference a variable name that is not in the current context?** - The value you get back is a special value called ``UNDEFINED``, or if the ``strict_undefined=True`` flag is used a ``NameError`` is raised. ``UNDEFINED`` is just a simple global variable with the class :class:`mako.runtime.Undefined`. The ``UNDEFINED`` object throws an error when you call ``str()`` on it, which is what happens if you try to use it in an expression. * **UNDEFINED makes it hard for me to find what name is missing** - An alternative is to specify the option ``strict_undefined=True`` to the :class:`.Template` or :class:`.TemplateLookup`. This will cause any non-present variables to raise an immediate ``NameError`` which includes the name of the variable in its message when :meth:`~.Template.render` is called -- ``UNDEFINED`` is not used. .. versionadded:: 0.3.6 * **Why not just return None?** Using ``UNDEFINED``, or raising a ``NameError`` is more explicit and allows differentiation between a value of ``None`` that was explicitly passed to the :class:`.Context` and a value that wasn't present at all. * **Why raise an exception when you call str() on it ? Why not just return a blank string?** - Mako tries to stick to the Python philosophy of "explicit is better than implicit". In this case, it's decided that the template author should be made to specifically handle a missing value rather than experiencing what may be a silent failure. Since ``UNDEFINED`` is a singleton object just like Python's ``True`` or ``False``, you can use the ``is`` operator to check for it: .. sourcecode:: mako % if someval is UNDEFINED: someval is: no value % else: someval is: ${someval} % endif Another facet of the :class:`.Context` is that its dictionary of variables is **immutable**. Whatever is set when :meth:`~.Template.render` is called is what stays. Of course, since its Python, you can hack around this and change values in the context's internal dictionary, but this will probably will not work as well as you'd think. The reason for this is that Mako in many cases creates copies of the :class:`.Context` object, which get sent to various elements of the template and inheriting templates used in an execution. So changing the value in your local :class:`.Context` will not necessarily make that value available in other parts of the template's execution. Examples of where Mako creates copies of the :class:`.Context` include within top-level def calls from the main body of the template (the context is used to propagate locally assigned variables into the scope of defs; since in the template's body they appear as inlined functions, Mako tries to make them act that way), and within an inheritance chain (each template in an inheritance chain has a different notion of ``parent`` and ``next``, which are all stored in unique :class:`.Context` instances). * **So what if I want to set values that are global to everyone within a template request?** - All you have to do is provide a dictionary to your :class:`.Context` when the template first runs, and everyone can just get/set variables from that. Lets say its called ``attributes``. Running the template looks like: .. sourcecode:: python output = template.render(attributes={}) Within a template, just reference the dictionary: .. sourcecode:: mako <% attributes['foo'] = 'bar' %> 'foo' attribute is: ${attributes['foo']} * **Why can't "attributes" be a built-in feature of the Context?** - This is an area where Mako is trying to make as few decisions about your application as it possibly can. Perhaps you don't want your templates to use this technique of assigning and sharing data, or perhaps you have a different notion of the names and kinds of data structures that should be passed around. Once again Mako would rather ask the user to be explicit. Context Methods and Accessors ----------------------------- Significant members of :class:`.Context` include: * ``context[key]`` / ``context.get(key, default=None)`` - dictionary-like accessors for the context. Normally, any variable you use in your template is automatically pulled from the context if it isn't defined somewhere already. Use the dictionary accessor and/or ``get`` method when you want a variable that *is* already defined somewhere else, such as in the local arguments sent to a ``%def`` call. If a key is not present, like a dictionary it raises ``KeyError``. * ``keys()`` - all the names defined within this context. * ``kwargs`` - this returns a **copy** of the context's dictionary of variables. This is useful when you want to propagate the variables in the current context to a function as keyword arguments, i.e.: .. sourcecode:: mako ${next.body(**context.kwargs)} * ``write(text)`` - write some text to the current output stream. * ``lookup`` - returns the :class:`.TemplateLookup` instance that is used for all file-lookups within the current execution (even though individual :class:`.Template` instances can conceivably have different instances of a :class:`.TemplateLookup`, only the :class:`.TemplateLookup` of the originally-called :class:`.Template` gets used in a particular execution). .. _loop_context: The Loop Context ================ Within ``% for`` blocks, the :ref:`reserved name` ``loop`` is available. ``loop`` tracks the progress of the ``for`` loop and makes it easy to use the iteration state to control template behavior: .. sourcecode:: mako
      % for a in ("one", "two", "three"):
    • Item ${loop.index}: ${a}
    • % endfor
    .. versionadded:: 0.7 Iterations ---------- Regardless of the type of iterable you're looping over, ``loop`` always tracks the 0-indexed iteration count (available at ``loop.index``), its parity (through the ``loop.even`` and ``loop.odd`` bools), and ``loop.first``, a bool indicating whether the loop is on its first iteration. If your iterable provides a ``__len__`` method, ``loop`` also provides access to a count of iterations remaining at ``loop.reverse_index`` and ``loop.last``, a bool indicating whether the loop is on its last iteration; accessing these without ``__len__`` will raise a ``TypeError``. Cycling ------- Cycling is available regardless of whether the iterable you're using provides a ``__len__`` method. Prior to Mako 0.7, you might have generated a simple zebra striped list using ``enumerate``: .. sourcecode:: mako
      % for i, item in enumerate(('spam', 'ham', 'eggs')):
    • ${item}
    • % endfor
    With ``loop.cycle``, you get the same results with cleaner code and less prep work: .. sourcecode:: mako
      % for item in ('spam', 'ham', 'eggs'):
    • ${item}
    • % endfor
    Both approaches produce output like the following: .. sourcecode:: html
    • spam
    • ham
    • eggs
    Parent Loops ------------ Loop contexts can also be transparently nested, and the Mako runtime will do the right thing and manage the scope for you. You can access the parent loop context through ``loop.parent``. This allows you to reach all the way back up through the loop stack by chaining ``parent`` attribute accesses, i.e. ``loop.parent.parent....`` as long as the stack depth isn't exceeded. For example, you can use the parent loop to make a checkered table: .. sourcecode:: mako
% for consonant in 'pbj': % for vowel in 'iou': % endfor % endfor
${consonant + vowel}t
.. sourcecode:: html
pit pot put
bit bot but
jit jot jut
.. _migrating_loop: Migrating Legacy Templates that Use the Word "loop" --------------------------------------------------- .. versionchanged:: 0.7 The ``loop`` name is now :ref:`reserved ` in Mako, which means a template that refers to a variable named ``loop`` won't function correctly when used in Mako 0.7. To ease the transition for such systems, the feature can be disabled across the board for all templates, then re-enabled on a per-template basis for those templates which wish to make use of the new system. First, the ``enable_loop=False`` flag is passed to either the :class:`.TemplateLookup` or :class:`.Template` object in use: .. sourcecode:: python lookup = TemplateLookup(directories=['/docs'], enable_loop=False) or: .. sourcecode:: python template = Template("some template", enable_loop=False) An individual template can make usage of the feature when ``enable_loop`` is set to ``False`` by switching it back on within the ``<%page>`` tag: .. sourcecode:: mako <%page enable_loop="True"/> % for i in collection: ${i} ${loop.index} % endfor Using the above scheme, it's safe to pass the name ``loop`` to the :meth:`.Template.render` method as well as to freely make usage of a variable named ``loop`` within a template, provided the ``<%page>`` tag doesn't override it. New templates that want to use the ``loop`` context can then set up ``<%page enable_loop="True"/>`` to use the new feature without affecting old templates. All the Built-in Names ====================== A one-stop shop for all the names Mako defines. Most of these names are instances of :class:`.Namespace`, which are described in the next section, :ref:`namespaces_toplevel`. Also, most of these names other than ``context``, ``UNDEFINED``, and ``loop`` are also present *within* the :class:`.Context` itself. The names ``context``, ``loop`` and ``UNDEFINED`` themselves can't be passed to the context and can't be substituted -- see the section :ref:`reserved_names`. * ``context`` - this is the :class:`.Context` object, introduced at :ref:`context`. * ``local`` - the namespace of the current template, described in :ref:`namespaces_builtin`. * ``self`` - the namespace of the topmost template in an inheritance chain (if any, otherwise the same as ``local``), mostly described in :ref:`inheritance_toplevel`. * ``parent`` - the namespace of the parent template in an inheritance chain (otherwise undefined); see :ref:`inheritance_toplevel`. * ``next`` - the namespace of the next template in an inheritance chain (otherwise undefined); see :ref:`inheritance_toplevel`. * ``caller`` - a "mini" namespace created when using the ``<%call>`` tag to define a "def call with content"; described in :ref:`defs_with_content`. * ``loop`` - this provides access to :class:`.LoopContext` objects when they are requested within ``% for`` loops, introduced at :ref:`loop_context`. * ``capture`` - a function that calls a given def and captures its resulting content into a string, which is returned. Usage is described in :ref:`filtering_toplevel`. * ``UNDEFINED`` - a global singleton that is applied to all otherwise uninitialized template variables that were not located within the :class:`.Context` when rendering began, unless the :class:`.Template` flag ``strict_undefined`` is set to ``True``. ``UNDEFINED`` is an instance of :class:`.Undefined`, and raises an exception when its ``__str__()`` method is called. * ``pageargs`` - this is a dictionary which is present in a template which does not define any ``**kwargs`` section in its ``<%page>`` tag. All keyword arguments sent to the ``body()`` function of a template (when used via namespaces) go here by default unless otherwise defined as a page argument. If this makes no sense, it shouldn't; read the section :ref:`namespaces_body`. .. _reserved_names: Reserved Names -------------- Mako has a few names that are considered to be "reserved" and can't be used as variable names. .. versionchanged:: 0.7 Mako raises an error if these words are found passed to the template as context arguments, whereas in previous versions they'd be silently ignored or lead to other error messages. * ``context`` - see :ref:`context`. * ``UNDEFINED`` - see :ref:`context_vars`. * ``loop`` - see :ref:`loop_context`. Note this can be disabled for legacy templates via the ``enable_loop=False`` argument; see :ref:`migrating_loop`. API Reference ============= .. autoclass:: mako.runtime.Context :show-inheritance: :members: .. autoclass:: mako.runtime.LoopContext :show-inheritance: :members: .. autoclass:: mako.runtime.Undefined :show-inheritance: Mako-0.9.1/doc/_sources/syntax.txt0000644000076500000240000003152412257136636017652 0ustar classicstaff00000000000000.. _syntax_toplevel: ====== Syntax ====== A Mako template is parsed from a text stream containing any kind of content, XML, HTML, email text, etc. The template can further contain Mako-specific directives which represent variable and/or expression substitutions, control structures (i.e. conditionals and loops), server-side comments, full blocks of Python code, as well as various tags that offer additional functionality. All of these constructs compile into real Python code. This means that you can leverage the full power of Python in almost every aspect of a Mako template. Expression Substitution ======================= The simplest expression is just a variable substitution. The syntax for this is the ``${}`` construct, which is inspired by Perl, Genshi, JSP EL, and others: .. sourcecode:: mako this is x: ${x} Above, the string representation of ``x`` is applied to the template's output stream. If you're wondering where ``x`` comes from, it's usually from the :class:`.Context` supplied to the template's rendering function. If ``x`` was not supplied to the template and was not otherwise assigned locally, it evaluates to a special value ``UNDEFINED``. More on that later. The contents within the ``${}`` tag are evaluated by Python directly, so full expressions are OK: .. sourcecode:: mako pythagorean theorem: ${pow(x,2) + pow(y,2)} The results of the expression are evaluated into a string result in all cases before being rendered to the output stream, such as the above example where the expression produces a numeric result. Expression Escaping =================== Mako includes a number of built-in escaping mechanisms, including HTML, URI and XML escaping, as well as a "trim" function. These escapes can be added to an expression substitution using the ``|`` operator: .. sourcecode:: mako ${"this is some text" | u} The above expression applies URL escaping to the expression, and produces ``this+is+some+text``. The ``u`` name indicates URL escaping, whereas ``h`` represents HTML escaping, ``x`` represents XML escaping, and ``trim`` applies a trim function. Read more about built-in filtering functions, including how to make your own filter functions, in :ref:`filtering_toplevel`. Control Structures ================== A control structure refers to all those things that control the flow of a program -- conditionals (i.e. ``if``/``else``), loops (like ``while`` and ``for``), as well as things like ``try``/``except``. In Mako, control structures are written using the ``%`` marker followed by a regular Python control expression, and are "closed" by using another ``%`` marker with the tag "``end``", where "````" is the keyword of the expression: .. sourcecode:: mako % if x==5: this is some output % endif The ``%`` can appear anywhere on the line as long as no text precedes it; indentation is not significant. The full range of Python "colon" expressions are allowed here, including ``if``/``elif``/``else``, ``while``, ``for``, and even ``def``, although Mako has a built-in tag for defs which is more full-featured. .. sourcecode:: mako % for a in ['one', 'two', 'three', 'four', 'five']: % if a[0] == 't': its two or three % elif a[0] == 'f': four/five % else: one % endif % endfor The ``%`` sign can also be "escaped", if you actually want to emit a percent sign as the first non whitespace character on a line, by escaping it as in ``%%``: .. sourcecode:: mako %% some text %% some more text The Loop Context ---------------- The **loop context** provides additional information about a loop while inside of a ``% for`` structure: .. sourcecode:: mako
    % for a in ("one", "two", "three"):
  • Item ${loop.index}: ${a}
  • % endfor
See :ref:`loop_context` for more information on this feature. .. versionadded:: 0.7 Comments ======== Comments come in two varieties. The single line comment uses ``##`` as the first non-space characters on a line: .. sourcecode:: mako ## this is a comment. ...text ... A multiline version exists using ``<%doc> ...text... ``: .. sourcecode:: mako <%doc> these are comments more comments Newline Filters =============== The backslash ("``\``") character, placed at the end of any line, will consume the newline character before continuing to the next line: .. sourcecode:: mako here is a line that goes onto \ another line. The above text evaluates to: .. sourcecode:: text here is a line that goes onto another line. Python Blocks ============= Any arbitrary block of python can be dropped in using the ``<% %>`` tags: .. sourcecode:: mako this is a template <% x = db.get_resource('foo') y = [z.element for z in x if x.frobnizzle==5] %> % for elem in y: element: ${elem} % endfor Within ``<% %>``, you're writing a regular block of Python code. While the code can appear with an arbitrary level of preceding whitespace, it has to be consistently formatted with itself. Mako's compiler will adjust the block of Python to be consistent with the surrounding generated Python code. Module-level Blocks =================== A variant on ``<% %>`` is the module-level code block, denoted by ``<%! %>``. Code within these tags is executed at the module level of the template, and not within the rendering function of the template. Therefore, this code does not have access to the template's context and is only executed when the template is loaded into memory (which can be only once per application, or more, depending on the runtime environment). Use the ``<%! %>`` tags to declare your template's imports, as well as any pure-Python functions you might want to declare: .. sourcecode:: mako <%! import mylib import re def filter(text): return re.sub(r'^@', '', text) %> Any number of ``<%! %>`` blocks can be declared anywhere in a template; they will be rendered in the resulting module in a single contiguous block above all render callables, in the order in which they appear in the source template. Tags ==== The rest of what Mako offers takes place in the form of tags. All tags use the same syntax, which is similar to an XML tag except that the first character of the tag name is a ``%`` character. The tag is closed either by a contained slash character, or an explicit closing tag: .. sourcecode:: mako <%include file="foo.txt"/> <%def name="foo" buffered="True"> this is a def All tags have a set of attributes which are defined for each tag. Some of these attributes are required. Also, many attributes support **evaluation**, meaning you can embed an expression (using ``${}``) inside the attribute text: .. sourcecode:: mako <%include file="/foo/bar/${myfile}.txt"/> Whether or not an attribute accepts runtime evaluation depends on the type of tag and how that tag is compiled into the template. The best way to find out if you can stick an expression in is to try it! The lexer will tell you if it's not valid. Heres a quick summary of all the tags: ``<%page>`` ----------- This tag defines general characteristics of the template, including caching arguments, and optional lists of arguments which the template expects when invoked. .. sourcecode:: mako <%page args="x, y, z='default'"/> Or a page tag that defines caching characteristics: .. sourcecode:: mako <%page cached="True" cache_type="memory"/> Currently, only one ``<%page>`` tag gets used per template, the rest get ignored. While this will be improved in a future release, for now make sure you have only one ``<%page>`` tag defined in your template, else you may not get the results you want. The details of what ``<%page>`` is used for are described further in :ref:`namespaces_body` as well as :ref:`caching_toplevel`. ``<%include>`` -------------- A tag that is familiar from other template languages, ``%include`` is a regular joe that just accepts a file argument and calls in the rendered result of that file: .. sourcecode:: mako <%include file="header.html"/> hello world <%include file="footer.html"/> Include also accepts arguments which are available as ``<%page>`` arguments in the receiving template: .. sourcecode:: mako <%include file="toolbar.html" args="current_section='members', username='ed'"/> ``<%def>`` ---------- The ``%def`` tag defines a Python function which contains a set of content, that can be called at some other point in the template. The basic idea is simple: .. sourcecode:: mako <%def name="myfunc(x)"> this is myfunc, x is ${x} ${myfunc(7)} The ``%def`` tag is a lot more powerful than a plain Python ``def``, as the Mako compiler provides many extra services with ``%def`` that you wouldn't normally have, such as the ability to export defs as template "methods", automatic propagation of the current :class:`.Context`, buffering/filtering/caching flags, and def calls with content, which enable packages of defs to be sent as arguments to other def calls (not as hard as it sounds). Get the full deal on what ``%def`` can do in :ref:`defs_toplevel`. ``<%block>`` ------------ ``%block`` is a tag that is close to a ``%def``, except executes itself immediately in its base-most scope, and can also be anonymous (i.e. with no name): .. sourcecode:: mako <%block filter="h"> some stuff. Inspired by Jinja2 blocks, named blocks offer a syntactically pleasing way to do inheritance: .. sourcecode:: mako <%block name="header">

<%block name="title"/>

${self.body()} Blocks are introduced in :ref:`blocks` and further described in :ref:`inheritance_toplevel`. .. versionadded:: 0.4.1 ``<%namespace>`` ---------------- ``%namespace`` is Mako's equivalent of Python's ``import`` statement. It allows access to all the rendering functions and metadata of other template files, plain Python modules, as well as locally defined "packages" of functions. .. sourcecode:: mako <%namespace file="functions.html" import="*"/> The underlying object generated by ``%namespace``, an instance of :class:`.mako.runtime.Namespace`, is a central construct used in templates to reference template-specific information such as the current URI, inheritance structures, and other things that are not as hard as they sound right here. Namespaces are described in :ref:`namespaces_toplevel`. ``<%inherit>`` -------------- Inherit allows templates to arrange themselves in **inheritance chains**. This is a concept familiar in many other template languages. .. sourcecode:: mako <%inherit file="base.html"/> When using the ``%inherit`` tag, control is passed to the topmost inherited template first, which then decides how to handle calling areas of content from its inheriting templates. Mako offers a lot of flexibility in this area, including dynamic inheritance, content wrapping, and polymorphic method calls. Check it out in :ref:`inheritance_toplevel`. ``<%``\ nsname\ ``:``\ defname\ ``>`` ------------------------------------- Any user-defined "tag" can be created against a namespace by using a tag with a name of the form ``<%:>``. The closed and open formats of such a tag are equivalent to an inline expression and the ``<%call>`` tag, respectively. .. sourcecode:: mako <%mynamespace:somedef param="some value"> this is the body To create custom tags which accept a body, see :ref:`defs_with_content`. .. versionadded:: 0.2.3 ``<%call>`` ----------- The call tag is the "classic" form of a user-defined tag, and is roughly equivalent to the ``<%namespacename:defname>`` syntax described above. This tag is also described in :ref:`defs_with_content`. ``<%doc>`` ---------- The ``%doc`` tag handles multiline comments: .. sourcecode:: mako <%doc> these are comments more comments Also the ``##`` symbol as the first non-space characters on a line can be used for single line comments. ``<%text>`` ----------- This tag suspends the Mako lexer's normal parsing of Mako template directives, and returns its entire body contents as plain text. It is used pretty much to write documentation about Mako: .. sourcecode:: mako <%text filter="h"> heres some fake mako ${syntax} <%def name="x()">${x} Returning Early from a Template =============================== Sometimes you want to stop processing a template or ``<%def>`` method in the middle and just use the text you've accumulated so far. You can use a ``return`` statement inside a Python block to do that. .. sourcecode:: mako % if not len(records): No records found. <% return %> % endif Or perhaps: .. sourcecode:: mako <% if not len(records): return %> Mako-0.9.1/doc/_sources/unicode.txt0000644000076500000240000003246712257136636017761 0ustar classicstaff00000000000000.. _unicode_toplevel: =================== The Unicode Chapter =================== The Python language supports two ways of representing what we know as "strings", i.e. series of characters. In Python 2, the two types are ``string`` and ``unicode``, and in Python 3 they are ``bytes`` and ``string``. A key aspect of the Python 2 ``string`` and Python 3 ``bytes`` types are that they contain no information regarding what **encoding** the data is stored in. For this reason they were commonly referred to as **byte strings** on Python 2, and Python 3 makes this name more explicit. The origins of this come from Python's background of being developed before the Unicode standard was even available, back when strings were C-style strings and were just that, a series of bytes. Strings that had only values below 128 just happened to be **ASCII** strings and were printable on the console, whereas strings with values above 128 would produce all kinds of graphical characters and bells. Contrast the "byte-string" type with the "unicode/string" type. Objects of this latter type are created whenever you say something like ``u"hello world"`` (or in Python 3, just ``"hello world"``). In this case, Python represents each character in the string internally using multiple bytes per character (something similar to UTF-16). What's important is that when using the ``unicode``/``string`` type to store strings, Python knows the data's encoding; it's in its own internal format. Whereas when using the ``string``/``bytes`` type, it does not. When Python 2 attempts to treat a byte-string as a string, which means it's attempting to compare/parse its characters, to coerce it into another encoding, or to decode it to a unicode object, it has to guess what the encoding is. In this case, it will pretty much always guess the encoding as ``ascii``... and if the byte-string contains bytes above value 128, you'll get an error. Python 3 eliminates much of this confusion by just raising an error unconditionally if a byte-string is used in a character-aware context. There is one operation that Python *can* do with a non-ASCII byte-string, and it's a great source of confusion: it can dump the byte-string straight out to a stream or a file, with nary a care what the encoding is. To Python, this is pretty much like dumping any other kind of binary data (like an image) to a stream somewhere. In Python 2, it is common to see programs that embed all kinds of international characters and encodings into plain byte-strings (i.e. using ``"hello world"`` style literals) can fly right through their run, sending reams of strings out to wherever they are going, and the programmer, seeing the same output as was expressed in the input, is now under the illusion that his or her program is Unicode-compliant. In fact, their program has no unicode awareness whatsoever, and similarly has no ability to interact with libraries that *are* unicode aware. Python 3 makes this much less likely by defaulting to unicode as the storage format for strings. The "pass through encoded data" scheme is what template languages like Cheetah and earlier versions of Myghty do by default. Mako as of version 0.2 also supports this mode of operation when using Python 2, using the ``disable_unicode=True`` flag. However, when using Mako in its default mode of unicode-aware, it requires explicitness when dealing with non-ASCII encodings. Additionally, if you ever need to handle unicode strings and other kinds of encoding conversions more intelligently, the usage of raw byte-strings quickly becomes a nightmare, since you are sending the Python interpreter collections of bytes for which it can make no intelligent decisions with regards to encoding. In Python 3 Mako only allows usage of native, unicode strings. In normal Mako operation, all parsed template constructs and output streams are handled internally as Python ``unicode`` objects. It's only at the point of :meth:`~.Template.render` that this unicode stream may be rendered into whatever the desired output encoding is. The implication here is that the template developer must :ensure that :ref:`the encoding of all non-ASCII templates is explicit ` (still required in Python 3), that :ref:`all non-ASCII-encoded expressions are in one way or another converted to unicode ` (not much of a burden in Python 3), and that :ref:`the output stream of the template is handled as a unicode stream being encoded to some encoding ` (still required in Python 3). .. _set_template_file_encoding: Specifying the Encoding of a Template File ========================================== This is the most basic encoding-related setting, and it is equivalent to Python's "magic encoding comment", as described in `pep-0263 `_. Any template that contains non-ASCII characters requires that this comment be present so that Mako can decode to unicode (and also make usage of Python's AST parsing services). Mako's lexer will use this encoding in order to convert the template source into a ``unicode`` object before continuing its parsing: .. sourcecode:: mako ## -*- coding: utf-8 -*- Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! » For the picky, the regular expression used is derived from that of the above mentioned pep: .. sourcecode:: python #.*coding[:=]\s*([-\w.]+).*\n The lexer will convert to unicode in all cases, so that if any characters exist in the template that are outside of the specified encoding (or the default of ``ascii``), the error will be immediate. As an alternative, the template encoding can be specified programmatically to either :class:`.Template` or :class:`.TemplateLookup` via the ``input_encoding`` parameter: .. sourcecode:: python t = TemplateLookup(directories=['./'], input_encoding='utf-8') The above will assume all located templates specify ``utf-8`` encoding, unless the template itself contains its own magic encoding comment, which takes precedence. .. _handling_non_ascii_expressions: Handling Expressions ==================== The next area that encoding comes into play is in expression constructs. By default, Mako's treatment of an expression like this: .. sourcecode:: mako ${"hello world"} looks something like this: .. sourcecode:: python context.write(unicode("hello world")) In Python 3, it's just: .. sourcecode:: python context.write(str("hello world")) That is, **the output of all expressions is run through the ``unicode`` built-in**. This is the default setting, and can be modified to expect various encodings. The ``unicode`` step serves both the purpose of rendering non-string expressions into strings (such as integers or objects which contain ``__str()__`` methods), and to ensure that the final output stream is constructed as a unicode object. The main implication of this is that **any raw byte-strings that contain an encoding other than ASCII must first be decoded to a Python unicode object**. It means you can't say this in Python 2: .. sourcecode:: mako ${"voix m’a réveillé."} ## error in Python 2! You must instead say this: .. sourcecode:: mako ${u"voix m’a réveillé."} ## OK ! Similarly, if you are reading data from a file that is streaming bytes, or returning data from some object that is returning a Python byte-string containing a non-ASCII encoding, you have to explicitly decode to unicode first, such as: .. sourcecode:: mako ${call_my_object().decode('utf-8')} Note that filehandles acquired by ``open()`` in Python 3 default to returning "text", that is the decoding is done for you. See Python 3's documentation for the ``open()`` built-in for details on this. If you want a certain encoding applied to *all* expressions, override the ``unicode`` builtin with the ``decode`` built-in at the :class:`.Template` or :class:`.TemplateLookup` level: .. sourcecode:: python t = Template(templatetext, default_filters=['decode.utf8']) Note that the built-in ``decode`` object is slower than the ``unicode`` function, since unlike ``unicode`` it's not a Python built-in, and it also checks the type of the incoming data to determine if string conversion is needed first. The ``default_filters`` argument can be used to entirely customize the filtering process of expressions. This argument is described in :ref:`filtering_default_filters`. .. _defining_output_encoding: Defining Output Encoding ======================== Now that we have a template which produces a pure unicode output stream, all the hard work is done. We can take the output and do anything with it. As stated in the :doc:`"Usage" chapter `, both :class:`.Template` and :class:`.TemplateLookup` accept ``output_encoding`` and ``encoding_errors`` parameters which can be used to encode the output in any Python supported codec: .. sourcecode:: python from mako.template import Template from mako.lookup import TemplateLookup mylookup = TemplateLookup(directories=['/docs'], output_encoding='utf-8', encoding_errors='replace') mytemplate = mylookup.get_template("foo.txt") print mytemplate.render() :meth:`~.Template.render` will return a ``bytes`` object in Python 3 if an output encoding is specified. By default it performs no encoding and returns a native string. :meth:`~.Template.render_unicode` will return the template output as a Python ``unicode`` object (or ``string`` in Python 3): .. sourcecode:: python print mytemplate.render_unicode() The above method disgards the output encoding keyword argument; you can encode yourself by saying: .. sourcecode:: python print mytemplate.render_unicode().encode('utf-8', 'replace') Buffer Selection ---------------- Mako does play some games with the style of buffering used internally, to maximize performance. Since the buffer is by far the most heavily used object in a render operation, it's important! When calling :meth:`~.Template.render` on a template that does not specify any output encoding (i.e. it's ``ascii``), Python's ``cStringIO`` module, which cannot handle encoding of non-ASCII ``unicode`` objects (even though it can send raw byte-strings through), is used for buffering. Otherwise, a custom Mako class called ``FastEncodingBuffer`` is used, which essentially is a super dumbed-down version of ``StringIO`` that gathers all strings into a list and uses ``u''.join(elements)`` to produce the final output -- it's markedly faster than ``StringIO``. .. _unicode_disabled: Saying to Heck with It: Disabling the Usage of Unicode Entirely =============================================================== Some segments of Mako's userbase choose to make no usage of Unicode whatsoever, and instead would prefer the "pass through" approach; all string expressions in their templates return encoded byte-strings, and they would like these strings to pass right through. The only advantage to this approach is that templates need not use ``u""`` for literal strings; there's an arguable speed improvement as well since raw byte-strings generally perform slightly faster than unicode objects in Python. For these users, assuming they're sticking with Python 2, they can hit the ``disable_unicode=True`` flag as so: .. sourcecode:: python # -*- coding:utf-8 -*- from mako.template import Template t = Template("drôle de petite voix m’a réveillé.", disable_unicode=True, input_encoding='utf-8') print t.code The ``disable_unicode`` mode is strictly a Python 2 thing. It is not supported at all in Python 3. The generated module source code will contain elements like these: .. sourcecode:: python # -*- coding:utf-8 -*- # ...more generated code ... def render_body(context,**pageargs): context.caller_stack.push_frame() try: __M_locals = dict(pageargs=pageargs) # SOURCE LINE 1 context.write('dr\xc3\xb4le de petite voix m\xe2\x80\x99a r\xc3\xa9veill\xc3\xa9.') return '' finally: context.caller_stack.pop_frame() Where above that the string literal used within :meth:`.Context.write` is a regular byte-string. When ``disable_unicode=True`` is turned on, the ``default_filters`` argument which normally defaults to ``["unicode"]`` now defaults to ``["str"]`` instead. Setting ``default_filters`` to the empty list ``[]`` can remove the overhead of the ``str`` call. Also, in this mode you **cannot** safely call :meth:`~.Template.render_unicode` -- you'll get unicode/decode errors. The ``h`` filter (HTML escape) uses a less performant pure Python escape function in non-unicode mode. This because MarkupSafe only supports Python unicode objects for non-ASCII strings. .. versionchanged:: 0.3.4 In prior versions, it used ``cgi.escape()``, which has been replaced with a function that also escapes single quotes. Rules for using ``disable_unicode=True`` ---------------------------------------- * Don't use this mode unless you really, really want to and you absolutely understand what you're doing. * Don't use this option just because you don't want to learn to use Unicode properly; we aren't supporting user issues in this mode of operation. We will however offer generous help for the vast majority of users who stick to the Unicode program. * Python 3 is unicode by default, and the flag is not available when running on Python 3. Mako-0.9.1/doc/_sources/usage.txt0000644000076500000240000004264412257136636017435 0ustar classicstaff00000000000000.. _usage_toplevel: ===== Usage ===== Basic Usage =========== This section describes the Python API for Mako templates. If you are using Mako within a web framework such as Pylons, the work of integrating Mako's API is already done for you, in which case you can skip to the next section, :ref:`syntax_toplevel`. The most basic way to create a template and render it is through the :class:`.Template` class: .. sourcecode:: python from mako.template import Template mytemplate = Template("hello world!") print mytemplate.render() Above, the text argument to :class:`.Template` is **compiled** into a Python module representation. This module contains a function called ``render_body()``, which produces the output of the template. When ``mytemplate.render()`` is called, Mako sets up a runtime environment for the template and calls the ``render_body()`` function, capturing the output into a buffer and returning its string contents. The code inside the ``render_body()`` function has access to a namespace of variables. You can specify these variables by sending them as additional keyword arguments to the :meth:`~.Template.render` method: .. sourcecode:: python from mako.template import Template mytemplate = Template("hello, ${name}!") print mytemplate.render(name="jack") The :meth:`~.Template.render` method calls upon Mako to create a :class:`.Context` object, which stores all the variable names accessible to the template and also stores a buffer used to capture output. You can create this :class:`.Context` yourself and have the template render with it, using the :meth:`~.Template.render_context` method: .. sourcecode:: python from mako.template import Template from mako.runtime import Context from StringIO import StringIO mytemplate = Template("hello, ${name}!") buf = StringIO() ctx = Context(buf, name="jack") mytemplate.render_context(ctx) print buf.getvalue() Using File-Based Templates ========================== A :class:`.Template` can also load its template source code from a file, using the ``filename`` keyword argument: .. sourcecode:: python from mako.template import Template mytemplate = Template(filename='/docs/mytmpl.txt') print mytemplate.render() For improved performance, a :class:`.Template` which is loaded from a file can also cache the source code to its generated module on the filesystem as a regular Python module file (i.e. a ``.py`` file). To do this, just add the ``module_directory`` argument to the template: .. sourcecode:: python from mako.template import Template mytemplate = Template(filename='/docs/mytmpl.txt', module_directory='/tmp/mako_modules') print mytemplate.render() When the above code is rendered, a file ``/tmp/mako_modules/docs/mytmpl.txt.py`` is created containing the source code for the module. The next time a :class:`.Template` with the same arguments is created, this module file will be automatically re-used. .. _usage_templatelookup: Using ``TemplateLookup`` ======================== All of the examples thus far have dealt with the usage of a single :class:`.Template` object. If the code within those templates tries to locate another template resource, it will need some way to find them, using simple URI strings. For this need, the resolution of other templates from within a template is accomplished by the :class:`.TemplateLookup` class. This class is constructed given a list of directories in which to search for templates, as well as keyword arguments that will be passed to the :class:`.Template` objects it creates: .. sourcecode:: python from mako.template import Template from mako.lookup import TemplateLookup mylookup = TemplateLookup(directories=['/docs']) mytemplate = Template("""<%include file="header.txt"/> hello world!""", lookup=mylookup) Above, we created a textual template which includes the file ``"header.txt"``. In order for it to have somewhere to look for ``"header.txt"``, we passed a :class:`.TemplateLookup` object to it, which will search in the directory ``/docs`` for the file ``"header.txt"``. Usually, an application will store most or all of its templates as text files on the filesystem. So far, all of our examples have been a little bit contrived in order to illustrate the basic concepts. But a real application would get most or all of its templates directly from the :class:`.TemplateLookup`, using the aptly named :meth:`~.TemplateLookup.get_template` method, which accepts the URI of the desired template: .. sourcecode:: python from mako.template import Template from mako.lookup import TemplateLookup mylookup = TemplateLookup(directories=['/docs'], module_directory='/tmp/mako_modules') def serve_template(templatename, **kwargs): mytemplate = mylookup.get_template(templatename) print mytemplate.render(**kwargs) In the example above, we create a :class:`.TemplateLookup` which will look for templates in the ``/docs`` directory, and will store generated module files in the ``/tmp/mako_modules`` directory. The lookup locates templates by appending the given URI to each of its search directories; so if you gave it a URI of ``/etc/beans/info.txt``, it would search for the file ``/docs/etc/beans/info.txt``, else raise a :class:`.TopLevelNotFound` exception, which is a custom Mako exception. When the lookup locates templates, it will also assign a ``uri`` property to the :class:`.Template` which is the URI passed to the :meth:`~.TemplateLookup.get_template()` call. :class:`.Template` uses this URI to calculate the name of its module file. So in the above example, a ``templatename`` argument of ``/etc/beans/info.txt`` will create a module file ``/tmp/mako_modules/etc/beans/info.txt.py``. Setting the Collection Size --------------------------- The :class:`.TemplateLookup` also serves the important need of caching a fixed set of templates in memory at a given time, so that successive URI lookups do not result in full template compilations and/or module reloads on each request. By default, the :class:`.TemplateLookup` size is unbounded. You can specify a fixed size using the ``collection_size`` argument: .. sourcecode:: python mylookup = TemplateLookup(directories=['/docs'], module_directory='/tmp/mako_modules', collection_size=500) The above lookup will continue to load templates into memory until it reaches a count of around 500. At that point, it will clean out a certain percentage of templates using a least recently used scheme. Setting Filesystem Checks ------------------------- Another important flag on :class:`.TemplateLookup` is ``filesystem_checks``. This defaults to ``True``, and says that each time a template is returned by the :meth:`~.TemplateLookup.get_template()` method, the revision time of the original template file is checked against the last time the template was loaded, and if the file is newer will reload its contents and recompile the template. On a production system, setting ``filesystem_checks`` to ``False`` can afford a small to moderate performance increase (depending on the type of filesystem used). .. _usage_unicode: Using Unicode and Encoding ========================== Both :class:`.Template` and :class:`.TemplateLookup` accept ``output_encoding`` and ``encoding_errors`` parameters which can be used to encode the output in any Python supported codec: .. sourcecode:: python from mako.template import Template from mako.lookup import TemplateLookup mylookup = TemplateLookup(directories=['/docs'], output_encoding='utf-8', encoding_errors='replace') mytemplate = mylookup.get_template("foo.txt") print mytemplate.render() When using Python 3, the :meth:`~.Template.render` method will return a ``bytes`` object, **if** ``output_encoding`` is set. Otherwise it returns a ``string``. Additionally, the :meth:`~.Template.render_unicode()` method exists which will return the template output as a Python ``unicode`` object, or in Python 3 a ``string``: .. sourcecode:: python print mytemplate.render_unicode() The above method disregards the output encoding keyword argument; you can encode yourself by saying: .. sourcecode:: python print mytemplate.render_unicode().encode('utf-8', 'replace') Note that Mako's ability to return data in any encoding and/or ``unicode`` implies that the underlying output stream of the template is a Python unicode object. This behavior is described fully in :ref:`unicode_toplevel`. .. _handling_exceptions: Handling Exceptions =================== Template exceptions can occur in two distinct places. One is when you **lookup, parse and compile** the template, the other is when you **run** the template. Within the running of a template, exceptions are thrown normally from whatever Python code originated the issue. Mako has its own set of exception classes which mostly apply to the lookup and lexer/compiler stages of template construction. Mako provides some library routines that can be used to help provide Mako-specific information about any exception's stack trace, as well as formatting the exception within textual or HTML format. In all cases, the main value of these handlers is that of converting Python filenames, line numbers, and code samples into Mako template filenames, line numbers, and code samples. All lines within a stack trace which correspond to a Mako template module will be converted to be against the originating template file. To format exception traces, the :func:`.text_error_template` and :func:`.html_error_template` functions are provided. They make usage of ``sys.exc_info()`` to get at the most recently thrown exception. Usage of these handlers usually looks like: .. sourcecode:: python from mako import exceptions try: template = lookup.get_template(uri) print template.render() except: print exceptions.text_error_template().render() Or for the HTML render function: .. sourcecode:: python from mako import exceptions try: template = lookup.get_template(uri) print template.render() except: print exceptions.html_error_template().render() The :func:`.html_error_template` template accepts two options: specifying ``full=False`` causes only a section of an HTML document to be rendered. Specifying ``css=False`` will disable the default stylesheet from being rendered. E.g.: .. sourcecode:: python print exceptions.html_error_template().render(full=False) The HTML render function is also available built-in to :class:`.Template` using the ``format_exceptions`` flag. In this case, any exceptions raised within the **render** stage of the template will result in the output being substituted with the output of :func:`.html_error_template`: .. sourcecode:: python template = Template(filename="/foo/bar", format_exceptions=True) print template.render() Note that the compile stage of the above template occurs when you construct the :class:`.Template` itself, and no output stream is defined. Therefore exceptions which occur within the lookup/parse/compile stage will not be handled and will propagate normally. While the pre-render traceback usually will not include any Mako-specific lines anyway, it will mean that exceptions which occur previous to rendering and those which occur within rendering will be handled differently... so the ``try``/``except`` patterns described previously are probably of more general use. The underlying object used by the error template functions is the :class:`.RichTraceback` object. This object can also be used directly to provide custom error views. Here's an example usage which describes its general API: .. sourcecode:: python from mako.exceptions import RichTraceback try: template = lookup.get_template(uri) print template.render() except: traceback = RichTraceback() for (filename, lineno, function, line) in traceback.traceback: print "File %s, line %s, in %s" % (filename, lineno, function) print line, "\n" print "%s: %s" % (str(traceback.error.__class__.__name__), traceback.error) Common Framework Integrations ============================= The Mako distribution includes a little bit of helper code for the purpose of using Mako in some popular web framework scenarios. This is a brief description of what's included. WSGI ---- A sample WSGI application is included in the distribution in the file ``examples/wsgi/run_wsgi.py``. This runner is set up to pull files from a `templates` as well as an `htdocs` directory and includes a rudimental two-file layout. The WSGI runner acts as a fully functional standalone web server, using ``wsgiutils`` to run itself, and propagates GET and POST arguments from the request into the :class:`.Context`, can serve images, CSS files and other kinds of files, and also displays errors using Mako's included exception-handling utilities. Pygments -------- A `Pygments `_-compatible syntax highlighting module is included under :mod:`mako.ext.pygmentplugin`. This module is used in the generation of Mako documentation and also contains various `setuptools` entry points under the heading ``pygments.lexers``, including ``mako``, ``html+mako``, ``xml+mako`` (see the ``setup.py`` file for all the entry points). Babel ----- Mako provides support for extracting `gettext` messages from templates via a `Babel`_ extractor entry point under ``mako.ext.babelplugin``. `Gettext` messages are extracted from all Python code sections, including those of control lines and expressions embedded in tags. `Translator comments `_ may also be extracted from Mako templates when a comment tag is specified to `Babel`_ (such as with the ``-c`` option). For example, a project ``"myproj"`` contains the following Mako template at ``myproj/myproj/templates/name.html``: .. sourcecode:: mako
Name: ## TRANSLATORS: This is a proper name. See the gettext ## manual, section Names. ${_('Francois Pinard')}
To extract gettext messages from this template the project needs a Mako section in its `Babel Extraction Method Mapping file `_ (typically located at ``myproj/babel.cfg``): .. sourcecode:: cfg # Extraction from Python source files [python: myproj/**.py] # Extraction from Mako templates [mako: myproj/templates/**.html] input_encoding = utf-8 The Mako extractor supports an optional ``input_encoding`` parameter specifying the encoding of the templates (identical to :class:`.Template`/:class:`.TemplateLookup`'s ``input_encoding`` parameter). Invoking `Babel`_'s extractor at the command line in the project's root directory: .. sourcecode:: sh myproj$ pybabel extract -F babel.cfg -c "TRANSLATORS:" . will output a `gettext` catalog to `stdout` including the following: .. sourcecode:: pot #. TRANSLATORS: This is a proper name. See the gettext #. manual, section Names. #: myproj/templates/name.html:5 msgid "Francois Pinard" msgstr "" This is only a basic example: `Babel`_ can be invoked from ``setup.py`` and its command line options specified in the accompanying ``setup.cfg`` via `Babel Distutils/Setuptools Integration `_. Comments must immediately precede a `gettext` message to be extracted. In the following case the ``TRANSLATORS:`` comment would not have been extracted: .. sourcecode:: mako
## TRANSLATORS: This is a proper name. See the gettext ## manual, section Names. Name: ${_('Francois Pinard')}
See the `Babel User Guide `_ for more information. .. _babel: http://babel.edgewall.org/ API Reference ============= .. autoclass:: mako.template.Template :show-inheritance: :members: .. autoclass:: mako.template.DefTemplate :show-inheritance: :members: .. autoclass:: mako.lookup.TemplateCollection :show-inheritance: :members: .. autoclass:: mako.lookup.TemplateLookup :show-inheritance: :members: .. autoclass:: mako.exceptions.RichTraceback :show-inheritance: .. py:attribute:: error the exception instance. .. py:attribute:: message the exception error message as unicode. .. py:attribute:: source source code of the file where the error occurred. If the error occurred within a compiled template, this is the template source. .. py:attribute:: lineno line number where the error occurred. If the error occurred within a compiled template, the line number is adjusted to that of the template source. .. py:attribute:: records a list of 8-tuples containing the original python traceback elements, plus the filename, line number, source line, and full template source for the traceline mapped back to its originating source template, if any for that traceline (else the fields are ``None``). .. py:attribute:: reverse_records the list of records in reverse traceback -- a list of 4-tuples, in the same format as a regular python traceback, with template-corresponding traceback records replacing the originals. .. py:attribute:: reverse_traceback the traceback list in reverse. .. autofunction:: mako.exceptions.html_error_template .. autofunction:: mako.exceptions.text_error_template Mako-0.9.1/doc/_static/0000755000076500000240000000000012257137143015354 5ustar classicstaff00000000000000Mako-0.9.1/doc/_static/basic.css0000644000076500000240000002041712257136657017164 0ustar classicstaff00000000000000/* * basic.css * ~~~~~~~~~ * * Sphinx stylesheet -- basic theme. * * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ /* -- main layout ----------------------------------------------------------- */ div.clearer { clear: both; } /* -- relbar ---------------------------------------------------------------- */ div.related { width: 100%; font-size: 90%; } div.related h3 { display: none; } div.related ul { margin: 0; padding: 0 0 0 10px; list-style: none; } div.related li { display: inline; } div.related li.right { float: right; margin-right: 5px; } /* -- sidebar --------------------------------------------------------------- */ div.sphinxsidebarwrapper { padding: 10px 5px 0 10px; } div.sphinxsidebar { float: left; width: 230px; margin-left: -100%; font-size: 90%; } div.sphinxsidebar ul { list-style: none; } div.sphinxsidebar ul ul, div.sphinxsidebar ul.want-points { margin-left: 20px; list-style: square; } div.sphinxsidebar ul ul { margin-top: 0; margin-bottom: 0; } div.sphinxsidebar form { margin-top: 10px; } div.sphinxsidebar input { border: 1px solid #98dbcc; font-family: sans-serif; font-size: 1em; } div.sphinxsidebar #searchbox input[type="text"] { width: 170px; } div.sphinxsidebar #searchbox input[type="submit"] { width: 30px; } img { border: 0; } /* -- search page ----------------------------------------------------------- */ ul.search { margin: 10px 0 0 20px; padding: 0; } ul.search li { padding: 5px 0 5px 20px; background-image: url(file.png); background-repeat: no-repeat; background-position: 0 7px; } ul.search li a { font-weight: bold; } ul.search li div.context { color: #888; margin: 2px 0 0 30px; text-align: left; } ul.keywordmatches li.goodmatch a { font-weight: bold; } /* -- index page ------------------------------------------------------------ */ table.contentstable { width: 90%; } table.contentstable p.biglink { line-height: 150%; } a.biglink { font-size: 1.3em; } span.linkdescr { font-style: italic; padding-top: 5px; font-size: 90%; } /* -- general index --------------------------------------------------------- */ table.indextable { width: 100%; } table.indextable td { text-align: left; vertical-align: top; } table.indextable dl, table.indextable dd { margin-top: 0; margin-bottom: 0; } table.indextable tr.pcap { height: 10px; } table.indextable tr.cap { margin-top: 10px; background-color: #f2f2f2; } img.toggler { margin-right: 3px; margin-top: 3px; cursor: pointer; } div.modindex-jumpbox { border-top: 1px solid #ddd; border-bottom: 1px solid #ddd; margin: 1em 0 1em 0; padding: 0.4em; } div.genindex-jumpbox { border-top: 1px solid #ddd; border-bottom: 1px solid #ddd; margin: 1em 0 1em 0; padding: 0.4em; } /* -- general body styles --------------------------------------------------- */ a.headerlink { visibility: hidden; } h1:hover > a.headerlink, h2:hover > a.headerlink, h3:hover > a.headerlink, h4:hover > a.headerlink, h5:hover > a.headerlink, h6:hover > a.headerlink, dt:hover > a.headerlink { visibility: visible; } div.body p.caption { text-align: inherit; } div.body td { text-align: left; } .field-list ul { padding-left: 1em; } .first { margin-top: 0 !important; } p.rubric { margin-top: 30px; font-weight: bold; } img.align-left, .figure.align-left, object.align-left { clear: left; float: left; margin-right: 1em; } img.align-right, .figure.align-right, object.align-right { clear: right; float: right; margin-left: 1em; } img.align-center, .figure.align-center, object.align-center { display: block; margin-left: auto; margin-right: auto; } .align-left { text-align: left; } .align-center { text-align: center; } .align-right { text-align: right; } /* -- sidebars -------------------------------------------------------------- */ div.sidebar { margin: 0 0 0.5em 1em; border: 1px solid #ddb; padding: 7px 7px 0 7px; background-color: #ffe; width: 40%; float: right; } p.sidebar-title { font-weight: bold; } /* -- topics ---------------------------------------------------------------- */ div.topic { border: 1px solid #ccc; padding: 7px 7px 0 7px; margin: 10px 0 10px 0; } p.topic-title { font-size: 1.1em; font-weight: bold; margin-top: 10px; } /* -- admonitions ----------------------------------------------------------- */ div.admonition { margin-top: 10px; margin-bottom: 10px; padding: 7px; } div.admonition dt { font-weight: bold; } div.admonition dl { margin-bottom: 0; } p.admonition-title { margin: 0px 10px 5px 0px; font-weight: bold; } div.body p.centered { text-align: center; margin-top: 25px; } /* -- tables ---------------------------------------------------------------- */ table.docutils { border: 0; border-collapse: collapse; } table.docutils td, table.docutils th { padding: 1px 8px 1px 5px; border-top: 0; border-left: 0; border-right: 0; border-bottom: 1px solid #aaa; } table.field-list td, table.field-list th { border: 0 !important; } table.footnote td, table.footnote th { border: 0 !important; } th { text-align: left; padding-right: 5px; } table.citation { border-left: solid 1px gray; margin-left: 1px; } table.citation td { border-bottom: none; } /* -- other body styles ----------------------------------------------------- */ ol.arabic { list-style: decimal; } ol.loweralpha { list-style: lower-alpha; } ol.upperalpha { list-style: upper-alpha; } ol.lowerroman { list-style: lower-roman; } ol.upperroman { list-style: upper-roman; } dl { margin-bottom: 15px; } dd p { margin-top: 0px; } dd ul, dd table { margin-bottom: 10px; } dd { margin-top: 3px; margin-bottom: 10px; margin-left: 30px; } dt:target, .highlighted { background-color: #fbe54e; } dl.glossary dt { font-weight: bold; font-size: 1.1em; } .field-list ul { margin: 0; padding-left: 1em; } .field-list p { margin: 0; } .refcount { color: #060; } .optional { font-size: 1.3em; } .versionmodified { font-style: italic; } .system-message { background-color: #fda; padding: 5px; border: 3px solid red; } .footnote:target { background-color: #ffa; } .line-block { display: block; margin-top: 1em; margin-bottom: 1em; } .line-block .line-block { margin-top: 0; margin-bottom: 0; margin-left: 1.5em; } .guilabel, .menuselection { font-family: sans-serif; } .accelerator { text-decoration: underline; } .classifier { font-style: oblique; } abbr, acronym { border-bottom: dotted 1px; cursor: help; } /* -- code displays --------------------------------------------------------- */ pre { overflow: auto; overflow-y: hidden; /* fixes display issues on Chrome browsers */ } td.linenos pre { padding: 5px 0px; border: 0; background-color: transparent; color: #aaa; } table.highlighttable { margin-left: 0.5em; } table.highlighttable td { padding: 0 0.5em 0 0.5em; } tt.descname { background-color: transparent; font-weight: bold; font-size: 1.2em; } tt.descclassname { background-color: transparent; } tt.xref, a tt { background-color: transparent; font-weight: bold; } h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { background-color: transparent; } .viewcode-link { float: right; } .viewcode-back { float: right; font-family: sans-serif; } div.viewcode-block:target { margin: -1px -10px; padding: 0 10px; } /* -- math display ---------------------------------------------------------- */ img.math { vertical-align: middle; } div.body div.math p { text-align: center; } span.eqno { float: right; } /* -- printout stylesheet --------------------------------------------------- */ @media print { div.document, div.documentwrapper, div.bodywrapper { margin: 0 !important; width: 100%; } div.sphinxsidebar, div.related, div.footer, #top-link { display: none; } }Mako-0.9.1/doc/_static/comment-bright.png0000644000076500000240000000665412167630573021021 0ustar classicstaff00000000000000PNG  IHDRa OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3-bKGD pHYs  tIME 6 B\<IDAT8˅Kh]es1mA`jh[-E(FEaA!bIȐ*BX"؁4)NURZ!Mhjssm؋^-\gg ]o|Ҭ[346>zd ]#8Oݺt{5uIXN!I=@Vf=v1}e>;fvnvxaHrʪJF`D¹WZ]S%S)WAb |0K=So7D~\~q-˟\aMZ,S'*} F`Nnz674U H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3-bKGD pHYs  tIME!,IDAT8e_Hu?}s3y˕U2MvQ֊FE.łĊbE$DDZF5b@Q":2{n.s<_ y?mwV@tR`}Z _# _=_@ w^R%6gC-έ(K>| ${} H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3-bKGD pHYs  tIME 1;VIDAT8ukU?sg4h`G1 RQܸp%Bn"bЍXJ .4V iZ##T;m!4bP~7r>ιbwc;m;oӍAΆ ζZ^/|s{;yR=9(rtVoG1w#_ө{*E&!(LVuoᲵ‘D PG4 :&~*ݳreu: S-,U^E&JY[P!RB ŖޞʖR@_ȐdBfNvHf"2T]R j'B1ddAak/DIJD D2H&L`&L $Ex,6|~_\P $MH`I=@Z||ttvgcЕWTZ'3rje"ܵx9W> mb|byfFRx{w%DZC$wdցHmWnta(M<~;9]C/_;Տ#}o`zSڷ_>:;x컓?yݩ|}~wam-/7=0S5RP"*֯ IENDB`Mako-0.9.1/doc/_static/default.css0000644000076500000240000000771012257136657017530 0ustar classicstaff00000000000000/* * default.css_t * ~~~~~~~~~~~~~ * * Sphinx stylesheet -- default theme. * * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ @import url("basic.css"); /* -- page layout ----------------------------------------------------------- */ body { font-family: sans-serif; font-size: 100%; background-color: #11303d; color: #000; margin: 0; padding: 0; } div.document { background-color: #1c4e63; } div.documentwrapper { float: left; width: 100%; } div.bodywrapper { margin: 0 0 0 230px; } div.body { background-color: #ffffff; color: #000000; padding: 0 20px 30px 20px; } div.footer { color: #ffffff; width: 100%; padding: 9px 0 9px 0; text-align: center; font-size: 75%; } div.footer a { color: #ffffff; text-decoration: underline; } div.related { background-color: #133f52; line-height: 30px; color: #ffffff; } div.related a { color: #ffffff; } div.sphinxsidebar { } div.sphinxsidebar h3 { font-family: 'Trebuchet MS', sans-serif; color: #ffffff; font-size: 1.4em; font-weight: normal; margin: 0; padding: 0; } div.sphinxsidebar h3 a { color: #ffffff; } div.sphinxsidebar h4 { font-family: 'Trebuchet MS', sans-serif; color: #ffffff; font-size: 1.3em; font-weight: normal; margin: 5px 0 0 0; padding: 0; } div.sphinxsidebar p { color: #ffffff; } div.sphinxsidebar p.topless { margin: 5px 10px 10px 10px; } div.sphinxsidebar ul { margin: 10px; padding: 0; color: #ffffff; } div.sphinxsidebar a { color: #98dbcc; } div.sphinxsidebar input { border: 1px solid #98dbcc; font-family: sans-serif; font-size: 1em; } /* -- hyperlink styles ------------------------------------------------------ */ a { color: #355f7c; text-decoration: none; } a:visited { color: #355f7c; text-decoration: none; } a:hover { text-decoration: underline; } /* -- body styles ----------------------------------------------------------- */ div.body h1, div.body h2, div.body h3, div.body h4, div.body h5, div.body h6 { font-family: 'Trebuchet MS', sans-serif; background-color: #f2f2f2; font-weight: normal; color: #20435c; border-bottom: 1px solid #ccc; margin: 20px -20px 10px -20px; padding: 3px 0 3px 10px; } div.body h1 { margin-top: 0; font-size: 200%; } div.body h2 { font-size: 160%; } div.body h3 { font-size: 140%; } div.body h4 { font-size: 120%; } div.body h5 { font-size: 110%; } div.body h6 { font-size: 100%; } a.headerlink { color: #c60f0f; font-size: 0.8em; padding: 0 4px 0 4px; text-decoration: none; } a.headerlink:hover { background-color: #c60f0f; color: white; } div.body p, div.body dd, div.body li { text-align: justify; line-height: 130%; } div.admonition p.admonition-title + p { display: inline; } div.admonition p { margin-bottom: 5px; } div.admonition pre { margin-bottom: 5px; } div.admonition ul, div.admonition ol { margin-bottom: 5px; } div.note { background-color: #eee; border: 1px solid #ccc; } div.seealso { background-color: #ffc; border: 1px solid #ff6; } div.topic { background-color: #eee; } div.warning { background-color: #ffe4e4; border: 1px solid #f66; } p.admonition-title { display: inline; } p.admonition-title:after { content: ":"; } pre { padding: 5px; background-color: #eeffcc; color: #333333; line-height: 120%; border: 1px solid #ac9; border-left: none; border-right: none; } tt { background-color: #ecf0f3; padding: 0 1px 0 1px; font-size: 0.95em; } th { background-color: #ede; } .warning tt { background: #efc2c2; } .note tt { background: #d6d6d6; } .viewcode-back { font-family: sans-serif; } div.viewcode-block:target { background-color: #f4debf; border-top: 1px solid #ac9; border-bottom: 1px solid #ac9; }Mako-0.9.1/doc/_static/docs.css0000644000076500000240000001554212257136636017033 0ustar classicstaff00000000000000/* global */ body { background-color: #FDFBFC; margin:38px; color:#333333; } a { font-weight:normal; text-decoration:none; } form { display:inline; } /* hyperlinks */ a:link, a:visited, a:active { color:#0000FF; } a:hover { color:#700000; text-decoration:underline; } /* paragraph links after sections. These aren't visible until hovering over the tag, then have a "reverse video" effect over the actual link */ a.headerlink { font-size: 0.8em; padding: 0 4px 0 4px; text-decoration: none; visibility: hidden; } h1:hover > a.headerlink, h2:hover > a.headerlink, h3:hover > a.headerlink, h4:hover > a.headerlink, h5:hover > a.headerlink, h6:hover > a.headerlink, dt:hover > a.headerlink { visibility: visible; } a.headerlink:hover { background-color: #990000; color: white; } /* Container setup */ #docs-container { max-width:1000px; } /* header/footer elements */ #docs-header h1 { font-size:20px; color: #222222; margin: 0; padding: 0; } #docs-header { font-family:Tahoma, Geneva,sans-serif; font-size:.9em; } #docs-top-navigation, #docs-bottom-navigation { font-family: Tahoma, Geneva, sans-serif; background-color: #EEE; border: solid 1px #CCC; padding:10px; font-size:.9em; } #docs-top-navigation { margin:10px 0px 10px 0px; line-height:1.2em; } .docs-navigation-links { font-family:Tahoma, Geneva,sans-serif; } #docs-bottom-navigation { float:right; margin: 1em 0 1em 5px; } #docs-copyright { font-size:.85em; padding:5px 0px; } #docs-header h1, #docs-top-navigation h1, #docs-top-navigation h2 { font-family:Tahoma,Geneva,sans-serif; font-weight:normal; } #docs-top-navigation h2 { margin:16px 4px 7px 5px; font-size:2em; } #docs-search { float:right; } #docs-top-page-control { float:right; width:350px; } #docs-top-page-control ul { padding:0; margin:0; } #docs-top-page-control li { list-style-type:none; padding:1px 8px; } #docs-container .version-num { font-weight: bold; } /* content container, sidebar */ #docs-body-container { background-color:#EFEFEF; border: solid 1px #CCC; } #docs-body, #docs-sidebar { /*font-family: helvetica, arial, sans-serif; font-size:.9em;*/ font-family: Tahoma, Geneva, sans-serif; /*font-size:.85em;*/ line-height:1.5em; } #docs-sidebar > ul { font-size:.9em; } #docs-sidebar { float:left; width:212px; padding: 10px 0 0 15px; /*font-size:.85em;*/ } #docs-sidebar h3, #docs-sidebar h4 { background-color: #DDDDDD; color: #222222; font-family: Tahoma, Geneva,sans-serif; font-size: 1.1em; font-weight: normal; margin: 10px 0 0 -15px; padding: 5px 10px 5px 10px; text-shadow: 1px 1px 0 white; width:210px; } #docs-sidebar h3 a, #docs-sidebar h4 a { color: #222222; } #docs-sidebar ul { margin: 10px 10px 10px 0px; padding: 0; list-style: none outside none; } #docs-sidebar ul ul { margin-bottom: 0; margin-top: 0; list-style: square outside none; margin-left: 20px; } #docs-body { background-color:#FFFFFF; padding:1px 10px 10px 10px; } #docs-body.withsidebar { margin: 0 0 0 230px; border-left:3px solid #DFDFDF; } #docs-body h1, #docs-body h2, #docs-body h3, #docs-body h4 { font-family:Tahoma, Geneva, sans-serif; } #docs-body h1 { /* hide the

for each content section. */ display:none; font-size:1.8em; } #docs-body h2 { font-size:1.6em; } #docs-body h3 { font-size:1.4em; } /* SQL popup, code styles */ .highlight { background:none; } #docs-container pre { font-size:1.2em; } #docs-container .pre { font-size:1.1em; } #docs-container pre { background-color: #f0f0f0; border: solid 1px #ccc; box-shadow: 2px 2px 3px #DFDFDF; padding:10px; margin: 5px 0px 5px 0px; overflow:auto; line-height:1.3em; } .popup_sql, .show_sql { background-color: #FBFBEE; padding:5px 10px; margin:10px -5px; border:1px dashed; } /* the [SQL] links used to display SQL */ #docs-container .sql_link { font-weight:normal; font-family: arial, sans-serif; font-size:.9em; text-transform: uppercase; color:#990000; border:1px solid; padding:1px 2px 1px 2px; margin:0px 10px 0px 15px; float:right; line-height:1.2em; } #docs-container a.sql_link, #docs-container .sql_link { text-decoration: none; padding:1px 2px; } #docs-container a.sql_link:hover { text-decoration: none; color:#fff; border:1px solid #900; background-color: #900; } /* docutils-specific elements */ th.field-name { text-align:right; } div.note, div.warning, p.deprecated, div.topic { background-color:#EEFFEF; } div.admonition, div.topic, p.deprecated, p.versionadded, p.versionchanged { border:1px solid #CCCCCC; padding:5px 10px; font-size:.9em; box-shadow: 2px 2px 3px #DFDFDF; } div.warning .admonition-title { color:#FF0000; } div.admonition .admonition-title, div.topic .topic-title { font-weight:bold; } .viewcode-back, .viewcode-link { float:right; } dl.function > dt, dl.attribute > dt, dl.classmethod > dt, dl.method > dt, dl.class > dt, dl.exception > dt { background-color:#F0F0F0; margin:25px -10px 10px 10px; padding: 0px 10px; } p.versionadded span.versionmodified, p.versionchanged span.versionmodified, p.deprecated span.versionmodified { background-color: #F0F0F0; font-style: italic; } dt:target, span.highlight { background-color:#FBE54E; } a.headerlink { font-size: 0.8em; padding: 0 4px 0 4px; text-decoration: none; visibility: hidden; } h1:hover > a.headerlink, h2:hover > a.headerlink, h3:hover > a.headerlink, h4:hover > a.headerlink, h5:hover > a.headerlink, h6:hover > a.headerlink, dt:hover > a.headerlink { visibility: visible; } a.headerlink:hover { background-color: #00f; color: white; } .clearboth { clear:both; } tt.descname { background-color:transparent; font-size:1.2em; font-weight:bold; } tt.descclassname { background-color:transparent; } tt { background-color:#ECF0F3; padding:0 1px; } /* syntax highlighting overrides */ .k, .kn {color:#0908CE;} .o {color:#BF0005;} .go {color:#804049;} /* special "index page" sections with specific formatting */ div#sqlalchemy-documentation { font-size:.95em; } div#sqlalchemy-documentation em { font-style:normal; } div#sqlalchemy-documentation .rubric{ font-size:14px; background-color:#EEFFEF; padding:5px; border:1px solid #BFBFBF; } div#sqlalchemy-documentation a, div#sqlalchemy-documentation li { padding:5px 0px; } div#getting-started { border-bottom:1px solid; } div#sqlalchemy-documentation div#sqlalchemy-orm { float:left; width:48%; } div#sqlalchemy-documentation div#sqlalchemy-core { float:left; width:48%; margin:0; padding-left:10px; border-left:1px solid; } div#dialect-documentation { border-top:1px solid; /*clear:left;*/ } Mako-0.9.1/doc/_static/doctools.js0000644000076500000240000001473412167630573017556 0ustar classicstaff00000000000000/* * doctools.js * ~~~~~~~~~~~ * * Sphinx JavaScript utilities for all documentation. * * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ /** * select a different prefix for underscore */ $u = _.noConflict(); /** * make the code below compatible with browsers without * an installed firebug like debugger if (!window.console || !console.firebug) { var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"]; window.console = {}; for (var i = 0; i < names.length; ++i) window.console[names[i]] = function() {}; } */ /** * small helper function to urldecode strings */ jQuery.urldecode = function(x) { return decodeURIComponent(x).replace(/\+/g, ' '); }; /** * small helper function to urlencode strings */ jQuery.urlencode = encodeURIComponent; /** * This function returns the parsed url parameters of the * current request. Multiple values per key are supported, * it will always return arrays of strings for the value parts. */ jQuery.getQueryParameters = function(s) { if (typeof s == 'undefined') s = document.location.search; var parts = s.substr(s.indexOf('?') + 1).split('&'); var result = {}; for (var i = 0; i < parts.length; i++) { var tmp = parts[i].split('=', 2); var key = jQuery.urldecode(tmp[0]); var value = jQuery.urldecode(tmp[1]); if (key in result) result[key].push(value); else result[key] = [value]; } return result; }; /** * highlight a given string on a jquery object by wrapping it in * span elements with the given class name. */ jQuery.fn.highlightText = function(text, className) { function highlight(node) { if (node.nodeType == 3) { var val = node.nodeValue; var pos = val.toLowerCase().indexOf(text); if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) { var span = document.createElement("span"); span.className = className; span.appendChild(document.createTextNode(val.substr(pos, text.length))); node.parentNode.insertBefore(span, node.parentNode.insertBefore( document.createTextNode(val.substr(pos + text.length)), node.nextSibling)); node.nodeValue = val.substr(0, pos); } } else if (!jQuery(node).is("button, select, textarea")) { jQuery.each(node.childNodes, function() { highlight(this); }); } } return this.each(function() { highlight(this); }); }; /** * Small JavaScript module for the documentation. */ var Documentation = { init : function() { this.fixFirefoxAnchorBug(); this.highlightSearchWords(); this.initIndexTable(); }, /** * i18n support */ TRANSLATIONS : {}, PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; }, LOCALE : 'unknown', // gettext and ngettext don't access this so that the functions // can safely bound to a different name (_ = Documentation.gettext) gettext : function(string) { var translated = Documentation.TRANSLATIONS[string]; if (typeof translated == 'undefined') return string; return (typeof translated == 'string') ? translated : translated[0]; }, ngettext : function(singular, plural, n) { var translated = Documentation.TRANSLATIONS[singular]; if (typeof translated == 'undefined') return (n == 1) ? singular : plural; return translated[Documentation.PLURALEXPR(n)]; }, addTranslations : function(catalog) { for (var key in catalog.messages) this.TRANSLATIONS[key] = catalog.messages[key]; this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); this.LOCALE = catalog.locale; }, /** * add context elements like header anchor links */ addContextElements : function() { $('div[id] > :header:first').each(function() { $('\u00B6'). attr('href', '#' + this.id). attr('title', _('Permalink to this headline')). appendTo(this); }); $('dt[id]').each(function() { $('\u00B6'). attr('href', '#' + this.id). attr('title', _('Permalink to this definition')). appendTo(this); }); }, /** * workaround a firefox stupidity */ fixFirefoxAnchorBug : function() { if (document.location.hash && $.browser.mozilla) window.setTimeout(function() { document.location.href += ''; }, 10); }, /** * highlight the search words provided in the url in the text */ highlightSearchWords : function() { var params = $.getQueryParameters(); var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; if (terms.length) { var body = $('div.body'); window.setTimeout(function() { $.each(terms, function() { body.highlightText(this.toLowerCase(), 'highlighted'); }); }, 10); $('') .appendTo($('#searchbox')); } }, /** * init the domain index toggle buttons */ initIndexTable : function() { var togglers = $('img.toggler').click(function() { var src = $(this).attr('src'); var idnum = $(this).attr('id').substr(7); $('tr.cg-' + idnum).toggle(); if (src.substr(-9) == 'minus.png') $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); else $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); }).css('display', ''); if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { togglers.click(); } }, /** * helper function to hide the search marks again */ hideSearchWords : function() { $('#searchbox .highlight-link').fadeOut(300); $('span.highlighted').removeClass('highlighted'); }, /** * make the url absolute */ makeURL : function(relativeURL) { return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; }, /** * get the current relative url */ getCurrentURL : function() { var path = document.location.pathname; var parts = path.split(/\//); $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { if (this == '..') parts.pop(); }); var url = parts.join('/'); return path.substring(url.lastIndexOf('/') + 1, path.length - 1); } }; // quick alias for translations _ = Documentation.gettext; $(document).ready(function() { Documentation.init(); }); Mako-0.9.1/doc/_static/down-pressed.png0000644000076500000240000000056012167630573020502 0ustar classicstaff00000000000000PNG  IHDRasRGBbKGDC pHYs B(xtIME -vF#IDAT8!OAJ, ++@I vbÿ@W7F HN#48646TMvv޼7Dsax1U q;< E-f)j%po4xF78G>)- EYm4%7YTk-Qa"NWAo-yeq,) Ypt\hqmszG]Nar߶s^l vh\2%0EeRvIENDB`Mako-0.9.1/doc/_static/down.png0000644000076500000240000000055312167630573017041 0ustar classicstaff00000000000000PNG  IHDRasRGBbKGDC pHYs B(xtIME"U{IDAT8ҡNCAJ, ++@4>/U^,~T&3M^^^PM6ٹs*RJa)eG*W<"F Fg78G>q OIp:sAj5GنyD^+yU:p_%G@D|aOs(yM,"msx:.b@D|`Vٟ۲иeKſ/G!IENDB`Mako-0.9.1/doc/_static/file.png0000644000076500000240000000061012167630573017003 0ustar classicstaff00000000000000PNG  IHDRabKGD pHYs  tIME  )TIDAT8˭J@Ir('[ "&xYZ X0!i|_@tD] #xjv YNaEi(əy@D&`6PZk$)5%"z.NA#Aba`Vs_3c,2mj [klvy|!Iմy;v "߮a?A7`c^nk?Bg}TЙD# "RD1yER*6MJ3K_Ut8F~IENDB`Mako-0.9.1/doc/_static/jquery.js0000644000076500000240000026725412167630573017256 0ustar classicstaff00000000000000/*! jQuery v1.7.1 jquery.com | jquery.org/license */ (function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cv(a){if(!ck[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){cl||(cl=c.createElement("iframe"),cl.frameBorder=cl.width=cl.height=0),b.appendChild(cl);if(!cm||!cl.createElement)cm=(cl.contentWindow||cl.contentDocument).document,cm.write((c.compatMode==="CSS1Compat"?"":"")+""),cm.close();d=cm.createElement(a),cm.body.appendChild(d),e=f.css(d,"display"),b.removeChild(cl)}ck[a]=e}return ck[a]}function cu(a,b){var c={};f.each(cq.concat.apply([],cq.slice(0,b)),function(){c[this]=a});return c}function ct(){cr=b}function cs(){setTimeout(ct,0);return cr=f.now()}function cj(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ci(){try{return new a.XMLHttpRequest}catch(b){}}function cc(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){if(c!=="border")for(;g=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?parseFloat(d):j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c
a",d=q.getElementsByTagName("*"),e=q.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=q.getElementsByTagName("input")[0],b={leadingWhitespace:q.firstChild.nodeType===3,tbody:!q.getElementsByTagName("tbody").length,htmlSerialize:!!q.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:q.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete q.test}catch(s){b.deleteExpando=!1}!q.addEventListener&&q.attachEvent&&q.fireEvent&&(q.attachEvent("onclick",function(){b.noCloneEvent=!1}),q.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),q.appendChild(i),k=c.createDocumentFragment(),k.appendChild(q.lastChild),b.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,k.removeChild(i),k.appendChild(q),q.innerHTML="",a.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",q.style.width="2px",q.appendChild(j),b.reliableMarginRight=(parseInt((a.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(q.attachEvent)for(o in{submit:1,change:1,focusin:1})n="on"+o,p=n in q,p||(q.setAttribute(n,"return;"),p=typeof q[n]=="function"),b[o+"Bubbles"]=p;k.removeChild(q),k=g=h=j=q=i=null,f(function(){var a,d,e,g,h,i,j,k,m,n,o,r=c.getElementsByTagName("body")[0];!r||(j=1,k="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",m="visibility:hidden;border:0;",n="style='"+k+"border:5px solid #000;padding:0;'",o="
"+""+"
",a=c.createElement("div"),a.style.cssText=m+"width:0;height:0;position:static;top:0;margin-top:"+j+"px",r.insertBefore(a,r.firstChild),q=c.createElement("div"),a.appendChild(q),q.innerHTML="
t
",l=q.getElementsByTagName("td"),p=l[0].offsetHeight===0,l[0].style.display="",l[1].style.display="none",b.reliableHiddenOffsets=p&&l[0].offsetHeight===0,q.innerHTML="",q.style.width=q.style.paddingLeft="1px",f.boxModel=b.boxModel=q.offsetWidth===2,typeof q.style.zoom!="undefined"&&(q.style.display="inline",q.style.zoom=1,b.inlineBlockNeedsLayout=q.offsetWidth===2,q.style.display="",q.innerHTML="
",b.shrinkWrapBlocks=q.offsetWidth!==2),q.style.cssText=k+m,q.innerHTML=o,d=q.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,i={doesNotAddBorder:e.offsetTop!==5,doesAddBorderForTableAndCells:h.offsetTop===5},e.style.position="fixed",e.style.top="20px",i.fixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",i.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,i.doesNotIncludeMarginInBodyOffset=r.offsetTop!==j,r.removeChild(a),q=a=null,f.extend(b,i))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;h=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/\bhover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")}; f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;le&&i.push({elem:this,matches:d.slice(e)});for(j=0;j0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h0)for(h=g;h=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/",""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div
","
"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function() {for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1>");try{for(var c=0,d=this.length;c1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||!bc.test("<"+a.nodeName)?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=bg[l]||bg._default,n=m[0],o=b.createElement("div");b===c?bh.appendChild(o):U(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]===""&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return br.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bq,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bq.test(g)?g.replace(bq,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bz(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bA=function(a,b){var c,d,e;b=b.replace(bs,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b)));return c}),c.documentElement.currentStyle&&(bB=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f===null&&g&&(e=g[b])&&(f=e),!bt.test(f)&&bu.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f||0,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),bz=bA||bB,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bD=/%20/g,bE=/\[\]$/,bF=/\r?\n/g,bG=/#.*$/,bH=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bI=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bJ=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bK=/^(?:GET|HEAD)$/,bL=/^\/\//,bM=/\?/,bN=/)<[^<]*)*<\/script>/gi,bO=/^(?:select|textarea)/i,bP=/\s+/,bQ=/([?&])_=[^&]*/,bR=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bS=f.fn.load,bT={},bU={},bV,bW,bX=["*/"]+["*"];try{bV=e.href}catch(bY){bV=c.createElement("a"),bV.href="",bV=bV.href}bW=bR.exec(bV.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bS)return bS.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
").append(c.replace(bN,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bO.test(this.nodeName)||bI.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bF,"\r\n")}}):{name:b.name,value:c.replace(bF,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b_(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b_(a,b);return a},ajaxSettings:{url:bV,isLocal:bJ.test(bW[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bX},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bZ(bT),ajaxTransport:bZ(bU),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?cb(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cc(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bH.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bG,"").replace(bL,bW[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bP),d.crossDomain==null&&(r=bR.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bW[1]&&r[2]==bW[2]&&(r[3]||(r[1]==="http:"?80:443))==(bW[3]||(bW[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),b$(bT,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bK.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bM.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bQ,"$1_="+x);d.url=y+(y===d.url?(bM.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bX+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=b$(bU,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)ca(g,a[g],c,e);return d.join("&").replace(bD,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cd=f.now(),ce=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cd++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ce.test(b.url)||e&&ce.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ce,l),b.url===j&&(e&&(k=k.replace(ce,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cf=a.ActiveXObject?function(){for(var a in ch)ch[a](0,1)}:!1,cg=0,ch;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ci()||cj()}:ci,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cf&&delete ch[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cg,cf&&(ch||(ch={},f(a).unload(cf)),ch[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var ck={},cl,cm,cn=/^(?:toggle|show|hide)$/,co=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cp,cq=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cr;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cu("show",3),a,b,c);for(var g=0,h=this.length;g=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cy(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cy(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,d,"padding")):this[d]():null},f.fn["outer"+c]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,d,a?"margin":"border")):this[d]():null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNumeric(j)?j:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window);Mako-0.9.1/doc/_static/makoLogo.png0000644000076500000240000002670312257136636017650 0ustar classicstaff00000000000000PNG  IHDRd gAMAOX2tEXtSoftwareAdobe ImageReadyqe<-UIDATxb?(D`cgprrb022b#'O0̚5a >| V+&<K s1k@ 4? Y 7k@f0@1fQ0Й ]!-Qzoܸð~zwR. @l Ħ@F e{@|7hbeQ<,-->}.xBBX-9@_Ak$Z4Zϟ3,_ٳg)BXw MϠr e bHKKcb/fϟ?&@ 4hT?~d>}:r')A};@;8/" 5#mxS fB4Z'O2XXX C3\$t vWx?o#q;ڟ\\\~~~!!!AAA{2 L6 9!@D6 >G W# !! ++ˠȠag,P:;;TBGh3i BCk $6qt(Ԡ --k='466 M@̂YFM͛7#k֬a.elV J${4ɀ<A527o0|ŋ`a`u eeeb >lFRR@4pB`-/&{[}/H:u?0wʔ)l"6(\3[X QK???phBt~ ֭[ 0x4؟"I/(b\5pyy94F1'e6& ΝL?`ݰ_b8^ZZ\  F#}hf7ukd0L\8ʖd`3ß4٣xm0@o@3O>2 E_> .0p F#y jzch2Y[[7ݽ&>`( zt$ N(7ߴi:Z {PTTDp@xPv35ا?Ro4x}Wj_ɮ.Sj FW|݃ @(j sfq;w*++SPbahPn?[]]}zg?S@o߾Qpd :t2f̘,Z{O SVBjd 01ւw7#z }z@gA; ht 8wۑ@˂ЦJW ʰd%%%Z@530|F=!ttY5Ȥ~Xg w7fY#(ymhc&hSEE'xsQ H=H`gf.Y MhDQUU0!Ј"B):舂*T[ԩS qZm.~ *7 DQ }`f1Ҩw t` YdáG޽]ȍAٱcM->f_UgL _fh:7@2|pe4 F3fZ&}kTO"&At4qÁ$U&ph. hy_z~ \zzUd۷if@dC"hQ&C*rȜG"dC>d4d 6˒% :1d7Zd.Ҭ&e]< 4<VP 0Lh&03031iZf>:PKpV9Y'}h\de2*ˌ(,fa /Qd'M4>gÛ_ @#t @fp2 3d_>}V`Ăfgcjݟn7d(APAi >NvN6A>. 4k.OiZ.eU p߹u$3 XN]yHNO _dLp EL 4PXZ/0Q~ex Ãgo%6zD L$? r beo> -@ aZB'8ؘy!NdhQ@髏 7LF6Y63prr1X._m:BMqqe^ՠD%0y˷_R$$6bFA /~f0ӑǨm|ps_0mHؙ '#;} *M_ppgfgtMx3!Aih,űg6@&-2r ^'M4K0@qMt,=]{D+@5(X K3 搀bO@_ ̐B oXSIAVB#dTdcB'T7#0"2iu*M2 !FAW! (aR2WXY3(%.aF)0ȃ ǖv>@| t# 9kw2{<8+Qj’^@  ī[@ yŅx$Dp7A?|$?2h%hf Z4o.Bl';;lDN ƃ)y !iz_LťIVa%=Cua:x @19y'zAC_w 5# 0e1@.z$LЅRt7t1(#g3@.Z#5t@5\`&֯<4pq`+qBd% Y N٨C3B`M~fb0Rt<~f8~>A5M!j"'haRC32|l3Æ (]gj,N޼vٟrndfX ;;C ï_XΣW1g ّ& XֆQc 5(YTӜvQ!3$PM Tӂ.jxHS߳ep߈UtC O!JDžzt+!/3V} ͠ - m.B2 BOז% [*{ XB{~|?s CazYh*Gpqk^>~)9n0~!a _]jbK! X K P@K5wP3QOL%{@jo޽g8}0A'Ⱞ0ˀ 2h j%>ge7yAqʙ d֏XX+DcA`xj8{2[ l- )\`w gEeUL&#>yY K\H9~ф@L7^Rt6^&v ^4$ @`*#Ġ@m?`ÕOão#3uȟӁX6{P`A>`nS?ُn `n: /_>1ϟ?ɠcZebPQPVÐWTVc1`ǰ%g2bu-0 A2Өu:@~A}5}1AAИ7^^ fS00qa@k_{Po gއ4S&cd0#ͥq> ϟ?AM9ATkakhА:1t@e.x@ t'0@P"ڂ@A`4,=$p :4PŁ`@[D8 fϧO@exEuqIiϟRBL\^Z)''Q& +7f j T ObAT h[h@2)`SJ[;0|@dLi?|A:lƁ4pb MOĀ $2Ȍx̭6]@\pM/G"x-3@lWf`ce5DIM6t=CV 27BD>(ـvQT`8ނq@)l 4 &OkWVP [dz < ߾b=junf3W0r1% @CY Tg@:& f41@&׉]{C{'…h$hNOJX|X8ϤEys(4 <\]F{H3?8S2&6íW(k nFA52? ǐ5fV2A @wK)ZP@ | 7 ԤOLJDHUy:.Gbd` L#`;B6Yj@V@JQLF8W ͬ[U~/`T;VÐ݇LjB2-<W^~jPf@"~dx ݇T? F_ -O*{Hh.ȴCw&3&_0/F-3(ĠQKo l@躧T kfl&{ O1> ]@߿#pv ex5ٶ@}?>` jzB2 skK dX[d D́P{_  6rf'/ -Aͼ*x3311lw: g@'mN`iTZg-~)H/;c-fyTm{ @ىQMdQ` L;0Q` A{/qtfX|}_ ?d/..Hiix&XEAG^0*JFMZVL<@U`mW- @ *Z`*Mp{k&y T&~vxT̈́F%}JҀG121"4C1zُht '&w9h$N%~Jk t~6߸@+Giwdؾy-6"Ho^}UU (AWC[;HT>Z E߭dDS`8212Ʊ 5)K)9% `S #)׏)hrߊN?b޼m#\tύ>xYH-#pjg|l @fd:Dž(;m#~دT `DZegpfVGL2`ϤŸ}Bv?K VvN`x~>@ |8`i~h؁.~ 4#UK̍La;d.T'P\@J03!f,^(H/ CkЦUȾ)pՖ߾~aE 0Phې4l3&3A-l菞~EPD 06/ANvmvܩ/=m#"" +w;Vw;?d/E rbvr1\qPyoA Q3p O~-C ]4!o}Ȱc1ZzܡtM0A XG?UP4v6t l:  f hf+Q2J082lZ,M֊:F2*7L);}-k!|VFFVp5 ltx8^}p%0Ph 4 ,!!@囷;T0 ްm?A}aL@@ zee ڏjuh%}( Ip!: b"Bt=SL͛] ߽!]wolhjqˉ>mXz&G >@#q!SPoP@;(Z\' LPYE0s5Дn!i -aΚM;=@w`T;O  A]Me`/~); ~P] yAP^IL@ɐ;0E:z,rgh ^KUAC N 4``g2P.ZtSCؠL ̬ ~! Hmu}Q/yɽk "7i'U.Of.8TQf#mV&d~9c f O=32B}V8y- j?UܽumZW@h- v1Mÿ ?/m_UT2-4@C0V%Ʒށ'ݑ<#;zML1.,6+P_4ZXX:{ v\d`6 (RiC퓁Ũhf&zFr7F匠>##$/-U& TSMa 4P3C 8%?3kۺqU9tw!oX )d2nMVdԍE:r VQͤ0ش Y/T[ fl! !NoFNׯ B"J*-7^@99`n +(?Ӭz WD>] TV̳PquR%XLLLqșˁr< -LnZ30)M?ghP&-M<򗃓EXTL4XAf:e7Y@Q&\aMbtdhNghQPBlfàx_ȹ\o߾C c0|=z"o_89A,ǏVj:7o]يa , (o^ A? G S. d[*Ԕmxy!+>pi;,It6^C=-  *|0"&ɨ7 '`|$1O~89\ -A gAf=X*@! *Z ۿm=Lr@_8)0t 覞+33nt ?# D Wx *.":iG,]]X4sZR0 0_pاeFu4'@fӷojMa^=_,\N?2x3()Pl(@Ѥz9'aB ZY;7̔;q 0 J1'ƠytЀ(ۘ08P`rs/ w'6ivj_qml@4@QH( : 0'@B[ t)0.6,11AR%EBf8@QwMM 5%10efu#OB< ^*d2I^=kg6|f4`XSUCNvfbb R`gO0\|/ g(--ePQQ>8!k?I `JaA64 N@N09s(ЦI%`ash>:͝m/>G'0ӡM T8;gWt3|'޿{/=ax 5k!|dVu3##J͆\QX~ΓG* op-B^PH24o0@RԒ@ÁAj$LLYYپ}aӚe~@GT.K9mX@\}HPMSưUyæm;޽՘Q RJPL3Z_ P!'=wЇ7`S6;$%j =}^2c{(JT-iM@ Ԅla;w=@,si apa0aرk?ñ^~ p%U{#*3"@A,%-CMw2 -]E8`4c8|$ÁCG3`" zb%"hj!ڏ+ZOO!++ARRxEȐpWK4ob8u<{޽N;PjBFb J f&Z i&5MY3]pm`5ް7;({Ν::;Ա $Ѡ튊A] vAAқG:Ǐ^y /hTNB\ Q2(~X{̙ K,^CA`+*l_D78>SQ&((ƣ`p5;+3xI th1&Z`1 F3(v@R & @fQ0.\ TkR@ CNV`PW'm F3(v:XAH" 2 P[HJ3htc ;;UUU0 jt (%4bP)hbYY fj 37'3Cee%M2h&a~sYˋnL6 %S4u @fQ0,FKPMfAMD%%% F3(@FFA_eK >Y& -4FgLIwrss%L6 - hedP4F jj(4_b'L6 -F9? + F3(tZq74>i%0“"XIENDB`Mako-0.9.1/doc/_static/minus.png0000644000076500000240000000030712167630573017222 0ustar classicstaff00000000000000PNG  IHDR &q pHYs  tIME <8tEXtComment̖RIDATcz(BpipPc |IENDB`Mako-0.9.1/doc/_static/pygments.css0000644000076500000240000000753412257136657017756 0ustar classicstaff00000000000000.highlight .hll { background-color: #ffffcc } .highlight { background: #eeffcc; } .highlight .c { color: #408090; font-style: italic } /* Comment */ .highlight .err { border: 1px solid #FF0000 } /* Error */ .highlight .k { color: #007020; font-weight: bold } /* Keyword */ .highlight .o { color: #666666 } /* Operator */ .highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */ .highlight .cp { color: #007020 } /* Comment.Preproc */ .highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */ .highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */ .highlight .gd { color: #A00000 } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .gr { color: #FF0000 } /* Generic.Error */ .highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ .highlight .gi { color: #00A000 } /* Generic.Inserted */ .highlight .go { color: #333333 } /* Generic.Output */ .highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ .highlight .gt { color: #0044DD } /* Generic.Traceback */ .highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #007020 } /* Keyword.Pseudo */ .highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #902000 } /* Keyword.Type */ .highlight .m { color: #208050 } /* Literal.Number */ .highlight .s { color: #4070a0 } /* Literal.String */ .highlight .na { color: #4070a0 } /* Name.Attribute */ .highlight .nb { color: #007020 } /* Name.Builtin */ .highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */ .highlight .no { color: #60add5 } /* Name.Constant */ .highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */ .highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */ .highlight .ne { color: #007020 } /* Name.Exception */ .highlight .nf { color: #06287e } /* Name.Function */ .highlight .nl { color: #002070; font-weight: bold } /* Name.Label */ .highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */ .highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #bb60d5 } /* Name.Variable */ .highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mf { color: #208050 } /* Literal.Number.Float */ .highlight .mh { color: #208050 } /* Literal.Number.Hex */ .highlight .mi { color: #208050 } /* Literal.Number.Integer */ .highlight .mo { color: #208050 } /* Literal.Number.Oct */ .highlight .sb { color: #4070a0 } /* Literal.String.Backtick */ .highlight .sc { color: #4070a0 } /* Literal.String.Char */ .highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */ .highlight .s2 { color: #4070a0 } /* Literal.String.Double */ .highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */ .highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */ .highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */ .highlight .sx { color: #c65d09 } /* Literal.String.Other */ .highlight .sr { color: #235388 } /* Literal.String.Regex */ .highlight .s1 { color: #4070a0 } /* Literal.String.Single */ .highlight .ss { color: #517918 } /* Literal.String.Symbol */ .highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */ .highlight .vc { color: #bb60d5 } /* Name.Variable.Class */ .highlight .vg { color: #bb60d5 } /* Name.Variable.Global */ .highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */ .highlight .il { color: #208050 } /* Literal.Number.Integer.Long */Mako-0.9.1/doc/_static/searchtools.js0000644000076500000240000004264712257136657020266 0ustar classicstaff00000000000000/* * searchtools.js_t * ~~~~~~~~~~~~~~~~ * * Sphinx JavaScript utilties for the full-text search. * * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ /** * Porter Stemmer */ var Stemmer = function() { var step2list = { ational: 'ate', tional: 'tion', enci: 'ence', anci: 'ance', izer: 'ize', bli: 'ble', alli: 'al', entli: 'ent', eli: 'e', ousli: 'ous', ization: 'ize', ation: 'ate', ator: 'ate', alism: 'al', iveness: 'ive', fulness: 'ful', ousness: 'ous', aliti: 'al', iviti: 'ive', biliti: 'ble', logi: 'log' }; var step3list = { icate: 'ic', ative: '', alize: 'al', iciti: 'ic', ical: 'ic', ful: '', ness: '' }; var c = "[^aeiou]"; // consonant var v = "[aeiouy]"; // vowel var C = c + "[^aeiouy]*"; // consonant sequence var V = v + "[aeiou]*"; // vowel sequence var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 var s_v = "^(" + C + ")?" + v; // vowel in stem this.stemWord = function (w) { var stem; var suffix; var firstch; var origword = w; if (w.length < 3) return w; var re; var re2; var re3; var re4; firstch = w.substr(0,1); if (firstch == "y") w = firstch.toUpperCase() + w.substr(1); // Step 1a re = /^(.+?)(ss|i)es$/; re2 = /^(.+?)([^s])s$/; if (re.test(w)) w = w.replace(re,"$1$2"); else if (re2.test(w)) w = w.replace(re2,"$1$2"); // Step 1b re = /^(.+?)eed$/; re2 = /^(.+?)(ed|ing)$/; if (re.test(w)) { var fp = re.exec(w); re = new RegExp(mgr0); if (re.test(fp[1])) { re = /.$/; w = w.replace(re,""); } } else if (re2.test(w)) { var fp = re2.exec(w); stem = fp[1]; re2 = new RegExp(s_v); if (re2.test(stem)) { w = stem; re2 = /(at|bl|iz)$/; re3 = new RegExp("([^aeiouylsz])\\1$"); re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); if (re2.test(w)) w = w + "e"; else if (re3.test(w)) { re = /.$/; w = w.replace(re,""); } else if (re4.test(w)) w = w + "e"; } } // Step 1c re = /^(.+?)y$/; if (re.test(w)) { var fp = re.exec(w); stem = fp[1]; re = new RegExp(s_v); if (re.test(stem)) w = stem + "i"; } // Step 2 re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; if (re.test(w)) { var fp = re.exec(w); stem = fp[1]; suffix = fp[2]; re = new RegExp(mgr0); if (re.test(stem)) w = stem + step2list[suffix]; } // Step 3 re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; if (re.test(w)) { var fp = re.exec(w); stem = fp[1]; suffix = fp[2]; re = new RegExp(mgr0); if (re.test(stem)) w = stem + step3list[suffix]; } // Step 4 re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; re2 = /^(.+?)(s|t)(ion)$/; if (re.test(w)) { var fp = re.exec(w); stem = fp[1]; re = new RegExp(mgr1); if (re.test(stem)) w = stem; } else if (re2.test(w)) { var fp = re2.exec(w); stem = fp[1] + fp[2]; re2 = new RegExp(mgr1); if (re2.test(stem)) w = stem; } // Step 5 re = /^(.+?)e$/; if (re.test(w)) { var fp = re.exec(w); stem = fp[1]; re = new RegExp(mgr1); re2 = new RegExp(meq1); re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) w = stem; } re = /ll$/; re2 = new RegExp(mgr1); if (re.test(w) && re2.test(w)) { re = /.$/; w = w.replace(re,""); } // and turn initial Y back to y if (firstch == "y") w = firstch.toLowerCase() + w.substr(1); return w; } } /** * Simple result scoring code. */ var Scorer = { // Implement the following function to further tweak the score for each result // The function takes a result array [filename, title, anchor, descr, score] // and returns the new score. /* score: function(result) { return result[4]; }, */ // query matches the full name of an object objNameMatch: 11, // or matches in the last dotted part of the object name objPartialMatch: 6, // Additive scores depending on the priority of the object objPrio: {0: 15, // used to be importantResults 1: 5, // used to be objectResults 2: -5}, // used to be unimportantResults // Used when the priority is not in the mapping. objPrioDefault: 0, // query found in title title: 15, // query found in terms term: 5 }; /** * Search Module */ var Search = { _index : null, _queued_query : null, _pulse_status : -1, init : function() { var params = $.getQueryParameters(); if (params.q) { var query = params.q[0]; $('input[name="q"]')[0].value = query; this.performSearch(query); } }, loadIndex : function(url) { $.ajax({type: "GET", url: url, data: null, dataType: "script", cache: true, complete: function(jqxhr, textstatus) { if (textstatus != "success") { document.getElementById("searchindexloader").src = url; } }}); }, setIndex : function(index) { var q; this._index = index; if ((q = this._queued_query) !== null) { this._queued_query = null; Search.query(q); } }, hasIndex : function() { return this._index !== null; }, deferQuery : function(query) { this._queued_query = query; }, stopPulse : function() { this._pulse_status = 0; }, startPulse : function() { if (this._pulse_status >= 0) return; function pulse() { var i; Search._pulse_status = (Search._pulse_status + 1) % 4; var dotString = ''; for (i = 0; i < Search._pulse_status; i++) dotString += '.'; Search.dots.text(dotString); if (Search._pulse_status > -1) window.setTimeout(pulse, 500); } pulse(); }, /** * perform a search for something (or wait until index is loaded) */ performSearch : function(query) { // create the required interface elements this.out = $('#search-results'); this.title = $('

' + _('Searching') + '

').appendTo(this.out); this.dots = $('').appendTo(this.title); this.status = $('

').appendTo(this.out); this.output = $('
'); } // Prettify the comment rating. comment.pretty_rating = comment.rating + ' point' + (comment.rating == 1 ? '' : 's'); // Make a class (for displaying not yet moderated comments differently) comment.css_class = comment.displayed ? '' : ' moderate'; // Create a div for this comment. var context = $.extend({}, opts, comment); var div = $(renderTemplate(commentTemplate, context)); // If the user has voted on this comment, highlight the correct arrow. if (comment.vote) { var direction = (comment.vote == 1) ? 'u' : 'd'; div.find('#' + direction + 'v' + comment.id).hide(); div.find('#' + direction + 'u' + comment.id).show(); } if (opts.moderator || comment.text != '[deleted]') { div.find('a.reply').show(); if (comment.proposal_diff) div.find('#sp' + comment.id).show(); if (opts.moderator && !comment.displayed) div.find('#cm' + comment.id).show(); if (opts.moderator || (opts.username == comment.username)) div.find('#dc' + comment.id).show(); } return div; } /** * A simple template renderer. Placeholders such as <%id%> are replaced * by context['id'] with items being escaped. Placeholders such as <#id#> * are not escaped. */ function renderTemplate(template, context) { var esc = $(document.createElement('div')); function handle(ph, escape) { var cur = context; $.each(ph.split('.'), function() { cur = cur[this]; }); return escape ? esc.text(cur || "").html() : cur; } return template.replace(/<([%#])([\w\.]*)\1>/g, function() { return handle(arguments[2], arguments[1] == '%' ? true : false); }); } /** Flash an error message briefly. */ function showError(message) { $(document.createElement('div')).attr({'class': 'popup-error'}) .append($(document.createElement('div')) .attr({'class': 'error-message'}).text(message)) .appendTo('body') .fadeIn("slow") .delay(2000) .fadeOut("slow"); } /** Add a link the user uses to open the comments popup. */ $.fn.comment = function() { return this.each(function() { var id = $(this).attr('id').substring(1); var count = COMMENT_METADATA[id]; var title = count + ' comment' + (count == 1 ? '' : 's'); var image = count > 0 ? opts.commentBrightImage : opts.commentImage; var addcls = count == 0 ? ' nocomment' : ''; $(this) .append( $(document.createElement('a')).attr({ href: '#', 'class': 'sphinx-comment-open' + addcls, id: 'ao' + id }) .append($(document.createElement('img')).attr({ src: image, alt: 'comment', title: title })) .click(function(event) { event.preventDefault(); show($(this).attr('id').substring(2)); }) ) .append( $(document.createElement('a')).attr({ href: '#', 'class': 'sphinx-comment-close hidden', id: 'ah' + id }) .append($(document.createElement('img')).attr({ src: opts.closeCommentImage, alt: 'close', title: 'close' })) .click(function(event) { event.preventDefault(); hide($(this).attr('id').substring(2)); }) ); }); }; var opts = { processVoteURL: '/_process_vote', addCommentURL: '/_add_comment', getCommentsURL: '/_get_comments', acceptCommentURL: '/_accept_comment', deleteCommentURL: '/_delete_comment', commentImage: '/static/_static/comment.png', closeCommentImage: '/static/_static/comment-close.png', loadingImage: '/static/_static/ajax-loader.gif', commentBrightImage: '/static/_static/comment-bright.png', upArrow: '/static/_static/up.png', downArrow: '/static/_static/down.png', upArrowPressed: '/static/_static/up-pressed.png', downArrowPressed: '/static/_static/down-pressed.png', voting: false, moderator: false }; if (typeof COMMENT_OPTIONS != "undefined") { opts = jQuery.extend(opts, COMMENT_OPTIONS); } var popupTemplate = '\
\

\ Sort by:\ best rated\ newest\ oldest\

\
Comments
\
\ loading comments...
\
    \
    \

    Add a comment\ (markup):

    \
    \ reStructured text markup: *emph*, **strong**, \ ``code``, \ code blocks: :: and an indented block after blank line
    \
    \ \

    \ \ Propose a change ▹\ \ \ Propose a change ▿\ \

    \ \ \ \ \ \
    \
    '; var commentTemplate = '\
    \
    \
    \ \ \ \ \ \ \
    \
    \ \ \ \ \ \ \
    \
    \
    \

    \ <%username%>\ <%pretty_rating%>\ <%time.delta%>\

    \
    <#text#>
    \

    \ \ reply ▿\ proposal ▹\ proposal ▿\ \ \

    \
    \
    <#proposal_diff#>\
            
    \
      \
      \
      \
      \ '; var replyTemplate = '\
    • \
      \
      \ \ \ \ \ \ \
      \
    • '; $(document).ready(function() { init(); }); })(jQuery); $(document).ready(function() { // add comment anchors for all paragraphs that are commentable $('.sphinx-has-comment').comment(); // highlight search words in search results $("div.context").each(function() { var params = $.getQueryParameters(); var terms = (params.q) ? params.q[0].split(/\s+/) : []; var result = $(this); $.each(terms, function() { result.highlightText(this.toLowerCase(), 'highlighted'); }); }); // directly open comment window if requested var anchor = document.location.hash; if (anchor.substring(0, 9) == '#comment-') { $('#ao' + anchor.substring(9)).click(); document.location.hash = '#s' + anchor.substring(9); } }); Mako-0.9.1/doc/build/0000755000076500000240000000000012257137143015025 5ustar classicstaff00000000000000Mako-0.9.1/doc/build/builder/0000755000076500000240000000000012257137143016453 5ustar classicstaff00000000000000Mako-0.9.1/doc/build/builder/__init__.py0000644000076500000240000000000012257136636020560 0ustar classicstaff00000000000000Mako-0.9.1/doc/build/builder/builders.py0000644000076500000240000000705412257136636020652 0ustar classicstaff00000000000000from sphinx.application import TemplateBridge from sphinx.builders.html import StandaloneHTMLBuilder from sphinx.highlighting import PygmentsBridge from sphinx.jinja2glue import BuiltinTemplateLoader from pygments import highlight from pygments.lexer import RegexLexer, bygroups, using from pygments.token import * from pygments.filter import Filter, apply_filters from pygments.lexers import PythonLexer, PythonConsoleLexer from pygments.formatters import HtmlFormatter, LatexFormatter import re import os from mako.lookup import TemplateLookup from mako.template import Template from mako.ext.pygmentplugin import MakoLexer rtd = os.environ.get('READTHEDOCS', None) == 'True' class MakoBridge(TemplateBridge): def init(self, builder, *args, **kw): self.jinja2_fallback = BuiltinTemplateLoader() self.jinja2_fallback.init(builder, *args, **kw) builder.config.html_context['site_base'] = builder.config['site_base'] self.lookup = TemplateLookup( directories=builder.config.templates_path, imports=[ "from builder import util" ], #format_exceptions=True, ) def render(self, template, context): template = template.replace(".html", ".mako") context['prevtopic'] = context.pop('prev', None) context['nexttopic'] = context.pop('next', None) # RTD layout if rtd: # add variables if not present, such # as if local test of READTHEDOCS variable if 'MEDIA_URL' not in context: context['MEDIA_URL'] = "http://media.readthedocs.org/" if 'slug' not in context: context['slug'] = "mako-test-slug" if 'url' not in context: context['url'] = "/some/test/url" if 'current_version' not in context: context['current_version'] = "some_version" if 'versions' not in context: context['versions'] = [('default', '/default/')] context['docs_base'] = "http://readthedocs.org" context['toolbar'] = True context['layout'] = "rtd_layout.mako" context['pdf_url'] = "%spdf/%s/%s/%s.pdf" % ( context['MEDIA_URL'], context['slug'], context['current_version'], context['slug'] ) # local docs layout else: context['toolbar'] = False context['docs_base'] = "/" context['layout'] = "layout.mako" context.setdefault('_', lambda x:x) return self.lookup.get_template(template).render_unicode(**context) def render_string(self, template, context): # this is used for .js, .css etc. and we don't have # local copies of that stuff here so use the jinja render. return self.jinja2_fallback.render_string(template, context) class StripDocTestFilter(Filter): def filter(self, lexer, stream): for ttype, value in stream: if ttype is Token.Comment and re.match(r'#\s*doctest:', value): continue yield ttype, value def autodoc_skip_member(app, what, name, obj, skip, options): if what == 'class' and skip and name == '__init__': return False else: return skip def setup(app): # app.connect('autodoc-skip-member', autodoc_skip_member) # Mako is already in Pygments, adding the local # lexer here so that the latest syntax is available app.add_lexer('mako', MakoLexer()) app.add_config_value('site_base', "", True) Mako-0.9.1/doc/build/builder/util.py0000644000076500000240000000044612257136636020014 0ustar classicstaff00000000000000import re def striptags(text): return re.compile(r'<[^>]*>').sub('', text) def go(m): # .html with no anchor if present, otherwise "#" for top of page return m.group(1) or '#' def strip_toplevel_anchors(text): return re.compile(r'(\.html)?#[-\w]+-toplevel').sub(go, text) Mako-0.9.1/doc/build/caching.rst0000644000076500000240000003302012257136636017157 0ustar classicstaff00000000000000.. _caching_toplevel: ======= Caching ======= Any template or component can be cached using the ``cache`` argument to the ``<%page>``, ``<%def>`` or ``<%block>`` directives: .. sourcecode:: mako <%page cached="True"/> template text The above template, after being executed the first time, will store its content within a cache that by default is scoped within memory. Subsequent calls to the template's :meth:`~.Template.render` method will return content directly from the cache. When the :class:`.Template` object itself falls out of scope, its corresponding cache is garbage collected along with the template. By default, caching requires that the `Beaker `_ package be installed on the system, however the mechanism of caching can be customized to use any third party or user defined system -- see :ref:`cache_plugins`. In addition to being available on the ``<%page>`` tag, the caching flag and all its options can be used with the ``<%def>`` tag as well: .. sourcecode:: mako <%def name="mycomp" cached="True" cache_timeout="60"> other text ... and equivalently with the ``<%block>`` tag, anonymous or named: .. sourcecode:: mako <%block cached="True" cache_timeout="60"> other text Cache Arguments =============== Mako has two cache arguments available on tags that are available in all cases. The rest of the arguments available are specific to a backend. The two generic tags arguments are: * ``cached="True"`` - enable caching for this ``<%page>``, ``<%def>``, or ``<%block>``. * ``cache_key`` - the "key" used to uniquely identify this content in the cache. Usually, this key is chosen automatically based on the name of the rendering callable (i.e. ``body`` when used in ``<%page>``, the name of the def when using ``<%def>``, the explicit or internally-generated name when using ``<%block>``). Using the ``cache_key`` parameter, the key can be overridden using a fixed or programmatically generated value. For example, here's a page that caches any page which inherits from it, based on the filename of the calling template: .. sourcecode:: mako <%page cached="True" cache_key="${self.filename}"/> ${next.body()} ## rest of template On a :class:`.Template` or :class:`.TemplateLookup`, the caching can be configured using these arguments: * ``cache_enabled`` - Setting this to ``False`` will disable all caching functionality when the template renders. Defaults to ``True``. e.g.: .. sourcecode:: python lookup = TemplateLookup( directories='/path/to/templates', cache_enabled = False ) * ``cache_impl`` - The string name of the cache backend to use. This defaults to ``'beaker'``, which has historically been the only cache backend supported by Mako. .. versionadded:: 0.6.0 For example, here's how to use the upcoming `dogpile.cache `_ backend: .. sourcecode:: python lookup = TemplateLookup( directories='/path/to/templates', cache_impl = 'dogpile.cache', cache_args = {'regions':my_dogpile_regions} ) * ``cache_args`` - A dictionary of cache parameters that will be consumed by the cache backend. See :ref:`beaker_backend` for examples. .. versionadded:: 0.6.0 Backend-Specific Cache Arguments -------------------------------- The ``<%page>``, ``<%def>``, and ``<%block>`` tags accept any named argument that starts with the prefix ``"cache_"``. Those arguments are then packaged up and passed along to the underlying caching implementation, minus the ``"cache_"`` prefix. The actual arguments understood are determined by the backend. * :ref:`beaker_backend` - Includes arguments understood by Beaker. * :ref:`dogpile.cache_backend` - Includes arguments understood by dogpile.cache. .. _beaker_backend: Using the Beaker Cache Backend ------------------------------ When using Beaker, new implementations will want to make usage of **cache regions** so that cache configurations can be maintained externally to templates. These configurations live under named "regions" that can be referred to within templates themselves. .. versionadded:: 0.6.0 Support for Beaker cache regions. For example, suppose we would like two regions. One is a "short term" region that will store content in a memory-based dictionary, expiring after 60 seconds. The other is a Memcached region, where values should expire in five minutes. To configure our :class:`.TemplateLookup`, first we get a handle to a :class:`beaker.cache.CacheManager`: .. sourcecode:: python from beaker.cache import CacheManager manager = CacheManager(cache_regions={ 'short_term':{ 'type': 'memory', 'expire': 60 }, 'long_term':{ 'type': 'ext:memcached', 'url': '127.0.0.1:11211', 'expire': 300 } }) lookup = TemplateLookup( directories=['/path/to/templates'], module_directory='/path/to/modules', cache_impl='beaker', cache_args={ 'manager':manager } ) Our templates can then opt to cache data in one of either region, using the ``cache_region`` argument. Such as using ``short_term`` at the ``<%page>`` level: .. sourcecode:: mako <%page cached="True" cache_region="short_term"> ## ... Or, ``long_term`` at the ``<%block>`` level: .. sourcecode:: mako <%block name="header" cached="True" cache_region="long_term"> other text The Beaker backend also works without regions. There are a variety of arguments that can be passed to the ``cache_args`` dictionary, which are also allowable in templates via the ``<%page>``, ``<%block>``, and ``<%def>`` tags specific to those sections. The values given override those specified at the :class:`.TemplateLookup` or :class:`.Template` level. With the possible exception of ``cache_timeout``, these arguments are probably better off staying at the template configuration level. Each argument specified as ``cache_XYZ`` in a template tag is specified without the ``cache_`` prefix in the ``cache_args`` dictionary: * ``cache_timeout`` - number of seconds in which to invalidate the cached data. After this timeout, the content is re-generated on the next call. Available as ``timeout`` in the ``cache_args`` dictionary. * ``cache_type`` - type of caching. ``'memory'``, ``'file'``, ``'dbm'``, or ``'ext:memcached'`` (note that the string ``memcached`` is also accepted by the dogpile.cache Mako plugin, though not by Beaker itself). Available as ``type`` in the ``cache_args`` dictionary. * ``cache_url`` - (only used for ``memcached`` but required) a single IP address or a semi-colon separated list of IP address of memcache servers to use. Available as ``url`` in the ``cache_args`` dictionary. * ``cache_dir`` - in the case of the ``'file'`` and ``'dbm'`` cache types, this is the filesystem directory with which to store data files. If this option is not present, the value of ``module_directory`` is used (i.e. the directory where compiled template modules are stored). If neither option is available an exception is thrown. Available as ``dir`` in the ``cache_args`` dictionary. .. _dogpile.cache_backend: Using the dogpile.cache Backend ------------------------------- `dogpile.cache`_ is a new replacement for Beaker. It provides a modernized, slimmed down interface and is generally easier to use than Beaker. As of this writing it has not yet been released. dogpile.cache includes its own Mako cache plugin -- see :mod:`dogpile.cache.plugins.mako_cache` in the dogpile.cache documentation. Programmatic Cache Access ========================= The :class:`.Template`, as well as any template-derived :class:`.Namespace`, has an accessor called ``cache`` which returns the :class:`.Cache` object for that template. This object is a facade on top of the underlying :class:`.CacheImpl` object, and provides some very rudimental capabilities, such as the ability to get and put arbitrary values: .. sourcecode:: mako <% local.cache.set("somekey", type="memory", "somevalue") %> Above, the cache associated with the ``local`` namespace is accessed and a key is placed within a memory cache. More commonly, the ``cache`` object is used to invalidate cached sections programmatically: .. sourcecode:: python template = lookup.get_template('/sometemplate.html') # invalidate the "body" of the template template.cache.invalidate_body() # invalidate an individual def template.cache.invalidate_def('somedef') # invalidate an arbitrary key template.cache.invalidate('somekey') You can access any special method or attribute of the :class:`.CacheImpl` itself using the :attr:`impl <.Cache.impl>` attribute: .. sourcecode:: python template.cache.impl.do_something_special() Note that using implementation-specific methods will mean you can't swap in a different kind of :class:`.CacheImpl` implementation at a later time. .. _cache_plugins: Cache Plugins ============= The mechanism used by caching can be plugged in using a :class:`.CacheImpl` subclass. This class implements the rudimental methods Mako needs to implement the caching API. Mako includes the :class:`.BeakerCacheImpl` class to provide the default implementation. A :class:`.CacheImpl` class is acquired by Mako using a ``pkg_resources`` entrypoint, using the name given as the ``cache_impl`` argument to :class:`.Template` or :class:`.TemplateLookup`. This entry point can be installed via the standard `setuptools`/``setup()`` procedure, underneath the `EntryPoint` group named ``"mako.cache"``. It can also be installed at runtime via a convenience installer :func:`.register_plugin` which accomplishes essentially the same task. An example plugin that implements a local dictionary cache: .. sourcecode:: python from mako.cache import Cacheimpl, register_plugin class SimpleCacheImpl(CacheImpl): def __init__(self, cache): super(SimpleCacheImpl, self).__init__(cache) self._cache = {} def get_or_create(self, key, creation_function, **kw): if key in self._cache: return self._cache[key] else: self._cache[key] = value = creation_function() return value def set(self, key, value, **kwargs): self._cache[key] = value def get(self, key, **kwargs): return self._cache.get(key) def invalidate(self, key, **kwargs): self._cache.pop(key, None) # optional - register the class locally register_plugin("simple", __name__, "SimpleCacheImpl") Enabling the above plugin in a template would look like: .. sourcecode:: python t = Template("mytemplate", file="mytemplate.html", cache_impl='simple') Guidelines for Writing Cache Plugins ------------------------------------ * The :class:`.CacheImpl` is created on a per-:class:`.Template` basis. The class should ensure that only data for the parent :class:`.Template` is persisted or returned by the cache methods. The actual :class:`.Template` is available via the ``self.cache.template`` attribute. The ``self.cache.id`` attribute, which is essentially the unique modulename of the template, is a good value to use in order to represent a unique namespace of keys specific to the template. * Templates only use the :meth:`.CacheImpl.get_or_create()` method in an implicit fashion. The :meth:`.CacheImpl.set`, :meth:`.CacheImpl.get`, and :meth:`.CacheImpl.invalidate` methods are only used in response to direct programmatic access to the corresponding methods on the :class:`.Cache` object. * :class:`.CacheImpl` will be accessed in a multithreaded fashion if the :class:`.Template` itself is used multithreaded. Care should be taken to ensure caching implementations are threadsafe. * A library like `Dogpile `_, which is a minimal locking system derived from Beaker, can be used to help implement the :meth:`.CacheImpl.get_or_create` method in a threadsafe way that can maximize effectiveness across multiple threads as well as processes. :meth:`.CacheImpl.get_or_create` is the key method used by templates. * All arguments passed to ``**kw`` come directly from the parameters inside the ``<%def>``, ``<%block>``, or ``<%page>`` tags directly, minus the ``"cache_"`` prefix, as strings, with the exception of the argument ``cache_timeout``, which is passed to the plugin as the name ``timeout`` with the value converted to an integer. Arguments present in ``cache_args`` on :class:`.Template` or :class:`.TemplateLookup` are passed directly, but are superseded by those present in the most specific template tag. * The directory where :class:`.Template` places module files can be acquired using the accessor ``self.cache.template.module_directory``. This directory can be a good place to throw cache-related work files, underneath a prefix like ``_my_cache_work`` so that name conflicts with generated modules don't occur. API Reference ============= .. autoclass:: mako.cache.Cache :members: :show-inheritance: .. autoclass:: mako.cache.CacheImpl :members: :show-inheritance: .. autofunction:: mako.cache.register_plugin .. autoclass:: mako.ext.beaker_cache.BeakerCacheImpl :members: :show-inheritance: Mako-0.9.1/doc/build/conf.py0000644000076500000240000002171112257136636016334 0ustar classicstaff00000000000000# -*- coding: utf-8 -*- # # Mako documentation build configuration file # # This file is execfile()d with the current directory set to its containing dir. # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. import sys, os # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. sys.path.insert(0, os.path.abspath('../..')) sys.path.insert(0, os.path.abspath('.')) import mako # -- General configuration ----------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. #needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. #extensions = ['sphinx.ext.autodoc', 'sphinx.ext.viewcode', # 'sphinx.ext.doctest', 'builder.builders'] extensions = ['sphinx.ext.autodoc','sphinx.ext.intersphinx', 'sphinx.ext.doctest', 'builder.builders'] # Add any paths that contain templates here, relative to this directory. templates_path = ['templates'] nitpicky = True site_base = "http://www.makotemplates.org" # The suffix of source filenames. source_suffix = '.rst' template_bridge = "builder.builders.MakoBridge" # The encoding of source files. #source_encoding = 'utf-8-sig' # The master toctree document. master_doc = 'index' # General information about the project. project = u'Mako' copyright = u'the Mako authors and contributors' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. version = mako.__version__ # The full version, including alpha/beta/rc tags. release = mako.__version__ # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. #language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: #today = '' # Else, today_fmt is used as the format for a strftime call. #today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = ['build'] # The reST default role (used for this markup: `text`) to use for all documents. #default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. #add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). #add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. #show_authors = False # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # A list of ignored prefixes for module index sorting. #modindex_common_prefix = [] # -- Options for HTML output --------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. html_theme = 'default' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. #html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. #html_theme_path = [] # The style sheet to use for HTML and HTML Help pages. A file of that name # must exist either in Sphinx' static/ path, or in one of the custom paths # given in html_static_path. html_style = 'default.css' # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". html_title = "%s %s Documentation" % (project, release) # A shorter title for the navigation bar. Default is the same as html_title. #html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. #html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. #html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['static'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. html_last_updated_fmt = '%m/%d/%Y %H:%M:%S' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. #html_use_smartypants = True # Custom sidebar templates, maps document names to template names. #html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. #html_additional_pages = {} # If false, no module index is generated. html_domain_indices = False # If false, no index is generated. #html_use_index = True # If true, the index is split into individual pages for each letter. #html_split_index = False # If true, the reST sources are included in the HTML build as _sources/. #html_copy_source = True # If true, links to the reST sources are added to the pages. #html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. #html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. #html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. #html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). #html_file_suffix = None # Output file base name for HTML help builder. htmlhelp_basename = 'Makodoc' #autoclass_content = 'both' # -- Options for LaTeX output -------------------------------------------------- # The paper size ('letter' or 'a4'). #latex_paper_size = 'letter' # The font size ('10pt', '11pt' or '12pt'). #latex_font_size = '10pt' # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ ('index', 'mako_%s.tex' % release.replace('.', '_'), ur'Mako Documentation', ur'Mike Bayer', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of # the title page. #latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. #latex_use_parts = False # If true, show page references after internal links. #latex_show_pagerefs = False # If true, show URL addresses after external links. #latex_show_urls = False # Additional stuff for the LaTeX preamble. # sets TOC depth to 2. latex_preamble = '\setcounter{tocdepth}{3}' # Documents to append as an appendix to all manuals. #latex_appendices = [] # If false, no module index is generated. #latex_domain_indices = True #latex_elements = { # 'papersize': 'letterpaper', # 'pointsize': '10pt', #} # -- Options for manual page output -------------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ ('index', 'mako', u'Mako Documentation', [u'Mako authors'], 1) ] # -- Options for Epub output --------------------------------------------------- # Bibliographic Dublin Core info. epub_title = u'Mako' epub_author = u'Mako authors' epub_publisher = u'Mako authors' epub_copyright = u'Mako authors' # The language of the text. It defaults to the language option # or en if the language is not set. #epub_language = '' # The scheme of the identifier. Typical schemes are ISBN or URL. #epub_scheme = '' # The unique identifier of the text. This can be a ISBN number # or the project homepage. #epub_identifier = '' # A unique identification for the text. #epub_uid = '' # HTML files that should be inserted before the pages created by sphinx. # The format is a list of tuples containing the path and title. #epub_pre_files = [] # HTML files shat should be inserted after the pages created by sphinx. # The format is a list of tuples containing the path and title. #epub_post_files = [] # A list of files that should not be packed into the epub file. #epub_exclude_files = [] # The depth of the table of contents in toc.ncx. #epub_tocdepth = 3 # Allow duplicate toc entries. #epub_tocdup = True intersphinx_mapping = { 'dogpilecache':('http://dogpilecache.readthedocs.org/en/latest', None), 'beaker':('http://beaker.readthedocs.org/en/latest',None), } Mako-0.9.1/doc/build/defs.rst0000644000076500000240000004245112257136636016514 0ustar classicstaff00000000000000.. _defs_toplevel: =============== Defs and Blocks =============== ``<%def>`` and ``<%block>`` are two tags that both demarcate any block of text and/or code. They both exist within generated Python as a callable function, i.e., a Python ``def``. They differ in their scope and calling semantics. Whereas ``<%def>`` provides a construct that is very much like a named Python ``def``, the ``<%block>`` is more layout oriented. Using Defs ========== The ``<%def>`` tag requires a ``name`` attribute, where the ``name`` references a Python function signature: .. sourcecode:: mako <%def name="hello()"> hello world To invoke the ``<%def>``, it is normally called as an expression: .. sourcecode:: mako the def: ${hello()} If the ``<%def>`` is not nested inside of another ``<%def>``, it's known as a **top level def** and can be accessed anywhere in the template, including above where it was defined. All defs, top level or not, have access to the current contextual namespace in exactly the same way their containing template does. Suppose the template below is executed with the variables ``username`` and ``accountdata`` inside the context: .. sourcecode:: mako Hello there ${username}, how are ya. Lets see what your account says: ${account()} <%def name="account()"> Account for ${username}:
      % for row in accountdata: Value: ${row}
      % endfor The ``username`` and ``accountdata`` variables are present within the main template body as well as the body of the ``account()`` def. Since defs are just Python functions, you can define and pass arguments to them as well: .. sourcecode:: mako ${account(accountname='john')} <%def name="account(accountname, type='regular')"> account name: ${accountname}, type: ${type} When you declare an argument signature for your def, they are required to follow normal Python conventions (i.e., all arguments are required except keyword arguments with a default value). This is in contrast to using context-level variables, which evaluate to ``UNDEFINED`` if you reference a name that does not exist. Calling Defs from Other Files ----------------------------- Top level ``<%def>``\ s are **exported** by your template's module, and can be called from the outside; including from other templates, as well as normal Python code. Calling a ``<%def>`` from another template is something like using an ``<%include>`` -- except you are calling a specific function within the template, not the whole template. The remote ``<%def>`` call is also a little bit like calling functions from other modules in Python. There is an "import" step to pull the names from another template into your own template; then the function or functions are available. To import another template, use the ``<%namespace>`` tag: .. sourcecode:: mako <%namespace name="mystuff" file="mystuff.html"/> The above tag adds a local variable ``mystuff`` to the current scope. Then, just call the defs off of ``mystuff``: .. sourcecode:: mako ${mystuff.somedef(x=5,y=7)} The ``<%namespace>`` tag also supports some of the other semantics of Python's ``import`` statement, including pulling names into the local variable space, or using ``*`` to represent all names, using the ``import`` attribute: .. sourcecode:: mako <%namespace file="mystuff.html" import="foo, bar"/> This is just a quick intro to the concept of a **namespace**, which is a central Mako concept that has its own chapter in these docs. For more detail and examples, see :ref:`namespaces_toplevel`. Calling Defs Programmatically ----------------------------- You can call defs programmatically from any :class:`.Template` object using the :meth:`~.Template.get_def()` method, which returns a :class:`.DefTemplate` object. This is a :class:`.Template` subclass which the parent :class:`.Template` creates, and is usable like any other template: .. sourcecode:: python from mako.template import Template template = Template(""" <%def name="hi(name)"> hi ${name}! <%def name="bye(name)"> bye ${name}! """) print template.get_def("hi").render(name="ed") print template.get_def("bye").render(name="ed") Defs within Defs ---------------- The def model follows regular Python rules for closures. Declaring ``<%def>`` inside another ``<%def>`` declares it within the parent's **enclosing scope**: .. sourcecode:: mako <%def name="mydef()"> <%def name="subdef()"> a sub def i'm the def, and the subcomponent is ${subdef()} Just like Python, names that exist outside the inner ``<%def>`` exist inside it as well: .. sourcecode:: mako <% x = 12 %> <%def name="outer()"> <% y = 15 %> <%def name="inner()"> inner, x is ${x}, y is ${y} outer, x is ${x}, y is ${y} Assigning to a name inside of a def declares that name as local to the scope of that def (again, like Python itself). This means the following code will raise an error: .. sourcecode:: mako <% x = 10 %> <%def name="somedef()"> ## error ! somedef, x is ${x} <% x = 27 %> ...because the assignment to ``x`` declares ``x`` as local to the scope of ``somedef``, rendering the "outer" version unreachable in the expression that tries to render it. .. _defs_with_content: Calling a Def with Embedded Content and/or Other Defs ----------------------------------------------------- A flip-side to def within def is a def call with content. This is where you call a def, and at the same time declare a block of content (or multiple blocks) that can be used by the def being called. The main point of such a call is to create custom, nestable tags, just like any other template language's custom-tag creation system -- where the external tag controls the execution of the nested tags and can communicate state to them. Only with Mako, you don't have to use any external Python modules, you can define arbitrarily nestable tags right in your templates. To achieve this, the target def is invoked using the form ``<%namepacename:defname>`` instead of the normal ``${}`` syntax. This syntax, introduced in Mako 0.2.3, is functionally equivalent to another tag known as ``%call``, which takes the form ``<%call expr='namespacename.defname(args)'>``. While ``%call`` is available in all versions of Mako, the newer style is probably more familiar looking. The ``namespace`` portion of the call is the name of the **namespace** in which the def is defined -- in the most simple cases, this can be ``local`` or ``self`` to reference the current template's namespace (the difference between ``local`` and ``self`` is one of inheritance -- see :ref:`namespaces_builtin` for details). When the target def is invoked, a variable ``caller`` is placed in its context which contains another namespace containing the body and other defs defined by the caller. The body itself is referenced by the method ``body()``. Below, we build a ``%def`` that operates upon ``caller.body()`` to invoke the body of the custom tag: .. sourcecode:: mako <%def name="buildtable()">
      ${caller.body()}
      <%self:buildtable> I am the table body. This produces the output (whitespace formatted): .. sourcecode:: html
      I am the table body.
      Using the older ``%call`` syntax looks like: .. sourcecode:: mako <%def name="buildtable()">
      ${caller.body()}
      <%call expr="buildtable()"> I am the table body. The ``body()`` can be executed multiple times or not at all. This means you can use def-call-with-content to build iterators, conditionals, etc: .. sourcecode:: mako <%def name="lister(count)"> % for x in range(count): ${caller.body()} % endfor <%self:lister count="${3}"> hi Produces: .. sourcecode:: html hi hi hi Notice above we pass ``3`` as a Python expression, so that it remains as an integer. A custom "conditional" tag: .. sourcecode:: mako <%def name="conditional(expression)"> % if expression: ${caller.body()} % endif <%self:conditional expression="${4==4}"> i'm the result Produces: .. sourcecode:: html i'm the result But that's not all. The ``body()`` function also can handle arguments, which will augment the local namespace of the body callable. The caller must define the arguments which it expects to receive from its target def using the ``args`` attribute, which is a comma-separated list of argument names. Below, our ``<%def>`` calls the ``body()`` of its caller, passing in an element of data from its argument: .. sourcecode:: mako <%def name="layoutdata(somedata)"> % for item in somedata: % for col in item: % endfor % endfor
      ${caller.body(col=col)}
      <%self:layoutdata somedata="${[[1,2,3],[4,5,6],[7,8,9]]}" args="col">\ Body data: ${col}\ Produces: .. sourcecode:: html
      Body data: 1 Body data: 2 Body data: 3
      Body data: 4 Body data: 5 Body data: 6
      Body data: 7 Body data: 8 Body data: 9
      You don't have to stick to calling just the ``body()`` function. The caller can define any number of callables, allowing the ``<%call>`` tag to produce whole layouts: .. sourcecode:: mako <%def name="layout()"> ## a layout def
      ${caller.header()}
      ${caller.body()}
      ## calls the layout def <%self:layout> <%def name="header()"> I am the header <%def name="sidebar()">
      • sidebar 1
      • sidebar 2
      this is the body The above layout would produce: .. sourcecode:: html
      I am the header
      this is the body
      The number of things you can do with ``<%call>`` and/or the ``<%namespacename:defname>`` calling syntax is enormous. You can create form widget libraries, such as an enclosing ``
      `` tag and nested HTML input elements, or portable wrapping schemes using ``
      `` or other elements. You can create tags that interpret rows of data, such as from a database, providing the individual columns of each row to a ``body()`` callable which lays out the row any way it wants. Basically anything you'd do with a "custom tag" or tag library in some other system, Mako provides via ``<%def>`` tags and plain Python callables which are invoked via ``<%namespacename:defname>`` or ``<%call>``. .. _blocks: Using Blocks ============ The ``<%block>`` tag introduces some new twists on the ``<%def>`` tag which make it more closely tailored towards layout. .. versionadded:: 0.4.1 An example of a block: .. sourcecode:: mako <%block> this is a block. In the above example, we define a simple block. The block renders its content in the place that it's defined. Since the block is called for us, it doesn't need a name and the above is referred to as an **anonymous block**. So the output of the above template will be: .. sourcecode:: html this is a block. So in fact the above block has absolutely no effect. Its usefulness comes when we start using modifiers. Such as, we can apply a filter to our block: .. sourcecode:: mako <%block filter="h"> this is some escaped html. or perhaps a caching directive: .. sourcecode:: mako <%block cached="True" cache_timeout="60"> This content will be cached for 60 seconds. Blocks also work in iterations, conditionals, just like defs: .. sourcecode:: mako % if some_condition: <%block>condition is met % endif While the block renders at the point it is defined in the template, the underlying function is present in the generated Python code only once, so there's no issue with placing a block inside of a loop or similar. Anonymous blocks are defined as closures in the local rendering body, so have access to local variable scope: .. sourcecode:: mako % for i in range(1, 4): <%block>i is ${i} % endfor Using Named Blocks ------------------ Possibly the more important area where blocks are useful is when we do actually give them names. Named blocks are tailored to behave somewhat closely to Jinja2's block tag, in that they define an area of a layout which can be overridden by an inheriting template. In sharp contrast to the ``<%def>`` tag, the name given to a block is global for the entire template regardless of how deeply it's nested: .. sourcecode:: mako <%block name="header"> <%block name="title">Title</%block> ${next.body()} The above example has two named blocks "``header``" and "``title``", both of which can be referred to by an inheriting template. A detailed walkthrough of this usage can be found at :ref:`inheritance_toplevel`. Note above that named blocks don't have any argument declaration the way defs do. They still implement themselves as Python functions, however, so they can be invoked additional times beyond their initial definition: .. sourcecode:: mako
      <%block name="pagecontrol"> previous page | next page ## some content
      ${pagecontrol()}
      The content referenced by ``pagecontrol`` above will be rendered both above and below the ```` tags. To keep things sane, named blocks have restrictions that defs do not: * The ``<%block>`` declaration cannot have any argument signature. * The name of a ``<%block>`` can only be defined once in a template -- an error is raised if two blocks of the same name occur anywhere in a single template, regardless of nesting. A similar error is raised if a top level def shares the same name as that of a block. * A named ``<%block>`` cannot be defined within a ``<%def>``, or inside the body of a "call", i.e. ``<%call>`` or ``<%namespacename:defname>`` tag. Anonymous blocks can, however. Using Page Arguments in Named Blocks ------------------------------------ A named block is very much like a top level def. It has a similar restriction to these types of defs in that arguments passed to the template via the ``<%page>`` tag aren't automatically available. Using arguments with the ``<%page>`` tag is described in the section :ref:`namespaces_body`, and refers to scenarios such as when the ``body()`` method of a template is called from an inherited template passing arguments, or the template is invoked from an ``<%include>`` tag with arguments. To allow a named block to share the same arguments passed to the page, the ``args`` attribute can be used: .. sourcecode:: mako <%page args="post"/> <%block name="post_prose" args="post"> ${post.content} Where above, if the template is called via a directive like ``<%include file="post.mako" args="post=post" />``, the ``post`` variable is available both in the main body as well as the ``post_prose`` block. Similarly, the ``**pageargs`` variable is present, in named blocks only, for those arguments not explicit in the ``<%page>`` tag: .. sourcecode:: mako <%block name="post_prose"> ${pageargs['post'].content} The ``args`` attribute is only allowed with named blocks. With anonymous blocks, the Python function is always rendered in the same scope as the call itself, so anything available directly outside the anonymous block is available inside as well. Mako-0.9.1/doc/build/filtering.rst0000644000076500000240000002442512257136636017557 0ustar classicstaff00000000000000.. _filtering_toplevel: ======================= Filtering and Buffering ======================= Expression Filtering ==================== As described in the chapter :ref:`syntax_toplevel`, the "``|``" operator can be applied to a "``${}``" expression to apply escape filters to the output: .. sourcecode:: mako ${"this is some text" | u} The above expression applies URL escaping to the expression, and produces ``this+is+some+text``. The built-in escape flags are: * ``u`` : URL escaping, provided by ``urllib.quote_plus(string.encode('utf-8'))`` * ``h`` : HTML escaping, provided by ``markupsafe.escape(string)`` .. versionadded:: 0.3.4 Prior versions use ``cgi.escape(string, True)``. * ``x`` : XML escaping * ``trim`` : whitespace trimming, provided by ``string.strip()`` * ``entity`` : produces HTML entity references for applicable strings, derived from ``htmlentitydefs`` * ``unicode`` (``str`` on Python 3): produces a Python unicode string (this function is applied by default) * ``decode.``: decode input into a Python unicode with the specified encoding * ``n`` : disable all default filtering; only filters specified in the local expression tag will be applied. To apply more than one filter, separate them by a comma: .. sourcecode:: mako ${" some value " | h,trim} The above produces ``<tag>some value</tag>``, with no leading or trailing whitespace. The HTML escaping function is applied first, the "trim" function second. Naturally, you can make your own filters too. A filter is just a Python function that accepts a single string argument, and returns the filtered result. The expressions after the ``|`` operator draw upon the local namespace of the template in which they appear, meaning you can define escaping functions locally: .. sourcecode:: mako <%! def myescape(text): return "" + text + "" %> Here's some tagged text: ${"text" | myescape} Or from any Python module: .. sourcecode:: mako <%! import myfilters %> Here's some tagged text: ${"text" | myfilters.tagfilter} A page can apply a default set of filters to all expression tags using the ``expression_filter`` argument to the ``%page`` tag: .. sourcecode:: mako <%page expression_filter="h"/> Escaped text: ${"some html"} Result: .. sourcecode:: html Escaped text: <html>some html</html> .. _filtering_default_filters: The ``default_filters`` Argument -------------------------------- In addition to the ``expression_filter`` argument, the ``default_filters`` argument to both :class:`.Template` and :class:`.TemplateLookup` can specify filtering for all expression tags at the programmatic level. This array-based argument, when given its default argument of ``None``, will be internally set to ``["unicode"]`` (or ``["str"]`` on Python 3), except when ``disable_unicode=True`` is set in which case it defaults to ``["str"]``: .. sourcecode:: python t = TemplateLookup(directories=['/tmp'], default_filters=['unicode']) To replace the usual ``unicode``/``str`` function with a specific encoding, the ``decode`` filter can be substituted: .. sourcecode:: python t = TemplateLookup(directories=['/tmp'], default_filters=['decode.utf8']) To disable ``default_filters`` entirely, set it to an empty list: .. sourcecode:: python t = TemplateLookup(directories=['/tmp'], default_filters=[]) Any string name can be added to ``default_filters`` where it will be added to all expressions as a filter. The filters are applied from left to right, meaning the leftmost filter is applied first. .. sourcecode:: python t = Template(templatetext, default_filters=['unicode', 'myfilter']) To ease the usage of ``default_filters`` with custom filters, you can also add imports (or other code) to all templates using the ``imports`` argument: .. sourcecode:: python t = TemplateLookup(directories=['/tmp'], default_filters=['unicode', 'myfilter'], imports=['from mypackage import myfilter']) The above will generate templates something like this: .. sourcecode:: python # .... from mypackage import myfilter def render_body(context): context.write(myfilter(unicode("some text"))) Turning off Filtering with the ``n`` Filter ------------------------------------------- In all cases the special ``n`` filter, used locally within an expression, will **disable** all filters declared in the ``<%page>`` tag as well as in ``default_filters``. Such as: .. sourcecode:: mako ${'myexpression' | n} will render ``myexpression`` with no filtering of any kind, and: .. sourcecode:: mako ${'myexpression' | n,trim} will render ``myexpression`` using the ``trim`` filter only. Filtering Defs and Blocks ========================= The ``%def`` and ``%block`` tags have an argument called ``filter`` which will apply the given list of filter functions to the output of the ``%def``: .. sourcecode:: mako <%def name="foo()" filter="h, trim"> this is bold When the ``filter`` attribute is applied to a def as above, the def is automatically **buffered** as well. This is described next. Buffering ========= One of Mako's central design goals is speed. To this end, all of the textual content within a template and its various callables is by default piped directly to the single buffer that is stored within the :class:`.Context` object. While this normally is easy to miss, it has certain side effects. The main one is that when you call a def using the normal expression syntax, i.e. ``${somedef()}``, it may appear that the return value of the function is the content it produced, which is then delivered to your template just like any other expression substitution, except that normally, this is not the case; the return value of ``${somedef()}`` is simply the empty string ``''``. By the time you receive this empty string, the output of ``somedef()`` has been sent to the underlying buffer. You may not want this effect, if for example you are doing something like this: .. sourcecode:: mako ${" results " + somedef() + " more results "} If the ``somedef()`` function produced the content "``somedef's results``", the above template would produce this output: .. sourcecode:: html somedef's results results more results This is because ``somedef()`` fully executes before the expression returns the results of its concatenation; the concatenation in turn receives just the empty string as its middle expression. Mako provides two ways to work around this. One is by applying buffering to the ``%def`` itself: .. sourcecode:: mako <%def name="somedef()" buffered="True"> somedef's results The above definition will generate code similar to this: .. sourcecode:: python def somedef(): context.push_buffer() try: context.write("somedef's results") finally: buf = context.pop_buffer() return buf.getvalue() So that the content of ``somedef()`` is sent to a second buffer, which is then popped off the stack and its value returned. The speed hit inherent in buffering the output of a def is also apparent. Note that the ``filter`` argument on ``%def`` also causes the def to be buffered. This is so that the final content of the ``%def`` can be delivered to the escaping function in one batch, which reduces method calls and also produces more deterministic behavior for the filtering function itself, which can possibly be useful for a filtering function that wishes to apply a transformation to the text as a whole. The other way to buffer the output of a def or any Mako callable is by using the built-in ``capture`` function. This function performs an operation similar to the above buffering operation except it is specified by the caller. .. sourcecode:: mako ${" results " + capture(somedef) + " more results "} Note that the first argument to the ``capture`` function is **the function itself**, not the result of calling it. This is because the ``capture`` function takes over the job of actually calling the target function, after setting up a buffered environment. To send arguments to the function, just send them to ``capture`` instead: .. sourcecode:: mako ${capture(somedef, 17, 'hi', use_paging=True)} The above call is equivalent to the unbuffered call: .. sourcecode:: mako ${somedef(17, 'hi', use_paging=True)} Decorating ========== .. versionadded:: 0.2.5 Somewhat like a filter for a ``%def`` but more flexible, the ``decorator`` argument to ``%def`` allows the creation of a function that will work in a similar manner to a Python decorator. The function can control whether or not the function executes. The original intent of this function is to allow the creation of custom cache logic, but there may be other uses as well. ``decorator`` is intended to be used with a regular Python function, such as one defined in a library module. Here we'll illustrate the python function defined in the template for simplicities' sake: .. sourcecode:: mako <%! def bar(fn): def decorate(context, *args, **kw): context.write("BAR") fn(*args, **kw) context.write("BAR") return '' return decorate %> <%def name="foo()" decorator="bar"> this is foo ${foo()} The above template will return, with more whitespace than this, ``"BAR this is foo BAR"``. The function is the render callable itself (or possibly a wrapper around it), and by default will write to the context. To capture its output, use the :func:`.capture` callable in the ``mako.runtime`` module (available in templates as just ``runtime``): .. sourcecode:: mako <%! def bar(fn): def decorate(context, *args, **kw): return "BAR" + runtime.capture(context, fn, *args, **kw) + "BAR" return decorate %> <%def name="foo()" decorator="bar"> this is foo ${foo()} The decorator can be used with top-level defs as well as nested defs, and blocks too. Note that when calling a top-level def from the :class:`.Template` API, i.e. ``template.get_def('somedef').render()``, the decorator has to write the output to the ``context``, i.e. as in the first example. The return value gets discarded. Mako-0.9.1/doc/build/index.rst0000644000076500000240000000037612257136636016702 0ustar classicstaff00000000000000Table of Contents ================= .. toctree:: :maxdepth: 2 usage syntax defs runtime namespaces inheritance filtering unicode caching Indices and Tables ------------------ * :ref:`genindex` * :ref:`search` Mako-0.9.1/doc/build/inheritance.rst0000644000076500000240000004003012257136636020053 0ustar classicstaff00000000000000.. _inheritance_toplevel: =========== Inheritance =========== .. note:: Most of the inheritance examples here take advantage of a feature that's new in Mako as of version 0.4.1 called the "block". This tag is very similar to the "def" tag but is more streamlined for usage with inheritance. Note that all of the examples here which use blocks can also use defs instead. Contrasting usages will be illustrated. Using template inheritance, two or more templates can organize themselves into an **inheritance chain**, where content and functions from all involved templates can be intermixed. The general paradigm of template inheritance is this: if a template ``A`` inherits from template ``B``, then template ``A`` agrees to send the executional control to template ``B`` at runtime (``A`` is called the **inheriting** template). Template ``B``, the **inherited** template, then makes decisions as to what resources from ``A`` shall be executed. In practice, it looks like this. Here's a hypothetical inheriting template, ``index.html``: .. sourcecode:: mako ## index.html <%inherit file="base.html"/> <%block name="header"> this is some header content this is the body content. And ``base.html``, the inherited template: .. sourcecode:: mako ## base.html
      <%block name="header"/>
      ${self.body()} Here is a breakdown of the execution: #. When ``index.html`` is rendered, control immediately passes to ``base.html``. #. ``base.html`` then renders the top part of an HTML document, then invokes the ``<%block name="header">`` block. It invokes the underlying ``header()`` function off of a built-in namespace called ``self`` (this namespace was first introduced in the :doc:`Namespaces chapter ` in :ref:`namespace_self`). Since ``index.html`` is the topmost template and also defines a block called ``header``, it's this ``header`` block that ultimately gets executed -- instead of the one that's present in ``base.html``. #. Control comes back to ``base.html``. Some more HTML is rendered. #. ``base.html`` executes ``self.body()``. The ``body()`` function on all template-based namespaces refers to the main body of the template, therefore the main body of ``index.html`` is rendered. #. When ``<%block name="header">`` is encountered in ``index.html`` during the ``self.body()`` call, a conditional is checked -- does the current inherited template, i.e. ``base.html``, also define this block? If yes, the ``<%block>`` is **not** executed here -- the inheritance mechanism knows that the parent template is responsible for rendering this block (and in fact it already has). In other words a block only renders in its *basemost scope*. #. Control comes back to ``base.html``. More HTML is rendered, then the ``<%block name="footer">`` expression is invoked. #. The ``footer`` block is only defined in ``base.html``, so being the topmost definition of ``footer``, it's the one that executes. If ``index.html`` also specified ``footer``, then its version would **override** that of the base. #. ``base.html`` finishes up rendering its HTML and the template is complete, producing: .. sourcecode:: html
      this is some header content
      this is the body content. ...and that is template inheritance in a nutshell. The main idea is that the methods that you call upon ``self`` always correspond to the topmost definition of that method. Very much the way ``self`` works in a Python class, even though Mako is not actually using Python class inheritance to implement this functionality. (Mako doesn't take the "inheritance" metaphor too seriously; while useful to setup some commonly recognized semantics, a textual template is not very much like an object-oriented class construct in practice). Nesting Blocks ============== The named blocks defined in an inherited template can also be nested within other blocks. The name given to each block is globally accessible via any inheriting template. We can add a new block ``title`` to our ``header`` block: .. sourcecode:: mako ## base.html
      <%block name="header">

      <%block name="title"/>

      ${self.body()} The inheriting template can name either or both of ``header`` and ``title``, separately or nested themselves: .. sourcecode:: mako ## index.html <%inherit file="base.html"/> <%block name="header"> this is some header content ${parent.header()} <%block name="title"> this is the title this is the body content. Note when we overrode ``header``, we added an extra call ``${parent.header()}`` in order to invoke the parent's ``header`` block in addition to our own. That's described in more detail below, in :ref:`parent_namespace`. Rendering a Named Block Multiple Times ====================================== Recall from the section :ref:`blocks` that a named block is just like a ``<%def>``, with some different usage rules. We can call one of our named sections distinctly, for example a section that is used more than once, such as the title of a page: .. sourcecode:: mako ${self.title()} <%block name="header">

      <%block name="title"/>

      ${self.body()} Where above an inheriting template can define ``<%block name="title">`` just once, and it will be used in the base template both in the ```` section as well as the ``<h2>``. But what about Defs? ==================== The previous example used the ``<%block>`` tag to produce areas of content to be overridden. Before Mako 0.4.1, there wasn't any such tag -- instead there was only the ``<%def>`` tag. As it turns out, named blocks and defs are largely interchangeable. The def simply doesn't call itself automatically, and has more open-ended naming and scoping rules that are more flexible and similar to Python itself, but less suited towards layout. The first example from this chapter using defs would look like: .. sourcecode:: mako ## index.html <%inherit file="base.html"/> <%def name="header()"> this is some header content </%def> this is the body content. And ``base.html``, the inherited template: .. sourcecode:: mako ## base.html <html> <body> <div class="header"> ${self.header()} </div> ${self.body()} <div class="footer"> ${self.footer()} </div> </body> </html> <%def name="header()"/> <%def name="footer()"> this is the footer </%def> Above, we illustrate that defs differ from blocks in that their definition and invocation are defined in two separate places, instead of at once. You can *almost* do exactly what a block does if you put the two together: .. sourcecode:: mako <div class="header"> <%def name="header()"></%def>${self.header()} </div> The ``<%block>`` is obviously more streamlined than the ``<%def>`` for this kind of usage. In addition, the above "inline" approach with ``<%def>`` does not work with nesting: .. sourcecode:: mako <head> <%def name="header()"> <title> ## this won't work ! <%def name="title()">default title</%def>${self.title()} ${self.header()} Where above, the ``title()`` def, because it's a def within a def, is not part of the template's exported namespace and will not be part of ``self``. If the inherited template did define its own ``title`` def at the top level, it would be called, but the "default title" above is not present at all on ``self`` no matter what. For this to work as expected you'd instead need to say: .. sourcecode:: mako <%def name="header()"> ${self.title()} ${self.header()} <%def name="title()"/> That is, ``title`` is defined outside of any other defs so that it is in the ``self`` namespace. It works, but the definition needs to be potentially far away from the point of render. A named block is always placed in the ``self`` namespace, regardless of nesting, so this restriction is lifted: .. sourcecode:: mako ## base.html <%block name="header"> <%block name="title"/> The above template defines ``title`` inside of ``header``, and an inheriting template can define one or both in **any** configuration, nested inside each other or not, in order for them to be used: .. sourcecode:: mako ## index.html <%inherit file="base.html"/> <%block name="title"> the title <%block name="header"> the header So while the ``<%block>`` tag lifts the restriction of nested blocks not being available externally, in order to achieve this it *adds* the restriction that all block names in a single template need to be globally unique within the template, and additionally that a ``<%block>`` can't be defined inside of a ``<%def>``. It's a more restricted tag suited towards a more specific use case than ``<%def>``. Using the ``next`` Namespace to Produce Content Wrapping ======================================================== Sometimes you have an inheritance chain that spans more than two templates. Or maybe you don't, but you'd like to build your system such that extra inherited templates can be inserted in the middle of a chain where they would be smoothly integrated. If each template wants to define its layout just within its main body, you can't just call ``self.body()`` to get at the inheriting template's body, since that is only the topmost body. To get at the body of the *next* template, you call upon the namespace ``next``, which is the namespace of the template **immediately following** the current template. Lets change the line in ``base.html`` which calls upon ``self.body()`` to instead call upon ``next.body()``: .. sourcecode:: mako ## base.html
      <%block name="header"/>
      ${next.body()} Lets also add an intermediate template called ``layout.html``, which inherits from ``base.html``: .. sourcecode:: mako ## layout.html <%inherit file="base.html"/>
        <%block name="toolbar">
      • selection 1
      • selection 2
      • selection 3
      ${next.body()}
      And finally change ``index.html`` to inherit from ``layout.html`` instead: .. sourcecode:: mako ## index.html <%inherit file="layout.html"/> ## .. rest of template In this setup, each call to ``next.body()`` will render the body of the next template in the inheritance chain (which can be written as ``base.html -> layout.html -> index.html``). Control is still first passed to the bottommost template ``base.html``, and ``self`` still references the topmost definition of any particular def. The output we get would be: .. sourcecode:: html
      this is some header content
      • selection 1
      • selection 2
      • selection 3
      this is the body content.
      So above, we have the ````, ```` and ``header``/``footer`` layout of ``base.html``, we have the ``
        `` and ``mainlayout`` section of ``layout.html``, and the main body of ``index.html`` as well as its overridden ``header`` def. The ``layout.html`` template is inserted into the middle of the chain without ``base.html`` having to change anything. Without the ``next`` namespace, only the main body of ``index.html`` could be used; there would be no way to call ``layout.html``'s body content. .. _parent_namespace: Using the ``parent`` Namespace to Augment Defs ============================================== Lets now look at the other inheritance-specific namespace, the opposite of ``next`` called ``parent``. ``parent`` is the namespace of the template **immediately preceding** the current template. What's useful about this namespace is that defs or blocks can call upon their overridden versions. This is not as hard as it sounds and is very much like using the ``super`` keyword in Python. Lets modify ``index.html`` to augment the list of selections provided by the ``toolbar`` function in ``layout.html``: .. sourcecode:: mako ## index.html <%inherit file="layout.html"/> <%block name="header"> this is some header content <%block name="toolbar"> ## call the parent's toolbar first ${parent.toolbar()}
      • selection 4
      • selection 5
      • this is the body content. Above, we implemented a ``toolbar()`` function, which is meant to override the definition of ``toolbar`` within the inherited template ``layout.html``. However, since we want the content from that of ``layout.html`` as well, we call it via the ``parent`` namespace whenever we want it's content, in this case before we add our own selections. So the output for the whole thing is now: .. sourcecode:: html
        this is some header content
        • selection 1
        • selection 2
        • selection 3
        • selection 4
        • selection 5
        this is the body content.
        and you're now a template inheritance ninja! .. _inheritance_attr: Inheritable Attributes ====================== The :attr:`attr <.Namespace.attr>` accessor of the :class:`.Namespace` object allows access to module level variables declared in a template. By accessing ``self.attr``, you can access regular attributes from the inheritance chain as declared in ``<%! %>`` sections. Such as: .. sourcecode:: mako <%! class_ = "grey" %>
        ${self.body()}
        If an inheriting template overrides ``class_`` to be ``"white"``, as in: .. sourcecode:: mako <%! class_ = "white" %> <%inherit file="parent.html"/> This is the body you'll get output like: .. sourcecode:: html
        This is the body
        .. seealso:: :ref:`namespace_attr_for_includes` - a more sophisticated example using :attr:`.Namespace.attr`. Mako-0.9.1/doc/build/Makefile0000644000076500000240000001137412257136636016501 0ustar classicstaff00000000000000# Makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build PAPER = BUILDDIR = output # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest dist-html site-mako help: @echo "Please use \`make ' where is one of" @echo " html to make standalone HTML files" @echo " dist-html same as html, but places files in /doc" @echo " dirhtml to make HTML files named index.html in directories" @echo " singlehtml to make a single large HTML file" @echo " pickle to make pickle files" @echo " json to make JSON files" @echo " htmlhelp to make HTML files and a HTML help project" @echo " qthelp to make HTML files and a qthelp project" @echo " devhelp to make HTML files and a Devhelp project" @echo " epub to make an epub" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " latexpdf to make LaTeX files and run them through pdflatex" @echo " text to make text files" @echo " man to make manual pages" @echo " changes to make an overview of all changed/added/deprecated items" @echo " linkcheck to check all external links for integrity" @echo " doctest to run all doctests embedded in the documentation (if enabled)" clean: -rm -rf $(BUILDDIR)/* html: $(SPHINXBUILD) -b html -A mako_layout=html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." dist-html: $(SPHINXBUILD) -b html -A mako_layout=html $(ALLSPHINXOPTS) .. @echo @echo "Build finished. The HTML pages are in ../." dirhtml: $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." singlehtml: $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml @echo @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." pickle: $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle @echo @echo "Build finished; now you can process the pickle files." json: $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json @echo @echo "Build finished; now you can process the JSON files." htmlhelp: $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ ".hhp project file in $(BUILDDIR)/htmlhelp." qthelp: $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp @echo @echo "Build finished; now you can run "qcollectiongenerator" with the" \ ".qhcp project file in $(BUILDDIR)/qthelp, like this:" @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/SQLAlchemy.qhcp" @echo "To view the help file:" @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/SQLAlchemy.qhc" devhelp: $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp @echo @echo "Build finished." @echo "To view the help file:" @echo "# mkdir -p $$HOME/.local/share/devhelp/SQLAlchemy" @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/SQLAlchemy" @echo "# devhelp" epub: $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub @echo @echo "Build finished. The epub file is in $(BUILDDIR)/epub." latex: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex cp texinputs/* $(BUILDDIR)/latex/ @echo @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." @echo "Run \`make' in that directory to run these through (pdf)latex" \ "(use \`make latexpdf' here to do that automatically)." latexpdf: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through pdflatex..." make -C $(BUILDDIR)/latex all-pdf @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." text: $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text @echo @echo "Build finished. The text files are in $(BUILDDIR)/text." man: $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man @echo @echo "Build finished. The manual pages are in $(BUILDDIR)/man." changes: $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes @echo @echo "The overview file is in $(BUILDDIR)/changes." linkcheck: $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck @echo @echo "Link check complete; look for any errors in the above output " \ "or in $(BUILDDIR)/linkcheck/output.txt." doctest: $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) . @echo "Testing of doctests in the sources finished, look at the " \ "results in $(BUILDDIR)/doctest/output.txt." Mako-0.9.1/doc/build/namespaces.rst0000644000076500000240000003435612257136636017717 0ustar classicstaff00000000000000.. _namespaces_toplevel: ========== Namespaces ========== Namespaces are used to organize groups of defs into categories, and also to "import" defs from other files. If the file ``components.html`` defines these two defs: .. sourcecode:: mako ## components.html <%def name="comp1()"> this is comp1 <%def name="comp2(x)"> this is comp2, x is ${x} you can make another file, for example ``index.html``, that pulls those two defs into a namespace called ``comp``: .. sourcecode:: mako ## index.html <%namespace name="comp" file="components.html"/> Here's comp1: ${comp.comp1()} Here's comp2: ${comp.comp2(x=5)} The ``comp`` variable above is an instance of :class:`.Namespace`, a **proxy object** which delivers method calls to the underlying template callable using the current context. ``<%namespace>`` also provides an ``import`` attribute which can be used to pull the names into the local namespace, removing the need to call it via the "``.``" operator. When ``import`` is used, the ``name`` attribute is optional. .. sourcecode:: mako <%namespace file="components.html" import="comp1, comp2"/> Heres comp1: ${comp1()} Heres comp2: ${comp2(x=5)} ``import`` also supports the "``*``" operator: .. sourcecode:: mako <%namespace file="components.html" import="*"/> Heres comp1: ${comp1()} Heres comp2: ${comp2(x=5)} The names imported by the ``import`` attribute take precedence over any names that exist within the current context. .. note:: In current versions of Mako, usage of ``import='*'`` is known to decrease performance of the template. This will be fixed in a future release. The ``file`` argument allows expressions -- if looking for context variables, the ``context`` must be named explicitly: .. sourcecode:: mako <%namespace name="dyn" file="${context['namespace_name']}"/> Ways to Call Namespaces ======================= There are essentially four ways to call a function from a namespace. The "expression" format, as described previously. Namespaces are just Python objects with functions on them, and can be used in expressions like any other function: .. sourcecode:: mako ${mynamespace.somefunction('some arg1', 'some arg2', arg3='some arg3', arg4='some arg4')} Synonymous with the "expression" format is the "custom tag" format, when a "closed" tag is used. This format, introduced in Mako 0.2.3, allows the usage of a "custom" Mako tag, with the function arguments passed in using named attributes: .. sourcecode:: mako <%mynamespace:somefunction arg1="some arg1" arg2="some arg2" arg3="some arg3" arg4="some arg4"/> When using tags, the values of the arguments are taken as literal strings by default. To embed Python expressions as arguments, use the embedded expression format: .. sourcecode:: mako <%mynamespace:somefunction arg1="${someobject.format()}" arg2="${somedef(5, 12)}"/> The "custom tag" format is intended mainly for namespace functions which recognize body content, which in Mako is known as a "def with embedded content": .. sourcecode:: mako <%mynamespace:somefunction arg1="some argument" args="x, y"> Some record: ${x}, ${y} The "classic" way to call defs with embedded content is the ``<%call>`` tag: .. sourcecode:: mako <%call expr="mynamespace.somefunction(arg1='some argument')" args="x, y"> Some record: ${x}, ${y} For information on how to construct defs that embed content from the caller, see :ref:`defs_with_content`. .. _namespaces_python_modules: Namespaces from Regular Python Modules ====================================== Namespaces can also import regular Python functions from modules. These callables need to take at least one argument, ``context``, an instance of :class:`.Context`. A module file ``some/module.py`` might contain the callable: .. sourcecode:: python def my_tag(context): context.write("hello world") return '' A template can use this module via: .. sourcecode:: mako <%namespace name="hw" module="some.module"/> ${hw.my_tag()} Note that the ``context`` argument is not needed in the call; the :class:`.Namespace` tag creates a locally-scoped callable which takes care of it. The ``return ''`` is so that the def does not dump a ``None`` into the output stream -- the return value of any def is rendered after the def completes, in addition to whatever was passed to :meth:`.Context.write` within its body. If your def is to be called in an "embedded content" context, that is as described in :ref:`defs_with_content`, you should use the :func:`.supports_caller` decorator, which will ensure that Mako will ensure the correct "caller" variable is available when your def is called, supporting embedded content: .. sourcecode:: python from mako.runtime import supports_caller @supports_caller def my_tag(context): context.write("
        ") context['caller'].body() context.write("
        ") return '' Capturing of output is available as well, using the outside-of-templates version of the :func:`.capture` function, which accepts the "context" as its first argument: .. sourcecode:: python from mako.runtime import supports_caller, capture @supports_caller def my_tag(context): return "
        %s
        " % \ capture(context, context['caller'].body, x="foo", y="bar") Declaring Defs in Namespaces ============================ The ``<%namespace>`` tag supports the definition of ``<%def>``\ s directly inside the tag. These defs become part of the namespace like any other function, and will override the definitions pulled in from a remote template or module: .. sourcecode:: mako ## define a namespace <%namespace name="stuff"> <%def name="comp1()"> comp1 ## then call it ${stuff.comp1()} .. _namespaces_body: The ``body()`` Method ===================== Every namespace that is generated from a template contains a method called ``body()``. This method corresponds to the main body of the template, and plays its most important roles when using inheritance relationships as well as def-calls-with-content. Since the ``body()`` method is available from a namespace just like all the other defs defined in a template, what happens if you send arguments to it? By default, the ``body()`` method accepts no positional arguments, and for usefulness in inheritance scenarios will by default dump all keyword arguments into a dictionary called ``pageargs``. But if you actually want to get at the keyword arguments, Mako recommends you define your own argument signature explicitly. You do this via using the ``<%page>`` tag: .. sourcecode:: mako <%page args="x, y, someval=8, scope='foo', **kwargs"/> A template which defines the above signature requires that the variables ``x`` and ``y`` are defined, defines default values for ``someval`` and ``scope``, and sets up ``**kwargs`` to receive all other keyword arguments. If ``**kwargs`` or similar is not present, the argument ``**pageargs`` gets tacked on by Mako. When the template is called as a top-level template (i.e. via :meth:`~.Template.render`) or via the ``<%include>`` tag, the values for these arguments will be pulled from the ``Context``. In all other cases, i.e. via calling the ``body()`` method, the arguments are taken as ordinary arguments from the method call. So above, the body might be called as: .. sourcecode:: mako ${self.body(5, y=10, someval=15, delta=7)} The :class:`.Context` object also supplies a :attr:`~.Context.kwargs` accessor, for cases when you'd like to pass along the top level context arguments to a ``body()`` callable: .. sourcecode:: mako ${next.body(**context.kwargs)} The usefulness of calls like the above become more apparent when one works with inheriting templates. For more information on this, as well as the meanings of the names ``self`` and ``next``, see :ref:`inheritance_toplevel`. .. _namespaces_builtin: Built-in Namespaces =================== The namespace is so great that Mako gives your template one (or two) for free. The names of these namespaces are ``local`` and ``self``. Other built-in namespaces include ``parent`` and ``next``, which are optional and are described in :ref:`inheritance_toplevel`. .. _namespace_local: ``local`` --------- The ``local`` namespace is basically the namespace for the currently executing template. This means that all of the top level defs defined in your template, as well as your template's ``body()`` function, are also available off of the ``local`` namespace. The ``local`` namespace is also where properties like ``uri``, ``filename``, and ``module`` and the ``get_namespace`` method can be particularly useful. .. _namespace_self: ``self`` -------- The ``self`` namespace, in the case of a template that does not use inheritance, is synonymous with ``local``. If inheritance is used, then ``self`` references the topmost template in the inheritance chain, where it is most useful for providing the ultimate form of various "method" calls which may have been overridden at various points in an inheritance chain. See :ref:`inheritance_toplevel`. Inheritable Namespaces ====================== The ``<%namespace>`` tag includes an optional attribute ``inheritable="True"``, which will cause the namespace to be attached to the ``self`` namespace. Since ``self`` is globally available throughout an inheritance chain (described in the next section), all the templates in an inheritance chain can get at the namespace imported in a super-template via ``self``. .. sourcecode:: mako ## base.html <%namespace name="foo" file="foo.html" inheritable="True"/> ${next.body()} ## somefile.html <%inherit file="base.html"/> ${self.foo.bar()} This allows a super-template to load a whole bunch of namespaces that its inheriting templates can get to, without them having to explicitly load those namespaces themselves. The ``import="*"`` part of the ``<%namespace>`` tag doesn't yet interact with the ``inheritable`` flag, so currently you have to use the explicit namespace name off of ``self``, followed by the desired function name. But more on this in a future release. Namespace API Usage Example - Static Dependencies ================================================== The ``<%namespace>`` tag at runtime produces an instance of :class:`.Namespace`. Programmatic access of :class:`.Namespace` can be used to build various kinds of scaffolding in templates and between templates. A common request is the ability for a particular template to declare "static includes" - meaning, the usage of a particular set of defs requires that certain Javascript/CSS files are present. Using :class:`.Namespace` as the object that holds together the various templates present, we can build a variety of such schemes. In particular, the :class:`.Context` has a ``namespaces`` attribute, which is a dictionary of all :class:`.Namespace` objects declared. Iterating the values of this dictionary will provide a :class:`.Namespace` object for each time the ``<%namespace>`` tag was used, anywhere within the inheritance chain. .. _namespace_attr_for_includes: Version One - Use :attr:`.Namespace.attr` ----------------------------------------- The :attr:`.Namespace.attr` attribute allows us to locate any variables declared in the ``<%! %>`` of a template. .. sourcecode:: mako ## base.mako ## base-most template, renders layout etc. ## traverse through all namespaces present, ## look for an attribute named 'includes' % for ns in context.namespaces.values(): % for incl in getattr(ns.attr, 'includes', []): ${incl} % endfor % endfor ${next.body()} ## library.mako ## library functions. <%! includes = [ '', '' ] %> <%def name="mytag()"> ${caller.body()} ## index.mako ## calling template. <%inherit file="base.mako"/> <%namespace name="foo" file="library.mako"/> <%foo:mytag> a form Above, the file ``library.mako`` declares an attribute ``includes`` inside its global ``<%! %>`` section. ``index.mako`` includes this template using the ``<%namespace>`` tag. The base template ``base.mako``, which is the inherited parent of ``index.mako`` and is reponsible for layout, then locates this attribute and iterates through its contents to produce the includes that are specific to ``library.mako``. Version Two - Use a specific named def ----------------------------------------- In this version, we put the includes into a ``<%def>`` that follows a naming convention. .. sourcecode:: mako ## base.mako ## base-most template, renders layout etc. ## traverse through all namespaces present, ## look for a %def named 'includes' % for ns in context.namespaces.values(): % if hasattr(ns, 'includes'): ${ns.includes()} % endif % endfor ${next.body()} ## library.mako ## library functions. <%def name="includes()"> <%def name="mytag()">
        ${caller.body()} ## index.mako ## calling template. <%inherit file="base.mako"/> <%namespace name="foo" file="library.mako"/> <%foo:mytag> a form In this version, ``library.mako`` declares a ``<%def>`` named ``includes``. The example works identically to the previous one, except that ``base.mako`` looks for defs named ``include`` on each namespace it examines. API Reference ============= .. autoclass:: mako.runtime.Namespace :show-inheritance: :members: .. autoclass:: mako.runtime.TemplateNamespace :show-inheritance: :members: .. autoclass:: mako.runtime.ModuleNamespace :show-inheritance: :members: .. autofunction:: mako.runtime.supports_caller .. autofunction:: mako.runtime.capture Mako-0.9.1/doc/build/runtime.rst0000644000076500000240000003741112257136636017256 0ustar classicstaff00000000000000.. _runtime_toplevel: ============================ The Mako Runtime Environment ============================ This section describes a little bit about the objects and built-in functions that are available in templates. .. _context: Context ======= The :class:`.Context` is the central object that is created when a template is first executed, and is responsible for handling all communication with the outside world. Within the template environment, it is available via the :ref:`reserved name ` ``context``. The :class:`.Context` includes two major components, one of which is the output buffer, which is a file-like object such as Python's ``StringIO`` or similar, and the other a dictionary of variables that can be freely referenced within a template; this dictionary is a combination of the arguments sent to the :meth:`~.Template.render` function and some built-in variables provided by Mako's runtime environment. The Buffer ---------- The buffer is stored within the :class:`.Context`, and writing to it is achieved by calling the :meth:`~.Context.write` method -- in a template this looks like ``context.write('some string')``. You usually don't need to care about this, as all text within a template, as well as all expressions provided by ``${}``, automatically send everything to this method. The cases you might want to be aware of its existence are if you are dealing with various filtering/buffering scenarios, which are described in :ref:`filtering_toplevel`, or if you want to programmatically send content to the output stream, such as within a ``<% %>`` block. .. sourcecode:: mako <% context.write("some programmatic text") %> The actual buffer may or may not be the original buffer sent to the :class:`.Context` object, as various filtering/caching scenarios may "push" a new buffer onto the context's underlying buffer stack. For this reason, just stick with ``context.write()`` and content will always go to the topmost buffer. .. _context_vars: Context Variables ----------------- When your template is compiled into a Python module, the body content is enclosed within a Python function called ``render_body``. Other top-level defs defined in the template are defined within their own function bodies which are named after the def's name with the prefix ``render_`` (i.e. ``render_mydef``). One of the first things that happens within these functions is that all variable names that are referenced within the function which are not defined in some other way (i.e. such as via assignment, module level imports, etc.) are pulled from the :class:`.Context` object's dictionary of variables. This is how you're able to freely reference variable names in a template which automatically correspond to what was passed into the current :class:`.Context`. * **What happens if I reference a variable name that is not in the current context?** - The value you get back is a special value called ``UNDEFINED``, or if the ``strict_undefined=True`` flag is used a ``NameError`` is raised. ``UNDEFINED`` is just a simple global variable with the class :class:`mako.runtime.Undefined`. The ``UNDEFINED`` object throws an error when you call ``str()`` on it, which is what happens if you try to use it in an expression. * **UNDEFINED makes it hard for me to find what name is missing** - An alternative is to specify the option ``strict_undefined=True`` to the :class:`.Template` or :class:`.TemplateLookup`. This will cause any non-present variables to raise an immediate ``NameError`` which includes the name of the variable in its message when :meth:`~.Template.render` is called -- ``UNDEFINED`` is not used. .. versionadded:: 0.3.6 * **Why not just return None?** Using ``UNDEFINED``, or raising a ``NameError`` is more explicit and allows differentiation between a value of ``None`` that was explicitly passed to the :class:`.Context` and a value that wasn't present at all. * **Why raise an exception when you call str() on it ? Why not just return a blank string?** - Mako tries to stick to the Python philosophy of "explicit is better than implicit". In this case, it's decided that the template author should be made to specifically handle a missing value rather than experiencing what may be a silent failure. Since ``UNDEFINED`` is a singleton object just like Python's ``True`` or ``False``, you can use the ``is`` operator to check for it: .. sourcecode:: mako % if someval is UNDEFINED: someval is: no value % else: someval is: ${someval} % endif Another facet of the :class:`.Context` is that its dictionary of variables is **immutable**. Whatever is set when :meth:`~.Template.render` is called is what stays. Of course, since its Python, you can hack around this and change values in the context's internal dictionary, but this will probably will not work as well as you'd think. The reason for this is that Mako in many cases creates copies of the :class:`.Context` object, which get sent to various elements of the template and inheriting templates used in an execution. So changing the value in your local :class:`.Context` will not necessarily make that value available in other parts of the template's execution. Examples of where Mako creates copies of the :class:`.Context` include within top-level def calls from the main body of the template (the context is used to propagate locally assigned variables into the scope of defs; since in the template's body they appear as inlined functions, Mako tries to make them act that way), and within an inheritance chain (each template in an inheritance chain has a different notion of ``parent`` and ``next``, which are all stored in unique :class:`.Context` instances). * **So what if I want to set values that are global to everyone within a template request?** - All you have to do is provide a dictionary to your :class:`.Context` when the template first runs, and everyone can just get/set variables from that. Lets say its called ``attributes``. Running the template looks like: .. sourcecode:: python output = template.render(attributes={}) Within a template, just reference the dictionary: .. sourcecode:: mako <% attributes['foo'] = 'bar' %> 'foo' attribute is: ${attributes['foo']} * **Why can't "attributes" be a built-in feature of the Context?** - This is an area where Mako is trying to make as few decisions about your application as it possibly can. Perhaps you don't want your templates to use this technique of assigning and sharing data, or perhaps you have a different notion of the names and kinds of data structures that should be passed around. Once again Mako would rather ask the user to be explicit. Context Methods and Accessors ----------------------------- Significant members of :class:`.Context` include: * ``context[key]`` / ``context.get(key, default=None)`` - dictionary-like accessors for the context. Normally, any variable you use in your template is automatically pulled from the context if it isn't defined somewhere already. Use the dictionary accessor and/or ``get`` method when you want a variable that *is* already defined somewhere else, such as in the local arguments sent to a ``%def`` call. If a key is not present, like a dictionary it raises ``KeyError``. * ``keys()`` - all the names defined within this context. * ``kwargs`` - this returns a **copy** of the context's dictionary of variables. This is useful when you want to propagate the variables in the current context to a function as keyword arguments, i.e.: .. sourcecode:: mako ${next.body(**context.kwargs)} * ``write(text)`` - write some text to the current output stream. * ``lookup`` - returns the :class:`.TemplateLookup` instance that is used for all file-lookups within the current execution (even though individual :class:`.Template` instances can conceivably have different instances of a :class:`.TemplateLookup`, only the :class:`.TemplateLookup` of the originally-called :class:`.Template` gets used in a particular execution). .. _loop_context: The Loop Context ================ Within ``% for`` blocks, the :ref:`reserved name` ``loop`` is available. ``loop`` tracks the progress of the ``for`` loop and makes it easy to use the iteration state to control template behavior: .. sourcecode:: mako
          % for a in ("one", "two", "three"):
        • Item ${loop.index}: ${a}
        • % endfor
        .. versionadded:: 0.7 Iterations ---------- Regardless of the type of iterable you're looping over, ``loop`` always tracks the 0-indexed iteration count (available at ``loop.index``), its parity (through the ``loop.even`` and ``loop.odd`` bools), and ``loop.first``, a bool indicating whether the loop is on its first iteration. If your iterable provides a ``__len__`` method, ``loop`` also provides access to a count of iterations remaining at ``loop.reverse_index`` and ``loop.last``, a bool indicating whether the loop is on its last iteration; accessing these without ``__len__`` will raise a ``TypeError``. Cycling ------- Cycling is available regardless of whether the iterable you're using provides a ``__len__`` method. Prior to Mako 0.7, you might have generated a simple zebra striped list using ``enumerate``: .. sourcecode:: mako
          % for i, item in enumerate(('spam', 'ham', 'eggs')):
        • ${item}
        • % endfor
        With ``loop.cycle``, you get the same results with cleaner code and less prep work: .. sourcecode:: mako
          % for item in ('spam', 'ham', 'eggs'):
        • ${item}
        • % endfor
        Both approaches produce output like the following: .. sourcecode:: html
        • spam
        • ham
        • eggs
        Parent Loops ------------ Loop contexts can also be transparently nested, and the Mako runtime will do the right thing and manage the scope for you. You can access the parent loop context through ``loop.parent``. This allows you to reach all the way back up through the loop stack by chaining ``parent`` attribute accesses, i.e. ``loop.parent.parent....`` as long as the stack depth isn't exceeded. For example, you can use the parent loop to make a checkered table: .. sourcecode:: mako
      % for consonant in 'pbj': % for vowel in 'iou': % endfor % endfor
      ${consonant + vowel}t
      .. sourcecode:: html
      pit pot put
      bit bot but
      jit jot jut
      .. _migrating_loop: Migrating Legacy Templates that Use the Word "loop" --------------------------------------------------- .. versionchanged:: 0.7 The ``loop`` name is now :ref:`reserved ` in Mako, which means a template that refers to a variable named ``loop`` won't function correctly when used in Mako 0.7. To ease the transition for such systems, the feature can be disabled across the board for all templates, then re-enabled on a per-template basis for those templates which wish to make use of the new system. First, the ``enable_loop=False`` flag is passed to either the :class:`.TemplateLookup` or :class:`.Template` object in use: .. sourcecode:: python lookup = TemplateLookup(directories=['/docs'], enable_loop=False) or: .. sourcecode:: python template = Template("some template", enable_loop=False) An individual template can make usage of the feature when ``enable_loop`` is set to ``False`` by switching it back on within the ``<%page>`` tag: .. sourcecode:: mako <%page enable_loop="True"/> % for i in collection: ${i} ${loop.index} % endfor Using the above scheme, it's safe to pass the name ``loop`` to the :meth:`.Template.render` method as well as to freely make usage of a variable named ``loop`` within a template, provided the ``<%page>`` tag doesn't override it. New templates that want to use the ``loop`` context can then set up ``<%page enable_loop="True"/>`` to use the new feature without affecting old templates. All the Built-in Names ====================== A one-stop shop for all the names Mako defines. Most of these names are instances of :class:`.Namespace`, which are described in the next section, :ref:`namespaces_toplevel`. Also, most of these names other than ``context``, ``UNDEFINED``, and ``loop`` are also present *within* the :class:`.Context` itself. The names ``context``, ``loop`` and ``UNDEFINED`` themselves can't be passed to the context and can't be substituted -- see the section :ref:`reserved_names`. * ``context`` - this is the :class:`.Context` object, introduced at :ref:`context`. * ``local`` - the namespace of the current template, described in :ref:`namespaces_builtin`. * ``self`` - the namespace of the topmost template in an inheritance chain (if any, otherwise the same as ``local``), mostly described in :ref:`inheritance_toplevel`. * ``parent`` - the namespace of the parent template in an inheritance chain (otherwise undefined); see :ref:`inheritance_toplevel`. * ``next`` - the namespace of the next template in an inheritance chain (otherwise undefined); see :ref:`inheritance_toplevel`. * ``caller`` - a "mini" namespace created when using the ``<%call>`` tag to define a "def call with content"; described in :ref:`defs_with_content`. * ``loop`` - this provides access to :class:`.LoopContext` objects when they are requested within ``% for`` loops, introduced at :ref:`loop_context`. * ``capture`` - a function that calls a given def and captures its resulting content into a string, which is returned. Usage is described in :ref:`filtering_toplevel`. * ``UNDEFINED`` - a global singleton that is applied to all otherwise uninitialized template variables that were not located within the :class:`.Context` when rendering began, unless the :class:`.Template` flag ``strict_undefined`` is set to ``True``. ``UNDEFINED`` is an instance of :class:`.Undefined`, and raises an exception when its ``__str__()`` method is called. * ``pageargs`` - this is a dictionary which is present in a template which does not define any ``**kwargs`` section in its ``<%page>`` tag. All keyword arguments sent to the ``body()`` function of a template (when used via namespaces) go here by default unless otherwise defined as a page argument. If this makes no sense, it shouldn't; read the section :ref:`namespaces_body`. .. _reserved_names: Reserved Names -------------- Mako has a few names that are considered to be "reserved" and can't be used as variable names. .. versionchanged:: 0.7 Mako raises an error if these words are found passed to the template as context arguments, whereas in previous versions they'd be silently ignored or lead to other error messages. * ``context`` - see :ref:`context`. * ``UNDEFINED`` - see :ref:`context_vars`. * ``loop`` - see :ref:`loop_context`. Note this can be disabled for legacy templates via the ``enable_loop=False`` argument; see :ref:`migrating_loop`. API Reference ============= .. autoclass:: mako.runtime.Context :show-inheritance: :members: .. autoclass:: mako.runtime.LoopContext :show-inheritance: :members: .. autoclass:: mako.runtime.Undefined :show-inheritance: Mako-0.9.1/doc/build/static/0000755000076500000240000000000012257137143016314 5ustar classicstaff00000000000000Mako-0.9.1/doc/build/static/docs.css0000644000076500000240000001554212257136636017773 0ustar classicstaff00000000000000/* global */ body { background-color: #FDFBFC; margin:38px; color:#333333; } a { font-weight:normal; text-decoration:none; } form { display:inline; } /* hyperlinks */ a:link, a:visited, a:active { color:#0000FF; } a:hover { color:#700000; text-decoration:underline; } /* paragraph links after sections. These aren't visible until hovering over the tag, then have a "reverse video" effect over the actual link */ a.headerlink { font-size: 0.8em; padding: 0 4px 0 4px; text-decoration: none; visibility: hidden; } h1:hover > a.headerlink, h2:hover > a.headerlink, h3:hover > a.headerlink, h4:hover > a.headerlink, h5:hover > a.headerlink, h6:hover > a.headerlink, dt:hover > a.headerlink { visibility: visible; } a.headerlink:hover { background-color: #990000; color: white; } /* Container setup */ #docs-container { max-width:1000px; } /* header/footer elements */ #docs-header h1 { font-size:20px; color: #222222; margin: 0; padding: 0; } #docs-header { font-family:Tahoma, Geneva,sans-serif; font-size:.9em; } #docs-top-navigation, #docs-bottom-navigation { font-family: Tahoma, Geneva, sans-serif; background-color: #EEE; border: solid 1px #CCC; padding:10px; font-size:.9em; } #docs-top-navigation { margin:10px 0px 10px 0px; line-height:1.2em; } .docs-navigation-links { font-family:Tahoma, Geneva,sans-serif; } #docs-bottom-navigation { float:right; margin: 1em 0 1em 5px; } #docs-copyright { font-size:.85em; padding:5px 0px; } #docs-header h1, #docs-top-navigation h1, #docs-top-navigation h2 { font-family:Tahoma,Geneva,sans-serif; font-weight:normal; } #docs-top-navigation h2 { margin:16px 4px 7px 5px; font-size:2em; } #docs-search { float:right; } #docs-top-page-control { float:right; width:350px; } #docs-top-page-control ul { padding:0; margin:0; } #docs-top-page-control li { list-style-type:none; padding:1px 8px; } #docs-container .version-num { font-weight: bold; } /* content container, sidebar */ #docs-body-container { background-color:#EFEFEF; border: solid 1px #CCC; } #docs-body, #docs-sidebar { /*font-family: helvetica, arial, sans-serif; font-size:.9em;*/ font-family: Tahoma, Geneva, sans-serif; /*font-size:.85em;*/ line-height:1.5em; } #docs-sidebar > ul { font-size:.9em; } #docs-sidebar { float:left; width:212px; padding: 10px 0 0 15px; /*font-size:.85em;*/ } #docs-sidebar h3, #docs-sidebar h4 { background-color: #DDDDDD; color: #222222; font-family: Tahoma, Geneva,sans-serif; font-size: 1.1em; font-weight: normal; margin: 10px 0 0 -15px; padding: 5px 10px 5px 10px; text-shadow: 1px 1px 0 white; width:210px; } #docs-sidebar h3 a, #docs-sidebar h4 a { color: #222222; } #docs-sidebar ul { margin: 10px 10px 10px 0px; padding: 0; list-style: none outside none; } #docs-sidebar ul ul { margin-bottom: 0; margin-top: 0; list-style: square outside none; margin-left: 20px; } #docs-body { background-color:#FFFFFF; padding:1px 10px 10px 10px; } #docs-body.withsidebar { margin: 0 0 0 230px; border-left:3px solid #DFDFDF; } #docs-body h1, #docs-body h2, #docs-body h3, #docs-body h4 { font-family:Tahoma, Geneva, sans-serif; } #docs-body h1 { /* hide the

      for each content section. */ display:none; font-size:1.8em; } #docs-body h2 { font-size:1.6em; } #docs-body h3 { font-size:1.4em; } /* SQL popup, code styles */ .highlight { background:none; } #docs-container pre { font-size:1.2em; } #docs-container .pre { font-size:1.1em; } #docs-container pre { background-color: #f0f0f0; border: solid 1px #ccc; box-shadow: 2px 2px 3px #DFDFDF; padding:10px; margin: 5px 0px 5px 0px; overflow:auto; line-height:1.3em; } .popup_sql, .show_sql { background-color: #FBFBEE; padding:5px 10px; margin:10px -5px; border:1px dashed; } /* the [SQL] links used to display SQL */ #docs-container .sql_link { font-weight:normal; font-family: arial, sans-serif; font-size:.9em; text-transform: uppercase; color:#990000; border:1px solid; padding:1px 2px 1px 2px; margin:0px 10px 0px 15px; float:right; line-height:1.2em; } #docs-container a.sql_link, #docs-container .sql_link { text-decoration: none; padding:1px 2px; } #docs-container a.sql_link:hover { text-decoration: none; color:#fff; border:1px solid #900; background-color: #900; } /* docutils-specific elements */ th.field-name { text-align:right; } div.note, div.warning, p.deprecated, div.topic { background-color:#EEFFEF; } div.admonition, div.topic, p.deprecated, p.versionadded, p.versionchanged { border:1px solid #CCCCCC; padding:5px 10px; font-size:.9em; box-shadow: 2px 2px 3px #DFDFDF; } div.warning .admonition-title { color:#FF0000; } div.admonition .admonition-title, div.topic .topic-title { font-weight:bold; } .viewcode-back, .viewcode-link { float:right; } dl.function > dt, dl.attribute > dt, dl.classmethod > dt, dl.method > dt, dl.class > dt, dl.exception > dt { background-color:#F0F0F0; margin:25px -10px 10px 10px; padding: 0px 10px; } p.versionadded span.versionmodified, p.versionchanged span.versionmodified, p.deprecated span.versionmodified { background-color: #F0F0F0; font-style: italic; } dt:target, span.highlight { background-color:#FBE54E; } a.headerlink { font-size: 0.8em; padding: 0 4px 0 4px; text-decoration: none; visibility: hidden; } h1:hover > a.headerlink, h2:hover > a.headerlink, h3:hover > a.headerlink, h4:hover > a.headerlink, h5:hover > a.headerlink, h6:hover > a.headerlink, dt:hover > a.headerlink { visibility: visible; } a.headerlink:hover { background-color: #00f; color: white; } .clearboth { clear:both; } tt.descname { background-color:transparent; font-size:1.2em; font-weight:bold; } tt.descclassname { background-color:transparent; } tt { background-color:#ECF0F3; padding:0 1px; } /* syntax highlighting overrides */ .k, .kn {color:#0908CE;} .o {color:#BF0005;} .go {color:#804049;} /* special "index page" sections with specific formatting */ div#sqlalchemy-documentation { font-size:.95em; } div#sqlalchemy-documentation em { font-style:normal; } div#sqlalchemy-documentation .rubric{ font-size:14px; background-color:#EEFFEF; padding:5px; border:1px solid #BFBFBF; } div#sqlalchemy-documentation a, div#sqlalchemy-documentation li { padding:5px 0px; } div#getting-started { border-bottom:1px solid; } div#sqlalchemy-documentation div#sqlalchemy-orm { float:left; width:48%; } div#sqlalchemy-documentation div#sqlalchemy-core { float:left; width:48%; margin:0; padding-left:10px; border-left:1px solid; } div#dialect-documentation { border-top:1px solid; /*clear:left;*/ } Mako-0.9.1/doc/build/static/makoLogo.png0000644000076500000240000002670312257136636020610 0ustar classicstaff00000000000000PNG  IHDRd gAMAOX2tEXtSoftwareAdobe ImageReadyqe<-UIDATxb?(D`cgprrb022b#'O0̚5a >| V+&<K s1k@ 4? Y 7k@f0@1fQ0Й ]!-Qzoܸð~zwR. @l Ħ@F e{@|7hbeQ<,-->}.xBBX-9@_Ak$Z4Zϟ3,_ٳg)BXw MϠr e bHKKcb/fϟ?&@ 4hT?~d>}:r')A};@;8/" 5#mxS fB4Z'O2XXX C3\$t vWx?o#q;ڟ\\\~~~!!!AAA{2 L6 9!@D6 >G W# !! ++ˠȠag,P:;;TBGh3i BCk $6qt(Ԡ --k='466 M@̂YFM͛7#k֬a.elV J${4ɀ<A527o0|ŋ`a`u eeeb >lFRR@4pB`-/&{[}/H:u?0wʔ)l"6(\3[X QK???phBt~ ֭[ 0x4؟"I/(b\5pyy94F1'e6& ΝL?`ݰ_b8^ZZ\  F#}hf7ukd0L\8ʖd`3ß4٣xm0@o@3O>2 E_> .0p F#y jzch2Y[[7ݽ&>`( zt$ N(7ߴi:Z {PTTDp@xPv35ا?Ro4x}Wj_ɮ.Sj FW|݃ @(j sfq;w*++SPbahPn?[]]}zg?S@o߾Qpd :t2f̘,Z{O SVBjd 01ւw7#z }z@gA; ht 8wۑ@˂ЦJW ʰd%%%Z@530|F=!ttY5Ȥ~Xg w7fY#(ymhc&hSEE'xsQ H=H`gf.Y MhDQUU0!Ј"B):舂*T[ԩS qZm.~ *7 DQ }`f1Ҩw t` YdáG޽]ȍAٱcM->f_UgL _fh:7@2|pe4 F3fZ&}kTO"&At4qÁ$U&ph. hy_z~ \zzUd۷if@dC"hQ&C*rȜG"dC>d4d 6˒% :1d7Zd.Ҭ&e]< 4<VP 0Lh&03031iZf>:PKpV9Y'}h\de2*ˌ(,fa /Qd'M4>gÛ_ @#t @fp2 3d_>}V`Ăfgcjݟn7d(APAi >NvN6A>. 4k.OiZ.eU p߹u$3 XN]yHNO _dLp EL 4PXZ/0Q~ex Ãgo%6zD L$? r beo> -@ aZB'8ؘy!NdhQ@髏 7LF6Y63prr1X._m:BMqqe^ՠD%0y˷_R$$6bFA /~f0ӑǨm|ps_0mHؙ '#;} *M_ppgfgtMx3!Aih,űg6@&-2r ^'M4K0@qMt,=]{D+@5(X K3 搀bO@_ ̐B oXSIAVB#dTdcB'T7#0"2iu*M2 !FAW! (aR2WXY3(%.aF)0ȃ ǖv>@| t# 9kw2{<8+Qj’^@  ī[@ yŅx$Dp7A?|$?2h%hf Z4o.Bl';;lDN ƃ)y !iz_LťIVa%=Cua:x @19y'zAC_w 5# 0e1@.z$LЅRt7t1(#g3@.Z#5t@5\`&֯<4pq`+qBd% Y N٨C3B`M~fb0Rt<~f8~>A5M!j"'haRC32|l3Æ (]gj,N޼vٟrndfX ;;C ï_XΣW1g ّ& XֆQc 5(YTӜvQ!3$PM Tӂ.jxHS߳ep߈UtC O!JDžzt+!/3V} ͠ - m.B2 BOז% [*{ XB{~|?s CazYh*Gpqk^>~)9n0~!a _]jbK! X K P@K5wP3QOL%{@jo޽g8}0A'Ⱞ0ˀ 2h j%>ge7yAqʙ d֏XX+DcA`xj8{2[ l- )\`w gEeUL&#>yY K\H9~ф@L7^Rt6^&v ^4$ @`*#Ġ@m?`ÕOão#3uȟӁX6{P`A>`nS?ُn `n: /_>1ϟ?ɠcZebPQPVÐWTVc1`ǰ%g2bu-0 A2Өu:@~A}5}1AAИ7^^ fS00qa@k_{Po gއ4S&cd0#ͥq> ϟ?AM9ATkakhА:1t@e.x@ t'0@P"ڂ@A`4,=$p :4PŁ`@[D8 fϧO@exEuqIiϟRBL\^Z)''Q& +7f j T ObAT h[h@2)`SJ[;0|@dLi?|A:lƁ4pb MOĀ $2Ȍx̭6]@\pM/G"x-3@lWf`ce5DIM6t=CV 27BD>(ـvQT`8ނq@)l 4 &OkWVP [dz < ߾b=junf3W0r1% @CY Tg@:& f41@&׉]{C{'…h$hNOJX|X8ϤEys(4 <\]F{H3?8S2&6íW(k nFA52? ǐ5fV2A @wK)ZP@ | 7 ԤOLJDHUy:.Gbd` L#`;B6Yj@V@JQLF8W ͬ[U~/`T;VÐ݇LjB2-<W^~jPf@"~dx ݇T? F_ -O*{Hh.ȴCw&3&_0/F-3(ĠQKo l@躧T kfl&{ O1> ]@߿#pv ex5ٶ@}?>` jzB2 skK dX[d D́P{_  6rf'/ -Aͼ*x3311lw: g@'mN`iTZg-~)H/;c-fyTm{ @ىQMdQ` L;0Q` A{/qtfX|}_ ?d/..Hiix&XEAG^0*JFMZVL<@U`mW- @ *Z`*Mp{k&y T&~vxT̈́F%}JҀG121"4C1zُht '&w9h$N%~Jk t~6߸@+Giwdؾy-6"Ho^}UU (AWC[;HT>Z E߭dDS`8212Ʊ 5)K)9% `S #)׏)hrߊN?b޼m#\tύ>xYH-#pjg|l @fd:Dž(;m#~دT `DZegpfVGL2`ϤŸ}Bv?K VvN`x~>@ |8`i~h؁.~ 4#UK̍La;d.T'P\@J03!f,^(H/ CkЦUȾ)pՖ߾~aE 0Phې4l3&3A-l菞~EPD 06/ANvmvܩ/=m#"" +w;Vw;?d/E rbvr1\qPyoA Q3p O~-C ]4!o}Ȱc1ZzܡtM0A XG?UP4v6t l:  f hf+Q2J082lZ,M֊:F2*7L);}-k!|VFFVp5 ltx8^}p%0Ph 4 ,!!@囷;T0 ްm?A}aL@@ zee ڏjuh%}( Ip!: b"Bt=SL͛] ߽!]wolhjqˉ>mXz&G >@#q!SPoP@;(Z\' LPYE0s5Дn!i -aΚM;=@w`T;O  A]Me`/~); ~P] yAP^IL@ɐ;0E:z,rgh ^KUAC N 4``g2P.ZtSCؠL ̬ ~! Hmu}Q/yɽk "7i'U.Of.8TQf#mV&d~9c f O=32B}V8y- j?UܽumZW@h- v1Mÿ ?/m_UT2-4@C0V%Ʒށ'ݑ<#;zML1.,6+P_4ZXX:{ v\d`6 (RiC퓁Ũhf&zFr7F匠>##$/-U& TSMa 4P3C 8%?3kۺqU9tw!oX )d2nMVdԍE:r VQͤ0ش Y/T[ fl! !NoFNׯ B"J*-7^@99`n +(?Ӭz WD>] TV̳PquR%XLLLqșˁr< -LnZ30)M?ghP&-M<򗃓EXTL4XAf:e7Y@Q&\aMbtdhNghQPBlfàx_ȹ\o߾C c0|=z"o_89A,ǏVj:7o]يa , (o^ A? G S. d[*Ԕmxy!+>pi;,It6^C=-  *|0"&ɨ7 '`|$1O~89\ -A gAf=X*@! *Z ۿm=Lr@_8)0t 覞+33nt ?# D Wx *.":iG,]]X4sZR0 0_pاeFu4'@fӷojMa^=_,\N?2x3()Pl(@Ѥz9'aB ZY;7̔;q 0 J1'ƠytЀ(ۘ08P`rs/ w'6ivj_qml@4@QH( : 0'@B[ t)0.6,11AR%EBf8@QwMM 5%10efu#OB< ^*d2I^=kg6|f4`XSUCNvfbb R`gO0\|/ g(--ePQQ>8!k?I `JaA64 N@N09s(ЦI%`ash>:͝m/>G'0ӡM T8;gWt3|'޿{/=ax 5k!|dVu3##J͆\QX~ΓG* op-B^PH24o0@RԒ@ÁAj$LLYYپ}aӚe~@GT.K9mX@\}HPMSưUyæm;޽՘Q RJPL3Z_ P!'=wЇ7`S6;$%j =}^2c{(JT-iM@ Ԅla;w=@,si apa0aرk?ñ^~ p%U{#*3"@A,%-CMw2 -]E8`4c8|$ÁCG3`" zb%"hj!ڏ+ZOO!++ARRxEȐpWK4ob8u<{޽N;PjBFb J f&Z i&5MY3]pm`5ް7;({Ν::;Ա $Ѡ튊A] vAAқG:Ǐ^y /hTNB\ Q2(~X{̙ K,^CA`+*l_D78>SQ&((ƣ`p5;+3xI th1&Z`1 F3(v@R & @fQ0.\ TkR@ CNV`PW'm F3(v:XAH" 2 P[HJ3htc ;;UUU0 jt (%4bP)hbYY fj 37'3Cee%M2h&a~sYˋnL6 %S4u @fQ0,FKPMfAMD%%% F3(@FFA_eK >Y& -4FgLIwrss%L6 - hedP4F jj(4_b'L6 -F9? + F3(tZq74>i%0“"XIENDB`Mako-0.9.1/doc/build/static/site.css0000644000076500000240000000221712257136636020002 0ustar classicstaff00000000000000body { font-family: Tahoma, Geneva, sans-serif; line-height:1.4em; margin:15px; background-color:#FFFFFF; } img {border:none;} a { text-decoration: none;} a:visited { color: #2929ff;} a:hover { color: #0000ff;} #wrap { margin:0 auto; max-width:1024px; min-width:480px; position:relative; } h1 { font-size:1.6em; font-weight:bold; } h2 { font-size:1.1em; font-weight:bold; margin:10px 0px 10px 0px; } .clearfix{ clear:both; } .red { font-weight:bold; color:#FF0000; } .rightbar { float:right; } .slogan { margin-top:10px; } #gittip_nav { float:right; margin:10px 0px 0px 0px; } .toolbar { margin-top:20px; } .copyright { font-size:.8em; text-align:center; color:909090; } .pylogo { text-align:right; float:right; } .code { font-family:monospace; } li { margin:1px 0px 1px 0px; } .speedchart td { font-size:small; } pre.codesample { margin: 1.5em; padding: .5em; font-size: .95em; line-height:1em; background-color: #eee; border: 1px solid #ccc; width:450px; overflow:auto; } #speedchart { margin:5px 10px 5px 10px; } Mako-0.9.1/doc/build/syntax.rst0000644000076500000240000003152412257136636017120 0ustar classicstaff00000000000000.. _syntax_toplevel: ====== Syntax ====== A Mako template is parsed from a text stream containing any kind of content, XML, HTML, email text, etc. The template can further contain Mako-specific directives which represent variable and/or expression substitutions, control structures (i.e. conditionals and loops), server-side comments, full blocks of Python code, as well as various tags that offer additional functionality. All of these constructs compile into real Python code. This means that you can leverage the full power of Python in almost every aspect of a Mako template. Expression Substitution ======================= The simplest expression is just a variable substitution. The syntax for this is the ``${}`` construct, which is inspired by Perl, Genshi, JSP EL, and others: .. sourcecode:: mako this is x: ${x} Above, the string representation of ``x`` is applied to the template's output stream. If you're wondering where ``x`` comes from, it's usually from the :class:`.Context` supplied to the template's rendering function. If ``x`` was not supplied to the template and was not otherwise assigned locally, it evaluates to a special value ``UNDEFINED``. More on that later. The contents within the ``${}`` tag are evaluated by Python directly, so full expressions are OK: .. sourcecode:: mako pythagorean theorem: ${pow(x,2) + pow(y,2)} The results of the expression are evaluated into a string result in all cases before being rendered to the output stream, such as the above example where the expression produces a numeric result. Expression Escaping =================== Mako includes a number of built-in escaping mechanisms, including HTML, URI and XML escaping, as well as a "trim" function. These escapes can be added to an expression substitution using the ``|`` operator: .. sourcecode:: mako ${"this is some text" | u} The above expression applies URL escaping to the expression, and produces ``this+is+some+text``. The ``u`` name indicates URL escaping, whereas ``h`` represents HTML escaping, ``x`` represents XML escaping, and ``trim`` applies a trim function. Read more about built-in filtering functions, including how to make your own filter functions, in :ref:`filtering_toplevel`. Control Structures ================== A control structure refers to all those things that control the flow of a program -- conditionals (i.e. ``if``/``else``), loops (like ``while`` and ``for``), as well as things like ``try``/``except``. In Mako, control structures are written using the ``%`` marker followed by a regular Python control expression, and are "closed" by using another ``%`` marker with the tag "``end``", where "````" is the keyword of the expression: .. sourcecode:: mako % if x==5: this is some output % endif The ``%`` can appear anywhere on the line as long as no text precedes it; indentation is not significant. The full range of Python "colon" expressions are allowed here, including ``if``/``elif``/``else``, ``while``, ``for``, and even ``def``, although Mako has a built-in tag for defs which is more full-featured. .. sourcecode:: mako % for a in ['one', 'two', 'three', 'four', 'five']: % if a[0] == 't': its two or three % elif a[0] == 'f': four/five % else: one % endif % endfor The ``%`` sign can also be "escaped", if you actually want to emit a percent sign as the first non whitespace character on a line, by escaping it as in ``%%``: .. sourcecode:: mako %% some text %% some more text The Loop Context ---------------- The **loop context** provides additional information about a loop while inside of a ``% for`` structure: .. sourcecode:: mako
        % for a in ("one", "two", "three"):
      • Item ${loop.index}: ${a}
      • % endfor
      See :ref:`loop_context` for more information on this feature. .. versionadded:: 0.7 Comments ======== Comments come in two varieties. The single line comment uses ``##`` as the first non-space characters on a line: .. sourcecode:: mako ## this is a comment. ...text ... A multiline version exists using ``<%doc> ...text... ``: .. sourcecode:: mako <%doc> these are comments more comments Newline Filters =============== The backslash ("``\``") character, placed at the end of any line, will consume the newline character before continuing to the next line: .. sourcecode:: mako here is a line that goes onto \ another line. The above text evaluates to: .. sourcecode:: text here is a line that goes onto another line. Python Blocks ============= Any arbitrary block of python can be dropped in using the ``<% %>`` tags: .. sourcecode:: mako this is a template <% x = db.get_resource('foo') y = [z.element for z in x if x.frobnizzle==5] %> % for elem in y: element: ${elem} % endfor Within ``<% %>``, you're writing a regular block of Python code. While the code can appear with an arbitrary level of preceding whitespace, it has to be consistently formatted with itself. Mako's compiler will adjust the block of Python to be consistent with the surrounding generated Python code. Module-level Blocks =================== A variant on ``<% %>`` is the module-level code block, denoted by ``<%! %>``. Code within these tags is executed at the module level of the template, and not within the rendering function of the template. Therefore, this code does not have access to the template's context and is only executed when the template is loaded into memory (which can be only once per application, or more, depending on the runtime environment). Use the ``<%! %>`` tags to declare your template's imports, as well as any pure-Python functions you might want to declare: .. sourcecode:: mako <%! import mylib import re def filter(text): return re.sub(r'^@', '', text) %> Any number of ``<%! %>`` blocks can be declared anywhere in a template; they will be rendered in the resulting module in a single contiguous block above all render callables, in the order in which they appear in the source template. Tags ==== The rest of what Mako offers takes place in the form of tags. All tags use the same syntax, which is similar to an XML tag except that the first character of the tag name is a ``%`` character. The tag is closed either by a contained slash character, or an explicit closing tag: .. sourcecode:: mako <%include file="foo.txt"/> <%def name="foo" buffered="True"> this is a def All tags have a set of attributes which are defined for each tag. Some of these attributes are required. Also, many attributes support **evaluation**, meaning you can embed an expression (using ``${}``) inside the attribute text: .. sourcecode:: mako <%include file="/foo/bar/${myfile}.txt"/> Whether or not an attribute accepts runtime evaluation depends on the type of tag and how that tag is compiled into the template. The best way to find out if you can stick an expression in is to try it! The lexer will tell you if it's not valid. Heres a quick summary of all the tags: ``<%page>`` ----------- This tag defines general characteristics of the template, including caching arguments, and optional lists of arguments which the template expects when invoked. .. sourcecode:: mako <%page args="x, y, z='default'"/> Or a page tag that defines caching characteristics: .. sourcecode:: mako <%page cached="True" cache_type="memory"/> Currently, only one ``<%page>`` tag gets used per template, the rest get ignored. While this will be improved in a future release, for now make sure you have only one ``<%page>`` tag defined in your template, else you may not get the results you want. The details of what ``<%page>`` is used for are described further in :ref:`namespaces_body` as well as :ref:`caching_toplevel`. ``<%include>`` -------------- A tag that is familiar from other template languages, ``%include`` is a regular joe that just accepts a file argument and calls in the rendered result of that file: .. sourcecode:: mako <%include file="header.html"/> hello world <%include file="footer.html"/> Include also accepts arguments which are available as ``<%page>`` arguments in the receiving template: .. sourcecode:: mako <%include file="toolbar.html" args="current_section='members', username='ed'"/> ``<%def>`` ---------- The ``%def`` tag defines a Python function which contains a set of content, that can be called at some other point in the template. The basic idea is simple: .. sourcecode:: mako <%def name="myfunc(x)"> this is myfunc, x is ${x} ${myfunc(7)} The ``%def`` tag is a lot more powerful than a plain Python ``def``, as the Mako compiler provides many extra services with ``%def`` that you wouldn't normally have, such as the ability to export defs as template "methods", automatic propagation of the current :class:`.Context`, buffering/filtering/caching flags, and def calls with content, which enable packages of defs to be sent as arguments to other def calls (not as hard as it sounds). Get the full deal on what ``%def`` can do in :ref:`defs_toplevel`. ``<%block>`` ------------ ``%block`` is a tag that is close to a ``%def``, except executes itself immediately in its base-most scope, and can also be anonymous (i.e. with no name): .. sourcecode:: mako <%block filter="h"> some stuff. Inspired by Jinja2 blocks, named blocks offer a syntactically pleasing way to do inheritance: .. sourcecode:: mako <%block name="header">

      <%block name="title"/>

      ${self.body()} Blocks are introduced in :ref:`blocks` and further described in :ref:`inheritance_toplevel`. .. versionadded:: 0.4.1 ``<%namespace>`` ---------------- ``%namespace`` is Mako's equivalent of Python's ``import`` statement. It allows access to all the rendering functions and metadata of other template files, plain Python modules, as well as locally defined "packages" of functions. .. sourcecode:: mako <%namespace file="functions.html" import="*"/> The underlying object generated by ``%namespace``, an instance of :class:`.mako.runtime.Namespace`, is a central construct used in templates to reference template-specific information such as the current URI, inheritance structures, and other things that are not as hard as they sound right here. Namespaces are described in :ref:`namespaces_toplevel`. ``<%inherit>`` -------------- Inherit allows templates to arrange themselves in **inheritance chains**. This is a concept familiar in many other template languages. .. sourcecode:: mako <%inherit file="base.html"/> When using the ``%inherit`` tag, control is passed to the topmost inherited template first, which then decides how to handle calling areas of content from its inheriting templates. Mako offers a lot of flexibility in this area, including dynamic inheritance, content wrapping, and polymorphic method calls. Check it out in :ref:`inheritance_toplevel`. ``<%``\ nsname\ ``:``\ defname\ ``>`` ------------------------------------- Any user-defined "tag" can be created against a namespace by using a tag with a name of the form ``<%:>``. The closed and open formats of such a tag are equivalent to an inline expression and the ``<%call>`` tag, respectively. .. sourcecode:: mako <%mynamespace:somedef param="some value"> this is the body To create custom tags which accept a body, see :ref:`defs_with_content`. .. versionadded:: 0.2.3 ``<%call>`` ----------- The call tag is the "classic" form of a user-defined tag, and is roughly equivalent to the ``<%namespacename:defname>`` syntax described above. This tag is also described in :ref:`defs_with_content`. ``<%doc>`` ---------- The ``%doc`` tag handles multiline comments: .. sourcecode:: mako <%doc> these are comments more comments Also the ``##`` symbol as the first non-space characters on a line can be used for single line comments. ``<%text>`` ----------- This tag suspends the Mako lexer's normal parsing of Mako template directives, and returns its entire body contents as plain text. It is used pretty much to write documentation about Mako: .. sourcecode:: mako <%text filter="h"> heres some fake mako ${syntax} <%def name="x()">${x} Returning Early from a Template =============================== Sometimes you want to stop processing a template or ``<%def>`` method in the middle and just use the text you've accumulated so far. You can use a ``return`` statement inside a Python block to do that. .. sourcecode:: mako % if not len(records): No records found. <% return %> % endif Or perhaps: .. sourcecode:: mako <% if not len(records): return %> Mako-0.9.1/doc/build/templates/0000755000076500000240000000000012257137143017023 5ustar classicstaff00000000000000Mako-0.9.1/doc/build/templates/base.mako0000644000076500000240000000322512257136636020616 0ustar classicstaff00000000000000 <%block name="head_title">Mako Templates for Python</%block> % for cssfile in self.attr.default_css_files + css_files: % endfor <%block name="headers">

      ${next.body()}
      <%block name="footer">
      Mako-0.9.1/doc/build/templates/genindex.mako0000644000076500000240000000351512257136636021507 0ustar classicstaff00000000000000<%inherit file="${context['layout']}"/> <%block name="show_title" filter="util.striptags"> ${_('Index')}

      ${_('Index')}

      % for i, (key, dummy) in enumerate(genindexentries): ${i != 0 and '| ' or ''}${key} % endfor
      % for i, (key, entries) in enumerate(genindexentries):

      ${key}

      <% breakat = genindexcounts[i] // 2 numcols = 1 numitems = 0 %> % for entryname, (links, subitems) in entries:
      % if links: ${entryname|h} % for unknown, link in links[1:]: , [${i}] % endfor % else: ${entryname|h} % endif
      % if subitems:
      % for subentryname, subentrylinks in subitems:
      ${subentryname|h} % for j, (unknown, link) in enumerate(subentrylinks[1:]): [${j}] % endfor
      % endfor
      % endif <% numitems = numitems + 1 + len(subitems) %> % if numcols <2 and numitems > breakat: <% numcols = numcols + 1 %>
      % endif % endfor
      % endfor <%def name="sidebarrel()"> % if split_index:

      ${_('Index')}

      % for i, (key, dummy) in enumerate(genindexentries): ${i > 0 and '| ' or ''} ${key} % endfor

      ${_('Full index on one page')}

      % endif ${parent.sidebarrel()} Mako-0.9.1/doc/build/templates/layout.mako0000644000076500000240000001333412257136636021223 0ustar classicstaff00000000000000## coding: utf-8 <%! local_script_files = [] default_css_files = [ '_static/pygments.css', '_static/docs.css', '_static/site.css' ] %> <%doc> Structural elements are all prefixed with "docs-" to prevent conflicts when the structure is integrated into the main site. docs-container -> docs-header -> docs-search docs-version-header docs-top-navigation docs-top-page-control docs-navigation-banner docs-body-container -> docs-sidebar docs-body docs-bottom-navigation docs-copyright <%inherit file="base.mako"/> <% withsidebar = bool(toc) and current_page_name != 'index' %> <%block name="head_title"> % if current_page_name != 'index': ${capture(self.show_title) | util.striptags} — % endif ${docstitle|h}
      <%block name="headers"> ${parent.headers()} % for scriptfile in script_files + self.attr.local_script_files: % endfor % if hasdoc('about'): % endif % if hasdoc('copyright'): % endif % if parents: % endif % if nexttopic: % endif % if prevtopic: % endif

      ${docstitle|h}

      Release: ${release}
      ${docstitle|h} % if parents: % for parent in parents: » ${parent['title']} % endfor % endif % if current_page_name != 'index': » ${self.show_title()} % endif

      <%block name="show_title"> ${title}

      % if withsidebar:

      Table of Contents

      ${toc} % if prevtopic:

      Previous Topic

      ${prevtopic['title']}

      % endif % if nexttopic:

      Next Topic

      ${nexttopic['title']}

      % endif

      Quick Search

      % endif
      ${next.body()}
      Mako-0.9.1/doc/build/templates/page.mako0000644000076500000240000000011412257136636020612 0ustar classicstaff00000000000000<%inherit file="${context['layout']}"/> ${body| util.strip_toplevel_anchors}Mako-0.9.1/doc/build/templates/rtd_layout.mako0000644000076500000240000000160112257136636022066 0ustar classicstaff00000000000000 <%inherit file="/layout.mako"/> <%block name="headers"> ${parent.headers()} ${next.body()} <%block name="footer"> ${parent.footer()} Mako-0.9.1/doc/build/templates/search.mako0000644000076500000240000000124012257136636021144 0ustar classicstaff00000000000000<%inherit file="${context['layout']}"/> <%! local_script_files = ['_static/searchtools.js'] %> <%block name="show_title" filter="util.striptags"> ${_('Search')}

      Enter Search Terms:

      <%block name="footer"> ${parent.footer()} Mako-0.9.1/doc/build/unicode.rst0000644000076500000240000003246712257136636017227 0ustar classicstaff00000000000000.. _unicode_toplevel: =================== The Unicode Chapter =================== The Python language supports two ways of representing what we know as "strings", i.e. series of characters. In Python 2, the two types are ``string`` and ``unicode``, and in Python 3 they are ``bytes`` and ``string``. A key aspect of the Python 2 ``string`` and Python 3 ``bytes`` types are that they contain no information regarding what **encoding** the data is stored in. For this reason they were commonly referred to as **byte strings** on Python 2, and Python 3 makes this name more explicit. The origins of this come from Python's background of being developed before the Unicode standard was even available, back when strings were C-style strings and were just that, a series of bytes. Strings that had only values below 128 just happened to be **ASCII** strings and were printable on the console, whereas strings with values above 128 would produce all kinds of graphical characters and bells. Contrast the "byte-string" type with the "unicode/string" type. Objects of this latter type are created whenever you say something like ``u"hello world"`` (or in Python 3, just ``"hello world"``). In this case, Python represents each character in the string internally using multiple bytes per character (something similar to UTF-16). What's important is that when using the ``unicode``/``string`` type to store strings, Python knows the data's encoding; it's in its own internal format. Whereas when using the ``string``/``bytes`` type, it does not. When Python 2 attempts to treat a byte-string as a string, which means it's attempting to compare/parse its characters, to coerce it into another encoding, or to decode it to a unicode object, it has to guess what the encoding is. In this case, it will pretty much always guess the encoding as ``ascii``... and if the byte-string contains bytes above value 128, you'll get an error. Python 3 eliminates much of this confusion by just raising an error unconditionally if a byte-string is used in a character-aware context. There is one operation that Python *can* do with a non-ASCII byte-string, and it's a great source of confusion: it can dump the byte-string straight out to a stream or a file, with nary a care what the encoding is. To Python, this is pretty much like dumping any other kind of binary data (like an image) to a stream somewhere. In Python 2, it is common to see programs that embed all kinds of international characters and encodings into plain byte-strings (i.e. using ``"hello world"`` style literals) can fly right through their run, sending reams of strings out to wherever they are going, and the programmer, seeing the same output as was expressed in the input, is now under the illusion that his or her program is Unicode-compliant. In fact, their program has no unicode awareness whatsoever, and similarly has no ability to interact with libraries that *are* unicode aware. Python 3 makes this much less likely by defaulting to unicode as the storage format for strings. The "pass through encoded data" scheme is what template languages like Cheetah and earlier versions of Myghty do by default. Mako as of version 0.2 also supports this mode of operation when using Python 2, using the ``disable_unicode=True`` flag. However, when using Mako in its default mode of unicode-aware, it requires explicitness when dealing with non-ASCII encodings. Additionally, if you ever need to handle unicode strings and other kinds of encoding conversions more intelligently, the usage of raw byte-strings quickly becomes a nightmare, since you are sending the Python interpreter collections of bytes for which it can make no intelligent decisions with regards to encoding. In Python 3 Mako only allows usage of native, unicode strings. In normal Mako operation, all parsed template constructs and output streams are handled internally as Python ``unicode`` objects. It's only at the point of :meth:`~.Template.render` that this unicode stream may be rendered into whatever the desired output encoding is. The implication here is that the template developer must :ensure that :ref:`the encoding of all non-ASCII templates is explicit ` (still required in Python 3), that :ref:`all non-ASCII-encoded expressions are in one way or another converted to unicode ` (not much of a burden in Python 3), and that :ref:`the output stream of the template is handled as a unicode stream being encoded to some encoding ` (still required in Python 3). .. _set_template_file_encoding: Specifying the Encoding of a Template File ========================================== This is the most basic encoding-related setting, and it is equivalent to Python's "magic encoding comment", as described in `pep-0263 `_. Any template that contains non-ASCII characters requires that this comment be present so that Mako can decode to unicode (and also make usage of Python's AST parsing services). Mako's lexer will use this encoding in order to convert the template source into a ``unicode`` object before continuing its parsing: .. sourcecode:: mako ## -*- coding: utf-8 -*- Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! » For the picky, the regular expression used is derived from that of the above mentioned pep: .. sourcecode:: python #.*coding[:=]\s*([-\w.]+).*\n The lexer will convert to unicode in all cases, so that if any characters exist in the template that are outside of the specified encoding (or the default of ``ascii``), the error will be immediate. As an alternative, the template encoding can be specified programmatically to either :class:`.Template` or :class:`.TemplateLookup` via the ``input_encoding`` parameter: .. sourcecode:: python t = TemplateLookup(directories=['./'], input_encoding='utf-8') The above will assume all located templates specify ``utf-8`` encoding, unless the template itself contains its own magic encoding comment, which takes precedence. .. _handling_non_ascii_expressions: Handling Expressions ==================== The next area that encoding comes into play is in expression constructs. By default, Mako's treatment of an expression like this: .. sourcecode:: mako ${"hello world"} looks something like this: .. sourcecode:: python context.write(unicode("hello world")) In Python 3, it's just: .. sourcecode:: python context.write(str("hello world")) That is, **the output of all expressions is run through the ``unicode`` built-in**. This is the default setting, and can be modified to expect various encodings. The ``unicode`` step serves both the purpose of rendering non-string expressions into strings (such as integers or objects which contain ``__str()__`` methods), and to ensure that the final output stream is constructed as a unicode object. The main implication of this is that **any raw byte-strings that contain an encoding other than ASCII must first be decoded to a Python unicode object**. It means you can't say this in Python 2: .. sourcecode:: mako ${"voix m’a réveillé."} ## error in Python 2! You must instead say this: .. sourcecode:: mako ${u"voix m’a réveillé."} ## OK ! Similarly, if you are reading data from a file that is streaming bytes, or returning data from some object that is returning a Python byte-string containing a non-ASCII encoding, you have to explicitly decode to unicode first, such as: .. sourcecode:: mako ${call_my_object().decode('utf-8')} Note that filehandles acquired by ``open()`` in Python 3 default to returning "text", that is the decoding is done for you. See Python 3's documentation for the ``open()`` built-in for details on this. If you want a certain encoding applied to *all* expressions, override the ``unicode`` builtin with the ``decode`` built-in at the :class:`.Template` or :class:`.TemplateLookup` level: .. sourcecode:: python t = Template(templatetext, default_filters=['decode.utf8']) Note that the built-in ``decode`` object is slower than the ``unicode`` function, since unlike ``unicode`` it's not a Python built-in, and it also checks the type of the incoming data to determine if string conversion is needed first. The ``default_filters`` argument can be used to entirely customize the filtering process of expressions. This argument is described in :ref:`filtering_default_filters`. .. _defining_output_encoding: Defining Output Encoding ======================== Now that we have a template which produces a pure unicode output stream, all the hard work is done. We can take the output and do anything with it. As stated in the :doc:`"Usage" chapter `, both :class:`.Template` and :class:`.TemplateLookup` accept ``output_encoding`` and ``encoding_errors`` parameters which can be used to encode the output in any Python supported codec: .. sourcecode:: python from mako.template import Template from mako.lookup import TemplateLookup mylookup = TemplateLookup(directories=['/docs'], output_encoding='utf-8', encoding_errors='replace') mytemplate = mylookup.get_template("foo.txt") print mytemplate.render() :meth:`~.Template.render` will return a ``bytes`` object in Python 3 if an output encoding is specified. By default it performs no encoding and returns a native string. :meth:`~.Template.render_unicode` will return the template output as a Python ``unicode`` object (or ``string`` in Python 3): .. sourcecode:: python print mytemplate.render_unicode() The above method disgards the output encoding keyword argument; you can encode yourself by saying: .. sourcecode:: python print mytemplate.render_unicode().encode('utf-8', 'replace') Buffer Selection ---------------- Mako does play some games with the style of buffering used internally, to maximize performance. Since the buffer is by far the most heavily used object in a render operation, it's important! When calling :meth:`~.Template.render` on a template that does not specify any output encoding (i.e. it's ``ascii``), Python's ``cStringIO`` module, which cannot handle encoding of non-ASCII ``unicode`` objects (even though it can send raw byte-strings through), is used for buffering. Otherwise, a custom Mako class called ``FastEncodingBuffer`` is used, which essentially is a super dumbed-down version of ``StringIO`` that gathers all strings into a list and uses ``u''.join(elements)`` to produce the final output -- it's markedly faster than ``StringIO``. .. _unicode_disabled: Saying to Heck with It: Disabling the Usage of Unicode Entirely =============================================================== Some segments of Mako's userbase choose to make no usage of Unicode whatsoever, and instead would prefer the "pass through" approach; all string expressions in their templates return encoded byte-strings, and they would like these strings to pass right through. The only advantage to this approach is that templates need not use ``u""`` for literal strings; there's an arguable speed improvement as well since raw byte-strings generally perform slightly faster than unicode objects in Python. For these users, assuming they're sticking with Python 2, they can hit the ``disable_unicode=True`` flag as so: .. sourcecode:: python # -*- coding:utf-8 -*- from mako.template import Template t = Template("drôle de petite voix m’a réveillé.", disable_unicode=True, input_encoding='utf-8') print t.code The ``disable_unicode`` mode is strictly a Python 2 thing. It is not supported at all in Python 3. The generated module source code will contain elements like these: .. sourcecode:: python # -*- coding:utf-8 -*- # ...more generated code ... def render_body(context,**pageargs): context.caller_stack.push_frame() try: __M_locals = dict(pageargs=pageargs) # SOURCE LINE 1 context.write('dr\xc3\xb4le de petite voix m\xe2\x80\x99a r\xc3\xa9veill\xc3\xa9.') return '' finally: context.caller_stack.pop_frame() Where above that the string literal used within :meth:`.Context.write` is a regular byte-string. When ``disable_unicode=True`` is turned on, the ``default_filters`` argument which normally defaults to ``["unicode"]`` now defaults to ``["str"]`` instead. Setting ``default_filters`` to the empty list ``[]`` can remove the overhead of the ``str`` call. Also, in this mode you **cannot** safely call :meth:`~.Template.render_unicode` -- you'll get unicode/decode errors. The ``h`` filter (HTML escape) uses a less performant pure Python escape function in non-unicode mode. This because MarkupSafe only supports Python unicode objects for non-ASCII strings. .. versionchanged:: 0.3.4 In prior versions, it used ``cgi.escape()``, which has been replaced with a function that also escapes single quotes. Rules for using ``disable_unicode=True`` ---------------------------------------- * Don't use this mode unless you really, really want to and you absolutely understand what you're doing. * Don't use this option just because you don't want to learn to use Unicode properly; we aren't supporting user issues in this mode of operation. We will however offer generous help for the vast majority of users who stick to the Unicode program. * Python 3 is unicode by default, and the flag is not available when running on Python 3. Mako-0.9.1/doc/build/usage.rst0000644000076500000240000004264412257136636016703 0ustar classicstaff00000000000000.. _usage_toplevel: ===== Usage ===== Basic Usage =========== This section describes the Python API for Mako templates. If you are using Mako within a web framework such as Pylons, the work of integrating Mako's API is already done for you, in which case you can skip to the next section, :ref:`syntax_toplevel`. The most basic way to create a template and render it is through the :class:`.Template` class: .. sourcecode:: python from mako.template import Template mytemplate = Template("hello world!") print mytemplate.render() Above, the text argument to :class:`.Template` is **compiled** into a Python module representation. This module contains a function called ``render_body()``, which produces the output of the template. When ``mytemplate.render()`` is called, Mako sets up a runtime environment for the template and calls the ``render_body()`` function, capturing the output into a buffer and returning its string contents. The code inside the ``render_body()`` function has access to a namespace of variables. You can specify these variables by sending them as additional keyword arguments to the :meth:`~.Template.render` method: .. sourcecode:: python from mako.template import Template mytemplate = Template("hello, ${name}!") print mytemplate.render(name="jack") The :meth:`~.Template.render` method calls upon Mako to create a :class:`.Context` object, which stores all the variable names accessible to the template and also stores a buffer used to capture output. You can create this :class:`.Context` yourself and have the template render with it, using the :meth:`~.Template.render_context` method: .. sourcecode:: python from mako.template import Template from mako.runtime import Context from StringIO import StringIO mytemplate = Template("hello, ${name}!") buf = StringIO() ctx = Context(buf, name="jack") mytemplate.render_context(ctx) print buf.getvalue() Using File-Based Templates ========================== A :class:`.Template` can also load its template source code from a file, using the ``filename`` keyword argument: .. sourcecode:: python from mako.template import Template mytemplate = Template(filename='/docs/mytmpl.txt') print mytemplate.render() For improved performance, a :class:`.Template` which is loaded from a file can also cache the source code to its generated module on the filesystem as a regular Python module file (i.e. a ``.py`` file). To do this, just add the ``module_directory`` argument to the template: .. sourcecode:: python from mako.template import Template mytemplate = Template(filename='/docs/mytmpl.txt', module_directory='/tmp/mako_modules') print mytemplate.render() When the above code is rendered, a file ``/tmp/mako_modules/docs/mytmpl.txt.py`` is created containing the source code for the module. The next time a :class:`.Template` with the same arguments is created, this module file will be automatically re-used. .. _usage_templatelookup: Using ``TemplateLookup`` ======================== All of the examples thus far have dealt with the usage of a single :class:`.Template` object. If the code within those templates tries to locate another template resource, it will need some way to find them, using simple URI strings. For this need, the resolution of other templates from within a template is accomplished by the :class:`.TemplateLookup` class. This class is constructed given a list of directories in which to search for templates, as well as keyword arguments that will be passed to the :class:`.Template` objects it creates: .. sourcecode:: python from mako.template import Template from mako.lookup import TemplateLookup mylookup = TemplateLookup(directories=['/docs']) mytemplate = Template("""<%include file="header.txt"/> hello world!""", lookup=mylookup) Above, we created a textual template which includes the file ``"header.txt"``. In order for it to have somewhere to look for ``"header.txt"``, we passed a :class:`.TemplateLookup` object to it, which will search in the directory ``/docs`` for the file ``"header.txt"``. Usually, an application will store most or all of its templates as text files on the filesystem. So far, all of our examples have been a little bit contrived in order to illustrate the basic concepts. But a real application would get most or all of its templates directly from the :class:`.TemplateLookup`, using the aptly named :meth:`~.TemplateLookup.get_template` method, which accepts the URI of the desired template: .. sourcecode:: python from mako.template import Template from mako.lookup import TemplateLookup mylookup = TemplateLookup(directories=['/docs'], module_directory='/tmp/mako_modules') def serve_template(templatename, **kwargs): mytemplate = mylookup.get_template(templatename) print mytemplate.render(**kwargs) In the example above, we create a :class:`.TemplateLookup` which will look for templates in the ``/docs`` directory, and will store generated module files in the ``/tmp/mako_modules`` directory. The lookup locates templates by appending the given URI to each of its search directories; so if you gave it a URI of ``/etc/beans/info.txt``, it would search for the file ``/docs/etc/beans/info.txt``, else raise a :class:`.TopLevelNotFound` exception, which is a custom Mako exception. When the lookup locates templates, it will also assign a ``uri`` property to the :class:`.Template` which is the URI passed to the :meth:`~.TemplateLookup.get_template()` call. :class:`.Template` uses this URI to calculate the name of its module file. So in the above example, a ``templatename`` argument of ``/etc/beans/info.txt`` will create a module file ``/tmp/mako_modules/etc/beans/info.txt.py``. Setting the Collection Size --------------------------- The :class:`.TemplateLookup` also serves the important need of caching a fixed set of templates in memory at a given time, so that successive URI lookups do not result in full template compilations and/or module reloads on each request. By default, the :class:`.TemplateLookup` size is unbounded. You can specify a fixed size using the ``collection_size`` argument: .. sourcecode:: python mylookup = TemplateLookup(directories=['/docs'], module_directory='/tmp/mako_modules', collection_size=500) The above lookup will continue to load templates into memory until it reaches a count of around 500. At that point, it will clean out a certain percentage of templates using a least recently used scheme. Setting Filesystem Checks ------------------------- Another important flag on :class:`.TemplateLookup` is ``filesystem_checks``. This defaults to ``True``, and says that each time a template is returned by the :meth:`~.TemplateLookup.get_template()` method, the revision time of the original template file is checked against the last time the template was loaded, and if the file is newer will reload its contents and recompile the template. On a production system, setting ``filesystem_checks`` to ``False`` can afford a small to moderate performance increase (depending on the type of filesystem used). .. _usage_unicode: Using Unicode and Encoding ========================== Both :class:`.Template` and :class:`.TemplateLookup` accept ``output_encoding`` and ``encoding_errors`` parameters which can be used to encode the output in any Python supported codec: .. sourcecode:: python from mako.template import Template from mako.lookup import TemplateLookup mylookup = TemplateLookup(directories=['/docs'], output_encoding='utf-8', encoding_errors='replace') mytemplate = mylookup.get_template("foo.txt") print mytemplate.render() When using Python 3, the :meth:`~.Template.render` method will return a ``bytes`` object, **if** ``output_encoding`` is set. Otherwise it returns a ``string``. Additionally, the :meth:`~.Template.render_unicode()` method exists which will return the template output as a Python ``unicode`` object, or in Python 3 a ``string``: .. sourcecode:: python print mytemplate.render_unicode() The above method disregards the output encoding keyword argument; you can encode yourself by saying: .. sourcecode:: python print mytemplate.render_unicode().encode('utf-8', 'replace') Note that Mako's ability to return data in any encoding and/or ``unicode`` implies that the underlying output stream of the template is a Python unicode object. This behavior is described fully in :ref:`unicode_toplevel`. .. _handling_exceptions: Handling Exceptions =================== Template exceptions can occur in two distinct places. One is when you **lookup, parse and compile** the template, the other is when you **run** the template. Within the running of a template, exceptions are thrown normally from whatever Python code originated the issue. Mako has its own set of exception classes which mostly apply to the lookup and lexer/compiler stages of template construction. Mako provides some library routines that can be used to help provide Mako-specific information about any exception's stack trace, as well as formatting the exception within textual or HTML format. In all cases, the main value of these handlers is that of converting Python filenames, line numbers, and code samples into Mako template filenames, line numbers, and code samples. All lines within a stack trace which correspond to a Mako template module will be converted to be against the originating template file. To format exception traces, the :func:`.text_error_template` and :func:`.html_error_template` functions are provided. They make usage of ``sys.exc_info()`` to get at the most recently thrown exception. Usage of these handlers usually looks like: .. sourcecode:: python from mako import exceptions try: template = lookup.get_template(uri) print template.render() except: print exceptions.text_error_template().render() Or for the HTML render function: .. sourcecode:: python from mako import exceptions try: template = lookup.get_template(uri) print template.render() except: print exceptions.html_error_template().render() The :func:`.html_error_template` template accepts two options: specifying ``full=False`` causes only a section of an HTML document to be rendered. Specifying ``css=False`` will disable the default stylesheet from being rendered. E.g.: .. sourcecode:: python print exceptions.html_error_template().render(full=False) The HTML render function is also available built-in to :class:`.Template` using the ``format_exceptions`` flag. In this case, any exceptions raised within the **render** stage of the template will result in the output being substituted with the output of :func:`.html_error_template`: .. sourcecode:: python template = Template(filename="/foo/bar", format_exceptions=True) print template.render() Note that the compile stage of the above template occurs when you construct the :class:`.Template` itself, and no output stream is defined. Therefore exceptions which occur within the lookup/parse/compile stage will not be handled and will propagate normally. While the pre-render traceback usually will not include any Mako-specific lines anyway, it will mean that exceptions which occur previous to rendering and those which occur within rendering will be handled differently... so the ``try``/``except`` patterns described previously are probably of more general use. The underlying object used by the error template functions is the :class:`.RichTraceback` object. This object can also be used directly to provide custom error views. Here's an example usage which describes its general API: .. sourcecode:: python from mako.exceptions import RichTraceback try: template = lookup.get_template(uri) print template.render() except: traceback = RichTraceback() for (filename, lineno, function, line) in traceback.traceback: print "File %s, line %s, in %s" % (filename, lineno, function) print line, "\n" print "%s: %s" % (str(traceback.error.__class__.__name__), traceback.error) Common Framework Integrations ============================= The Mako distribution includes a little bit of helper code for the purpose of using Mako in some popular web framework scenarios. This is a brief description of what's included. WSGI ---- A sample WSGI application is included in the distribution in the file ``examples/wsgi/run_wsgi.py``. This runner is set up to pull files from a `templates` as well as an `htdocs` directory and includes a rudimental two-file layout. The WSGI runner acts as a fully functional standalone web server, using ``wsgiutils`` to run itself, and propagates GET and POST arguments from the request into the :class:`.Context`, can serve images, CSS files and other kinds of files, and also displays errors using Mako's included exception-handling utilities. Pygments -------- A `Pygments `_-compatible syntax highlighting module is included under :mod:`mako.ext.pygmentplugin`. This module is used in the generation of Mako documentation and also contains various `setuptools` entry points under the heading ``pygments.lexers``, including ``mako``, ``html+mako``, ``xml+mako`` (see the ``setup.py`` file for all the entry points). Babel ----- Mako provides support for extracting `gettext` messages from templates via a `Babel`_ extractor entry point under ``mako.ext.babelplugin``. `Gettext` messages are extracted from all Python code sections, including those of control lines and expressions embedded in tags. `Translator comments `_ may also be extracted from Mako templates when a comment tag is specified to `Babel`_ (such as with the ``-c`` option). For example, a project ``"myproj"`` contains the following Mako template at ``myproj/myproj/templates/name.html``: .. sourcecode:: mako
      Name: ## TRANSLATORS: This is a proper name. See the gettext ## manual, section Names. ${_('Francois Pinard')}
      To extract gettext messages from this template the project needs a Mako section in its `Babel Extraction Method Mapping file `_ (typically located at ``myproj/babel.cfg``): .. sourcecode:: cfg # Extraction from Python source files [python: myproj/**.py] # Extraction from Mako templates [mako: myproj/templates/**.html] input_encoding = utf-8 The Mako extractor supports an optional ``input_encoding`` parameter specifying the encoding of the templates (identical to :class:`.Template`/:class:`.TemplateLookup`'s ``input_encoding`` parameter). Invoking `Babel`_'s extractor at the command line in the project's root directory: .. sourcecode:: sh myproj$ pybabel extract -F babel.cfg -c "TRANSLATORS:" . will output a `gettext` catalog to `stdout` including the following: .. sourcecode:: pot #. TRANSLATORS: This is a proper name. See the gettext #. manual, section Names. #: myproj/templates/name.html:5 msgid "Francois Pinard" msgstr "" This is only a basic example: `Babel`_ can be invoked from ``setup.py`` and its command line options specified in the accompanying ``setup.cfg`` via `Babel Distutils/Setuptools Integration `_. Comments must immediately precede a `gettext` message to be extracted. In the following case the ``TRANSLATORS:`` comment would not have been extracted: .. sourcecode:: mako
      ## TRANSLATORS: This is a proper name. See the gettext ## manual, section Names. Name: ${_('Francois Pinard')}
      See the `Babel User Guide `_ for more information. .. _babel: http://babel.edgewall.org/ API Reference ============= .. autoclass:: mako.template.Template :show-inheritance: :members: .. autoclass:: mako.template.DefTemplate :show-inheritance: :members: .. autoclass:: mako.lookup.TemplateCollection :show-inheritance: :members: .. autoclass:: mako.lookup.TemplateLookup :show-inheritance: :members: .. autoclass:: mako.exceptions.RichTraceback :show-inheritance: .. py:attribute:: error the exception instance. .. py:attribute:: message the exception error message as unicode. .. py:attribute:: source source code of the file where the error occurred. If the error occurred within a compiled template, this is the template source. .. py:attribute:: lineno line number where the error occurred. If the error occurred within a compiled template, the line number is adjusted to that of the template source. .. py:attribute:: records a list of 8-tuples containing the original python traceback elements, plus the filename, line number, source line, and full template source for the traceline mapped back to its originating source template, if any for that traceline (else the fields are ``None``). .. py:attribute:: reverse_records the list of records in reverse traceback -- a list of 4-tuples, in the same format as a regular python traceback, with template-corresponding traceback records replacing the originals. .. py:attribute:: reverse_traceback the traceback list in reverse. .. autofunction:: mako.exceptions.html_error_template .. autofunction:: mako.exceptions.text_error_template Mako-0.9.1/doc/caching.html0000644000076500000240000016204712257136656016232 0ustar classicstaff00000000000000 Caching — Mako 0.9.1 Documentation
      Hyperfast and lightweight templating for the Python platform.

      Mako 0.9.1 Documentation

      Release: 0.9.1

      Caching

      Any template or component can be cached using the cache argument to the <%page>, <%def> or <%block> directives:

      <%page cached="True"/>
      
      template text
      

      The above template, after being executed the first time, will store its content within a cache that by default is scoped within memory. Subsequent calls to the template’s render() method will return content directly from the cache. When the Template object itself falls out of scope, its corresponding cache is garbage collected along with the template.

      By default, caching requires that the Beaker package be installed on the system, however the mechanism of caching can be customized to use any third party or user defined system – see Cache Plugins.

      In addition to being available on the <%page> tag, the caching flag and all its options can be used with the <%def> tag as well:

      <%def name="mycomp" cached="True" cache_timeout="60">
          other text
      </%def>
      

      ... and equivalently with the <%block> tag, anonymous or named:

      <%block cached="True" cache_timeout="60">
          other text
      </%block>
      

      Cache Arguments

      Mako has two cache arguments available on tags that are available in all cases. The rest of the arguments available are specific to a backend.

      The two generic tags arguments are:

      • cached="True" - enable caching for this <%page>, <%def>, or <%block>.

      • cache_key - the “key” used to uniquely identify this content in the cache. Usually, this key is chosen automatically based on the name of the rendering callable (i.e. body when used in <%page>, the name of the def when using <%def>, the explicit or internally-generated name when using <%block>). Using the cache_key parameter, the key can be overridden using a fixed or programmatically generated value.

        For example, here’s a page that caches any page which inherits from it, based on the filename of the calling template:

        <%page cached="True" cache_key="${self.filename}"/>
        
        ${next.body()}
        
        ## rest of template
        

      On a Template or TemplateLookup, the caching can be configured using these arguments:

      • cache_enabled - Setting this to False will disable all caching functionality when the template renders. Defaults to True. e.g.:

        lookup = TemplateLookup(
                        directories='/path/to/templates',
                        cache_enabled = False
                        )
        
      • cache_impl - The string name of the cache backend to use. This defaults to 'beaker', which has historically been the only cache backend supported by Mako.

        New in version 0.6.0.

        For example, here’s how to use the upcoming dogpile.cache backend:

        lookup = TemplateLookup(
                        directories='/path/to/templates',
                        cache_impl = 'dogpile.cache',
                        cache_args = {'regions':my_dogpile_regions}
                        )
        
      • cache_args - A dictionary of cache parameters that will be consumed by the cache backend. See Using the Beaker Cache Backend for examples.

        New in version 0.6.0.

      Backend-Specific Cache Arguments

      The <%page>, <%def>, and <%block> tags accept any named argument that starts with the prefix "cache_". Those arguments are then packaged up and passed along to the underlying caching implementation, minus the "cache_" prefix.

      The actual arguments understood are determined by the backend.

      Using the Beaker Cache Backend

      When using Beaker, new implementations will want to make usage of cache regions so that cache configurations can be maintained externally to templates. These configurations live under named “regions” that can be referred to within templates themselves.

      New in version 0.6.0: Support for Beaker cache regions.

      For example, suppose we would like two regions. One is a “short term” region that will store content in a memory-based dictionary, expiring after 60 seconds. The other is a Memcached region, where values should expire in five minutes. To configure our TemplateLookup, first we get a handle to a beaker.cache.CacheManager:

      from beaker.cache import CacheManager
      
      manager = CacheManager(cache_regions={
          'short_term':{
              'type': 'memory',
              'expire': 60
          },
          'long_term':{
              'type': 'ext:memcached',
              'url': '127.0.0.1:11211',
              'expire': 300
          }
      })
      
      lookup = TemplateLookup(
                      directories=['/path/to/templates'],
                      module_directory='/path/to/modules',
                      cache_impl='beaker',
                      cache_args={
                          'manager':manager
                      }
              )
      

      Our templates can then opt to cache data in one of either region, using the cache_region argument. Such as using short_term at the <%page> level:

      <%page cached="True" cache_region="short_term">
      
      ## ...
      

      Or, long_term at the <%block> level:

      <%block name="header" cached="True" cache_region="long_term">
          other text
      </%block>
      

      The Beaker backend also works without regions. There are a variety of arguments that can be passed to the cache_args dictionary, which are also allowable in templates via the <%page>, <%block>, and <%def> tags specific to those sections. The values given override those specified at the TemplateLookup or Template level.

      With the possible exception of cache_timeout, these arguments are probably better off staying at the template configuration level. Each argument specified as cache_XYZ in a template tag is specified without the cache_ prefix in the cache_args dictionary:

      • cache_timeout - number of seconds in which to invalidate the cached data. After this timeout, the content is re-generated on the next call. Available as timeout in the cache_args dictionary.
      • cache_type - type of caching. 'memory', 'file', 'dbm', or 'ext:memcached' (note that the string memcached is also accepted by the dogpile.cache Mako plugin, though not by Beaker itself). Available as type in the cache_args dictionary.
      • cache_url - (only used for memcached but required) a single IP address or a semi-colon separated list of IP address of memcache servers to use. Available as url in the cache_args dictionary.
      • cache_dir - in the case of the 'file' and 'dbm' cache types, this is the filesystem directory with which to store data files. If this option is not present, the value of module_directory is used (i.e. the directory where compiled template modules are stored). If neither option is available an exception is thrown. Available as dir in the cache_args dictionary.

      Using the dogpile.cache Backend

      dogpile.cache is a new replacement for Beaker. It provides a modernized, slimmed down interface and is generally easier to use than Beaker. As of this writing it has not yet been released. dogpile.cache includes its own Mako cache plugin – see dogpile.cache.plugins.mako_cache in the dogpile.cache documentation.

      Programmatic Cache Access

      The Template, as well as any template-derived Namespace, has an accessor called cache which returns the Cache object for that template. This object is a facade on top of the underlying CacheImpl object, and provides some very rudimental capabilities, such as the ability to get and put arbitrary values:

      <%
          local.cache.set("somekey", type="memory", "somevalue")
      %>
      

      Above, the cache associated with the local namespace is accessed and a key is placed within a memory cache.

      More commonly, the cache object is used to invalidate cached sections programmatically:

      template = lookup.get_template('/sometemplate.html')
      
      # invalidate the "body" of the template
      template.cache.invalidate_body()
      
      # invalidate an individual def
      template.cache.invalidate_def('somedef')
      
      # invalidate an arbitrary key
      template.cache.invalidate('somekey')
      

      You can access any special method or attribute of the CacheImpl itself using the impl attribute:

      template.cache.impl.do_something_special()
      

      Note that using implementation-specific methods will mean you can’t swap in a different kind of CacheImpl implementation at a later time.

      Cache Plugins

      The mechanism used by caching can be plugged in using a CacheImpl subclass. This class implements the rudimental methods Mako needs to implement the caching API. Mako includes the BeakerCacheImpl class to provide the default implementation. A CacheImpl class is acquired by Mako using a pkg_resources entrypoint, using the name given as the cache_impl argument to Template or TemplateLookup. This entry point can be installed via the standard setuptools/setup() procedure, underneath the EntryPoint group named "mako.cache". It can also be installed at runtime via a convenience installer register_plugin() which accomplishes essentially the same task.

      An example plugin that implements a local dictionary cache:

      from mako.cache import Cacheimpl, register_plugin
      
      class SimpleCacheImpl(CacheImpl):
          def __init__(self, cache):
              super(SimpleCacheImpl, self).__init__(cache)
              self._cache = {}
      
          def get_or_create(self, key, creation_function, **kw):
              if key in self._cache:
                  return self._cache[key]
              else:
                  self._cache[key] = value = creation_function()
                  return value
      
          def set(self, key, value, **kwargs):
              self._cache[key] = value
      
          def get(self, key, **kwargs):
              return self._cache.get(key)
      
          def invalidate(self, key, **kwargs):
              self._cache.pop(key, None)
      
      # optional - register the class locally
      register_plugin("simple", __name__, "SimpleCacheImpl")
      

      Enabling the above plugin in a template would look like:

      t = Template("mytemplate",
                   file="mytemplate.html",
                   cache_impl='simple')
      

      Guidelines for Writing Cache Plugins

      • The CacheImpl is created on a per-Template basis. The class should ensure that only data for the parent Template is persisted or returned by the cache methods. The actual Template is available via the self.cache.template attribute. The self.cache.id attribute, which is essentially the unique modulename of the template, is a good value to use in order to represent a unique namespace of keys specific to the template.
      • Templates only use the CacheImpl.get_or_create() method in an implicit fashion. The CacheImpl.set(), CacheImpl.get(), and CacheImpl.invalidate() methods are only used in response to direct programmatic access to the corresponding methods on the Cache object.
      • CacheImpl will be accessed in a multithreaded fashion if the Template itself is used multithreaded. Care should be taken to ensure caching implementations are threadsafe.
      • A library like Dogpile, which is a minimal locking system derived from Beaker, can be used to help implement the CacheImpl.get_or_create() method in a threadsafe way that can maximize effectiveness across multiple threads as well as processes. CacheImpl.get_or_create() is the key method used by templates.
      • All arguments passed to **kw come directly from the parameters inside the <%def>, <%block>, or <%page> tags directly, minus the "cache_" prefix, as strings, with the exception of the argument cache_timeout, which is passed to the plugin as the name timeout with the value converted to an integer. Arguments present in cache_args on Template or TemplateLookup are passed directly, but are superseded by those present in the most specific template tag.
      • The directory where Template places module files can be acquired using the accessor self.cache.template.module_directory. This directory can be a good place to throw cache-related work files, underneath a prefix like _my_cache_work so that name conflicts with generated modules don’t occur.

      API Reference

      class mako.cache.Cache(template, *args)

      Bases: object

      Represents a data content cache made available to the module space of a specific Template object.

      New in version 0.6: Cache by itself is mostly a container for a CacheImpl object, which implements a fixed API to provide caching services; specific subclasses exist to implement different caching strategies. Mako includes a backend that works with the Beaker caching system. Beaker itself then supports a number of backends (i.e. file, memory, memcached, etc.)

      The construction of a Cache is part of the mechanics of a Template, and programmatic access to this cache is typically via the Template.cache attribute.

      get(key, **kw)

      Retrieve a value from the cache.

      Parameters:
      • key – the value’s key.
      • **kw – cache configuration arguments. The backend is configured using these arguments upon first request. Subsequent requests that use the same series of configuration values will use that same backend.
      get_or_create(key, creation_function, **kw)

      Retrieve a value from the cache, using the given creation function to generate a new value.

      id = None

      Return the ‘id’ that identifies this cache.

      This is a value that should be globally unique to the Template associated with this cache, and can be used by a caching system to name a local container for data specific to this template.

      impl = None

      Provide the CacheImpl in use by this Cache.

      This accessor allows a CacheImpl with additional methods beyond that of Cache to be used programmatically.

      invalidate(key, **kw)

      Invalidate a value in the cache.

      Parameters:
      • key – the value’s key.
      • **kw – cache configuration arguments. The backend is configured using these arguments upon first request. Subsequent requests that use the same series of configuration values will use that same backend.
      invalidate_body()

      Invalidate the cached content of the “body” method for this template.

      invalidate_closure(name)

      Invalidate a nested <%def> within this template.

      Caching of nested defs is a blunt tool as there is no management of scope – nested defs that use cache tags need to have names unique of all other nested defs in the template, else their content will be overwritten by each other.

      invalidate_def(name)

      Invalidate the cached content of a particular <%def> within this template.

      put(key, value, **kw)

      A synonym for Cache.set().

      This is here for backwards compatibility.

      set(key, value, **kw)

      Place a value in the cache.

      Parameters:
      • key – the value’s key.
      • value – the value.
      • **kw – cache configuration arguments.
      starttime = None

      Epochal time value for when the owning Template was first compiled.

      A cache implementation may wish to invalidate data earlier than this timestamp; this has the effect of the cache for a specific Template starting clean any time the Template is recompiled, such as when the original template file changed on the filesystem.

      class mako.cache.CacheImpl(cache)

      Bases: object

      Provide a cache implementation for use by Cache.

      get(key, **kw)

      Retrieve a value from the cache.

      Parameters:
      • key – the value’s key.
      • **kw – cache configuration arguments.
      get_or_create(key, creation_function, **kw)

      Retrieve a value from the cache, using the given creation function to generate a new value.

      This function must return a value, either from the cache, or via the given creation function. If the creation function is called, the newly created value should be populated into the cache under the given key before being returned.

      Parameters:
      • key – the value’s key.
      • creation_function – function that when called generates a new value.
      • **kw – cache configuration arguments.
      invalidate(key, **kw)

      Invalidate a value in the cache.

      Parameters:
      • key – the value’s key.
      • **kw – cache configuration arguments.
      pass_context = False

      If True, the Context will be passed to get_or_create as the name 'context'.

      set(key, value, **kw)

      Place a value in the cache.

      Parameters:
      • key – the value’s key.
      • value – the value.
      • **kw – cache configuration arguments.
      mako.cache.register_plugin(self, name, modulepath, objname)
      class mako.ext.beaker_cache.BeakerCacheImpl(cache)

      Bases: mako.cache.CacheImpl

      A CacheImpl provided for the Beaker caching system.

      This plugin is used by default, based on the default value of 'beaker' for the cache_impl parameter of the Template or TemplateLookup classes.


      Mako-0.9.1/doc/defs.html0000644000076500000240000015064012257136656015553 0ustar classicstaff00000000000000 Defs and Blocks — Mako 0.9.1 Documentation
      Hyperfast and lightweight templating for the Python platform.

      Mako 0.9.1 Documentation

      Release: 0.9.1

      Defs and Blocks

      <%def> and <%block> are two tags that both demarcate any block of text and/or code. They both exist within generated Python as a callable function, i.e., a Python def. They differ in their scope and calling semantics. Whereas <%def> provides a construct that is very much like a named Python def, the <%block> is more layout oriented.

      Using Defs

      The <%def> tag requires a name attribute, where the name references a Python function signature:

      <%def name="hello()">
          hello world
      </%def>
      

      To invoke the <%def>, it is normally called as an expression:

      the def:  ${hello()}
      

      If the <%def> is not nested inside of another <%def>, it’s known as a top level def and can be accessed anywhere in the template, including above where it was defined.

      All defs, top level or not, have access to the current contextual namespace in exactly the same way their containing template does. Suppose the template below is executed with the variables username and accountdata inside the context:

      Hello there ${username}, how are ya.  Lets see what your account says:
      
      ${account()}
      
      <%def name="account()">
          Account for ${username}:<br/>
      
          % for row in accountdata:
              Value: ${row}<br/>
          % endfor
      </%def>
      

      The username and accountdata variables are present within the main template body as well as the body of the account() def.

      Since defs are just Python functions, you can define and pass arguments to them as well:

      ${account(accountname='john')}
      
      <%def name="account(accountname, type='regular')">
          account name: ${accountname}, type: ${type}
      </%def>
      

      When you declare an argument signature for your def, they are required to follow normal Python conventions (i.e., all arguments are required except keyword arguments with a default value). This is in contrast to using context-level variables, which evaluate to UNDEFINED if you reference a name that does not exist.

      Calling Defs from Other Files

      Top level <%def>s are exported by your template’s module, and can be called from the outside; including from other templates, as well as normal Python code. Calling a <%def> from another template is something like using an <%include> – except you are calling a specific function within the template, not the whole template.

      The remote <%def> call is also a little bit like calling functions from other modules in Python. There is an “import” step to pull the names from another template into your own template; then the function or functions are available.

      To import another template, use the <%namespace> tag:

      <%namespace name="mystuff" file="mystuff.html"/>
      

      The above tag adds a local variable mystuff to the current scope.

      Then, just call the defs off of mystuff:

      ${mystuff.somedef(x=5,y=7)}
      

      The <%namespace> tag also supports some of the other semantics of Python’s import statement, including pulling names into the local variable space, or using * to represent all names, using the import attribute:

      <%namespace file="mystuff.html" import="foo, bar"/>
      

      This is just a quick intro to the concept of a namespace, which is a central Mako concept that has its own chapter in these docs. For more detail and examples, see Namespaces.

      Calling Defs Programmatically

      You can call defs programmatically from any Template object using the get_def() method, which returns a DefTemplate object. This is a Template subclass which the parent Template creates, and is usable like any other template:

      from mako.template import Template
      
      template = Template("""
          <%def name="hi(name)">
              hi ${name}!
          </%def>
      
          <%def name="bye(name)">
              bye ${name}!
          </%def>
      """)
      
      print template.get_def("hi").render(name="ed")
      print template.get_def("bye").render(name="ed")
      

      Defs within Defs

      The def model follows regular Python rules for closures. Declaring <%def> inside another <%def> declares it within the parent’s enclosing scope:

      <%def name="mydef()">
          <%def name="subdef()">
              a sub def
          </%def>
      
          i'm the def, and the subcomponent is ${subdef()}
      </%def>
      

      Just like Python, names that exist outside the inner <%def> exist inside it as well:

      <%
          x = 12
      %>
      <%def name="outer()">
          <%
              y = 15
          %>
          <%def name="inner()">
              inner, x is ${x}, y is ${y}
          </%def>
      
          outer, x is ${x}, y is ${y}
      </%def>
      

      Assigning to a name inside of a def declares that name as local to the scope of that def (again, like Python itself). This means the following code will raise an error:

      <%
          x = 10
      %>
      <%def name="somedef()">
          ## error !
          somedef, x is ${x}
          <%
              x = 27
          %>
      </%def>
      

      ...because the assignment to x declares x as local to the scope of somedef, rendering the “outer” version unreachable in the expression that tries to render it.

      Calling a Def with Embedded Content and/or Other Defs

      A flip-side to def within def is a def call with content. This is where you call a def, and at the same time declare a block of content (or multiple blocks) that can be used by the def being called. The main point of such a call is to create custom, nestable tags, just like any other template language’s custom-tag creation system – where the external tag controls the execution of the nested tags and can communicate state to them. Only with Mako, you don’t have to use any external Python modules, you can define arbitrarily nestable tags right in your templates.

      To achieve this, the target def is invoked using the form <%namepacename:defname> instead of the normal ${} syntax. This syntax, introduced in Mako 0.2.3, is functionally equivalent to another tag known as %call, which takes the form <%call expr='namespacename.defname(args)'>. While %call is available in all versions of Mako, the newer style is probably more familiar looking. The namespace portion of the call is the name of the namespace in which the def is defined – in the most simple cases, this can be local or self to reference the current template’s namespace (the difference between local and self is one of inheritance – see Built-in Namespaces for details).

      When the target def is invoked, a variable caller is placed in its context which contains another namespace containing the body and other defs defined by the caller. The body itself is referenced by the method body(). Below, we build a %def that operates upon caller.body() to invoke the body of the custom tag:

      <%def name="buildtable()">
          <table>
              <tr><td>
                  ${caller.body()}
              </td></tr>
          </table>
      </%def>
      
      <%self:buildtable>
          I am the table body.
      </%self:buildtable>
      

      This produces the output (whitespace formatted):

      <table>
          <tr><td>
              I am the table body.
          </td></tr>
      </table>
      

      Using the older %call syntax looks like:

      <%def name="buildtable()">
          <table>
              <tr><td>
                  ${caller.body()}
              </td></tr>
          </table>
      </%def>
      
      <%call expr="buildtable()">
          I am the table body.
      </%call>
      

      The body() can be executed multiple times or not at all. This means you can use def-call-with-content to build iterators, conditionals, etc:

      <%def name="lister(count)">
          % for x in range(count):
              ${caller.body()}
          % endfor
      </%def>
      
      <%self:lister count="${3}">
          hi
      </%self:lister>
      

      Produces:

      hi
      hi
      hi
      

      Notice above we pass 3 as a Python expression, so that it remains as an integer.

      A custom “conditional” tag:

      <%def name="conditional(expression)">
          % if expression:
              ${caller.body()}
          % endif
      </%def>
      
      <%self:conditional expression="${4==4}">
          i'm the result
      </%self:conditional>
      

      Produces:

      i'm the result
      

      But that’s not all. The body() function also can handle arguments, which will augment the local namespace of the body callable. The caller must define the arguments which it expects to receive from its target def using the args attribute, which is a comma-separated list of argument names. Below, our <%def> calls the body() of its caller, passing in an element of data from its argument:

      <%def name="layoutdata(somedata)">
          <table>
          % for item in somedata:
              <tr>
              % for col in item:
                  <td>${caller.body(col=col)}</td>
              % endfor
              </tr>
          % endfor
          </table>
      </%def>
      
      <%self:layoutdata somedata="${[[1,2,3],[4,5,6],[7,8,9]]}" args="col">\
      Body data: ${col}\
      </%self:layoutdata>
      

      Produces:

      <table>
          <tr>
              <td>Body data: 1</td>
              <td>Body data: 2</td>
              <td>Body data: 3</td>
          </tr>
          <tr>
              <td>Body data: 4</td>
              <td>Body data: 5</td>
              <td>Body data: 6</td>
          </tr>
          <tr>
              <td>Body data: 7</td>
              <td>Body data: 8</td>
              <td>Body data: 9</td>
          </tr>
      </table>
      

      You don’t have to stick to calling just the body() function. The caller can define any number of callables, allowing the <%call> tag to produce whole layouts:

      <%def name="layout()">
          ## a layout def
          <div class="mainlayout">
              <div class="header">
                  ${caller.header()}
              </div>
      
              <div class="sidebar">
                  ${caller.sidebar()}
              </div>
      
              <div class="content">
                  ${caller.body()}
              </div>
          </div>
      </%def>
      
      ## calls the layout def
      <%self:layout>
          <%def name="header()">
              I am the header
          </%def>
          <%def name="sidebar()">
              <ul>
                  <li>sidebar 1</li>
                  <li>sidebar 2</li>
              </ul>
          </%def>
      
              this is the body
      </%self:layout>
      

      The above layout would produce:

      <div class="mainlayout">
          <div class="header">
          I am the header
          </div>
      
          <div class="sidebar">
          <ul>
              <li>sidebar 1</li>
              <li>sidebar 2</li>
          </ul>
          </div>
      
          <div class="content">
          this is the body
          </div>
      </div>
      

      The number of things you can do with <%call> and/or the <%namespacename:defname> calling syntax is enormous. You can create form widget libraries, such as an enclosing <FORM> tag and nested HTML input elements, or portable wrapping schemes using <div> or other elements. You can create tags that interpret rows of data, such as from a database, providing the individual columns of each row to a body() callable which lays out the row any way it wants. Basically anything you’d do with a “custom tag” or tag library in some other system, Mako provides via <%def> tags and plain Python callables which are invoked via <%namespacename:defname> or <%call>.

      Using Blocks

      The <%block> tag introduces some new twists on the <%def> tag which make it more closely tailored towards layout.

      New in version 0.4.1.

      An example of a block:

      <html>
          <body>
              <%block>
                  this is a block.
              </%block>
          </body>
      </html>
      

      In the above example, we define a simple block. The block renders its content in the place that it’s defined. Since the block is called for us, it doesn’t need a name and the above is referred to as an anonymous block. So the output of the above template will be:

      <html>
          <body>
                  this is a block.
          </body>
      </html>
      

      So in fact the above block has absolutely no effect. Its usefulness comes when we start using modifiers. Such as, we can apply a filter to our block:

      <html>
          <body>
              <%block filter="h">
                  <html>this is some escaped html.</html>
              </%block>
          </body>
      </html>
      

      or perhaps a caching directive:

      <html>
          <body>
              <%block cached="True" cache_timeout="60">
                  This content will be cached for 60 seconds.
              </%block>
          </body>
      </html>
      

      Blocks also work in iterations, conditionals, just like defs:

      % if some_condition:
          <%block>condition is met</%block>
      % endif
      

      While the block renders at the point it is defined in the template, the underlying function is present in the generated Python code only once, so there’s no issue with placing a block inside of a loop or similar. Anonymous blocks are defined as closures in the local rendering body, so have access to local variable scope:

      % for i in range(1, 4):
          <%block>i is ${i}</%block>
      % endfor
      

      Using Named Blocks

      Possibly the more important area where blocks are useful is when we do actually give them names. Named blocks are tailored to behave somewhat closely to Jinja2’s block tag, in that they define an area of a layout which can be overridden by an inheriting template. In sharp contrast to the <%def> tag, the name given to a block is global for the entire template regardless of how deeply it’s nested:

      <html>
      <%block name="header">
          <head>
              <title>
                  <%block name="title">Title</%block>
              </title>
          </head>
      </%block>
      <body>
          ${next.body()}
      </body>
      </html>
      

      The above example has two named blocks “header” and “title”, both of which can be referred to by an inheriting template. A detailed walkthrough of this usage can be found at Inheritance.

      Note above that named blocks don’t have any argument declaration the way defs do. They still implement themselves as Python functions, however, so they can be invoked additional times beyond their initial definition:

      <div name="page">
          <%block name="pagecontrol">
              <a href="">previous page</a> |
              <a href="">next page</a>
          </%block>
      
          <table>
              ## some content
          </table>
      
          ${pagecontrol()}
      </div>
      

      The content referenced by pagecontrol above will be rendered both above and below the <table> tags.

      To keep things sane, named blocks have restrictions that defs do not:

      • The <%block> declaration cannot have any argument signature.
      • The name of a <%block> can only be defined once in a template – an error is raised if two blocks of the same name occur anywhere in a single template, regardless of nesting. A similar error is raised if a top level def shares the same name as that of a block.
      • A named <%block> cannot be defined within a <%def>, or inside the body of a “call”, i.e. <%call> or <%namespacename:defname> tag. Anonymous blocks can, however.

      Using Page Arguments in Named Blocks

      A named block is very much like a top level def. It has a similar restriction to these types of defs in that arguments passed to the template via the <%page> tag aren’t automatically available. Using arguments with the <%page> tag is described in the section The body() Method, and refers to scenarios such as when the body() method of a template is called from an inherited template passing arguments, or the template is invoked from an <%include> tag with arguments. To allow a named block to share the same arguments passed to the page, the args attribute can be used:

      <%page args="post"/>
      
      <a name="${post.title}" />
      
      <span class="post_prose">
          <%block name="post_prose" args="post">
              ${post.content}
          </%block>
      </span>
      

      Where above, if the template is called via a directive like <%include file="post.mako" args="post=post" />, the post variable is available both in the main body as well as the post_prose block.

      Similarly, the **pageargs variable is present, in named blocks only, for those arguments not explicit in the <%page> tag:

      <%block name="post_prose">
          ${pageargs['post'].content}
      </%block>
      

      The args attribute is only allowed with named blocks. With anonymous blocks, the Python function is always rendered in the same scope as the call itself, so anything available directly outside the anonymous block is available inside as well.


      Mako-0.9.1/doc/filtering.html0000644000076500000240000010116412257136656016612 0ustar classicstaff00000000000000 Filtering and Buffering — Mako 0.9.1 Documentation
      Hyperfast and lightweight templating for the Python platform.

      Mako 0.9.1 Documentation

      Release: 0.9.1
      Mako 0.9.1 Documentation » Filtering and Buffering

      Filtering and Buffering

      Filtering and Buffering

      Expression Filtering

      As described in the chapter Syntax, the “|” operator can be applied to a “${}” expression to apply escape filters to the output:

      ${"this is some text" | u}
      

      The above expression applies URL escaping to the expression, and produces this+is+some+text.

      The built-in escape flags are:

      • u : URL escaping, provided by urllib.quote_plus(string.encode('utf-8'))

      • h : HTML escaping, provided by markupsafe.escape(string)

        New in version 0.3.4: Prior versions use cgi.escape(string, True).

      • x : XML escaping

      • trim : whitespace trimming, provided by string.strip()

      • entity : produces HTML entity references for applicable strings, derived from htmlentitydefs

      • unicode (str on Python 3): produces a Python unicode string (this function is applied by default)

      • decode.<some encoding>: decode input into a Python unicode with the specified encoding

      • n : disable all default filtering; only filters specified in the local expression tag will be applied.

      To apply more than one filter, separate them by a comma:

      ${" <tag>some value</tag> " | h,trim}
      

      The above produces &lt;tag&gt;some value&lt;/tag&gt;, with no leading or trailing whitespace. The HTML escaping function is applied first, the “trim” function second.

      Naturally, you can make your own filters too. A filter is just a Python function that accepts a single string argument, and returns the filtered result. The expressions after the | operator draw upon the local namespace of the template in which they appear, meaning you can define escaping functions locally:

      <%!
          def myescape(text):
              return "<TAG>" + text + "</TAG>"
      %>
      
      Here's some tagged text: ${"text" | myescape}
      

      Or from any Python module:

      <%!
          import myfilters
      %>
      
      Here's some tagged text: ${"text" | myfilters.tagfilter}
      

      A page can apply a default set of filters to all expression tags using the expression_filter argument to the %page tag:

      <%page expression_filter="h"/>
      
      Escaped text:  ${"<html>some html</html>"}
      

      Result:

      Escaped text: &lt;html&gt;some html&lt;/html&gt;
      

      The default_filters Argument

      In addition to the expression_filter argument, the default_filters argument to both Template and TemplateLookup can specify filtering for all expression tags at the programmatic level. This array-based argument, when given its default argument of None, will be internally set to ["unicode"] (or ["str"] on Python 3), except when disable_unicode=True is set in which case it defaults to ["str"]:

      t = TemplateLookup(directories=['/tmp'], default_filters=['unicode'])
      

      To replace the usual unicode/str function with a specific encoding, the decode filter can be substituted:

      t = TemplateLookup(directories=['/tmp'], default_filters=['decode.utf8'])
      

      To disable default_filters entirely, set it to an empty list:

      t = TemplateLookup(directories=['/tmp'], default_filters=[])
      

      Any string name can be added to default_filters where it will be added to all expressions as a filter. The filters are applied from left to right, meaning the leftmost filter is applied first.

      t = Template(templatetext, default_filters=['unicode', 'myfilter'])
      

      To ease the usage of default_filters with custom filters, you can also add imports (or other code) to all templates using the imports argument:

      t = TemplateLookup(directories=['/tmp'],
                         default_filters=['unicode', 'myfilter'],
                         imports=['from mypackage import myfilter'])
      

      The above will generate templates something like this:

      # ....
      from mypackage import myfilter
      
      def render_body(context):
          context.write(myfilter(unicode("some text")))
      

      Turning off Filtering with the n Filter

      In all cases the special n filter, used locally within an expression, will disable all filters declared in the <%page> tag as well as in default_filters. Such as:

      ${'myexpression' | n}
      

      will render myexpression with no filtering of any kind, and:

      ${'myexpression' | n,trim}
      

      will render myexpression using the trim filter only.

      Filtering Defs and Blocks

      The %def and %block tags have an argument called filter which will apply the given list of filter functions to the output of the %def:

      <%def name="foo()" filter="h, trim">
          <b>this is bold</b>
      </%def>
      

      When the filter attribute is applied to a def as above, the def is automatically buffered as well. This is described next.

      Buffering

      One of Mako’s central design goals is speed. To this end, all of the textual content within a template and its various callables is by default piped directly to the single buffer that is stored within the Context object. While this normally is easy to miss, it has certain side effects. The main one is that when you call a def using the normal expression syntax, i.e. ${somedef()}, it may appear that the return value of the function is the content it produced, which is then delivered to your template just like any other expression substitution, except that normally, this is not the case; the return value of ${somedef()} is simply the empty string ''. By the time you receive this empty string, the output of somedef() has been sent to the underlying buffer.

      You may not want this effect, if for example you are doing something like this:

      ${" results " + somedef() + " more results "}
      

      If the somedef() function produced the content “somedef's results”, the above template would produce this output:

      somedef's results results more results
      

      This is because somedef() fully executes before the expression returns the results of its concatenation; the concatenation in turn receives just the empty string as its middle expression.

      Mako provides two ways to work around this. One is by applying buffering to the %def itself:

      <%def name="somedef()" buffered="True">
          somedef's results
      </%def>
      

      The above definition will generate code similar to this:

      def somedef():
          context.push_buffer()
          try:
              context.write("somedef's results")
          finally:
              buf = context.pop_buffer()
          return buf.getvalue()
      

      So that the content of somedef() is sent to a second buffer, which is then popped off the stack and its value returned. The speed hit inherent in buffering the output of a def is also apparent.

      Note that the filter argument on %def also causes the def to be buffered. This is so that the final content of the %def can be delivered to the escaping function in one batch, which reduces method calls and also produces more deterministic behavior for the filtering function itself, which can possibly be useful for a filtering function that wishes to apply a transformation to the text as a whole.

      The other way to buffer the output of a def or any Mako callable is by using the built-in capture function. This function performs an operation similar to the above buffering operation except it is specified by the caller.

      ${" results " + capture(somedef) + " more results "}
      

      Note that the first argument to the capture function is the function itself, not the result of calling it. This is because the capture function takes over the job of actually calling the target function, after setting up a buffered environment. To send arguments to the function, just send them to capture instead:

      ${capture(somedef, 17, 'hi', use_paging=True)}
      

      The above call is equivalent to the unbuffered call:

      ${somedef(17, 'hi', use_paging=True)}
      

      Decorating

      New in version 0.2.5.

      Somewhat like a filter for a %def but more flexible, the decorator argument to %def allows the creation of a function that will work in a similar manner to a Python decorator. The function can control whether or not the function executes. The original intent of this function is to allow the creation of custom cache logic, but there may be other uses as well.

      decorator is intended to be used with a regular Python function, such as one defined in a library module. Here we’ll illustrate the python function defined in the template for simplicities’ sake:

      <%!
          def bar(fn):
              def decorate(context, *args, **kw):
                  context.write("BAR")
                  fn(*args, **kw)
                  context.write("BAR")
                  return ''
              return decorate
      %>
      
      <%def name="foo()" decorator="bar">
          this is foo
      </%def>
      
      ${foo()}
      

      The above template will return, with more whitespace than this, "BAR this is foo BAR". The function is the render callable itself (or possibly a wrapper around it), and by default will write to the context. To capture its output, use the capture() callable in the mako.runtime module (available in templates as just runtime):

      <%!
          def bar(fn):
              def decorate(context, *args, **kw):
                  return "BAR" + runtime.capture(context, fn, *args, **kw) + "BAR"
              return decorate
      %>
      
      <%def name="foo()" decorator="bar">
          this is foo
      </%def>
      
      ${foo()}
      

      The decorator can be used with top-level defs as well as nested defs, and blocks too. Note that when calling a top-level def from the Template API, i.e. template.get_def('somedef').render(), the decorator has to write the output to the context, i.e. as in the first example. The return value gets discarded.


      Mako-0.9.1/doc/genindex.html0000644000076500000240000004341312257136657016433 0ustar classicstaff00000000000000 Index — Mako 0.9.1 Documentation
      Hyperfast and lightweight templating for the Python platform.

      Mako 0.9.1 Documentation

      Release: 0.9.1

      Index

      A | B | C | D | E | F | G | H | I | K | L | M | N | P | R | S | T | U | W

      A

      adjust_uri() (mako.lookup.TemplateCollection method)
      (mako.lookup.TemplateLookup method)
      attr (mako.runtime.Namespace attribute)

      B

      BeakerCacheImpl (class in mako.ext.beaker_cache)

      C

      Cache (class in mako.cache)
      cache (mako.runtime.Namespace attribute)
      CacheImpl (class in mako.cache)
      capture() (in module mako.runtime)
      code (mako.template.Template attribute)
      Context (class in mako.runtime)
      context (mako.runtime.Namespace attribute)
      cycle() (mako.runtime.LoopContext method)

      D

      DefTemplate (class in mako.template)

      E

      error (RichTraceback attribute)

      F

      filename (mako.runtime.ModuleNamespace attribute)
      (mako.runtime.Namespace attribute)
      (mako.runtime.TemplateNamespace attribute)
      filename_to_uri() (mako.lookup.TemplateCollection method)
      (mako.lookup.TemplateLookup method)

      G

      get() (mako.cache.Cache method)
      (mako.cache.CacheImpl method)
      (mako.runtime.Context method)
      get_cached() (mako.runtime.Namespace method)
      get_def() (mako.template.Template method)
      get_namespace() (mako.runtime.Namespace method)
      get_or_create() (mako.cache.Cache method)
      (mako.cache.CacheImpl method)
      get_template() (mako.lookup.TemplateCollection method)
      (mako.lookup.TemplateLookup method)
      (mako.runtime.Namespace method)

      H

      has_template() (mako.lookup.TemplateCollection method)
      html_error_template() (in module mako.exceptions)

      I

      id (mako.cache.Cache attribute)
      impl (mako.cache.Cache attribute)
      include_file() (mako.runtime.Namespace method)
      invalidate() (mako.cache.Cache method)
      (mako.cache.CacheImpl method)
      invalidate_body() (mako.cache.Cache method)
      invalidate_closure() (mako.cache.Cache method)
      invalidate_def() (mako.cache.Cache method)

      K

      keys() (mako.runtime.Context method)
      kwargs (mako.runtime.Context attribute)

      L

      lineno (RichTraceback attribute)
      lookup (mako.runtime.Context attribute)
      LoopContext (class in mako.runtime)

      M

      message (RichTraceback attribute)
      module (mako.runtime.Namespace attribute)
      (mako.runtime.TemplateNamespace attribute)
      ModuleNamespace (class in mako.runtime)

      N

      Namespace (class in mako.runtime)

      P

      pass_context (mako.cache.CacheImpl attribute)
      pop_caller() (mako.runtime.Context method)
      push_caller() (mako.runtime.Context method)
      put() (mako.cache.Cache method)
      put_string() (mako.lookup.TemplateLookup method)
      put_template() (mako.lookup.TemplateLookup method)

      R

      records (RichTraceback attribute)
      register_plugin() (in module mako.cache)
      render() (mako.template.Template method)
      render_context() (mako.template.Template method)
      render_unicode() (mako.template.Template method)
      reverse_records (RichTraceback attribute)
      reverse_traceback (RichTraceback attribute)
      RichTraceback (class in mako.exceptions)

      S

      set() (mako.cache.Cache method)
      (mako.cache.CacheImpl method)
      source (mako.template.Template attribute)
      (RichTraceback attribute)
      starttime (mako.cache.Cache attribute)
      supports_caller() (in module mako.runtime)

      T

      Template (class in mako.template)
      template (mako.runtime.Namespace attribute)
      TemplateCollection (class in mako.lookup)
      TemplateLookup (class in mako.lookup)
      TemplateNamespace (class in mako.runtime)
      text_error_template() (in module mako.exceptions)

      U

      Undefined (class in mako.runtime)
      uri (mako.runtime.Namespace attribute)
      (mako.runtime.TemplateNamespace attribute)

      W

      write() (mako.runtime.Context method)
      writer() (mako.runtime.Context method)

      Mako-0.9.1/doc/index.html0000644000076500000240000002617312257136656015744 0ustar classicstaff00000000000000 Mako 0.9.1 Documentation
      Hyperfast and lightweight templating for the Python platform.

      Mako 0.9.1 Documentation

      Release: 0.9.1

      Mako-0.9.1/doc/inheritance.html0000644000076500000240000013646612257136656017135 0ustar classicstaff00000000000000 Inheritance — Mako 0.9.1 Documentation
      Hyperfast and lightweight templating for the Python platform.

      Mako 0.9.1 Documentation

      Release: 0.9.1

      Inheritance

      Note

      Most of the inheritance examples here take advantage of a feature that’s new in Mako as of version 0.4.1 called the “block”. This tag is very similar to the “def” tag but is more streamlined for usage with inheritance. Note that all of the examples here which use blocks can also use defs instead. Contrasting usages will be illustrated.

      Using template inheritance, two or more templates can organize themselves into an inheritance chain, where content and functions from all involved templates can be intermixed. The general paradigm of template inheritance is this: if a template A inherits from template B, then template A agrees to send the executional control to template B at runtime (A is called the inheriting template). Template B, the inherited template, then makes decisions as to what resources from A shall be executed.

      In practice, it looks like this. Here’s a hypothetical inheriting template, index.html:

      ## index.html
      <%inherit file="base.html"/>
      
      <%block name="header">
          this is some header content
      </%block>
      
      this is the body content.
      

      And base.html, the inherited template:

      ## base.html
      <html>
          <body>
              <div class="header">
                  <%block name="header"/>
              </div>
      
              ${self.body()}
      
              <div class="footer">
                  <%block name="footer">
                      this is the footer
                  </%block>
              </div>
          </body>
      </html>
      

      Here is a breakdown of the execution:

      1. When index.html is rendered, control immediately passes to base.html.

      2. base.html then renders the top part of an HTML document, then invokes the <%block name="header"> block. It invokes the underlying header() function off of a built-in namespace called self (this namespace was first introduced in the Namespaces chapter in self). Since index.html is the topmost template and also defines a block called header, it’s this header block that ultimately gets executed – instead of the one that’s present in base.html.

      3. Control comes back to base.html. Some more HTML is rendered.

      4. base.html executes self.body(). The body() function on all template-based namespaces refers to the main body of the template, therefore the main body of index.html is rendered.

      5. When <%block name="header"> is encountered in index.html during the self.body() call, a conditional is checked – does the current inherited template, i.e. base.html, also define this block? If yes, the <%block> is not executed here – the inheritance mechanism knows that the parent template is responsible for rendering this block (and in fact it already has). In other words a block only renders in its basemost scope.

      6. Control comes back to base.html. More HTML is rendered, then the <%block name="footer"> expression is invoked.

      7. The footer block is only defined in base.html, so being the topmost definition of footer, it’s the one that executes. If index.html also specified footer, then its version would override that of the base.

      8. base.html finishes up rendering its HTML and the template is complete, producing:

        <html>
            <body>
                <div class="header">
                    this is some header content
                </div>
        
                this is the body content.
        
                <div class="footer">
                    this is the footer
                </div>
            </body>
        </html>
        

      ...and that is template inheritance in a nutshell. The main idea is that the methods that you call upon self always correspond to the topmost definition of that method. Very much the way self works in a Python class, even though Mako is not actually using Python class inheritance to implement this functionality. (Mako doesn’t take the “inheritance” metaphor too seriously; while useful to setup some commonly recognized semantics, a textual template is not very much like an object-oriented class construct in practice).

      Nesting Blocks

      The named blocks defined in an inherited template can also be nested within other blocks. The name given to each block is globally accessible via any inheriting template. We can add a new block title to our header block:

      ## base.html
      <html>
          <body>
              <div class="header">
                  <%block name="header">
                      <h2>
                          <%block name="title"/>
                      </h2>
                  </%block>
              </div>
      
              ${self.body()}
      
              <div class="footer">
                  <%block name="footer">
                      this is the footer
                  </%block>
              </div>
          </body>
      </html>
      

      The inheriting template can name either or both of header and title, separately or nested themselves:

      ## index.html
      <%inherit file="base.html"/>
      
      <%block name="header">
          this is some header content
          ${parent.header()}
      </%block>
      
      <%block name="title">
          this is the title
      </%block>
      
      this is the body content.
      

      Note when we overrode header, we added an extra call ${parent.header()} in order to invoke the parent’s header block in addition to our own. That’s described in more detail below, in Using the parent Namespace to Augment Defs.

      Rendering a Named Block Multiple Times

      Recall from the section Using Blocks that a named block is just like a <%def>, with some different usage rules. We can call one of our named sections distinctly, for example a section that is used more than once, such as the title of a page:

      <html>
          <head>
              <title>${self.title()}</title>
          </head>
          <body>
          <%block name="header">
              <h2><%block name="title"/></h2>
          </%block>
          ${self.body()}
          </body>
      </html>
      

      Where above an inheriting template can define <%block name="title"> just once, and it will be used in the base template both in the <title> section as well as the <h2>.

      But what about Defs?

      The previous example used the <%block> tag to produce areas of content to be overridden. Before Mako 0.4.1, there wasn’t any such tag – instead there was only the <%def> tag. As it turns out, named blocks and defs are largely interchangeable. The def simply doesn’t call itself automatically, and has more open-ended naming and scoping rules that are more flexible and similar to Python itself, but less suited towards layout. The first example from this chapter using defs would look like:

      ## index.html
      <%inherit file="base.html"/>
      
      <%def name="header()">
          this is some header content
      </%def>
      
      this is the body content.
      

      And base.html, the inherited template:

      ## base.html
      <html>
          <body>
              <div class="header">
                  ${self.header()}
              </div>
      
              ${self.body()}
      
              <div class="footer">
                  ${self.footer()}
              </div>
          </body>
      </html>
      
      <%def name="header()"/>
      <%def name="footer()">
          this is the footer
      </%def>
      

      Above, we illustrate that defs differ from blocks in that their definition and invocation are defined in two separate places, instead of at once. You can almost do exactly what a block does if you put the two together:

      <div class="header">
          <%def name="header()"></%def>${self.header()}
      </div>
      

      The <%block> is obviously more streamlined than the <%def> for this kind of usage. In addition, the above “inline” approach with <%def> does not work with nesting:

      <head>
          <%def name="header()">
              <title>
              ## this won't work !
              <%def name="title()">default title</%def>${self.title()}
              </title>
          </%def>${self.header()}
      </head>
      

      Where above, the title() def, because it’s a def within a def, is not part of the template’s exported namespace and will not be part of self. If the inherited template did define its own title def at the top level, it would be called, but the “default title” above is not present at all on self no matter what. For this to work as expected you’d instead need to say:

      <head>
          <%def name="header()">
              <title>
              ${self.title()}
              </title>
          </%def>${self.header()}
      
          <%def name="title()"/>
      </head>
      

      That is, title is defined outside of any other defs so that it is in the self namespace. It works, but the definition needs to be potentially far away from the point of render.

      A named block is always placed in the self namespace, regardless of nesting, so this restriction is lifted:

      ## base.html
      <head>
          <%block name="header">
              <title>
              <%block name="title"/>
              </title>
          </%block>
      </head>
      

      The above template defines title inside of header, and an inheriting template can define one or both in any configuration, nested inside each other or not, in order for them to be used:

      ## index.html
      <%inherit file="base.html"/>
      <%block name="title">
          the title
      </%block>
      <%block name="header">
          the header
      </%block>
      

      So while the <%block> tag lifts the restriction of nested blocks not being available externally, in order to achieve this it adds the restriction that all block names in a single template need to be globally unique within the template, and additionally that a <%block> can’t be defined inside of a <%def>. It’s a more restricted tag suited towards a more specific use case than <%def>.

      Using the next Namespace to Produce Content Wrapping

      Sometimes you have an inheritance chain that spans more than two templates. Or maybe you don’t, but you’d like to build your system such that extra inherited templates can be inserted in the middle of a chain where they would be smoothly integrated. If each template wants to define its layout just within its main body, you can’t just call self.body() to get at the inheriting template’s body, since that is only the topmost body. To get at the body of the next template, you call upon the namespace next, which is the namespace of the template immediately following the current template.

      Lets change the line in base.html which calls upon self.body() to instead call upon next.body():

      ## base.html
      <html>
          <body>
              <div class="header">
                  <%block name="header"/>
              </div>
      
              ${next.body()}
      
              <div class="footer">
                  <%block name="footer">
                      this is the footer
                  </%block>
              </div>
          </body>
      </html>
      

      Lets also add an intermediate template called layout.html, which inherits from base.html:

      ## layout.html
      <%inherit file="base.html"/>
      <ul>
          <%block name="toolbar">
              <li>selection 1</li>
              <li>selection 2</li>
              <li>selection 3</li>
          </%block>
      </ul>
      <div class="mainlayout">
          ${next.body()}
      </div>
      

      And finally change index.html to inherit from layout.html instead:

      ## index.html
      <%inherit file="layout.html"/>
      
      ## .. rest of template
      

      In this setup, each call to next.body() will render the body of the next template in the inheritance chain (which can be written as base.html -> layout.html -> index.html). Control is still first passed to the bottommost template base.html, and self still references the topmost definition of any particular def.

      The output we get would be:

      <html>
          <body>
              <div class="header">
                  this is some header content
              </div>
      
              <ul>
                  <li>selection 1</li>
                  <li>selection 2</li>
                  <li>selection 3</li>
              </ul>
      
              <div class="mainlayout">
              this is the body content.
              </div>
      
              <div class="footer">
                  this is the footer
              </div>
          </body>
      </html>
      

      So above, we have the <html>, <body> and header/footer layout of base.html, we have the <ul> and mainlayout section of layout.html, and the main body of index.html as well as its overridden header def. The layout.html template is inserted into the middle of the chain without base.html having to change anything. Without the next namespace, only the main body of index.html could be used; there would be no way to call layout.html‘s body content.

      Using the parent Namespace to Augment Defs

      Lets now look at the other inheritance-specific namespace, the opposite of next called parent. parent is the namespace of the template immediately preceding the current template. What’s useful about this namespace is that defs or blocks can call upon their overridden versions. This is not as hard as it sounds and is very much like using the super keyword in Python. Lets modify index.html to augment the list of selections provided by the toolbar function in layout.html:

      ## index.html
      <%inherit file="layout.html"/>
      
      <%block name="header">
          this is some header content
      </%block>
      
      <%block name="toolbar">
          ## call the parent's toolbar first
          ${parent.toolbar()}
          <li>selection 4</li>
          <li>selection 5</li>
      </%block>
      
      this is the body content.
      

      Above, we implemented a toolbar() function, which is meant to override the definition of toolbar within the inherited template layout.html. However, since we want the content from that of layout.html as well, we call it via the parent namespace whenever we want it’s content, in this case before we add our own selections. So the output for the whole thing is now:

      <html>
          <body>
              <div class="header">
                  this is some header content
              </div>
      
              <ul>
                  <li>selection 1</li>
                  <li>selection 2</li>
                  <li>selection 3</li>
                  <li>selection 4</li>
                  <li>selection 5</li>
              </ul>
      
              <div class="mainlayout">
              this is the body content.
              </div>
      
              <div class="footer">
                  this is the footer
              </div>
          </body>
      </html>
      

      and you’re now a template inheritance ninja!

      Inheritable Attributes

      The attr accessor of the Namespace object allows access to module level variables declared in a template. By accessing self.attr, you can access regular attributes from the inheritance chain as declared in <%! %> sections. Such as:

      <%!
          class_ = "grey"
      %>
      
      <div class="${self.attr.class_}">
          ${self.body()}
      </div>
      

      If an inheriting template overrides class_ to be "white", as in:

      <%!
          class_ = "white"
      %>
      <%inherit file="parent.html"/>
      
      This is the body
      

      you’ll get output like:

      <div class="white">
          This is the body
      </div>
      

      See also

      Version One - Use Namespace.attr - a more sophisticated example using Namespace.attr.


      Mako-0.9.1/doc/namespaces.html0000644000076500000240000017773112257136657016764 0ustar classicstaff00000000000000 Namespaces — Mako 0.9.1 Documentation
      Hyperfast and lightweight templating for the Python platform.

      Mako 0.9.1 Documentation

      Release: 0.9.1

      Namespaces

      Namespaces are used to organize groups of defs into categories, and also to “import” defs from other files.

      If the file components.html defines these two defs:

      ## components.html
      <%def name="comp1()">
          this is comp1
      </%def>
      
      <%def name="comp2(x)">
          this is comp2, x is ${x}
      </%def>
      

      you can make another file, for example index.html, that pulls those two defs into a namespace called comp:

      ## index.html
      <%namespace name="comp" file="components.html"/>
      
      Here's comp1:  ${comp.comp1()}
      Here's comp2:  ${comp.comp2(x=5)}
      

      The comp variable above is an instance of Namespace, a proxy object which delivers method calls to the underlying template callable using the current context.

      <%namespace> also provides an import attribute which can be used to pull the names into the local namespace, removing the need to call it via the “.” operator. When import is used, the name attribute is optional.

      <%namespace file="components.html" import="comp1, comp2"/>
      
      Heres comp1:  ${comp1()}
      Heres comp2:  ${comp2(x=5)}
      

      import also supports the “*” operator:

      <%namespace file="components.html" import="*"/>
      
      Heres comp1:  ${comp1()}
      Heres comp2:  ${comp2(x=5)}
      

      The names imported by the import attribute take precedence over any names that exist within the current context.

      Note

      In current versions of Mako, usage of import='*' is known to decrease performance of the template. This will be fixed in a future release.

      The file argument allows expressions – if looking for context variables, the context must be named explicitly:

      <%namespace name="dyn" file="${context['namespace_name']}"/>
      

      Ways to Call Namespaces

      There are essentially four ways to call a function from a namespace.

      The “expression” format, as described previously. Namespaces are just Python objects with functions on them, and can be used in expressions like any other function:

      ${mynamespace.somefunction('some arg1', 'some arg2', arg3='some arg3', arg4='some arg4')}
      

      Synonymous with the “expression” format is the “custom tag” format, when a “closed” tag is used. This format, introduced in Mako 0.2.3, allows the usage of a “custom” Mako tag, with the function arguments passed in using named attributes:

      <%mynamespace:somefunction arg1="some arg1" arg2="some arg2" arg3="some arg3" arg4="some arg4"/>
      

      When using tags, the values of the arguments are taken as literal strings by default. To embed Python expressions as arguments, use the embedded expression format:

      <%mynamespace:somefunction arg1="${someobject.format()}" arg2="${somedef(5, 12)}"/>
      

      The “custom tag” format is intended mainly for namespace functions which recognize body content, which in Mako is known as a “def with embedded content”:

      <%mynamespace:somefunction arg1="some argument" args="x, y">
          Some record: ${x}, ${y}
      </%mynamespace:somefunction>
      

      The “classic” way to call defs with embedded content is the <%call> tag:

      <%call expr="mynamespace.somefunction(arg1='some argument')" args="x, y">
          Some record: ${x}, ${y}
      </%call>
      

      For information on how to construct defs that embed content from the caller, see Calling a Def with Embedded Content and/or Other Defs.

      Namespaces from Regular Python Modules

      Namespaces can also import regular Python functions from modules. These callables need to take at least one argument, context, an instance of Context. A module file some/module.py might contain the callable:

      def my_tag(context):
          context.write("hello world")
          return ''
      

      A template can use this module via:

      <%namespace name="hw" module="some.module"/>
      
      ${hw.my_tag()}
      

      Note that the context argument is not needed in the call; the Namespace tag creates a locally-scoped callable which takes care of it. The return '' is so that the def does not dump a None into the output stream – the return value of any def is rendered after the def completes, in addition to whatever was passed to Context.write() within its body.

      If your def is to be called in an “embedded content” context, that is as described in Calling a Def with Embedded Content and/or Other Defs, you should use the supports_caller() decorator, which will ensure that Mako will ensure the correct “caller” variable is available when your def is called, supporting embedded content:

      from mako.runtime import supports_caller
      
      @supports_caller
      def my_tag(context):
          context.write("<div>")
          context['caller'].body()
          context.write("</div>")
          return ''
      

      Capturing of output is available as well, using the outside-of-templates version of the capture() function, which accepts the “context” as its first argument:

      from mako.runtime import supports_caller, capture
      
      @supports_caller
      def my_tag(context):
          return "<div>%s</div>" % \
                  capture(context, context['caller'].body, x="foo", y="bar")
      

      Declaring Defs in Namespaces

      The <%namespace> tag supports the definition of <%def>s directly inside the tag. These defs become part of the namespace like any other function, and will override the definitions pulled in from a remote template or module:

      ## define a namespace
      <%namespace name="stuff">
          <%def name="comp1()">
              comp1
          </%def>
      </%namespace>
      
      ## then call it
      ${stuff.comp1()}
      

      The body() Method

      Every namespace that is generated from a template contains a method called body(). This method corresponds to the main body of the template, and plays its most important roles when using inheritance relationships as well as def-calls-with-content.

      Since the body() method is available from a namespace just like all the other defs defined in a template, what happens if you send arguments to it? By default, the body() method accepts no positional arguments, and for usefulness in inheritance scenarios will by default dump all keyword arguments into a dictionary called pageargs. But if you actually want to get at the keyword arguments, Mako recommends you define your own argument signature explicitly. You do this via using the <%page> tag:

      <%page args="x, y, someval=8, scope='foo', **kwargs"/>
      

      A template which defines the above signature requires that the variables x and y are defined, defines default values for someval and scope, and sets up **kwargs to receive all other keyword arguments. If **kwargs or similar is not present, the argument **pageargs gets tacked on by Mako. When the template is called as a top-level template (i.e. via render()) or via the <%include> tag, the values for these arguments will be pulled from the Context. In all other cases, i.e. via calling the body() method, the arguments are taken as ordinary arguments from the method call. So above, the body might be called as:

      ${self.body(5, y=10, someval=15, delta=7)}
      

      The Context object also supplies a kwargs accessor, for cases when you’d like to pass along the top level context arguments to a body() callable:

      ${next.body(**context.kwargs)}
      

      The usefulness of calls like the above become more apparent when one works with inheriting templates. For more information on this, as well as the meanings of the names self and next, see Inheritance.

      Built-in Namespaces

      The namespace is so great that Mako gives your template one (or two) for free. The names of these namespaces are local and self. Other built-in namespaces include parent and next, which are optional and are described in Inheritance.

      local

      The local namespace is basically the namespace for the currently executing template. This means that all of the top level defs defined in your template, as well as your template’s body() function, are also available off of the local namespace.

      The local namespace is also where properties like uri, filename, and module and the get_namespace method can be particularly useful.

      self

      The self namespace, in the case of a template that does not use inheritance, is synonymous with local. If inheritance is used, then self references the topmost template in the inheritance chain, where it is most useful for providing the ultimate form of various “method” calls which may have been overridden at various points in an inheritance chain. See Inheritance.

      Inheritable Namespaces

      The <%namespace> tag includes an optional attribute inheritable="True", which will cause the namespace to be attached to the self namespace. Since self is globally available throughout an inheritance chain (described in the next section), all the templates in an inheritance chain can get at the namespace imported in a super-template via self.

      ## base.html
      <%namespace name="foo" file="foo.html" inheritable="True"/>
      
      ${next.body()}
      
      ## somefile.html
      <%inherit file="base.html"/>
      
      ${self.foo.bar()}
      

      This allows a super-template to load a whole bunch of namespaces that its inheriting templates can get to, without them having to explicitly load those namespaces themselves.

      The import="*" part of the <%namespace> tag doesn’t yet interact with the inheritable flag, so currently you have to use the explicit namespace name off of self, followed by the desired function name. But more on this in a future release.

      Namespace API Usage Example - Static Dependencies

      The <%namespace> tag at runtime produces an instance of Namespace. Programmatic access of Namespace can be used to build various kinds of scaffolding in templates and between templates.

      A common request is the ability for a particular template to declare “static includes” - meaning, the usage of a particular set of defs requires that certain Javascript/CSS files are present. Using Namespace as the object that holds together the various templates present, we can build a variety of such schemes. In particular, the Context has a namespaces attribute, which is a dictionary of all Namespace objects declared. Iterating the values of this dictionary will provide a Namespace object for each time the <%namespace> tag was used, anywhere within the inheritance chain.

      Version One - Use Namespace.attr

      The Namespace.attr attribute allows us to locate any variables declared in the <%! %> of a template.

      ## base.mako
      ## base-most template, renders layout etc.
      <html>
      <head>
      ## traverse through all namespaces present,
      ## look for an attribute named 'includes'
      % for ns in context.namespaces.values():
          % for incl in getattr(ns.attr, 'includes', []):
              ${incl}
          % endfor
      % endfor
      </head>
      <body>
      ${next.body()}
      </body
      </html>
      
      ## library.mako
      ## library functions.
      <%!
          includes = [
              '<link rel="stylesheet" type="text/css" href="mystyle.css"/>',
              '<script type="text/javascript" src="functions.js"></script>'
          ]
      %>
      
      <%def name="mytag()">
          <form>
              ${caller.body()}
          </form>
      </%def>
      
      ## index.mako
      ## calling template.
      <%inherit file="base.mako"/>
      <%namespace name="foo" file="library.mako"/>
      
      <%foo:mytag>
          a form
      </%foo:mytag>
      

      Above, the file library.mako declares an attribute includes inside its global <%! %> section. index.mako includes this template using the <%namespace> tag. The base template base.mako, which is the inherited parent of index.mako and is reponsible for layout, then locates this attribute and iterates through its contents to produce the includes that are specific to library.mako.

      Version Two - Use a specific named def

      In this version, we put the includes into a <%def> that follows a naming convention.

      ## base.mako
      ## base-most template, renders layout etc.
      <html>
      <head>
      ## traverse through all namespaces present,
      ## look for a %def named 'includes'
      % for ns in context.namespaces.values():
          % if hasattr(ns, 'includes'):
              ${ns.includes()}
          % endif
      % endfor
      </head>
      <body>
      ${next.body()}
      </body
      </html>
      
      ## library.mako
      ## library functions.
      
      <%def name="includes()">
          <link rel="stylesheet" type="text/css" href="mystyle.css"/>
          <script type="text/javascript" src="functions.js"></script>
      </%def>
      
      <%def name="mytag()">
          <form>
              ${caller.body()}
          </form>
      </%def>
      
      
      ## index.mako
      ## calling template.
      <%inherit file="base.mako"/>
      <%namespace name="foo" file="library.mako"/>
      
      <%foo:mytag>
          a form
      </%foo:mytag>
      

      In this version, library.mako declares a <%def> named includes. The example works identically to the previous one, except that base.mako looks for defs named include on each namespace it examines.

      API Reference

      class mako.runtime.Namespace(name, context, callables=None, inherits=None, populate_self=True, calling_uri=None)

      Bases: object

      Provides access to collections of rendering methods, which can be local, from other templates, or from imported modules.

      To access a particular rendering method referenced by a Namespace, use plain attribute access:

      ${some_namespace.foo(x, y, z)}
      

      Namespace also contains several built-in attributes described here.

      attr

      Access module level attributes by name.

      This accessor allows templates to supply “scalar” attributes which are particularly handy in inheritance relationships.

      cache

      Return the Cache object referenced by this Namespace object’s Template.

      context = None

      The Context object for this Namespace.

      Namespaces are often created with copies of contexts that contain slightly different data, particularly in inheritance scenarios. Using the Context off of a Namespace one can traverse an entire chain of templates that inherit from one-another.

      filename = None

      The path of the filesystem file used for this Namespace‘s module or template.

      If this is a pure module-based Namespace, this evaluates to module.__file__. If a template-based namespace, it evaluates to the original template file location.

      get_cached(key, **kwargs)

      Return a value from the Cache referenced by this Namespace object’s Template.

      The advantage to this method versus direct access to the Cache is that the configuration parameters declared in <%page> take effect here, thereby calling up the same configured backend as that configured by <%page>.

      get_namespace(uri)

      Return a Namespace corresponding to the given uri.

      If the given uri is a relative URI (i.e. it does not contain a leading slash /), the uri is adjusted to be relative to the uri of the namespace itself. This method is therefore mostly useful off of the built-in local namespace, described in local.

      In most cases, a template wouldn’t need this function, and should instead use the <%namespace> tag to load namespaces. However, since all <%namespace> tags are evaluated before the body of a template ever runs, this method can be used to locate namespaces using expressions that were generated within the body code of the template, or to conditionally use a particular namespace.

      get_template(uri)

      Return a Template from the given uri.

      The uri resolution is relative to the uri of this Namespace object’s Template.

      include_file(uri, **kwargs)

      Include a file at the given uri.

      module = None

      The Python module referenced by this Namespace.

      If the namespace references a Template, then this module is the equivalent of template.module, i.e. the generated module for the template.

      template = None

      The Template object referenced by this Namespace, if any.

      uri = None

      The URI for this Namespace‘s template.

      I.e. whatever was sent to TemplateLookup.get_template().

      This is the equivalent of Template.uri.

      class mako.runtime.TemplateNamespace(name, context, template=None, templateuri=None, callables=None, inherits=None, populate_self=True, calling_uri=None)

      Bases: mako.runtime.Namespace

      A Namespace specific to a Template instance.

      filename

      The path of the filesystem file used for this Namespace‘s module or template.

      module

      The Python module referenced by this Namespace.

      If the namespace references a Template, then this module is the equivalent of template.module, i.e. the generated module for the template.

      uri

      The URI for this Namespace‘s template.

      I.e. whatever was sent to TemplateLookup.get_template().

      This is the equivalent of Template.uri.

      class mako.runtime.ModuleNamespace(name, context, module, callables=None, inherits=None, populate_self=True, calling_uri=None)

      Bases: mako.runtime.Namespace

      A Namespace specific to a Python module instance.

      filename

      The path of the filesystem file used for this Namespace‘s module or template.

      mako.runtime.supports_caller(func)

      Apply a caller_stack compatibility decorator to a plain Python function.

      See the example in Namespaces from Regular Python Modules.

      mako.runtime.capture(context, callable_, *args, **kwargs)

      Execute the given template def, capturing the output into a buffer.

      See the example in Namespaces from Regular Python Modules.


      Mako-0.9.1/doc/runtime.html0000644000076500000240000015520612257136657016321 0ustar classicstaff00000000000000 The Mako Runtime Environment — Mako 0.9.1 Documentation
      Hyperfast and lightweight templating for the Python platform.

      Mako 0.9.1 Documentation

      Release: 0.9.1
      Mako 0.9.1 Documentation » The Mako Runtime Environment

      The Mako Runtime Environment

      The Mako Runtime Environment

      This section describes a little bit about the objects and built-in functions that are available in templates.

      Context

      The Context is the central object that is created when a template is first executed, and is responsible for handling all communication with the outside world. Within the template environment, it is available via the reserved name context. The Context includes two major components, one of which is the output buffer, which is a file-like object such as Python’s StringIO or similar, and the other a dictionary of variables that can be freely referenced within a template; this dictionary is a combination of the arguments sent to the render() function and some built-in variables provided by Mako’s runtime environment.

      The Buffer

      The buffer is stored within the Context, and writing to it is achieved by calling the write() method – in a template this looks like context.write('some string'). You usually don’t need to care about this, as all text within a template, as well as all expressions provided by ${}, automatically send everything to this method. The cases you might want to be aware of its existence are if you are dealing with various filtering/buffering scenarios, which are described in Filtering and Buffering, or if you want to programmatically send content to the output stream, such as within a <% %> block.

      <%
          context.write("some programmatic text")
      %>
      

      The actual buffer may or may not be the original buffer sent to the Context object, as various filtering/caching scenarios may “push” a new buffer onto the context’s underlying buffer stack. For this reason, just stick with context.write() and content will always go to the topmost buffer.

      Context Variables

      When your template is compiled into a Python module, the body content is enclosed within a Python function called render_body. Other top-level defs defined in the template are defined within their own function bodies which are named after the def’s name with the prefix render_ (i.e. render_mydef). One of the first things that happens within these functions is that all variable names that are referenced within the function which are not defined in some other way (i.e. such as via assignment, module level imports, etc.) are pulled from the Context object’s dictionary of variables. This is how you’re able to freely reference variable names in a template which automatically correspond to what was passed into the current Context.

      • What happens if I reference a variable name that is not in the current context? - The value you get back is a special value called UNDEFINED, or if the strict_undefined=True flag is used a NameError is raised. UNDEFINED is just a simple global variable with the class mako.runtime.Undefined. The UNDEFINED object throws an error when you call str() on it, which is what happens if you try to use it in an expression.

      • UNDEFINED makes it hard for me to find what name is missing - An alternative is to specify the option strict_undefined=True to the Template or TemplateLookup. This will cause any non-present variables to raise an immediate NameError which includes the name of the variable in its message when render() is called – UNDEFINED is not used.

        New in version 0.3.6.

      • Why not just return None? Using UNDEFINED, or raising a NameError is more explicit and allows differentiation between a value of None that was explicitly passed to the Context and a value that wasn’t present at all.

      • Why raise an exception when you call str() on it ? Why not just return a blank string? - Mako tries to stick to the Python philosophy of “explicit is better than implicit”. In this case, it’s decided that the template author should be made to specifically handle a missing value rather than experiencing what may be a silent failure. Since UNDEFINED is a singleton object just like Python’s True or False, you can use the is operator to check for it:

        % if someval is UNDEFINED:
            someval is: no value
        % else:
            someval is: ${someval}
        % endif
        

      Another facet of the Context is that its dictionary of variables is immutable. Whatever is set when render() is called is what stays. Of course, since its Python, you can hack around this and change values in the context’s internal dictionary, but this will probably will not work as well as you’d think. The reason for this is that Mako in many cases creates copies of the Context object, which get sent to various elements of the template and inheriting templates used in an execution. So changing the value in your local Context will not necessarily make that value available in other parts of the template’s execution. Examples of where Mako creates copies of the Context include within top-level def calls from the main body of the template (the context is used to propagate locally assigned variables into the scope of defs; since in the template’s body they appear as inlined functions, Mako tries to make them act that way), and within an inheritance chain (each template in an inheritance chain has a different notion of parent and next, which are all stored in unique Context instances).

      • So what if I want to set values that are global to everyone within a template request? - All you have to do is provide a dictionary to your Context when the template first runs, and everyone can just get/set variables from that. Lets say its called attributes.

        Running the template looks like:

        output = template.render(attributes={})
        

        Within a template, just reference the dictionary:

        <%
            attributes['foo'] = 'bar'
        %>
        'foo' attribute is: ${attributes['foo']}
        
      • Why can’t “attributes” be a built-in feature of the Context? - This is an area where Mako is trying to make as few decisions about your application as it possibly can. Perhaps you don’t want your templates to use this technique of assigning and sharing data, or perhaps you have a different notion of the names and kinds of data structures that should be passed around. Once again Mako would rather ask the user to be explicit.

      Context Methods and Accessors

      Significant members of Context include:

      • context[key] / context.get(key, default=None) - dictionary-like accessors for the context. Normally, any variable you use in your template is automatically pulled from the context if it isn’t defined somewhere already. Use the dictionary accessor and/or get method when you want a variable that is already defined somewhere else, such as in the local arguments sent to a %def call. If a key is not present, like a dictionary it raises KeyError.

      • keys() - all the names defined within this context.

      • kwargs - this returns a copy of the context’s dictionary of variables. This is useful when you want to propagate the variables in the current context to a function as keyword arguments, i.e.:

        ${next.body(**context.kwargs)}
        
      • write(text) - write some text to the current output stream.

      • lookup - returns the TemplateLookup instance that is used for all file-lookups within the current execution (even though individual Template instances can conceivably have different instances of a TemplateLookup, only the TemplateLookup of the originally-called Template gets used in a particular execution).

      The Loop Context

      Within % for blocks, the reserved name loop is available. loop tracks the progress of the for loop and makes it easy to use the iteration state to control template behavior:

      <ul>
      % for a in ("one", "two", "three"):
          <li>Item ${loop.index}: ${a}</li>
      % endfor
      </ul>
      

      New in version 0.7.

      Iterations

      Regardless of the type of iterable you’re looping over, loop always tracks the 0-indexed iteration count (available at loop.index), its parity (through the loop.even and loop.odd bools), and loop.first, a bool indicating whether the loop is on its first iteration. If your iterable provides a __len__ method, loop also provides access to a count of iterations remaining at loop.reverse_index and loop.last, a bool indicating whether the loop is on its last iteration; accessing these without __len__ will raise a TypeError.

      Cycling

      Cycling is available regardless of whether the iterable you’re using provides a __len__ method. Prior to Mako 0.7, you might have generated a simple zebra striped list using enumerate:

      <ul>
      % for i, item in enumerate(('spam', 'ham', 'eggs')):
        <li class="${'odd' if i % 2 else 'even'}">${item}</li>
      % endfor
      </ul>
      

      With loop.cycle, you get the same results with cleaner code and less prep work:

      <ul>
      % for item in ('spam', 'ham', 'eggs'):
        <li class="${loop.cycle('even', 'odd')}">${item}</li>
      % endfor
      </ul>
      

      Both approaches produce output like the following:

      <ul>
        <li class="even">spam</li>
        <li class="odd">ham</li>
        <li class="even">eggs</li>
      </ul>
      

      Parent Loops

      Loop contexts can also be transparently nested, and the Mako runtime will do the right thing and manage the scope for you. You can access the parent loop context through loop.parent.

      This allows you to reach all the way back up through the loop stack by chaining parent attribute accesses, i.e. loop.parent.parent.... as long as the stack depth isn’t exceeded. For example, you can use the parent loop to make a checkered table:

      <table>
      % for consonant in 'pbj':
        <tr>
        % for vowel in 'iou':
          <td class="${'black' if (loop.parent.even == loop.even) else 'red'}">
            ${consonant + vowel}t
          </td>
        % endfor
        </tr>
      % endfor
      </table>
      
      <table>
        <tr>
          <td class="black">
            pit
          </td>
          <td class="red">
            pot
          </td>
          <td class="black">
            put
          </td>
        </tr>
        <tr>
          <td class="red">
            bit
          </td>
          <td class="black">
            bot
          </td>
          <td class="red">
            but
          </td>
        </tr>
        <tr>
          <td class="black">
            jit
          </td>
          <td class="red">
            jot
          </td>
          <td class="black">
            jut
          </td>
        </tr>
      </table>
      

      Migrating Legacy Templates that Use the Word “loop”

      Changed in version 0.7: The loop name is now reserved in Mako, which means a template that refers to a variable named loop won’t function correctly when used in Mako 0.7.

      To ease the transition for such systems, the feature can be disabled across the board for all templates, then re-enabled on a per-template basis for those templates which wish to make use of the new system.

      First, the enable_loop=False flag is passed to either the TemplateLookup or Template object in use:

      lookup = TemplateLookup(directories=['/docs'], enable_loop=False)
      

      or:

      template = Template("some template", enable_loop=False)
      

      An individual template can make usage of the feature when enable_loop is set to False by switching it back on within the <%page> tag:

      <%page enable_loop="True"/>
      
      % for i in collection:
          ${i} ${loop.index}
      % endfor
      

      Using the above scheme, it’s safe to pass the name loop to the Template.render() method as well as to freely make usage of a variable named loop within a template, provided the <%page> tag doesn’t override it. New templates that want to use the loop context can then set up <%page enable_loop="True"/> to use the new feature without affecting old templates.

      All the Built-in Names

      A one-stop shop for all the names Mako defines. Most of these names are instances of Namespace, which are described in the next section, Namespaces. Also, most of these names other than context, UNDEFINED, and loop are also present within the Context itself. The names context, loop and UNDEFINED themselves can’t be passed to the context and can’t be substituted – see the section Reserved Names.

      • context - this is the Context object, introduced at Context.
      • local - the namespace of the current template, described in Built-in Namespaces.
      • self - the namespace of the topmost template in an inheritance chain (if any, otherwise the same as local), mostly described in Inheritance.
      • parent - the namespace of the parent template in an inheritance chain (otherwise undefined); see Inheritance.
      • next - the namespace of the next template in an inheritance chain (otherwise undefined); see Inheritance.
      • caller - a “mini” namespace created when using the <%call> tag to define a “def call with content”; described in Calling a Def with Embedded Content and/or Other Defs.
      • loop - this provides access to LoopContext objects when they are requested within % for loops, introduced at The Loop Context.
      • capture - a function that calls a given def and captures its resulting content into a string, which is returned. Usage is described in Filtering and Buffering.
      • UNDEFINED - a global singleton that is applied to all otherwise uninitialized template variables that were not located within the Context when rendering began, unless the Template flag strict_undefined is set to True. UNDEFINED is an instance of Undefined, and raises an exception when its __str__() method is called.
      • pageargs - this is a dictionary which is present in a template which does not define any **kwargs section in its <%page> tag. All keyword arguments sent to the body() function of a template (when used via namespaces) go here by default unless otherwise defined as a page argument. If this makes no sense, it shouldn’t; read the section The body() Method.

      Reserved Names

      Mako has a few names that are considered to be “reserved” and can’t be used as variable names.

      Changed in version 0.7: Mako raises an error if these words are found passed to the template as context arguments, whereas in previous versions they’d be silently ignored or lead to other error messages.

      API Reference

      class mako.runtime.Context(buffer, **data)

      Bases: object

      Provides runtime namespace, output buffer, and various callstacks for templates.

      See The Mako Runtime Environment for detail on the usage of Context.

      get(key, default=None)

      Return a value from this Context.

      keys()

      Return a list of all names established in this Context.

      kwargs

      Return the dictionary of top level keyword arguments associated with this Context.

      This dictionary only includes the top-level arguments passed to Template.render(). It does not include names produced within the template execution such as local variable names or special names such as self, next, etc.

      The purpose of this dictionary is primarily for the case that a Template accepts arguments via its <%page> tag, which are normally expected to be passed via Template.render(), except the template is being called in an inheritance context, using the body() method. Context.kwargs can then be used to propagate these arguments to the inheriting template:

      ${next.body(**context.kwargs)}
      lookup

      Return the TemplateLookup associated with this Context.

      pop_caller()

      Pop a caller callable onto the callstack for this Context.

      push_caller(caller)

      Push a caller callable onto the callstack for this Context.

      write(string)

      Write a string to this Context object’s underlying output buffer.

      writer()

      Return the current writer function.

      class mako.runtime.LoopContext(iterable)

      Bases: object

      A magic loop variable. Automatically accessible in any % for block.

      See the section The Loop Context for usage notes.

      parent -> LoopContext or None
      The parent loop, if one exists.
      index -> int
      The 0-based iteration count.
      reverse_index -> int
      The number of iterations remaining.
      first -> bool
      True on the first iteration, False otherwise.
      last -> bool
      True on the last iteration, False otherwise.
      even -> bool
      True when index is even.
      odd -> bool
      True when index is odd.
      cycle(*values)

      Cycle through values as the loop progresses.

      class mako.runtime.Undefined

      Bases: object

      Represents an undefined value in a template.

      All template modules have a constant value UNDEFINED present which is an instance of this object.


      Mako-0.9.1/doc/search.html0000644000076500000240000000712312257136657016075 0ustar classicstaff00000000000000 Search — Mako 0.9.1 Documentation
      Hyperfast and lightweight templating for the Python platform.

      Mako 0.9.1 Documentation

      Release: 0.9.1

      Enter Search Terms:


      Mako-0.9.1/doc/searchindex.js0000644000076500000240000005270212257136657016600 0ustar classicstaff00000000000000Search.setIndex({envversion:42,terms:{interchang:4,four:[3,5],prefix:[6,9],dirnam:8,"_my_cache_work":6,typeerror:9,swap:6,under:[8,6,7],everi:[3,5],long_term:6,jack:8,voix:7,appar:[2,3],vast:7,pagearg:[0,9,3,7],get_templ:[8,6,3,7],buildtabl:0,cache_kei:6,direct:[0,8,6,3,5],batch:2,outputpath:8,second:[0,6,2],even:[5,9,7,4],"new":[0,2,4,5,6,8,9],ever:[3,7],metadata:5,widget:0,behavior:[8,2,9],here:[2,7,4,5,6,3,8,9],met:0,path:[8,6,3],interpret:[0,8,7],tagfilt:2,portabl:0,txt:[8,7,5],describ:[0,2,3,4,5,7,8,9],would:[0,2,4,6,7,8,9],call:6,recommend:3,type:[0,7,5,6,3,8,9],until:8,relat:[8,6,7],notic:0,pkg_resourc:6,hold:3,must:[0,8,6,3,7],join:7,setup:[8,6,4],work:[0,2,7,4,6,3,8,9],root:8,overrid:[7,4,6,3,8,9],give:[0,3],somefil:3,do_something_speci:6,want:[0,2,7,4,5,3,6,9],end:[5,2,4],quot:7,ordinari:3,output_encod:[8,7],how:[0,5,6,3,8,9],cheetah:7,updat:8,module_filenam:8,recogn:[3,4],lai:0,after:[8,6,2,3,9],befor:[2,7,4,5,6,3,8],attempt:7,third:6,recompil:[8,6],maintain:[8,6],environ:[1,2],exclus:8,order:[8,6,5,7,4],origin:[2,7,6,3,8,9],somedata:0,over:[2,3,9],fall:6,becaus:[0,2,7,4],demarc:0,affect:9,flexibl:[5,2,4],myfil:5,streamlin:4,fix:[8,6,3],"__class__":8,better:[6,9],persist:6,easier:6,them:[0,2,4,3,8,9],thei:[0,2,4,5,7,8,9],safe:[9,7],jinja2:[0,5],html_error_templ:8,getvalu:[8,2],myghti:7,timeout:6,each:[0,7,4,5,6,3,8,9],side:[0,2,5],mean:[0,2,7,5,6,3,8,9],enorm:0,cacheimpl:[8,6],extract:8,expression_filt:2,unbound:8,goe:5,newli:6,content:6,sane:0,mypackag:2,multilin:5,bottommost:4,free:3,standard:[6,7],traceback:8,moment:8,filter:0,heck:1,isn:9,text_error_templ:8,onto:[9,5],user:[8,6,9,7,5],rang:[0,5],render:[0,1,2,6],restrict:[0,4],unlik:7,alreadi:[8,9,4],wrapper:2,wasn:[9,4],agre:4,primari:8,lister:0,top:[0,2,4,3,6,9],sometim:[5,4],stack:[8,2,9],cache_region:6,too:[2,4],similarli:[0,7],john:0,consol:7,conson:9,namespac:[0,1,2,6],tool:6,setuptool:[8,6],somewhat:[0,2],some_namespac:3,myfilt:2,target:[0,2],keyword:[0,7,4,5,3,8,9],provid:[0,2,4,5,6,3,8,9],expr:[0,3],project:8,matter:4,minut:6,thu:8,mini:9,fashion:6,runner:8,modern:6,htmlentityreplac:8,raw:[8,7],manner:2,templatelookup:[1,2,7,3,6,9],minu:6,latter:7,mytag:3,shall:4,usernam:[0,5],object:[0,2,3,4,5,6,7,8,9],regular:[0,1,2,4],phase:8,invalidate_closur:6,simplic:2,paradigm:4,don:[0,6,9,7,4],doc:[0,9],flow:5,doe:[0,7,4,5,3,9],declar:[0,1,2,4],tracelin:8,notion:9,opposit:4,"__str__":9,syntax:[0,1,2],get_resourc:5,involv:4,absolut:[0,7],layout:[0,8,3,4],acquir:[6,7],configur:[8,6,3,4],stop:[9,5],report:8,bar:[0,2,5,3,8,9],emb:[3,7,5],reload:8,short_term:6,black:9,elimin:7,result:[0,8,2,9,5],respons:[6,9,4],basemost:4,awar:[8,9,7],databas:0,urllib:2,implicit:[6,9],simplest:5,pybabel:8,awai:4,approach:[9,7,4],attribut:[0,1,2,6],preprocessor:8,easi:[2,9],howev:[0,6,3,7,4],against:[8,5],facet:9,logic:2,col:0,guid:8,assum:[8,7],templatenamespac:3,three:[9,5],been:[8,6,2,3,7],accumul:5,much:[0,5,7,4],interest:8,basic:[0,1,3,7,5],"__len__":9,quickli:7,disable_unicod:2,anywher:[0,3,5],multithread:6,lift:4,ident:[8,3],servic:[6,7,5],properti:[8,3],calcul:8,printabl:7,kwarg:[8,6,9,3],somekei:6,sever:3,mako:[0,1,2,4,3,6],quand:7,perform:[8,2,3,7],make:[0,2,3,4,5,6,7,8,9],format:[0,8,3,7,5],push_cal:9,complet:[8,3,4],rais:[0,8,9,7],caller_stack:[3,7],scenario:[0,8,9,3],get_cach:3,hypothet:4,inherit:[0,1,6],thi:[0,2,3,4,5,6,7,8,9],endif:[0,9,3,5],programm:7,everyth:9,pagecontrol:0,left:[8,2],identifi:[8,6],just:[0,2,3,4,5,7,8,9],invalidate_bodi:6,unbuff:2,yet:[6,3],languag:[0,7,5],previous:[8,3],enable_loop:[8,9],pygmentplugin:8,ham:9,ell:7,had:7,input_encod:[8,7],board:9,els:[8,6,9,5],gave:8,opt:[8,6],applic:[8,2,9,5],mayb:4,background:7,arbitrari:[6,5],manual:8,babelplugin:8,underli:[0,2,4,5,6,3,8,9],right:[0,2,9,7,5],old:9,deal:[9,7,5],excerpt:8,maxim:[6,7],percentag:8,intern:[8,6,2,7,9],subclass:[0,8,6],condit:[0,5,4],foo:[0,2,7,5,3,8,9],plu:8,bold:2,relationship:3,post:[0,8],"super":[6,3,7,4],plug:6,slightli:[3,7],surround:5,future_import:8,produc:[0,1,2],rudiment:[8,6],encod:[1,2],down:[6,7],lieu:8,wrap:[0,1],storag:7,accordingli:8,wai:[0,1,2,6,4],support:[0,7,5,6,3,8],transform:2,why:9,avail:[0,2,3,4,5,6,7,8,9],overhead:7,head:[0,8,3,4],form:[0,3,5],offer:[7,5],forc:8,get_def:[0,8,2],taken:[8,6,3],"true":[0,2,5,3,6,9],attr:4,tell:5,emit:5,trim:[2,5],featur:[8,5,9,4],classic:[3,5],petit:7,"abstract":8,exist:[0,7,5,6,3,8,9],check:[5,9,7,4],when:[0,2,3,4,5,6,7,8,9],entrypoint:6,intend:[2,3],stringio:[8,9,7],intent:2,consid:[8,9],receiv:[0,2,3,5],faster:7,cache_en:[8,6],htdoc:8,ignor:[9,5],time:[0,1,2,6],push:9,serious:4,backward:6,concept:[0,8,5],chain:[5,9,3,4],skip:8,consum:[6,5],signific:[9,5],subcompon:0,row:0,decid:[9,5],middl:[5,2,4],depend:1,mainlayout:[0,4],intermedi:4,decis:[9,7,4],sourc:[8,7,5],string:[2,7,5,6,3,8,9],word:4,level:[0,1,2,4,3,6,9],did:4,iter:[0,3],item:[0,9,5],mycomp:6,quick:[0,5],lever:7,div:[0,8,3,4],dir:[8,6],slower:7,sign:5,namepacenam:0,appear:[8,2,9,5],scaffold:3,current:[0,4,5,3,8,9],deriv:[6,2,7],gener:[0,2,3,4,5,6,7,8,9],address:[8,6],along:[6,3],toolbar:[5,4],bot:9,behav:0,commonli:[6,7,4],semant:[0,4],regardless:[0,9,4],extra:[5,4],modul:[0,1,2,6,4],prefer:7,render_bodi:[8,2,7,9],fake:5,marker:5,instal:6,callstack:9,memori:[8,6,5],sake:2,perl:5,live:6,handler:8,scope:[0,4,5,3,6,9],prep:9,chapter:[0,1,2,4],afford:8,accept:[2,7,5,6,3,8,9],examin:3,render_:9,myexpress:2,mylookup:[8,7],fly:7,graphic:7,uniqu:[6,9,4],whatev:[8,9,3,7],purpos:[8,9,7],stream:[8,9,3,7,5],backslash:5,occur:[0,8,6],alwai:[0,9,7,4],differenti:9,multipl:[0,1,6],get:[2,7,4,5,6,3,8,9],modulenam:6,pure:[3,7,5],cache_xyz:6,somevalu:6,map:8,product:8,usabl:0,mai:[2,7,5,6,3,8,9],data:[0,7,6,3,8,9],goal:2,practic:4,explicit:[0,7,5,3,6,9],format_except:8,inform:[8,3,7,5],"switch":9,preced:[8,5,3,7,4],combin:9,callabl:[0,2,5,6,3,8,9],extractor:8,still:[0,7,4],mainli:3,dynam:5,entiti:2,conjunct:8,group:[6,3],platform:8,jit:9,push_buff:2,main:[0,2,7,4,3,8,9],non:[8,9,7,5],recal:4,francoi:8,contriv:8,supersed:6,initi:0,underneath:6,therebi:3,now:[5,9,7,4],pop_fram:7,term:6,name:6,drop:5,separ:[0,8,2,6,4],"__str":7,compil:[8,6,9,5],replac:[8,6,2,7],individu:[0,8,9,6],arg3:3,arg4:3,continu:[8,7,5],zebra:9,happen:[9,3,7],accomplish:[8,6],space:[0,6,5],intermix:4,correct:3,earlier:[6,7],"byte":[8,7],care:[6,9,3,7],thing:[0,5,9,7,4],place:[0,8,5,6,4],think:9,first:[2,7,4,5,6,3,8,9],oper:[0,2,7,5,3,8,9],suspend:5,directli:[0,2,5,6,3,8],onc:[0,5,9,4],arrai:2,yourself:[8,7],walkthrough:0,textual:[8,2,4],custom:[0,2,7,5,6,3,8],open:[5,7,4],given:[0,2,4,6,3,8,9],silent:9,convent:[0,3],caught:8,checker:9,necessarili:9,white:4,conveni:6,programat:8,copi:[9,3],specifi:[6,1,2,9,4],enclos:[0,9],mostli:[8,6,9,3],than:[2,4,5,7,6,9],serv:[8,7],"__m_local":7,were:[9,3,7],posit:3,seri:[8,6,7],pre:8,sai:[0,1,9,4],put_str:8,ani:[0,2,3,4,5,6,7,8,9],deliv:[2,3],notimplementederror:8,techniqu:9,pop_cal:9,note:[0,2,7,4,6,3,8,9],take:[0,2,7,4,5,3],blunt:6,begin:8,sure:5,trace:8,normal:[0,2,5,7,8,9],track:9,subdef:0,synonym:[6,3],later:[6,5],highlight:8,templatenam:8,runtim:[6,1,2,3,4],preambl:8,shop:9,imaginez:7,delta:3,permiss:8,hack:9,xml:[8,2,5],onli:[0,2,4,5,6,7,8,9],explicitli:[8,9,3,7],state:[0,9,7],dict:7,overwritten:6,variou:[2,7,5,3,8,9],distinctli:4,dyn:3,tailor:0,requir:[0,6,3,7,5],where:[0,2,3,4,5,6,7,8,9],summari:5,wonder:5,nestabl:0,enumer:9,getattr:3,between:[0,9,3],"import":[0,2,7,5,6,3,8,9],across:[6,9],parent:[0,1,6],comp:3,my_dogpile_region:6,uncondition:7,come:[0,4,5,6,7,8],cache_url:[8,6],region:6,mani:[9,5],pow:5,pot:9,inspir:5,pop:[6,2,9],colon:[6,5],encoding_error:[8,7],ultim:[3,4],dessin:7,markedli:7,repons:3,resolut:[8,3],hasattr:3,"case":[0,2,3,4,5,6,7,8,9],mouton:7,invok:[0,8,5,4],cannot:[0,8,7],invoc:4,advantag:[8,3,7,4],stdout:8,threadsaf:6,destin:8,shutil:8,ascii:7,"__init__":6,develop:7,author:9,same:[0,7,5,6,3,8,9],binari:7,epoch:6,html:[0,2,3,4,5,6,7,8],document:[8,6,5,7,4],breakdown:4,finish:4,utf8:[2,7],nest:[0,1,2,6],capabl:[8,6],vowel:9,improv:[8,7,5],extern:[0,6,4],moder:8,facad:6,without:[6,9,3,4],model:0,roughli:5,execut:[0,2,4,5,6,3,8,9],rest:[6,5,4],aspect:[7,5],speed:[2,7],versu:[8,3],except:[0,1,2,5,3,6,9],littl:[0,8,9],treatment:7,role:3,earli:1,ream:7,around:[8,2,9],read:[9,7,5],moi:7,world:[0,7,5,3,8,9],use_pag:2,serve_templ:8,integ:[0,6,7],server:[8,6,5],either:[4,5,6,7,8,9],output:[0,1,2,4,5,3,9],manag:[6,9],somefunct:3,definit:[0,2,3,4],disait:7,inject:8,some_templ:8,power:5,garbag:6,pass_context:6,starttim:6,found:[0,9,5],"__name__":[8,6],"throw":[6,9],src:3,central:[0,2,9,5],act:[8,9],mytempl:[8,6,7],routin:8,overrod:4,strip:2,your:[0,2,4,5,3,9],msgstr:8,fast:8,her:7,area:[0,5,9,7,4],aren:[0,7],start:[0,6],compliant:7,interfac:6,lot:5,strictli:7,tupl:8,regard:7,jut:9,illus:7,pull:[0,8,9,3],possibl:[0,6,2,9],"default":[0,2,3,4,5,6,7,8,9],unusu:8,creat:[0,7,5,6,3,8,9],multibyt:8,certain:[8,2,3,7],somedef:[0,6,2,3,5],intro:0,decreas:3,file:6,again:[0,9],gettext:8,field:8,valid:5,you:[0,2,3,4,5,6,7,8,9],symbol:5,reduc:2,directori:[8,6,2,7,9],descript:8,mimic:8,potenti:4,escap:[0,1,2],represent:[8,5],all:[0,1,2,4,3,6],illustr:[8,2,4],scalar:3,abil:[8,6,3,7,5],follow:[0,4,5,3,8,9],program:[7,5],those:[0,5,6,3,8,9],objnam:6,introduc:[0,5,9,3,4],sound:[5,4],"pla\u00eet":7,liter:[8,3,7],fals:[8,6,9],util:8,mechan:[6,5,4],failur:9,veri:[0,8,6,4],condition:3,list:[0,2,4,5,6,7,8,9],adjust:[8,3,5],small:8,pbj:9,aptli:8,design:2,pass:[0,7,4,5,6,3,8,9],further:5,what:[0,1],sub:[0,5],section:[0,4,6,3,8,9],advanc:8,abl:9,brief:8,version:[0,6,2,4],deepli:0,method:[0,1,2,6,4],contrast:[0,7,4],full:[8,5],themselv:[0,4,5,3,6,9],sophist:4,shouldn:9,inher:2,modifi:[0,8,7,4],valu:[0,2,7,5,6,3,8,9],search:[8,1],memcach:6,prior:[2,7,9],real:[8,5],render_mydef:9,via:[0,7,4,6,3,8,9],transit:9,deprec:8,href:[0,3],pythagorean:5,establish:[8,9],select:4,mylib:5,distinct:8,regist:6,two:[0,6,2,4],push_fram:7,minor:8,more:[0,2,3,4,5,6,7,8,9],desir:[8,3,7],flag:[2,7,5,6,3,8,9],stick:[0,9,7,5],particular:[8,6,9,3,4],known:[0,3],none:[8,6,2,3,9],remain:[0,9],learn:7,def:6,someobject:3,userbas:7,share:[0,9],templat:[0,1,2,4,3,6],sharp:0,wsgiutil:8,cours:9,newlin:1,rather:9,anoth:[0,7,5,3,8,9],divis:8,render_unicod:[8,7],simpl:[0,8,9,6,5],css:[8,3],regener:8,resourc:[8,4],referenc:[0,9,3],variant:5,catalog:8,associ:[6,9],"short":6,footer:[5,4],confus:7,caus:[8,2,3,9],egg:9,help:[8,6,7],singleton:9,through:[8,9,3,7],paramet:[8,6,3,7],style:[0,7],might:[9,3,5],wouldn:[3,5],good:6,"return":[0,1,2,3,6,9],timestamp:6,framework:1,ninja:4,achiev:[0,9,4],fulli:[8,2],unicod:[1,2],hard:[5,9,7,4],idea:[5,4],procedur:6,realli:7,expect:[0,5,9,7,4],beyond:[0,6],orient:[0,4],sometempl:6,lineno:8,print:[0,8,7],proxi:3,ast:7,guess:7,reason:[9,7],base:[1,2,4,5,3,6,9],ask:9,basi:[6,9],thrown:[8,6],thread:6,perhap:[0,9,5],assign:[0,8,9,5],major:[9,7],number:[0,8,9,6,5],done:[8,7],defnam:0,blank:9,miss:[8,2,9],differ:[0,4,6,3,8,9],script:3,interact:[3,7],least:[8,3],calling_uri:3,statement:[0,8,5],natur:2,scheme:[0,8,9,3,7],store:[8,6,2,7,9],option:[7,5,6,3,8,9],modulenamespac:3,part:[6,9,3,4],pars:[8,7,5],kind:[2,7,4,5,6,3,8,9],whenev:[8,7,4],remot:[0,3],remov:[3,7],str:[8,2,7,9],arrang:5,toward:[0,4],grei:4,cleaner:9,mytmpl:8,get_namespac:3,comp2:3,packag:[6,5],comp1:3,expir:6,deftempl:[0,8],jour:7,built:[0,1,2,4],equival:[0,2,7,5,3,6],self:[0,6,4],undeclar:8,also:[0,2,3,4,5,6,7,8,9],build:[0,3,4],distribut:8,filesystem:[6,3],reach:[8,9],disgard:7,most:[0,7,4,5,6,3,8,9],plai:[3,7],jsp:5,ext:[8,6],fastencodingbuff:7,particularli:3,find:[8,9,5],mydef:0,coerc:7,pretti:[7,5],writer:9,lexer_cl:8,hit:[2,7],"__file__":3,express:0,nativ:7,common:[1,3,7],set:[2,7,5,3,6,9],genshi:5,dump:[3,7],see:[0,7,5,6,3,8,9],dumb:7,arg:[0,2,5,6,3,8],close:[0,8,3,5],whatsoev:7,someth:[0,2,7],topmost:[5,9,3,4],won:[8,9,4],altern:[8,9,7],signatur:[0,3],syntact:5,numer:5,javascript:3,popul:6,both:[0,2,4,7,8,9],last:[8,9],put_templ:8,alor:7,context:[0,1,2,6,3],whole:[0,2,3,4],load:[8,3,5],simpli:[2,4],bell:7,arbitrarili:0,header:[0,8,5,6,4],uniniti:9,param:5,suppli:[3,5],frobnizzl:5,throughout:3,empti:[2,7],accessor:[6,3,4],strategi:6,error_handl:8,imag:[8,7],great:[3,7],understand:7,func:3,xa9:7,look:[0,7,4,6,3,8,9],get_or_cr:6,straight:[8,7],histor:6,"while":[0,8,5,2,4],abov:[0,2,3,4,5,6,7,8,9],error:[0,8,9,7],anonym:[0,6,5],everyon:9,loop:[0,1],pylon:8,propag:[8,9,5],richtraceback:8,vou:7,itself:[0,2,3,4,5,6,7,8,9],minim:6,decod:[2,7],conflict:6,x80:7,wherea:[0,9,7,5],has_templ:8,stripe:9,pop_buff:2,typic:[8,6],recent:8,travers:3,task:6,older:0,cachemanag:6,entri:[8,6],somev:[9,3],elem:5,picki:7,endfor:[0,9,3,5],construct:[0,7,4,5,6,3,8],burden:7,sidebar:0,adjust_uri:8,msgid:8,theorem:5,input:[0,2,7],subsequ:6,transpar:9,game:7,bit:[0,8,9],characterist:5,creation_funct:6,semi:6,whitespac:[0,2,5],resolv:8,collect:[6,9,3,7],popular:8,encount:4,often:3,creation:[0,8,2,6],some:[0,2,3,4,5,6,7,8,9],back:[8,9,7,4],global:[0,6,9,3,4],understood:6,sampl:8,mirror:8,surpris:7,modulepath:6,though:[6,9,7,4],pep:7,per:[6,9,7,5],namespace_nam:3,substitut:[1,2,9],larg:4,slash:[3,5],leftmost:2,cgi:[2,7],buffer_filt:8,previou:[0,8,9,3,4],run:[8,9,3,7],namespacenam:[0,5],reverse_traceback:8,step:[0,8,7],loopcontext:9,from:6,mynamespac:[3,5],exc_info:8,block:6,"__future__":8,primarili:9,within:6,toplevelnotfound:8,ensur:[6,3,7],chang:[6,9,7,4],run_wsgi:8,span:[0,4],reverse_index:9,spam:9,bodi:[0,1,6,4],stylesheet:[8,3],"long":[9,5],beaker_cach:6,includ:[0,6,9,3],suit:4,myfunc:5,properli:7,templatelookupexcept:8,link:[8,3],translat:8,newer:[0,8],atom:8,line:[8,5,7,4],info:8,concaten:[8,2],utf:[8,2,7],consist:5,caller:[0,2,3,9],my_tag:3,myescap:2,similar:[0,2,3,4,5,7,8,9],impl:6,constant:9,doesn:[0,9,3,4],repres:[0,5,6,7,8,9],modulename_cal:8,titl:[0,5,4],invalid:6,codec:[8,7],accountdata:0,draw:2,clean:[8,6],nightmar:7,bytestring_passthrough:8,xb4le:7,cache_typ:[8,6,5],depth:9,far:[8,5,7,4],hello:[0,8,3,7,5],code:[0,2,7,5,3,8,9],templatetext:[2,7],send:[2,7,4,3,8,9],sens:9,sent:[2,9,3,5],tri:[0,8,9],magic:[9,7],"try":[8,2,9,7,5],dealt:8,pleas:5,impli:8,cfg:8,odd:9,append:8,compat:[8,6,3],index:[1,4,5,3,8,9],compar:[8,7],xa9veil:7,can:[0,2,3,4,5,6,7,8,9],len:5,closur:0,let:[0,8,9,4],becom:[8,3,7],sinc:[0,7,4,3,8,9],filesystem_check:8,convert:[8,6,7],convers:7,conceiv:9,ctx:8,implement:[0,8,6,4],appli:[0,2,7,5,3,8,9],approxim:8,mystuff:0,"boolean":8,immut:9,register_plugin:6,metaphor:4,commun:[0,9],next:[0,1,2,6],implic:7,few:9,trail:2,beakercacheimpl:6,account:0,retriev:6,augment:[0,1],obvious:4,control:[0,1,2,9,4],accountnam:0,process:[6,7,5],lock:6,slim:6,tag:[0,1,2,4,3,6,9],layoutdata:0,nari:7,instead:[0,2,7,4,3,8],templatecollect:8,overridden:[0,6,3,4],class_:4,tack:3,philosophi:9,callable_:[8,3],essenti:[6,3,7],correspond:[8,6,9,3,4],element:[0,8,9,7,5],issu:[0,8,7],allow:[0,2,3,4,5,6,7,8,9],elif:5,move:8,comma:[0,8,2],bunch:3,outer:0,chosen:6,myproj:8,bye:0,python:[0,1,2,4],handi:3,"r\u00e9veill\u00e9":7,relativeto:8,somewher:[8,9,7],anyth:[0,7,4],nameerror:[8,9],mode:7,mystyl:3,disregard:8,intellig:7,filehandl:7,"static":1,our:[0,8,6,4],special:[8,6,2,9,5],out:[0,4,5,6,7,8],variabl:[0,3,4],contigu:5,categori:3,rel:[8,3],red:9,insid:[0,4,5,6,3,8],call_my_object:7,standalon:8,dictionari:[8,6,9,3],releas:[6,3,5],indent:5,xc3:7,could:4,lexer:[8,7,5],put:[6,9,3,4],keep:0,outsid:[0,9,3,7,4],strict:8,system:[0,8,9,6,4],messag:[8,9],attach:3,"final":[2,7,4],cache_dir:[8,6],accompani:8,exactli:[0,4],filename_to_uri:8,structur:[1,9],charact:[8,7,5],simplecacheimpl:6,have:[0,2,3,4,5,6,7,8,9],tabl:0,need:[0,7,4,6,3,8,9],outward:8,builtin:7,best:5,which:[0,2,3,4,5,6,7,8,9],singl:[0,2,4,5,6,7,8],unless:[9,7],who:7,segment:7,"class":[0,7,4,6,3,8,9],url:[8,6,2,5],gather:7,request:[8,6,9,3],uri:[8,3,5],pipe:2,determin:[6,7],"_cach":6,fact:[0,7,4],render_context:8,dbm:6,text:[0,6,2,3,9],cache_timeout:[0,6],anywai:8,locat:[8,9,3,7],should:[8,6,9,3],suppos:[0,6],local:[0,6,2],meant:4,familiar:[0,5],bean:8,cache_:6,increas:8,cstringio:[8,7],enabl:[8,6,9,5],organ:[3,4],current_sect:5,stuff:[3,5],integr:[1,4],contain:[0,7,5,6,3,8],view:8,reverse_record:8,collection_s:8,pinard:8,flip:0,bytestr:8,mako_modul:8,polymorph:5,correctli:9,pattern:8,written:[8,5,4],futures_import:8,progress:9,neither:6,email:5,jot:9,kei:[8,6,9,3,7],module_directori:[8,6],tempfil:8,job:2,entir:[0,1,2,3,5],joe:5,cache_arg:[8,6],addit:[0,2,4,5,6,3,8],etc:[0,5,6,3,8,9],instanc:[8,9,3,5],freeli:9,comment:1,mako_cach:6,respect:5,addition:[8,7,4],compon:[6,9,3],include_fil:3,treat:7,immedi:[8,5,9,7,4],upcom:6,togeth:[3,4],present:[0,7,4,6,3,8,9],determinist:2,therefor:[8,5,3,4],plain:[0,8,3,7,5],contextu:0,defin:[0,1,2,4,5,3,6,9],helper:8,almost:[5,4],incom:7,revis:8,parti:6,began:9,member:[8,9,5],handl:[0,1,9,6,5],incl:3,denot:5,iou:9,upon:[0,8,2,6,4],effect:[0,8,2,6,3],distutil:8,markupsaf:[2,7],off:[0,6],mention:7,well:[0,2,3,4,5,6,7,8,9],exampl:[0,1,2,6,4],command:8,choos:7,undefin:[0,8,9,5],usual:[8,6,2,9,5],module_writ:8,less:[9,7,4],heavili:7,web:8,point:[0,7,4,5,6,3,8],add:[0,8,2,4],lookup:[8,6,9,7],dest:8,arguabl:7,cache_impl:[8,6],five:[6,5],know:[7,4],xe2:7,mkstemp:8,insert:[8,4],like:[0,2,3,4,5,6,7,8,9],success:8,page:6,unreach:0,exceed:9,revers:8,convei:8,captur:[8,2,3,9],pariti:9,"export":[0,5,4],smoothli:4,proper:8,librari:[0,2,7,6,3,8],tmp:[8,2],lead:[2,3,9],usag:[0,1,2,6,4],nutshel:4,although:5,stage:8,about:1,actual:[0,2,4,5,6,3,8,9],column:0,htmlentitydef:2,discard:2,x99a:7,disabl:[6,1,2,9],own:[0,2,3,4,5,6,7,8,9],populate_self:3,automat:[0,2,4,5,6,8,9],"dr\u00f4le":7,leverag:5,quote_plu:2,inner:0,arg1:3,arg2:3,"function":[0,2,3,4,5,6,7,8,9],keyerror:9,invalidate_def:6,eas:[2,9],inlin:[5,9,4],buf:[8,2],wherev:7,count:[0,8,9],made:[6,9],whether:[2,9,5],wish:[6,2,9],displai:8,record:[8,3,5],below:[0,7,4],otherwis:[8,9,7,5],evalu:[0,3,5],"int":9,dure:[8,4],filenam:[8,6,3],twist:0,pit:9,probabl:[0,8,9,6],mutual:8,percent:5,detail:[0,4,5,7,8,9],other:6,bool:9,futur:[3,5],varieti:[6,3,5],post_pros:0,supports_cal:3,templateuri:3,some_condit:0,stai:[6,9],experienc:9,strict_undefin:[8,9],rule:[0,4],portion:0},objtypes:{"0":"py:attribute","1":"py:method","2":"py:class","3":"py:function"},objnames:{"0":["py","attribute","Python attribute"],"1":["py","method","Python method"],"2":["py","class","Python class"],"3":["py","function","Python function"]},filenames:["defs","index","filtering","namespaces","inheritance","syntax","caching","unicode","usage","runtime"],titles:["Defs and Blocks","Table of Contents","Filtering and Buffering","Namespaces","Inheritance","Syntax","Caching","The Unicode Chapter","Usage","The Mako Runtime Environment"],objects:{RichTraceback:{records:[8,0,1,""],reverse_traceback:[8,0,1,""],source:[8,0,1,""],lineno:[8,0,1,""],reverse_records:[8,0,1,""],error:[8,0,1,""],message:[8,0,1,""]},"mako.exceptions":{text_error_template:[8,3,1,""],RichTraceback:[8,2,1,""],html_error_template:[8,3,1,""]},"mako.lookup.TemplateLookup":{put_template:[8,1,1,""],get_template:[8,1,1,""],put_string:[8,1,1,""],adjust_uri:[8,1,1,""],filename_to_uri:[8,1,1,""]},"mako.runtime.Context":{get:[9,1,1,""],keys:[9,1,1,""],push_caller:[9,1,1,""],writer:[9,1,1,""],pop_caller:[9,1,1,""],write:[9,1,1,""],lookup:[9,0,1,""],kwargs:[9,0,1,""]},"mako.lookup.TemplateCollection":{get_template:[8,1,1,""],adjust_uri:[8,1,1,""],has_template:[8,1,1,""],filename_to_uri:[8,1,1,""]},"mako.runtime.ModuleNamespace":{filename:[3,0,1,""]},"mako.cache.CacheImpl":{invalidate:[6,1,1,""],get_or_create:[6,1,1,""],pass_context:[6,0,1,""],set:[6,1,1,""],get:[6,1,1,""]},"mako.runtime.LoopContext":{cycle:[9,1,1,""]},"mako.cache":{register_plugin:[6,3,1,""],CacheImpl:[6,2,1,""],Cache:[6,2,1,""]},"mako.runtime.Namespace":{include_file:[3,1,1,""],template:[3,0,1,""],get_cached:[3,1,1,""],get_namespace:[3,1,1,""],cache:[3,0,1,""],uri:[3,0,1,""],module:[3,0,1,""],filename:[3,0,1,""],context:[3,0,1,""],get_template:[3,1,1,""],attr:[3,0,1,""]},"mako.lookup":{TemplateLookup:[8,2,1,""],TemplateCollection:[8,2,1,""]},"mako.runtime.TemplateNamespace":{uri:[3,0,1,""],module:[3,0,1,""],filename:[3,0,1,""]},"mako.runtime":{capture:[3,3,1,""],Undefined:[9,2,1,""],Namespace:[3,2,1,""],ModuleNamespace:[3,2,1,""],supports_caller:[3,3,1,""],Context:[9,2,1,""],LoopContext:[9,2,1,""],TemplateNamespace:[3,2,1,""]},"mako.ext.beaker_cache":{BeakerCacheImpl:[6,2,1,""]},"mako.cache.Cache":{invalidate:[6,1,1,""],set:[6,1,1,""],invalidate_body:[6,1,1,""],get:[6,1,1,""],invalidate_closure:[6,1,1,""],invalidate_def:[6,1,1,""],starttime:[6,0,1,""],put:[6,1,1,""],get_or_create:[6,1,1,""],id:[6,0,1,""],impl:[6,0,1,""]},"mako.template.Template":{render_context:[8,1,1,""],code:[8,0,1,""],render:[8,1,1,""],source:[8,0,1,""],render_unicode:[8,1,1,""],get_def:[8,1,1,""]},"mako.template":{DefTemplate:[8,2,1,""],Template:[8,2,1,""]}},titleterms:{all:9,text:5,wsgi:8,syntax:5,content:[0,1,4],depend:3,except:8,local:3,earli:5,"return":5,python:[3,5],express:[2,7,5],default_filt:2,framework:8,common:8,name:[0,9,3,4],specif:[6,3],level:5,iter:9,collect:8,integr:8,output:7,unicod:[8,7],refer:[8,6,9,3],page:[0,5],pygment:8,set:8,"static":3,nsname:5,reserv:9,variabl:9,what:4,entir:7,access:6,substitut:5,version:3,size:8,method:[9,3],attribut:4,parent:[9,4],migrat:9,usag:[8,3,7],bodi:3,cycl:9,base:8,accessor:9,chapter:7,about:4,plugin:6,filter:[2,5],turn:2,heck:7,loop:[9,5],context:[9,5],produc:4,block:[0,5,2,4],dogpil:6,comment:5,render:4,guidelin:6,modul:[3,5],within:0,encod:[8,7],api:[8,6,9,3],defnam:5,wrap:4,select:7,backend:6,from:[0,3,5],wai:3,two:3,next:4,call:[0,3,5],includ:5,basic:8,beaker:6,legaci:9,namespac:[5,3,4],disable_unicod:7,specifi:7,indic:1,"true":7,cach:6,word:9,attr:3,augment:4,structur:5,exampl:3,defin:7,embed:0,def:[0,5,2,3,4],control:5,sai:7,argument:[0,6,2],templat:[8,9,7,5],tag:5,inherit:[5,3,4],file:[0,8,7],tabl:1,templatelookup:8,check:8,mako:9,decor:2,multipl:4,built:[9,3],programmat:[0,6],babel:8,self:3,write:6,handl:[8,7],other:0,buffer:[2,7,9],nest:4,time:4,regular:3,newlin:5,off:2,doc:5,rule:7,disabl:7,declar:3,environ:9,runtim:9,filesystem:8,escap:5}})Mako-0.9.1/doc/syntax.html0000644000076500000240000011666312257136657016170 0ustar classicstaff00000000000000 Syntax — Mako 0.9.1 Documentation
      Hyperfast and lightweight templating for the Python platform.

      Mako 0.9.1 Documentation

      Release: 0.9.1

      Syntax

      A Mako template is parsed from a text stream containing any kind of content, XML, HTML, email text, etc. The template can further contain Mako-specific directives which represent variable and/or expression substitutions, control structures (i.e. conditionals and loops), server-side comments, full blocks of Python code, as well as various tags that offer additional functionality. All of these constructs compile into real Python code. This means that you can leverage the full power of Python in almost every aspect of a Mako template.

      Expression Substitution

      The simplest expression is just a variable substitution. The syntax for this is the ${} construct, which is inspired by Perl, Genshi, JSP EL, and others:

      this is x: ${x}
      

      Above, the string representation of x is applied to the template’s output stream. If you’re wondering where x comes from, it’s usually from the Context supplied to the template’s rendering function. If x was not supplied to the template and was not otherwise assigned locally, it evaluates to a special value UNDEFINED. More on that later.

      The contents within the ${} tag are evaluated by Python directly, so full expressions are OK:

      pythagorean theorem:  ${pow(x,2) + pow(y,2)}
      

      The results of the expression are evaluated into a string result in all cases before being rendered to the output stream, such as the above example where the expression produces a numeric result.

      Expression Escaping

      Mako includes a number of built-in escaping mechanisms, including HTML, URI and XML escaping, as well as a “trim” function. These escapes can be added to an expression substitution using the | operator:

      ${"this is some text" | u}
      

      The above expression applies URL escaping to the expression, and produces this+is+some+text. The u name indicates URL escaping, whereas h represents HTML escaping, x represents XML escaping, and trim applies a trim function.

      Read more about built-in filtering functions, including how to make your own filter functions, in Filtering and Buffering.

      Control Structures

      A control structure refers to all those things that control the flow of a program – conditionals (i.e. if/else), loops (like while and for), as well as things like try/except. In Mako, control structures are written using the % marker followed by a regular Python control expression, and are “closed” by using another % marker with the tag “end<name>”, where “<name>” is the keyword of the expression:

      % if x==5:
          this is some output
      % endif
      

      The % can appear anywhere on the line as long as no text precedes it; indentation is not significant. The full range of Python “colon” expressions are allowed here, including if/elif/else, while, for, and even def, although Mako has a built-in tag for defs which is more full-featured.

      % for a in ['one', 'two', 'three', 'four', 'five']:
          % if a[0] == 't':
          its two or three
          % elif a[0] == 'f':
          four/five
          % else:
          one
          % endif
      % endfor
      

      The % sign can also be “escaped”, if you actually want to emit a percent sign as the first non whitespace character on a line, by escaping it as in %%:

      %% some text
      
          %% some more text
      

      The Loop Context

      The loop context provides additional information about a loop while inside of a % for structure:

      <ul>
      % for a in ("one", "two", "three"):
          <li>Item ${loop.index}: ${a}</li>
      % endfor
      </ul>
      

      See The Loop Context for more information on this feature.

      New in version 0.7.

      Comments

      Comments come in two varieties. The single line comment uses ## as the first non-space characters on a line:

      ## this is a comment.
      ...text ...
      

      A multiline version exists using <%doc> ...text... </%doc>:

      <%doc>
          these are comments
          more comments
      </%doc>
      

      Newline Filters

      The backslash (“\”) character, placed at the end of any line, will consume the newline character before continuing to the next line:

      here is a line that goes onto \
      another line.
      

      The above text evaluates to:

      here is a line that goes onto another line.
      

      Python Blocks

      Any arbitrary block of python can be dropped in using the <% %> tags:

      this is a template
      <%
          x = db.get_resource('foo')
          y = [z.element for z in x if x.frobnizzle==5]
      %>
      % for elem in y:
          element: ${elem}
      % endfor
      

      Within <% %>, you’re writing a regular block of Python code. While the code can appear with an arbitrary level of preceding whitespace, it has to be consistently formatted with itself. Mako’s compiler will adjust the block of Python to be consistent with the surrounding generated Python code.

      Module-level Blocks

      A variant on <% %> is the module-level code block, denoted by <%! %>. Code within these tags is executed at the module level of the template, and not within the rendering function of the template. Therefore, this code does not have access to the template’s context and is only executed when the template is loaded into memory (which can be only once per application, or more, depending on the runtime environment). Use the <%! %> tags to declare your template’s imports, as well as any pure-Python functions you might want to declare:

      <%!
          import mylib
          import re
      
          def filter(text):
              return re.sub(r'^@', '', text)
      %>
      

      Any number of <%! %> blocks can be declared anywhere in a template; they will be rendered in the resulting module in a single contiguous block above all render callables, in the order in which they appear in the source template.

      Tags

      The rest of what Mako offers takes place in the form of tags. All tags use the same syntax, which is similar to an XML tag except that the first character of the tag name is a % character. The tag is closed either by a contained slash character, or an explicit closing tag:

      <%include file="foo.txt"/>
      
      <%def name="foo" buffered="True">
          this is a def
      </%def>
      

      All tags have a set of attributes which are defined for each tag. Some of these attributes are required. Also, many attributes support evaluation, meaning you can embed an expression (using ${}) inside the attribute text:

      <%include file="/foo/bar/${myfile}.txt"/>
      

      Whether or not an attribute accepts runtime evaluation depends on the type of tag and how that tag is compiled into the template. The best way to find out if you can stick an expression in is to try it! The lexer will tell you if it’s not valid.

      Heres a quick summary of all the tags:

      <%page>

      This tag defines general characteristics of the template, including caching arguments, and optional lists of arguments which the template expects when invoked.

      <%page args="x, y, z='default'"/>
      

      Or a page tag that defines caching characteristics:

      <%page cached="True" cache_type="memory"/>
      

      Currently, only one <%page> tag gets used per template, the rest get ignored. While this will be improved in a future release, for now make sure you have only one <%page> tag defined in your template, else you may not get the results you want. The details of what <%page> is used for are described further in The body() Method as well as Caching.

      <%include>

      A tag that is familiar from other template languages, %include is a regular joe that just accepts a file argument and calls in the rendered result of that file:

      <%include file="header.html"/>
      
          hello world
      
      <%include file="footer.html"/>
      

      Include also accepts arguments which are available as <%page> arguments in the receiving template:

      <%include file="toolbar.html" args="current_section='members', username='ed'"/>
      

      <%def>

      The %def tag defines a Python function which contains a set of content, that can be called at some other point in the template. The basic idea is simple:

      <%def name="myfunc(x)">
          this is myfunc, x is ${x}
      </%def>
      
      ${myfunc(7)}
      

      The %def tag is a lot more powerful than a plain Python def, as the Mako compiler provides many extra services with %def that you wouldn’t normally have, such as the ability to export defs as template “methods”, automatic propagation of the current Context, buffering/filtering/caching flags, and def calls with content, which enable packages of defs to be sent as arguments to other def calls (not as hard as it sounds). Get the full deal on what %def can do in Defs and Blocks.

      <%block>

      %block is a tag that is close to a %def, except executes itself immediately in its base-most scope, and can also be anonymous (i.e. with no name):

      <%block filter="h">
          some <html> stuff.
      </%block>
      

      Inspired by Jinja2 blocks, named blocks offer a syntactically pleasing way to do inheritance:

      <html>
          <body>
          <%block name="header">
              <h2><%block name="title"/></h2>
          </%block>
          ${self.body()}
          </body>
      </html>
      

      Blocks are introduced in Using Blocks and further described in Inheritance.

      New in version 0.4.1.

      <%namespace>

      %namespace is Mako’s equivalent of Python’s import statement. It allows access to all the rendering functions and metadata of other template files, plain Python modules, as well as locally defined “packages” of functions.

      <%namespace file="functions.html" import="*"/>
      

      The underlying object generated by %namespace, an instance of mako.runtime.Namespace, is a central construct used in templates to reference template-specific information such as the current URI, inheritance structures, and other things that are not as hard as they sound right here. Namespaces are described in Namespaces.

      <%inherit>

      Inherit allows templates to arrange themselves in inheritance chains. This is a concept familiar in many other template languages.

      <%inherit file="base.html"/>
      

      When using the %inherit tag, control is passed to the topmost inherited template first, which then decides how to handle calling areas of content from its inheriting templates. Mako offers a lot of flexibility in this area, including dynamic inheritance, content wrapping, and polymorphic method calls. Check it out in Inheritance.

      <%nsname:defname>

      Any user-defined “tag” can be created against a namespace by using a tag with a name of the form <%<namespacename>:<defname>>. The closed and open formats of such a tag are equivalent to an inline expression and the <%call> tag, respectively.

      <%mynamespace:somedef param="some value">
          this is the body
      </%mynamespace:somedef>
      

      To create custom tags which accept a body, see Calling a Def with Embedded Content and/or Other Defs.

      New in version 0.2.3.

      <%call>

      The call tag is the “classic” form of a user-defined tag, and is roughly equivalent to the <%namespacename:defname> syntax described above. This tag is also described in Calling a Def with Embedded Content and/or Other Defs.

      <%doc>

      The %doc tag handles multiline comments:

      <%doc>
          these are comments
          more comments
      </%doc>
      

      Also the ## symbol as the first non-space characters on a line can be used for single line comments.

      <%text>

      This tag suspends the Mako lexer’s normal parsing of Mako template directives, and returns its entire body contents as plain text. It is used pretty much to write documentation about Mako:

      <%text filter="h">
          heres some fake mako ${syntax}
          <%def name="x()">${x}</%def>
      </%text>
      

      Returning Early from a Template

      Sometimes you want to stop processing a template or <%def> method in the middle and just use the text you’ve accumulated so far. You can use a return statement inside a Python block to do that.

      % if not len(records):
          No records found.
          <% return %>
      % endif
      

      Or perhaps:

      <%
          if not len(records):
              return
      %>
      

      Mako-0.9.1/doc/unicode.html0000644000076500000240000007614712257136657016272 0ustar classicstaff00000000000000 The Unicode Chapter — Mako 0.9.1 Documentation
      Hyperfast and lightweight templating for the Python platform.

      Mako 0.9.1 Documentation

      Release: 0.9.1

      The Unicode Chapter

      The Python language supports two ways of representing what we know as “strings”, i.e. series of characters. In Python 2, the two types are string and unicode, and in Python 3 they are bytes and string. A key aspect of the Python 2 string and Python 3 bytes types are that they contain no information regarding what encoding the data is stored in. For this reason they were commonly referred to as byte strings on Python 2, and Python 3 makes this name more explicit. The origins of this come from Python’s background of being developed before the Unicode standard was even available, back when strings were C-style strings and were just that, a series of bytes. Strings that had only values below 128 just happened to be ASCII strings and were printable on the console, whereas strings with values above 128 would produce all kinds of graphical characters and bells.

      Contrast the “byte-string” type with the “unicode/string” type. Objects of this latter type are created whenever you say something like u"hello world" (or in Python 3, just "hello world"). In this case, Python represents each character in the string internally using multiple bytes per character (something similar to UTF-16). What’s important is that when using the unicode/string type to store strings, Python knows the data’s encoding; it’s in its own internal format. Whereas when using the string/bytes type, it does not.

      When Python 2 attempts to treat a byte-string as a string, which means it’s attempting to compare/parse its characters, to coerce it into another encoding, or to decode it to a unicode object, it has to guess what the encoding is. In this case, it will pretty much always guess the encoding as ascii... and if the byte-string contains bytes above value 128, you’ll get an error. Python 3 eliminates much of this confusion by just raising an error unconditionally if a byte-string is used in a character-aware context.

      There is one operation that Python can do with a non-ASCII byte-string, and it’s a great source of confusion: it can dump the byte-string straight out to a stream or a file, with nary a care what the encoding is. To Python, this is pretty much like dumping any other kind of binary data (like an image) to a stream somewhere. In Python 2, it is common to see programs that embed all kinds of international characters and encodings into plain byte-strings (i.e. using "hello world" style literals) can fly right through their run, sending reams of strings out to wherever they are going, and the programmer, seeing the same output as was expressed in the input, is now under the illusion that his or her program is Unicode-compliant. In fact, their program has no unicode awareness whatsoever, and similarly has no ability to interact with libraries that are unicode aware. Python 3 makes this much less likely by defaulting to unicode as the storage format for strings.

      The “pass through encoded data” scheme is what template languages like Cheetah and earlier versions of Myghty do by default. Mako as of version 0.2 also supports this mode of operation when using Python 2, using the disable_unicode=True flag. However, when using Mako in its default mode of unicode-aware, it requires explicitness when dealing with non-ASCII encodings. Additionally, if you ever need to handle unicode strings and other kinds of encoding conversions more intelligently, the usage of raw byte-strings quickly becomes a nightmare, since you are sending the Python interpreter collections of bytes for which it can make no intelligent decisions with regards to encoding. In Python 3 Mako only allows usage of native, unicode strings.

      In normal Mako operation, all parsed template constructs and output streams are handled internally as Python unicode objects. It’s only at the point of render() that this unicode stream may be rendered into whatever the desired output encoding is. The implication here is that the template developer must :ensure that the encoding of all non-ASCII templates is explicit (still required in Python 3), that all non-ASCII-encoded expressions are in one way or another converted to unicode (not much of a burden in Python 3), and that the output stream of the template is handled as a unicode stream being encoded to some encoding (still required in Python 3).

      Specifying the Encoding of a Template File

      This is the most basic encoding-related setting, and it is equivalent to Python’s “magic encoding comment”, as described in pep-0263. Any template that contains non-ASCII characters requires that this comment be present so that Mako can decode to unicode (and also make usage of Python’s AST parsing services). Mako’s lexer will use this encoding in order to convert the template source into a unicode object before continuing its parsing:

      ## -*- coding: utf-8 -*-
      
      Alors vous imaginez ma surprise, au lever du jour, quand
      une drôle de petite voix m’a réveillé. Elle disait:
       « S’il vous plaît… dessine-moi un mouton! »
      

      For the picky, the regular expression used is derived from that of the above mentioned pep:

      #.*coding[:=]\s*([-\w.]+).*\n
      

      The lexer will convert to unicode in all cases, so that if any characters exist in the template that are outside of the specified encoding (or the default of ascii), the error will be immediate.

      As an alternative, the template encoding can be specified programmatically to either Template or TemplateLookup via the input_encoding parameter:

      t = TemplateLookup(directories=['./'], input_encoding='utf-8')
      

      The above will assume all located templates specify utf-8 encoding, unless the template itself contains its own magic encoding comment, which takes precedence.

      Handling Expressions

      The next area that encoding comes into play is in expression constructs. By default, Mako’s treatment of an expression like this:

      ${"hello world"}
      

      looks something like this:

      context.write(unicode("hello world"))
      

      In Python 3, it’s just:

      context.write(str("hello world"))
      

      That is, the output of all expressions is run through the ``unicode`` built-in. This is the default setting, and can be modified to expect various encodings. The unicode step serves both the purpose of rendering non-string expressions into strings (such as integers or objects which contain __str()__ methods), and to ensure that the final output stream is constructed as a unicode object. The main implication of this is that any raw byte-strings that contain an encoding other than ASCII must first be decoded to a Python unicode object. It means you can’t say this in Python 2:

      ${"voix m’a réveillé."}  ## error in Python 2!
      

      You must instead say this:

      ${u"voix m’a réveillé."}  ## OK !
      

      Similarly, if you are reading data from a file that is streaming bytes, or returning data from some object that is returning a Python byte-string containing a non-ASCII encoding, you have to explicitly decode to unicode first, such as:

      ${call_my_object().decode('utf-8')}
      

      Note that filehandles acquired by open() in Python 3 default to returning “text”, that is the decoding is done for you. See Python 3’s documentation for the open() built-in for details on this.

      If you want a certain encoding applied to all expressions, override the unicode builtin with the decode built-in at the Template or TemplateLookup level:

      t = Template(templatetext, default_filters=['decode.utf8'])
      

      Note that the built-in decode object is slower than the unicode function, since unlike unicode it’s not a Python built-in, and it also checks the type of the incoming data to determine if string conversion is needed first.

      The default_filters argument can be used to entirely customize the filtering process of expressions. This argument is described in The default_filters Argument.

      Defining Output Encoding

      Now that we have a template which produces a pure unicode output stream, all the hard work is done. We can take the output and do anything with it.

      As stated in the “Usage” chapter, both Template and TemplateLookup accept output_encoding and encoding_errors parameters which can be used to encode the output in any Python supported codec:

      from mako.template import Template
      from mako.lookup import TemplateLookup
      
      mylookup = TemplateLookup(directories=['/docs'], output_encoding='utf-8', encoding_errors='replace')
      
      mytemplate = mylookup.get_template("foo.txt")
      print mytemplate.render()
      

      render() will return a bytes object in Python 3 if an output encoding is specified. By default it performs no encoding and returns a native string.

      render_unicode() will return the template output as a Python unicode object (or string in Python 3):

      print mytemplate.render_unicode()
      

      The above method disgards the output encoding keyword argument; you can encode yourself by saying:

      print mytemplate.render_unicode().encode('utf-8', 'replace')
      

      Buffer Selection

      Mako does play some games with the style of buffering used internally, to maximize performance. Since the buffer is by far the most heavily used object in a render operation, it’s important!

      When calling render() on a template that does not specify any output encoding (i.e. it’s ascii), Python’s cStringIO module, which cannot handle encoding of non-ASCII unicode objects (even though it can send raw byte-strings through), is used for buffering. Otherwise, a custom Mako class called FastEncodingBuffer is used, which essentially is a super dumbed-down version of StringIO that gathers all strings into a list and uses u''.join(elements) to produce the final output – it’s markedly faster than StringIO.

      Saying to Heck with It: Disabling the Usage of Unicode Entirely

      Some segments of Mako’s userbase choose to make no usage of Unicode whatsoever, and instead would prefer the “pass through” approach; all string expressions in their templates return encoded byte-strings, and they would like these strings to pass right through. The only advantage to this approach is that templates need not use u"" for literal strings; there’s an arguable speed improvement as well since raw byte-strings generally perform slightly faster than unicode objects in Python. For these users, assuming they’re sticking with Python 2, they can hit the disable_unicode=True flag as so:

      # -*- coding:utf-8 -*-
      from mako.template import Template
      
      t = Template("drôle de petite voix m’a réveillé.", disable_unicode=True, input_encoding='utf-8')
      print t.code
      

      The disable_unicode mode is strictly a Python 2 thing. It is not supported at all in Python 3.

      The generated module source code will contain elements like these:

      # -*- coding:utf-8 -*-
      #  ...more generated code ...
      
      def render_body(context,**pageargs):
          context.caller_stack.push_frame()
          try:
              __M_locals = dict(pageargs=pageargs)
              # SOURCE LINE 1
              context.write('dr\xc3\xb4le de petite voix m\xe2\x80\x99a r\xc3\xa9veill\xc3\xa9.')
              return ''
          finally:
              context.caller_stack.pop_frame()
      

      Where above that the string literal used within Context.write() is a regular byte-string.

      When disable_unicode=True is turned on, the default_filters argument which normally defaults to ["unicode"] now defaults to ["str"] instead. Setting default_filters to the empty list [] can remove the overhead of the str call. Also, in this mode you cannot safely call render_unicode() – you’ll get unicode/decode errors.

      The h filter (HTML escape) uses a less performant pure Python escape function in non-unicode mode. This because MarkupSafe only supports Python unicode objects for non-ASCII strings.

      Changed in version 0.3.4: In prior versions, it used cgi.escape(), which has been replaced with a function that also escapes single quotes.

      Rules for using disable_unicode=True

      • Don’t use this mode unless you really, really want to and you absolutely understand what you’re doing.
      • Don’t use this option just because you don’t want to learn to use Unicode properly; we aren’t supporting user issues in this mode of operation. We will however offer generous help for the vast majority of users who stick to the Unicode program.
      • Python 3 is unicode by default, and the flag is not available when running on Python 3.

      Mako-0.9.1/doc/usage.html0000644000076500000240000026115312257136657015741 0ustar classicstaff00000000000000 Usage — Mako 0.9.1 Documentation
      Hyperfast and lightweight templating for the Python platform.

      Mako 0.9.1 Documentation

      Release: 0.9.1

      Usage

      Basic Usage

      This section describes the Python API for Mako templates. If you are using Mako within a web framework such as Pylons, the work of integrating Mako’s API is already done for you, in which case you can skip to the next section, Syntax.

      The most basic way to create a template and render it is through the Template class:

      from mako.template import Template
      
      mytemplate = Template("hello world!")
      print mytemplate.render()
      

      Above, the text argument to Template is compiled into a Python module representation. This module contains a function called render_body(), which produces the output of the template. When mytemplate.render() is called, Mako sets up a runtime environment for the template and calls the render_body() function, capturing the output into a buffer and returning its string contents.

      The code inside the render_body() function has access to a namespace of variables. You can specify these variables by sending them as additional keyword arguments to the render() method:

      from mako.template import Template
      
      mytemplate = Template("hello, ${name}!")
      print mytemplate.render(name="jack")
      

      The render() method calls upon Mako to create a Context object, which stores all the variable names accessible to the template and also stores a buffer used to capture output. You can create this Context yourself and have the template render with it, using the render_context() method:

      from mako.template import Template
      from mako.runtime import Context
      from StringIO import StringIO
      
      mytemplate = Template("hello, ${name}!")
      buf = StringIO()
      ctx = Context(buf, name="jack")
      mytemplate.render_context(ctx)
      print buf.getvalue()
      

      Using File-Based Templates

      A Template can also load its template source code from a file, using the filename keyword argument:

      from mako.template import Template
      
      mytemplate = Template(filename='/docs/mytmpl.txt')
      print mytemplate.render()
      

      For improved performance, a Template which is loaded from a file can also cache the source code to its generated module on the filesystem as a regular Python module file (i.e. a .py file). To do this, just add the module_directory argument to the template:

      from mako.template import Template
      
      mytemplate = Template(filename='/docs/mytmpl.txt', module_directory='/tmp/mako_modules')
      print mytemplate.render()
      

      When the above code is rendered, a file /tmp/mako_modules/docs/mytmpl.txt.py is created containing the source code for the module. The next time a Template with the same arguments is created, this module file will be automatically re-used.

      Using TemplateLookup

      All of the examples thus far have dealt with the usage of a single Template object. If the code within those templates tries to locate another template resource, it will need some way to find them, using simple URI strings. For this need, the resolution of other templates from within a template is accomplished by the TemplateLookup class. This class is constructed given a list of directories in which to search for templates, as well as keyword arguments that will be passed to the Template objects it creates:

      from mako.template import Template
      from mako.lookup import TemplateLookup
      
      mylookup = TemplateLookup(directories=['/docs'])
      mytemplate = Template("""<%include file="header.txt"/> hello world!""", lookup=mylookup)
      

      Above, we created a textual template which includes the file "header.txt". In order for it to have somewhere to look for "header.txt", we passed a TemplateLookup object to it, which will search in the directory /docs for the file "header.txt".

      Usually, an application will store most or all of its templates as text files on the filesystem. So far, all of our examples have been a little bit contrived in order to illustrate the basic concepts. But a real application would get most or all of its templates directly from the TemplateLookup, using the aptly named get_template() method, which accepts the URI of the desired template:

      from mako.template import Template
      from mako.lookup import TemplateLookup
      
      mylookup = TemplateLookup(directories=['/docs'], module_directory='/tmp/mako_modules')
      
      def serve_template(templatename, **kwargs):
          mytemplate = mylookup.get_template(templatename)
          print mytemplate.render(**kwargs)
      

      In the example above, we create a TemplateLookup which will look for templates in the /docs directory, and will store generated module files in the /tmp/mako_modules directory. The lookup locates templates by appending the given URI to each of its search directories; so if you gave it a URI of /etc/beans/info.txt, it would search for the file /docs/etc/beans/info.txt, else raise a TopLevelNotFound exception, which is a custom Mako exception.

      When the lookup locates templates, it will also assign a uri property to the Template which is the URI passed to the get_template() call. Template uses this URI to calculate the name of its module file. So in the above example, a templatename argument of /etc/beans/info.txt will create a module file /tmp/mako_modules/etc/beans/info.txt.py.

      Setting the Collection Size

      The TemplateLookup also serves the important need of caching a fixed set of templates in memory at a given time, so that successive URI lookups do not result in full template compilations and/or module reloads on each request. By default, the TemplateLookup size is unbounded. You can specify a fixed size using the collection_size argument:

      mylookup = TemplateLookup(directories=['/docs'],
                      module_directory='/tmp/mako_modules', collection_size=500)
      

      The above lookup will continue to load templates into memory until it reaches a count of around 500. At that point, it will clean out a certain percentage of templates using a least recently used scheme.

      Setting Filesystem Checks

      Another important flag on TemplateLookup is filesystem_checks. This defaults to True, and says that each time a template is returned by the get_template() method, the revision time of the original template file is checked against the last time the template was loaded, and if the file is newer will reload its contents and recompile the template. On a production system, setting filesystem_checks to False can afford a small to moderate performance increase (depending on the type of filesystem used).

      Using Unicode and Encoding

      Both Template and TemplateLookup accept output_encoding and encoding_errors parameters which can be used to encode the output in any Python supported codec:

      from mako.template import Template
      from mako.lookup import TemplateLookup
      
      mylookup = TemplateLookup(directories=['/docs'], output_encoding='utf-8', encoding_errors='replace')
      
      mytemplate = mylookup.get_template("foo.txt")
      print mytemplate.render()
      

      When using Python 3, the render() method will return a bytes object, if output_encoding is set. Otherwise it returns a string.

      Additionally, the render_unicode() method exists which will return the template output as a Python unicode object, or in Python 3 a string:

      print mytemplate.render_unicode()
      

      The above method disregards the output encoding keyword argument; you can encode yourself by saying:

      print mytemplate.render_unicode().encode('utf-8', 'replace')
      

      Note that Mako’s ability to return data in any encoding and/or unicode implies that the underlying output stream of the template is a Python unicode object. This behavior is described fully in The Unicode Chapter.

      Handling Exceptions

      Template exceptions can occur in two distinct places. One is when you lookup, parse and compile the template, the other is when you run the template. Within the running of a template, exceptions are thrown normally from whatever Python code originated the issue. Mako has its own set of exception classes which mostly apply to the lookup and lexer/compiler stages of template construction. Mako provides some library routines that can be used to help provide Mako-specific information about any exception’s stack trace, as well as formatting the exception within textual or HTML format. In all cases, the main value of these handlers is that of converting Python filenames, line numbers, and code samples into Mako template filenames, line numbers, and code samples. All lines within a stack trace which correspond to a Mako template module will be converted to be against the originating template file.

      To format exception traces, the text_error_template() and html_error_template() functions are provided. They make usage of sys.exc_info() to get at the most recently thrown exception. Usage of these handlers usually looks like:

      from mako import exceptions
      
      try:
          template = lookup.get_template(uri)
          print template.render()
      except:
          print exceptions.text_error_template().render()
      

      Or for the HTML render function:

      from mako import exceptions
      
      try:
          template = lookup.get_template(uri)
          print template.render()
      except:
          print exceptions.html_error_template().render()
      

      The html_error_template() template accepts two options: specifying full=False causes only a section of an HTML document to be rendered. Specifying css=False will disable the default stylesheet from being rendered.

      E.g.:

      print exceptions.html_error_template().render(full=False)
      

      The HTML render function is also available built-in to Template using the format_exceptions flag. In this case, any exceptions raised within the render stage of the template will result in the output being substituted with the output of html_error_template():

      template = Template(filename="/foo/bar", format_exceptions=True)
      print template.render()
      

      Note that the compile stage of the above template occurs when you construct the Template itself, and no output stream is defined. Therefore exceptions which occur within the lookup/parse/compile stage will not be handled and will propagate normally. While the pre-render traceback usually will not include any Mako-specific lines anyway, it will mean that exceptions which occur previous to rendering and those which occur within rendering will be handled differently... so the try/except patterns described previously are probably of more general use.

      The underlying object used by the error template functions is the RichTraceback object. This object can also be used directly to provide custom error views. Here’s an example usage which describes its general API:

      from mako.exceptions import RichTraceback
      
      try:
          template = lookup.get_template(uri)
          print template.render()
      except:
          traceback = RichTraceback()
          for (filename, lineno, function, line) in traceback.traceback:
              print "File %s, line %s, in %s" % (filename, lineno, function)
              print line, "\n"
          print "%s: %s" % (str(traceback.error.__class__.__name__), traceback.error)
      

      Common Framework Integrations

      The Mako distribution includes a little bit of helper code for the purpose of using Mako in some popular web framework scenarios. This is a brief description of what’s included.

      WSGI

      A sample WSGI application is included in the distribution in the file examples/wsgi/run_wsgi.py. This runner is set up to pull files from a templates as well as an htdocs directory and includes a rudimental two-file layout. The WSGI runner acts as a fully functional standalone web server, using wsgiutils to run itself, and propagates GET and POST arguments from the request into the Context, can serve images, CSS files and other kinds of files, and also displays errors using Mako’s included exception-handling utilities.

      Pygments

      A Pygments-compatible syntax highlighting module is included under mako.ext.pygmentplugin. This module is used in the generation of Mako documentation and also contains various setuptools entry points under the heading pygments.lexers, including mako, html+mako, xml+mako (see the setup.py file for all the entry points).

      Babel

      Mako provides support for extracting gettext messages from templates via a Babel extractor entry point under mako.ext.babelplugin.

      Gettext messages are extracted from all Python code sections, including those of control lines and expressions embedded in tags.

      Translator comments may also be extracted from Mako templates when a comment tag is specified to Babel (such as with the -c option).

      For example, a project "myproj" contains the following Mako template at myproj/myproj/templates/name.html:

      <div id="name">
        Name:
        ## TRANSLATORS: This is a proper name. See the gettext
        ## manual, section Names.
        ${_('Francois Pinard')}
      </div>
      

      To extract gettext messages from this template the project needs a Mako section in its Babel Extraction Method Mapping file (typically located at myproj/babel.cfg):

      # Extraction from Python source files
      
      [python: myproj/**.py]
      
      # Extraction from Mako templates
      
      [mako: myproj/templates/**.html]
      input_encoding = utf-8
      

      The Mako extractor supports an optional input_encoding parameter specifying the encoding of the templates (identical to Template/TemplateLookup‘s input_encoding parameter).

      Invoking Babel‘s extractor at the command line in the project’s root directory:

      myproj$ pybabel extract -F babel.cfg -c "TRANSLATORS:" .
      

      will output a gettext catalog to stdout including the following:

      #. TRANSLATORS: This is a proper name. See the gettext
      #. manual, section Names.
      #: myproj/templates/name.html:5
      msgid "Francois Pinard"
      msgstr ""
      

      This is only a basic example: Babel can be invoked from setup.py and its command line options specified in the accompanying setup.cfg via Babel Distutils/Setuptools Integration.

      Comments must immediately precede a gettext message to be extracted. In the following case the TRANSLATORS: comment would not have been extracted:

      <div id="name">
        ## TRANSLATORS: This is a proper name. See the gettext
        ## manual, section Names.
        Name: ${_('Francois Pinard')}
      </div>
      

      See the Babel User Guide for more information.

      API Reference

      class mako.template.Template(text=None, filename=None, uri=None, format_exceptions=False, error_handler=None, lookup=None, output_encoding=None, encoding_errors='strict', module_directory=None, cache_args=None, cache_impl='beaker', cache_enabled=True, cache_type=None, cache_dir=None, cache_url=None, module_filename=None, input_encoding=None, disable_unicode=False, module_writer=None, bytestring_passthrough=False, default_filters=None, buffer_filters=(), strict_undefined=False, imports=None, future_imports=None, enable_loop=True, preprocessor=None, lexer_cls=None)

      Bases: object

      Represents a compiled template.

      Template includes a reference to the original template source (via the source attribute) as well as the source code of the generated Python module (i.e. the code attribute), as well as a reference to an actual Python module.

      Template is constructed using either a literal string representing the template text, or a filename representing a filesystem path to a source file.

      Parameters:
      • text – textual template source. This argument is mutually exclusive versus the filename parameter.
      • filename – filename of the source template. This argument is mutually exclusive versus the text parameter.
      • buffer_filters – string list of filters to be applied to the output of %defs which are buffered, cached, or otherwise filtered, after all filters defined with the %def itself have been applied. Allows the creation of default expression filters that let the output of return-valued %defs “opt out” of that filtering via passing special attributes or objects.
      • bytestring_passthrough

        When True, and output_encoding is set to None, and Template.render() is used to render, the StringIO or cStringIO buffer will be used instead of the default “fast” buffer. This allows raw bytestrings in the output stream, such as in expressions, to pass straight through to the buffer. This flag is forced to True if disable_unicode is also configured.

        New in version 0.4: Added to provide the same behavior as that of the previous series.

      • cache_args – Dictionary of cache configuration arguments that will be passed to the CacheImpl. See Caching.
      • cache_dir

        Deprecated since version 0.6: Use the 'dir' argument in the cache_args dictionary. See Caching.

      • cache_enabled – Boolean flag which enables caching of this template. See Caching.
      • cache_impl – String name of a CacheImpl caching implementation to use. Defaults to 'beaker'.
      • cache_type

        Deprecated since version 0.6: Use the 'type' argument in the cache_args dictionary. See Caching.

      • cache_url

        Deprecated since version 0.6: Use the 'url' argument in the cache_args dictionary. See Caching.

      • default_filters – List of string filter names that will be applied to all expressions. See The default_filters Argument.
      • disable_unicode – Disables all awareness of Python Unicode objects. See Saying to Heck with It: Disabling the Usage of Unicode Entirely.
      • enable_loop – When True, enable the loop context variable. This can be set to False to support templates that may be making usage of the name “loop”. Individual templates can re-enable the “loop” context by placing the directive enable_loop="True" inside the <%page> tag – see Migrating Legacy Templates that Use the Word “loop”.
      • encoding_errors – Error parameter passed to encode() when string encoding is performed. See Using Unicode and Encoding.
      • error_handler – Python callable which is called whenever compile or runtime exceptions occur. The callable is passed the current context as well as the exception. If the callable returns True, the exception is considered to be handled, else it is re-raised after the function completes. Is used to provide custom error-rendering functions.
      • format_exceptions – if True, exceptions which occur during the render phase of this template will be caught and formatted into an HTML error page, which then becomes the rendered result of the render() call. Otherwise, runtime exceptions are propagated outwards.
      • imports – String list of Python statements, typically individual “import” lines, which will be placed into the module level preamble of all generated Python modules. See the example in The default_filters Argument.
      • future_imports – String list of names to import from __future__. These will be concatenated into a comma-separated string and inserted into the beginning of the template, e.g. futures_imports=['FOO', 'BAR'] results in from __future__ import FOO, BAR. If you’re interested in using features like the new division operator, you must use future_imports to convey that to the renderer, as otherwise the import will not appear as the first executed statement in the generated code and will therefore not have the desired effect.
      • input_encoding – Encoding of the template’s source code. Can be used in lieu of the coding comment. See Using Unicode and Encoding as well as The Unicode Chapter for details on source encoding.
      • lookup – a TemplateLookup instance that will be used for all file lookups via the <%namespace>, <%include>, and <%inherit> tags. See Using TemplateLookup.
      • module_directory – Filesystem location where generated Python module files will be placed.
      • module_filename – Overrides the filename of the generated Python module file. For advanced usage only.
      • module_writer

        A callable which overrides how the Python module is written entirely. The callable is passed the encoded source content of the module and the destination path to be written to. The default behavior of module writing uses a tempfile in conjunction with a file move in order to make the operation atomic. So a user-defined module writing function that mimics the default behavior would be:

        import tempfile
        import os
        import shutil
        
        def module_writer(source, outputpath):
            (dest, name) = \
                tempfile.mkstemp(
                    dir=os.path.dirname(outputpath)
                )
        
            os.write(dest, source)
            os.close(dest)
            shutil.move(name, outputpath)
        
        from mako.template import Template
        mytemplate = Template(
                        filename="index.html",
                        module_directory="/path/to/modules",
                        module_writer=module_writer
                    )
        

        The function is provided for unusual configurations where certain platform-specific permissions or other special steps are needed.

      • output_encoding – The encoding to use when render() is called. See Using Unicode and Encoding as well as The Unicode Chapter.
      • preprocessor – Python callable which will be passed the full template source before it is parsed. The return result of the callable will be used as the template source code.
      • lexer_cls

        A Lexer class used to parse the template. The Lexer class is used by default.

        New in version 0.7.4.

      • strict_undefined

        Replaces the automatic usage of UNDEFINED for any undeclared variables not located in the Context with an immediate raise of NameError. The advantage is immediate reporting of missing variables which include the name.

        New in version 0.3.6.

      • uri – string URI or other identifier for this template. If not provided, the uri is generated from the filesystem path, or from the in-memory identity of a non-file-based template. The primary usage of the uri is to provide a key within TemplateLookup, as well as to generate the file path of the generated Python module file, if module_directory is specified.
      code

      Return the module source code for this Template.

      get_def(name)

      Return a def of this template as a DefTemplate.

      render(*args, **data)

      Render the output of this template as a string.

      If the template specifies an output encoding, the string will be encoded accordingly, else the output is raw (raw output uses cStringIO and can’t handle multibyte characters). A Context object is created corresponding to the given data. Arguments that are explicitly declared by this template’s internal rendering method are also pulled from the given *args, **data members.

      render_context(context, *args, **kwargs)

      Render this Template with the given context.

      The data is written to the context’s buffer.

      render_unicode(*args, **data)

      Render the output of this template as a unicode object.

      source

      Return the template source code for this Template.

      class mako.template.DefTemplate(parent, callable_)

      Bases: mako.template.Template

      A Template which represents a callable def in a parent template.

      class mako.lookup.TemplateCollection

      Bases: object

      Represent a collection of Template objects, identifiable via URI.

      A TemplateCollection is linked to the usage of all template tags that address other templates, such as <%include>, <%namespace>, and <%inherit>. The file attribute of each of those tags refers to a string URI that is passed to that Template object’s TemplateCollection for resolution.

      TemplateCollection is an abstract class, with the usual default implementation being TemplateLookup.

      adjust_uri(uri, filename)

      Adjust the given uri based on the calling filename.

      When this method is called from the runtime, the filename parameter is taken directly to the filename attribute of the calling template. Therefore a custom TemplateCollection subclass can place any string identifier desired in the filename parameter of the Template objects it constructs and have them come back here.

      filename_to_uri(uri, filename)

      Convert the given filename to a URI relative to this TemplateCollection.

      get_template(uri, relativeto=None)

      Return a Template object corresponding to the given uri.

      The default implementation raises NotImplementedError. Implementations should raise TemplateLookupException if the given uri cannot be resolved.

      Parameters:
      • uri – String URI of the template to be resolved.
      • relativeto – if present, the given uri is assumed to be relative to this URI.
      has_template(uri)

      Return True if this TemplateLookup is capable of returning a Template object for the given uri.

      Parameters:uri – String URI of the template to be resolved.
      class mako.lookup.TemplateLookup(directories=None, module_directory=None, filesystem_checks=True, collection_size=-1, format_exceptions=False, error_handler=None, disable_unicode=False, bytestring_passthrough=False, output_encoding=None, encoding_errors='strict', cache_args=None, cache_impl='beaker', cache_enabled=True, cache_type=None, cache_dir=None, cache_url=None, modulename_callable=None, module_writer=None, default_filters=None, buffer_filters=(), strict_undefined=False, imports=None, future_imports=None, enable_loop=True, input_encoding=None, preprocessor=None, lexer_cls=None)

      Bases: mako.lookup.TemplateCollection

      Represent a collection of templates that locates template source files from the local filesystem.

      The primary argument is the directories argument, the list of directories to search:

      lookup = TemplateLookup(["/path/to/templates"])
      some_template = lookup.get_template("/index.html")
      

      The TemplateLookup can also be given Template objects programatically using put_string() or put_template():

      lookup = TemplateLookup()
      lookup.put_string("base.html", '''
          <html><body>${self.next()}</body></html>
      ''')
      lookup.put_string("hello.html", '''
          <%include file='base.html'/>
      
          Hello, world !
      ''')
      
      Parameters:
      • directories – A list of directory names which will be searched for a particular template URI. The URI is appended to each directory and the filesystem checked.
      • collection_size – Approximate size of the collection used to store templates. If left at its default of -1, the size is unbounded, and a plain Python dictionary is used to relate URI strings to Template instances. Otherwise, a least-recently-used cache object is used which will maintain the size of the collection approximately to the number given.
      • filesystem_checks – When at its default value of True, each call to TemplateLookup.get_template() will compare the filesystem last modified time to the time in which an existing Template object was created. This allows the TemplateLookup to regenerate a new Template whenever the original source has been updated. Set this to False for a very minor performance increase.
      • modulename_callable – A callable which, when present, is passed the path of the source file as well as the requested URI, and then returns the full path of the generated Python module file. This is used to inject alternate schemes for Python module location. If left at its default of None, the built in system of generation based on module_directory plus uri is used.

      All other keyword parameters available for Template are mirrored here. When new Template objects are created, the keywords established with this TemplateLookup are passed on to each new Template.

      adjust_uri(uri, relativeto)

      Adjust the given uri based on the given relative URI.

      filename_to_uri(filename)

      Convert the given filename to a URI relative to this TemplateCollection.

      get_template(uri)

      Return a Template object corresponding to the given uri.

      Note

      The relativeto argument is not supported here at the moment.

      put_string(uri, text)

      Place a new Template object into this TemplateLookup, based on the given string of text.

      put_template(uri, template)

      Place a new Template object into this TemplateLookup, based on the given Template object.

      class mako.exceptions.RichTraceback(error=None, traceback=None)

      Bases: object

      Pull the current exception from the sys traceback and extracts Mako-specific template information.

      See the usage examples in Handling Exceptions.

      error

      the exception instance.

      message

      the exception error message as unicode.

      source

      source code of the file where the error occurred. If the error occurred within a compiled template, this is the template source.

      lineno

      line number where the error occurred. If the error occurred within a compiled template, the line number is adjusted to that of the template source.

      records

      a list of 8-tuples containing the original python traceback elements, plus the filename, line number, source line, and full template source for the traceline mapped back to its originating source template, if any for that traceline (else the fields are None).

      reverse_records

      the list of records in reverse traceback – a list of 4-tuples, in the same format as a regular python traceback, with template-corresponding traceback records replacing the originals.

      reverse_traceback

      the traceback list in reverse.

      mako.exceptions.html_error_template()

      Provides a template that renders a stack trace in an HTML format, providing an excerpt of code as well as substituting source template filenames, line numbers and code for that of the originating source template, as applicable.

      The template’s default encoding_errors value is 'htmlentityreplace'. The template has two options. With the full option disabled, only a section of an HTML document is returned. With the css option disabled, the default stylesheet won’t be included.

      mako.exceptions.text_error_template(lookup=None)

      Provides a template that renders a stack trace in a similar format to the Python interpreter, substituting source template filenames, line numbers and code for that of the originating source template, as applicable.


      Mako-0.9.1/examples/0000755000076500000240000000000012257137143014777 5ustar classicstaff00000000000000Mako-0.9.1/examples/bench/0000755000076500000240000000000012257137143016056 5ustar classicstaff00000000000000Mako-0.9.1/examples/bench/basic.py0000644000076500000240000001540112257136636017520 0ustar classicstaff00000000000000# basic.py - basic benchmarks adapted from Genshi # Copyright (C) 2006 Edgewall Software # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # 3. The name of the author may not be used to endorse or promote # products derived from this software without specific prior # written permission. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER # IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN # IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from cgi import escape import os try: from StringIO import StringIO except ImportError: from io import StringIO import sys import timeit def u(stringlit): if sys.version_info >= (3,): return stringlit else: return stringlit.decode('latin1') __all__ = ['mako', 'mako_inheritance', 'jinja2', 'jinja2_inheritance', 'cheetah', 'django', 'myghty', 'genshi', 'kid'] # Templates content and constants TITLE = 'Just a test' USER = 'joe' ITEMS = ['Number %d' % num for num in range(1, 15)] U_ITEMS = [u(item) for item in ITEMS] def genshi(dirname, verbose=False): from genshi.template import TemplateLoader loader = TemplateLoader([dirname], auto_reload=False) template = loader.load('template.html') def render(): data = dict(title=TITLE, user=USER, items=ITEMS) return template.generate(**data).render('xhtml') if verbose: print(render()) return render def myghty(dirname, verbose=False): from myghty import interp interpreter = interp.Interpreter(component_root=dirname) def render(): data = dict(title=TITLE, user=USER, items=ITEMS) buffer = StringIO() interpreter.execute("template.myt", request_args=data, out_buffer=buffer) return buffer.getvalue() if verbose: print(render()) return render def mako(dirname, verbose=False): from mako.template import Template from mako.lookup import TemplateLookup disable_unicode = (sys.version_info < (3,)) lookup = TemplateLookup(directories=[dirname], filesystem_checks=False, disable_unicode=disable_unicode) template = lookup.get_template('template.html') def render(): return template.render(title=TITLE, user=USER, list_items=U_ITEMS) if verbose: print(template.code + " " + render()) return render mako_inheritance = mako def jinja2(dirname, verbose=False): from jinja2 import Environment, FileSystemLoader env = Environment(loader=FileSystemLoader(dirname)) template = env.get_template('template.html') def render(): return template.render(title=TITLE, user=USER, list_items=U_ITEMS) if verbose: print(render()) return render jinja2_inheritance = jinja2 def cheetah(dirname, verbose=False): from Cheetah.Template import Template filename = os.path.join(dirname, 'template.tmpl') template = Template(file=filename) def render(): template.__dict__.update({'title': TITLE, 'user': USER, 'list_items': U_ITEMS}) return template.respond() if verbose: print(dir(template)) print(template.generatedModuleCode()) print(render()) return render def django(dirname, verbose=False): from django.conf import settings settings.configure(TEMPLATE_DIRS=[os.path.join(dirname, 'templates')]) from django import template, templatetags from django.template import loader templatetags.__path__.append(os.path.join(dirname, 'templatetags')) tmpl = loader.get_template('template.html') def render(): data = {'title': TITLE, 'user': USER, 'items': ITEMS} return tmpl.render(template.Context(data)) if verbose: print(render()) return render def kid(dirname, verbose=False): import kid kid.path = kid.TemplatePath([dirname]) template = kid.Template(file='template.kid') def render(): template = kid.Template(file='template.kid', title=TITLE, user=USER, items=ITEMS) return template.serialize(output='xhtml') if verbose: print(render()) return render def run(engines, number=2000, verbose=False): basepath = os.path.abspath(os.path.dirname(__file__)) for engine in engines: dirname = os.path.join(basepath, engine) if verbose: print('%s:' % engine.capitalize()) print('--------------------------------------------------------') else: sys.stdout.write('%s:' % engine.capitalize()) t = timeit.Timer(setup='from __main__ import %s; render = %s(r"%s", %s)' % (engine, engine, dirname, verbose), stmt='render()') time = t.timeit(number=number) / number if verbose: print('--------------------------------------------------------') print('%.2f ms' % (1000 * time)) if verbose: print('--------------------------------------------------------') if __name__ == '__main__': engines = [arg for arg in sys.argv[1:] if arg[0] != '-'] if not engines: engines = __all__ verbose = '-v' in sys.argv if '-p' in sys.argv: try: import hotshot, hotshot.stats prof = hotshot.Profile("template.prof") benchtime = prof.runcall(run, engines, number=100, verbose=verbose) stats = hotshot.stats.load("template.prof") except ImportError: import cProfile, pstats stmt = "run(%r, number=%r, verbose=%r)" % (engines, 1000, verbose) cProfile.runctx(stmt, globals(), {}, "template.prof") stats = pstats.Stats("template.prof") stats.strip_dirs() stats.sort_stats('time', 'calls') stats.print_stats() else: run(engines, verbose=verbose) Mako-0.9.1/examples/bench/cheetah/0000755000076500000240000000000012257137143017457 5ustar classicstaff00000000000000Mako-0.9.1/examples/bench/cheetah/footer.tmpl0000644000076500000240000000003112257136636021653 0ustar classicstaff00000000000000 Mako-0.9.1/examples/bench/cheetah/header.tmpl0000644000076500000240000000005512257136636021613 0ustar classicstaff00000000000000 Mako-0.9.1/examples/bench/cheetah/template.tmpl0000644000076500000240000000124612257136636022201 0ustar classicstaff00000000000000 ${title} #def greeting(name)

      hello ${name}!

      #end def #include "cheetah/header.tmpl" $greeting($user) $greeting('me') $greeting('world')

      Loop

      #if $list_items
        #for $list_item in $list_items
      • $list_item
      • #end for
      #end if #include "cheetah/footer.tmpl" Mako-0.9.1/examples/bench/django/0000755000076500000240000000000012257137143017320 5ustar classicstaff00000000000000Mako-0.9.1/examples/bench/django/templatetags/0000755000076500000240000000000012257137143022012 5ustar classicstaff00000000000000Mako-0.9.1/examples/bench/django/templatetags/__init__.py0000644000076500000240000000000012257136636024117 0ustar classicstaff00000000000000Mako-0.9.1/examples/bench/django/templatetags/bench.py0000644000076500000240000000033412257136636023451 0ustar classicstaff00000000000000from django.template import Library, Node, resolve_variable from django.utils.html import escape register = Library() def greeting(name): return 'Hello, %s!' % escape(name) greeting = register.simple_tag(greeting) Mako-0.9.1/examples/bench/kid/0000755000076500000240000000000012257137143016625 5ustar classicstaff00000000000000Mako-0.9.1/examples/bench/kid/base.kid0000644000076500000240000000052012257136636020233 0ustar classicstaff00000000000000

      Hello, ${name}!

      ${item}

      '\ .encode('ascii') not in markup assert '<span style="color:red"'\ '>Foobar</span>'\ .encode('ascii') in markup else: assert 'Foobar' \ not in markup assert '<span style="color:red"'\ '>Foobar</span>' in markup def test_unicode(self): self._do_memory_test( u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""), u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""") ) def test_encoding_doesnt_conflict(self): self._do_memory_test( u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""), u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""), output_encoding='utf-8' ) def test_unicode_arg(self): val = u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""") self._do_memory_test( "${val}", u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""), template_args={'val':val} ) def test_unicode_file(self): self._do_file_test( "unicode.html", u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""") ) def test_unicode_file_code(self): self._do_file_test( 'unicode_code.html', u("""hi, drôle de petite voix m’a réveillé."""), filters=flatten_result ) def test_unicode_file_lookup(self): lookup = TemplateLookup( directories=[template_base], output_encoding='utf-8', default_filters=['decode.utf8']) if compat.py3k: template = lookup.get_template('/chs_unicode_py3k.html') else: template = lookup.get_template('/chs_unicode.html') eq_( flatten_result(template.render_unicode(name='毛泽东')), u('毛泽东 是 新中国的主席
      Welcome 你 to 北京.') ) def test_unicode_bom(self): self._do_file_test( 'bom.html', u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""") ) self._do_file_test( 'bommagic.html', u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""") ) self.assertRaises( exceptions.CompileException, Template, filename=self._file_path('badbom.html'), module_directory=module_base ) def test_unicode_memory(self): val = u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""") self._do_memory_test( ("## -*- coding: utf-8 -*-\n" + val).encode('utf-8'), u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""") ) def test_unicode_text(self): val = u("""<%text>Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""") self._do_memory_test( ("## -*- coding: utf-8 -*-\n" + val).encode('utf-8'), u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""") ) def test_unicode_text_ccall(self): val = u(""" <%def name="foo()"> ${capture(caller.body)} <%call expr="foo()"> <%text>Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! » """) self._do_memory_test( ("## -*- coding: utf-8 -*-\n" + val).encode('utf-8'), u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""), filters=flatten_result ) def test_unicode_literal_in_expr(self): if compat.py3k: self._do_memory_test( u("""## -*- coding: utf-8 -*- ${"Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"} """).encode('utf-8'), u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""), filters = lambda s:s.strip() ) else: self._do_memory_test( u("""## -*- coding: utf-8 -*- ${u"Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"} """).encode('utf-8'), u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""), filters = lambda s:s.strip() ) def test_unicode_literal_in_expr_file(self): self._do_file_test( 'unicode_expr.html', u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""), lambda t:t.strip() ) def test_unicode_literal_in_code(self): if compat.py3k: self._do_memory_test( u("""## -*- coding: utf-8 -*- <% context.write("Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »") %> """).encode('utf-8'), u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""), filters=lambda s:s.strip() ) else: self._do_memory_test( u("""## -*- coding: utf-8 -*- <% context.write(u"Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »") %> """).encode('utf-8'), u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""), filters=lambda s:s.strip() ) def test_unicode_literal_in_controlline(self): if compat.py3k: self._do_memory_test( u("""## -*- coding: utf-8 -*- <% x = "drôle de petite voix m’a réveillé." %> % if x=="drôle de petite voix m’a réveillé.": hi, ${x} % endif """).encode('utf-8'), u("""hi, drôle de petite voix m’a réveillé."""), filters=lambda s:s.strip(), ) else: self._do_memory_test( u("""## -*- coding: utf-8 -*- <% x = u"drôle de petite voix m’a réveillé." %> % if x==u"drôle de petite voix m’a réveillé.": hi, ${x} % endif """).encode('utf-8'), u("""hi, drôle de petite voix m’a réveillé."""), filters=lambda s:s.strip(), ) def test_unicode_literal_in_tag(self): self._do_file_test( "unicode_arguments.html", [ u('x is: drôle de petite voix m’a réveillé'), u('x is: drôle de petite voix m’a réveillé'), u('x is: drôle de petite voix m’a réveillé'), u('x is: drôle de petite voix m’a réveillé'), ], filters=result_lines ) self._do_memory_test( util.read_file(self._file_path("unicode_arguments.html")), [ u('x is: drôle de petite voix m’a réveillé'), u('x is: drôle de petite voix m’a réveillé'), u('x is: drôle de petite voix m’a réveillé'), u('x is: drôle de petite voix m’a réveillé'), ], filters=result_lines ) def test_unicode_literal_in_def(self): if compat.py3k: self._do_memory_test( u("""## -*- coding: utf-8 -*- <%def name="bello(foo, bar)"> Foo: ${ foo } Bar: ${ bar } <%call expr="bello(foo='árvíztűrő tükörfúrógép', bar='ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP')"> """).encode('utf-8'), u("""Foo: árvíztűrő tükörfúrógép Bar: ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP"""), filters=flatten_result ) self._do_memory_test( u("""## -*- coding: utf-8 -*- <%def name="hello(foo='árvíztűrő tükörfúrógép', bar='ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP')"> Foo: ${ foo } Bar: ${ bar } ${ hello() }""").encode('utf-8'), u("""Foo: árvíztűrő tükörfúrógép Bar: ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP"""), filters=flatten_result ) else: self._do_memory_test( u("""## -*- coding: utf-8 -*- <%def name="bello(foo, bar)"> Foo: ${ foo } Bar: ${ bar } <%call expr="bello(foo=u'árvíztűrő tükörfúrógép', bar=u'ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP')"> """).encode('utf-8'), u("""Foo: árvíztűrő tükörfúrógép Bar: ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP"""), filters=flatten_result ) self._do_memory_test( u("""## -*- coding: utf-8 -*- <%def name="hello(foo=u'árvíztűrő tükörfúrógép', bar=u'ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP')"> Foo: ${ foo } Bar: ${ bar } ${ hello() }""").encode('utf-8'), u("""Foo: árvíztűrő tükörfúrógép Bar: ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP"""), filters=flatten_result ) def test_input_encoding(self): """test the 'input_encoding' flag on Template, and that unicode objects arent double-decoded""" if compat.py3k: self._do_memory_test( u("hello ${f('śląsk')}"), u("hello śląsk"), input_encoding='utf-8', template_args={'f': lambda x:x} ) self._do_memory_test( u("## -*- coding: utf-8 -*-\nhello ${f('śląsk')}"), u("hello śląsk"), template_args={'f': lambda x:x} ) else: self._do_memory_test( u("hello ${f(u'śląsk')}"), u("hello śląsk"), input_encoding='utf-8', template_args={'f': lambda x:x} ) self._do_memory_test( u("## -*- coding: utf-8 -*-\nhello ${f(u'śląsk')}"), u("hello śląsk"), template_args={'f': lambda x:x} ) def test_raw_strings(self): """test that raw strings go straight thru with default_filters turned off, bytestring_passthrough enabled. """ self._do_memory_test( u("## -*- coding: utf-8 -*-\nhello ${x}"), "hello śląsk", default_filters=[], template_args={'x':'śląsk'}, unicode_=False, bytestring_passthrough=True, output_encoding=None #'ascii' ) # now, the way you *should* be doing it.... self._do_memory_test( u("## -*- coding: utf-8 -*-\nhello ${x}"), u("hello śląsk"), template_args={'x':u('śląsk')} ) def test_encoding(self): self._do_memory_test( u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""), u("""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""").encode('utf-8'), output_encoding='utf-8', unicode_=False ) def test_encoding_errors(self): self._do_memory_test( u("""KGB (transliteration of "КГБ") is the Russian-language abbreviation for Committee for State Security, (Russian: Комит́ет Госуд́арственной Безоп́асности (help·info); Komitet Gosudarstvennoy Bezopasnosti)"""), u("""KGB (transliteration of "КГБ") is the Russian-language abbreviation for Committee for State Security, (Russian: Комит́ет Госуд́арственной Безоп́асности (help·info); Komitet Gosudarstvennoy Bezopasnosti)""").encode('iso-8859-1', 'replace'), output_encoding='iso-8859-1', encoding_errors='replace', unicode_=False ) def test_read_unicode(self): lookup = TemplateLookup(directories=[template_base], filesystem_checks=True, output_encoding='utf-8') if compat.py3k: template = lookup.get_template('/read_unicode_py3k.html') else: template = lookup.get_template('/read_unicode.html') # TODO: I've no idea what encoding this file is, Python 3.1.2 # won't read the file even with open(...encoding='utf-8') unless # errors is specified. or if there's some quirk in 3.1.2 # since I'm pretty sure this test worked with py3k when I wrote it. data = template.render(path=self._file_path('internationalization.html')) @requires_python_2 def test_bytestring_passthru(self): self._do_file_test( 'chs_utf8.html', '毛泽东 是 新中国的主席
      Welcome 你 to 北京. Welcome 你 to 北京.', default_filters=[], disable_unicode=True, output_encoding=None, template_args={'name':'毛泽东'}, filters=flatten_result, unicode_=False ) self._do_file_test( 'chs_utf8.html', '毛泽东 是 新中国的主席
      Welcome 你 to 北京. Welcome 你 to 北京.', disable_unicode=True, output_encoding=None, template_args={'name':'毛泽东'}, filters=flatten_result, unicode_=False ) template = self._file_template('chs_utf8.html', output_encoding=None, disable_unicode=True) self.assertRaises(UnicodeDecodeError, template.render_unicode, name='毛泽东') template = Template( "${'Alors vous imaginez ma surprise, au lever" " du jour, quand une drôle de petite voix m’a " "réveillé. Elle disait: « S’il vous plaît… " "dessine-moi un mouton! »'}", output_encoding=None, disable_unicode=True, input_encoding='utf-8') assert template.render() == "Alors vous imaginez ma surprise, "\ "au lever du jour, quand une drôle de petite "\ "voix m’a réveillé. Elle disait: « S’il vous "\ "plaît… dessine-moi un mouton! »" template = Template( "${'Alors vous imaginez ma surprise, au " "lever du jour, quand une drôle de petite " "voix m’a réveillé. Elle disait: « S’il " "vous plaît… dessine-moi un mouton! »'}", input_encoding='utf8', output_encoding='utf8', disable_unicode=False, default_filters=[]) # raises because expression contains an encoded bytestring which cannot be decoded self.assertRaises(UnicodeDecodeError, template.render) class PageArgsTest(TemplateTest): def test_basic(self): template = Template(""" <%page args="x, y, z=7"/> this is page, ${x}, ${y}, ${z} """) assert flatten_result(template.render(x=5, y=10)) == "this is page, 5, 10, 7" assert flatten_result(template.render(x=5, y=10, z=32)) == "this is page, 5, 10, 32" assert_raises(TypeError, template.render, y=10) def test_inherits(self): lookup = TemplateLookup() lookup.put_string("base.tmpl", """ <%page args="bar" /> ${bar} ${pageargs['foo']} ${self.body(**pageargs)} """ ) lookup.put_string("index.tmpl", """ <%inherit file="base.tmpl" /> <%page args="variable" /> ${variable} """) self._do_test( lookup.get_template("index.tmpl"), "bar foo var", filters=flatten_result, template_args={'variable':'var', 'bar':'bar', 'foo':'foo'} ) def test_includes(self): lookup = TemplateLookup() lookup.put_string("incl1.tmpl", """ <%page args="bar" /> ${bar} ${pageargs['foo']} """ ) lookup.put_string("incl2.tmpl", """ ${pageargs} """ ) lookup.put_string("index.tmpl", """ <%include file="incl1.tmpl" args="**pageargs"/> <%page args="variable" /> ${variable} <%include file="incl2.tmpl" /> """) self._do_test( lookup.get_template("index.tmpl"), "bar foo var {}", filters=flatten_result, template_args={'variable':'var', 'bar':'bar', 'foo':'foo'} ) def test_context_small(self): ctx = runtime.Context([].append, x=5, y=4) eq_(sorted(ctx.keys()), ['caller', 'capture', 'x', 'y']) def test_with_context(self): template = Template(""" <%page args="x, y, z=7"/> this is page, ${x}, ${y}, ${z}, ${w} """) #print template.code assert flatten_result(template.render(x=5, y=10, w=17)) == "this is page, 5, 10, 7, 17" def test_overrides_builtins(self): template = Template(""" <%page args="id"/> this is page, id is ${id} """) assert flatten_result(template.render(id="im the id")) == "this is page, id is im the id" def test_canuse_builtin_names(self): template = Template(""" exception: ${Exception} id: ${id} """) assert flatten_result(template.render(id='some id', Exception='some exception')) == "exception: some exception id: some id" def test_builtin_names_dont_clobber_defaults_in_includes(self): lookup = TemplateLookup() lookup.put_string("test.mako", """ <%include file="test1.mako"/> """) lookup.put_string("test1.mako", """ <%page args="id='foo'"/> ${id} """) for template in ("test.mako", "test1.mako"): assert flatten_result(lookup.get_template(template).render()) == "foo" assert flatten_result(lookup.get_template(template).render(id=5)) == "5" assert flatten_result(lookup.get_template(template).render(id=id)) == "" def test_dict_locals(self): template = Template(""" <% dict = "this is dict" locals = "this is locals" %> dict: ${dict} locals: ${locals} """) assert flatten_result(template.render()) == "dict: this is dict locals: this is locals" class IncludeTest(TemplateTest): def test_basic(self): lookup = TemplateLookup() lookup.put_string("a", """ this is a <%include file="b" args="a=3,b=4,c=5"/> """) lookup.put_string("b", """ <%page args="a,b,c"/> this is b. ${a}, ${b}, ${c} """) assert flatten_result(lookup.get_template("a").render()) == "this is a this is b. 3, 4, 5" def test_localargs(self): lookup = TemplateLookup() lookup.put_string("a", """ this is a <%include file="b" args="a=a,b=b,c=5"/> """) lookup.put_string("b", """ <%page args="a,b,c"/> this is b. ${a}, ${b}, ${c} """) assert flatten_result(lookup.get_template("a").render(a=7,b=8)) == "this is a this is b. 7, 8, 5" def test_viakwargs(self): lookup = TemplateLookup() lookup.put_string("a", """ this is a <%include file="b" args="c=5, **context.kwargs"/> """) lookup.put_string("b", """ <%page args="a,b,c"/> this is b. ${a}, ${b}, ${c} """) #print lookup.get_template("a").code assert flatten_result(lookup.get_template("a").render(a=7,b=8)) == "this is a this is b. 7, 8, 5" def test_include_withargs(self): lookup = TemplateLookup() lookup.put_string("a", """ this is a <%include file="${i}" args="c=5, **context.kwargs"/> """) lookup.put_string("b", """ <%page args="a,b,c"/> this is b. ${a}, ${b}, ${c} """) assert flatten_result(lookup.get_template("a").render(a=7,b=8,i='b')) == "this is a this is b. 7, 8, 5" def test_within_ccall(self): lookup = TemplateLookup() lookup.put_string("a", """this is a""") lookup.put_string("b", """ <%def name="bar()"> bar: ${caller.body()} <%include file="a"/> """) lookup.put_string("c", """ <%namespace name="b" file="b"/> <%b:bar> calling bar """) assert flatten_result(lookup.get_template("c").render()) == "bar: calling bar this is a" class UndefinedVarsTest(TemplateTest): def test_undefined(self): t = Template(""" % if x is UNDEFINED: undefined % else: x: ${x} % endif """) assert result_lines(t.render(x=12)) == ["x: 12"] assert result_lines(t.render(y=12)) == ["undefined"] def test_strict(self): t = Template(""" % if x is UNDEFINED: undefined % else: x: ${x} % endif """, strict_undefined=True) assert result_lines(t.render(x=12)) == ['x: 12'] assert_raises( NameError, t.render, y=12 ) l = TemplateLookup(strict_undefined=True) l.put_string("a", "some template") l.put_string("b", """ <%namespace name='a' file='a' import='*'/> % if x is UNDEFINED: undefined % else: x: ${x} % endif """) assert result_lines(t.render(x=12)) == ['x: 12'] assert_raises( NameError, t.render, y=12 ) def test_expression_declared(self): t = Template(""" ${",".join([t for t in ("a", "b", "c")])} """, strict_undefined=True) eq_(result_lines(t.render()), ['a,b,c']) t = Template(""" <%self:foo value="${[(val, n) for val, n in [(1, 2)]]}"/> <%def name="foo(value)"> ${value} """, strict_undefined=True) eq_(result_lines(t.render()), ['[(1, 2)]']) t = Template(""" <%call expr="foo(value=[(val, n) for val, n in [(1, 2)]])" /> <%def name="foo(value)"> ${value} """, strict_undefined=True) eq_(result_lines(t.render()), ['[(1, 2)]']) l = TemplateLookup(strict_undefined=True) l.put_string("i", "hi, ${pageargs['y']}") l.put_string("t", """ <%include file="i" args="y=[x for x in range(3)]" /> """) eq_( result_lines(l.get_template("t").render()), ['hi, [0, 1, 2]'] ) l.put_string('q', """ <%namespace name="i" file="${(str([x for x in range(3)][2]) + 'i')[-1]}" /> ${i.body(y='x')} """) eq_( result_lines(l.get_template("q").render()), ['hi, x'] ) t = Template(""" <% y = lambda q: str(q) %> ${y('hi')} """, strict_undefined=True) eq_( result_lines(t.render()), ["hi"] ) def test_list_comprehensions_plus_undeclared_nonstrict(self): # traditional behavior. variable inside a list comprehension # is treated as an "undefined", so is pulled from the context. t = Template(""" t is: ${t} ${",".join([t for t in ("a", "b", "c")])} """) eq_( result_lines(t.render(t="T")), ['t is: T', 'a,b,c'] ) def test_traditional_assignment_plus_undeclared(self): t = Template(""" t is: ${t} <% t = 12 %> """) assert_raises( UnboundLocalError, t.render, t="T" ) def test_list_comprehensions_plus_undeclared_strict(self): # with strict, a list comprehension now behaves # like the undeclared case above. t = Template(""" t is: ${t} ${",".join([t for t in ("a", "b", "c")])} """, strict_undefined=True) eq_( result_lines(t.render(t="T")), ['t is: T', 'a,b,c'] ) class ReservedNameTest(TemplateTest): def test_names_on_context(self): for name in ('context', 'loop', 'UNDEFINED'): assert_raises_message( exceptions.NameConflictError, r"Reserved words passed to render\(\): %s" % name, Template("x").render, **{name:'foo'} ) def test_names_in_template(self): for name in ('context', 'loop', 'UNDEFINED'): assert_raises_message( exceptions.NameConflictError, r"Reserved words declared in template: %s" % name, Template, "<%% %s = 5 %%>" % name ) def test_exclude_loop_context(self): self._do_memory_test( "loop is ${loop}", "loop is 5", template_args=dict(loop=5), enable_loop=False ) def test_exclude_loop_template(self): self._do_memory_test( "<% loop = 12 %>loop is ${loop}", "loop is 12", enable_loop=False ) class ControlTest(TemplateTest): def test_control(self): t = Template(""" ## this is a template. % for x in y: % if 'test' in x: yes x has test % else: no x does not have test %endif %endfor """) assert result_lines(t.render(y=[{'test':'one'}, {'foo':'bar'}, {'foo':'bar', 'test':'two'}])) == [ "yes x has test", "no x does not have test", "yes x has test" ] def test_blank_control_1(self): self._do_memory_test( """ % if True: % endif """, "", filters=lambda s:s.strip() ) def test_blank_control_2(self): self._do_memory_test( """ % if True: % elif True: % endif """, "", filters=lambda s:s.strip() ) def test_blank_control_3(self): self._do_memory_test( """ % if True: % else: % endif """, "", filters=lambda s:s.strip() ) def test_blank_control_4(self): self._do_memory_test( """ % if True: % elif True: % else: % endif """, "", filters=lambda s:s.strip() ) def test_blank_control_5(self): self._do_memory_test( """ % for x in range(10): % endfor """, "", filters=lambda s:s.strip() ) def test_blank_control_6(self): self._do_memory_test( """ % while False: % endwhile """, "", filters=lambda s:s.strip() ) def test_blank_control_7(self): self._do_memory_test( """ % try: % except: % endtry """, "", filters=lambda s:s.strip() ) @requires_python_26_or_greater def test_blank_control_8(self): self._do_memory_test( """ % with ctx('x', 'w') as fp: % endwith """, "", filters=lambda s: s.strip(), template_args={"ctx": ctx} ) def test_commented_blank_control_1(self): self._do_memory_test( """ % if True: ## comment % endif """, "", filters=lambda s:s.strip() ) def test_commented_blank_control_2(self): self._do_memory_test( """ % if True: ## comment % elif True: ## comment % endif """, "", filters=lambda s:s.strip() ) def test_commented_blank_control_3(self): self._do_memory_test( """ % if True: ## comment % else: ## comment % endif """, "", filters=lambda s:s.strip() ) def test_commented_blank_control_4(self): self._do_memory_test( """ % if True: ## comment % elif True: ## comment % else: ## comment % endif """, "", filters=lambda s:s.strip() ) def test_commented_blank_control_5(self): self._do_memory_test( """ % for x in range(10): ## comment % endfor """, "", filters=lambda s:s.strip() ) def test_commented_blank_control_6(self): self._do_memory_test( """ % while False: ## comment % endwhile """, "", filters=lambda s:s.strip() ) def test_commented_blank_control_7(self): self._do_memory_test( """ % try: ## comment % except: ## comment % endtry """, "", filters=lambda s:s.strip() ) @requires_python_26_or_greater def test_commented_blank_control_8(self): self._do_memory_test( """ % with ctx('x', 'w') as fp: ## comment % endwith """, "", filters=lambda s: s.strip(), template_args={"ctx": ctx} ) def test_multiline_control(self): t = Template(""" % for x in \\ [y for y in [1,2,3]]: ${x} % endfor """) #print t.code assert flatten_result(t.render()) == "1 2 3" class GlobalsTest(TemplateTest): def test_globals(self): self._do_memory_test( """ <%! y = "hi" %> y is ${y} """, "y is hi", filters=lambda t:t.strip() ) class RichTracebackTest(TemplateTest): def _do_test_traceback(self, utf8, memory, syntax): if memory: if syntax: source = u('## coding: utf-8\n<% print "m’a réveillé. '\ 'Elle disait: « S’il vous plaît… dessine-moi un mouton! » %>') else: source = u('## coding: utf-8\n<% print u"m’a réveillé. '\ 'Elle disait: « S’il vous plaît… dessine-moi un mouton! »" + str(5/0) %>') if utf8: source = source.encode('utf-8') else: source = source templateargs = {'text': source} else: if syntax: filename = 'unicode_syntax_error.html' else: filename = 'unicode_runtime_error.html' source = util.read_file(self._file_path(filename), 'rb') if not utf8: source = source.decode('utf-8') templateargs = {'filename': self._file_path(filename)} try: template = Template(**templateargs) if not syntax: template.render_unicode() assert False except Exception: tback = exceptions.RichTraceback() if utf8: assert tback.source == source.decode('utf-8') else: assert tback.source == source for utf8 in (True, False): for memory in (True, False): for syntax in (True, False): def _do_test(self): self._do_test_traceback(utf8, memory, syntax) name = 'test_%s_%s_%s' % (utf8 and 'utf8' or 'unicode', memory and 'memory' or 'file', syntax and 'syntax' or 'runtime') _do_test.__name__ = name setattr(RichTracebackTest, name, _do_test) del _do_test class ModuleDirTest(TemplateTest): def tearDown(self): import shutil shutil.rmtree(module_base, True) def test_basic(self): t = self._file_template("modtest.html") t2 = self._file_template('subdir/modtest.html') eq_( t.module.__file__, os.path.join(module_base, 'modtest.html.py') ) eq_( t2.module.__file__, os.path.join(module_base, 'subdir', 'modtest.html.py') ) def test_callable(self): def get_modname(filename, uri): return os.path.join( module_base, os.path.dirname(uri)[1:], 'foo', os.path.basename(filename) + ".py") lookup = TemplateLookup(template_base, modulename_callable=get_modname) t = lookup.get_template('/modtest.html') t2 = lookup.get_template('/subdir/modtest.html') eq_( t.module.__file__, os.path.join(module_base, 'foo', 'modtest.html.py') ) eq_( t2.module.__file__, os.path.join(module_base, 'subdir', 'foo', 'modtest.html.py') ) def test_custom_writer(self): canary = [] def write_module(source, outputpath): f = open(outputpath, 'wb') canary.append(outputpath) f.write(source) f.close() lookup = TemplateLookup(template_base, module_writer=write_module, module_directory=module_base) t = lookup.get_template('/modtest.html') t2 = lookup.get_template('/subdir/modtest.html') eq_( canary, [os.path.join(module_base, "modtest.html.py"), os.path.join(module_base, "subdir/modtest.html.py")] ) class FilenameToURITest(TemplateTest): def test_windows_paths(self): """test that windows filenames are handled appropriately by Template.""" current_path = os.path import ntpath os.path = ntpath try: class NoCompileTemplate(Template): def _compile_from_file(self, path, filename): self.path = path return Template("foo bar").module t1 = NoCompileTemplate( filename="c:\\foo\\template.html", module_directory="c:\\modules\\") eq_(t1.uri, "/foo/template.html") eq_(t1.path, "c:\\modules\\foo\\template.html.py") t1 = NoCompileTemplate( filename="c:\\path\\to\\templates\\template.html", uri = "/bar/template.html", module_directory="c:\\modules\\") eq_(t1.uri, "/bar/template.html") eq_(t1.path, "c:\\modules\\bar\\template.html.py") finally: os.path = current_path def test_posix_paths(self): """test that posixs filenames are handled appropriately by Template.""" current_path = os.path import posixpath os.path = posixpath try: class NoCompileTemplate(Template): def _compile_from_file(self, path, filename): self.path = path return Template("foo bar").module t1 = NoCompileTemplate( filename="/var/www/htdocs/includes/template.html", module_directory="/var/lib/modules") eq_(t1.uri, "/var/www/htdocs/includes/template.html") eq_(t1.path, "/var/lib/modules/var/www/htdocs/includes/template.html.py") t1 = NoCompileTemplate( filename="/var/www/htdocs/includes/template.html", uri = "/bar/template.html", module_directory="/var/lib/modules") eq_(t1.uri, "/bar/template.html") eq_(t1.path, "/var/lib/modules/bar/template.html.py") finally: os.path = current_path def test_dont_accept_relative_outside_of_root(self): assert_raises_message( exceptions.TemplateLookupException, "Template uri \"../../foo.html\" is invalid - it " "cannot be relative outside of the root path", Template, "test", uri="../../foo.html", ) assert_raises_message( exceptions.TemplateLookupException, "Template uri \"/../../foo.html\" is invalid - it " "cannot be relative outside of the root path", Template, "test", uri="/../../foo.html", ) # normalizes in the root is OK t = Template("test", uri="foo/bar/../../foo.html") eq_(t.uri, "foo/bar/../../foo.html") class ModuleTemplateTest(TemplateTest): def test_module_roundtrip(self): lookup = TemplateLookup() template = Template(""" <%inherit file="base.html"/> % for x in range(5): ${x} % endfor """, lookup=lookup) base = Template(""" This is base. ${self.body()} """, lookup=lookup) lookup.put_template("base.html", base) lookup.put_template("template.html", template) assert result_lines(template.render()) == [ "This is base.", "0", "1", "2", "3", "4" ] lookup = TemplateLookup() template = ModuleTemplate(template.module, lookup=lookup) base = ModuleTemplate(base.module, lookup=lookup) lookup.put_template("base.html", base) lookup.put_template("template.html", template) assert result_lines(template.render()) == [ "This is base.", "0", "1", "2", "3", "4" ] class PreprocessTest(TemplateTest): def test_old_comments(self): t = Template(""" im a template # old style comment # more old style comment ## new style comment - # not a comment - ## not a comment """, preprocessor=convert_comments) assert flatten_result(t.render()) == "im a template - # not a comment - ## not a comment" class LexerTest(TemplateTest): def _fixture(self): from mako.parsetree import TemplateNode, Text class MyLexer(object): encoding = 'ascii' def __init__(self, *arg, **kw): pass def parse(self): t = TemplateNode("foo") t.nodes.append( Text("hello world", source="foo", lineno=0, pos=0, filename=None) ) return t return MyLexer def _test_custom_lexer(self, template): eq_( result_lines(template.render()), ["hello world"] ) def test_via_template(self): t = Template("foo", lexer_cls=self._fixture()) self._test_custom_lexer(t) def test_via_lookup(self): tl = TemplateLookup(lexer_cls=self._fixture()) tl.put_string("foo", "foo") t = tl.get_template("foo") self._test_custom_lexer(t) class FuturesTest(TemplateTest): def test_future_import(self): t = Template("${ x / y }", future_imports=["division"]) assert result_lines(t.render(x=12, y=5)) == ["2.4"] Mako-0.9.1/test/test_tgplugin.py0000644000076500000240000000274512257136636017420 0ustar classicstaff00000000000000from mako.ext.turbogears import TGPlugin from test.util import result_lines from test import TemplateTest, template_base from mako import compat tl = TGPlugin(options=dict(directories=[template_base]), extension='html') class TestTGPlugin(TemplateTest): def test_basic(self): t = tl.load_template('/index.html') assert result_lines(t.render()) == [ "this is index" ] def test_subdir(self): t = tl.load_template('/subdir/index.html') assert result_lines(t.render()) == [ "this is sub index", "this is include 2" ] assert tl.load_template('/subdir/index.html').module_id == '_subdir_index_html' def test_basic_dot(self): t = tl.load_template('index') assert result_lines(t.render()) == [ "this is index" ] def test_subdir_dot(self): t = tl.load_template('subdir.index') assert result_lines(t.render()) == [ "this is sub index", "this is include 2" ] assert tl.load_template('subdir.index').module_id == '_subdir_index_html' def test_string(self): t = tl.load_template('foo', "hello world") assert t.render() == "hello world" def test_render(self): assert result_lines(tl.render({}, template='/index.html')) == [ "this is index" ] assert result_lines(tl.render({}, template=compat.u('/index.html'))) == [ "this is index" ] Mako-0.9.1/test/test_util.py0000644000076500000240000000323112257136636016533 0ustar classicstaff00000000000000# -*- coding: utf-8 -*- import os import unittest from mako import util, exceptions, compat from test import eq_, skip_if, assert_raises_message from mako.compat import u class UtilTest(unittest.TestCase): def test_fast_buffer_write(self): buf = util.FastEncodingBuffer() buf.write("string a ") buf.write("string b") eq_(buf.getvalue(), "string a string b") def test_fast_buffer_truncate(self): buf = util.FastEncodingBuffer() buf.write("string a ") buf.write("string b") buf.truncate() buf.write("string c ") buf.write("string d") eq_(buf.getvalue(), "string c string d") def test_fast_buffer_encoded(self): s = u("drôl m’a rée « S’il") buf = util.FastEncodingBuffer(encoding='utf-8') buf.write(s[0:10]) buf.write(s[10:]) q = buf.getvalue() eq_(buf.getvalue(), s.encode('utf-8')) def test_read_file(self): fn = os.path.join(os.path.dirname(__file__), 'test_util.py') data = util.read_file(fn, 'rb') assert 'test_util' in str(data) # str() for py3k @skip_if(lambda: compat.pypy, "Pypy does this differently") def test_load_module(self): fn = os.path.join(os.path.dirname(__file__), 'test_util.py') module = compat.load_module('mako.template', fn) import mako.template self.assertEqual(module, mako.template) def test_load_plugin_failure(self): loader = util.PluginLoader("fakegroup") assert_raises_message( exceptions.RuntimeException, "Can't load plugin fakegroup fake", loader.load, "fake" ) Mako-0.9.1/test/util.py0000644000076500000240000000033012257136636015471 0ustar classicstaff00000000000000import re def flatten_result(result): return re.sub(r'[\s\r\n]+', ' ', result).strip() def result_lines(result): return [x.strip() for x in re.split(r'\r?\n', re.sub(r' +', ' ', result)) if x.strip() != '']