Cheetah Template Engine

repository·master·Indexed 40 days ago

https://github.com/cheetahtemplate/cheetah

A flexible, open-source template engine and code generation tool used for web development and generating source code in languages such as C++, Java, and Python. It features a Python-based Template class, late binding via NameMapper, and CLI tools like cheetah-compile and cheetah-analyze for compiling and analyzing templates.

Tokens
34.3K
Snippets
124
Records
170
Agent score
100%

What's inside Cheetah

  1. Introduction to Cheetah Template Engine

    master

    Cheetah is an open-source template engine and code-generation tool written in Python. It functions as a domain-specific language for markup generation and templating.

    Key characteristics include:

    • Python Integration: Provides full integration with existing Python code, allowing templates to access any Python data structure, module, function, object, or method.
    • Compilation: Cheetah compiles templates into optimized, readable Python code.
    • Versatility: Can generate any text-based format and is supported by major Python web frameworks.
    • Object-Oriented: Templates support inheritance (subclassing) and can be used as subclasses of Python classes or vice-versa.
    • Performance: Includes a caching mechanism to improve performance for dynamic websites.
    • CLI Support: Can be used via command-line tools to generate static HTML.
  2. Overview of Cheetah Template Engine

    master
    Cheetah is an open source template engine and code generation tool designed for flexibility. While primarily used for web development, it is capable of generating various formats including C++, Java, SQL, form emails, and Python code. It can be used as a standalone tool or integrated into existing frameworks.
  3. What is Cheetah and its core features

    master

    Cheetah is a Python-powered template engine and code generator designed to complement Python. It can generate various text-based formats including HTML, SGML, XML, SQL, Postscript, form email, and LaTeX, and can even be used to produce source code for Python, Java, and PHP.

    Key Features:

    • Full Python Access: Template writers have full access to any Python data structure, module, function, object, or method.
    • Object-Oriented Templates: Compiled templates are Python classes. This allows templates to subclass other templates or pure Python classes, enabling easy code reuse.
    • Separation of Concerns: Designed to cleanly separate content, graphic design, and program code.
    • Caching: Includes a simple yet powerful caching mechanism.
  4. Organize code changes in Cheetah

    master

    When contributing to or modifying the Cheetah codebase, follow these architectural guidelines for where to place new code:

    • Template class: Use this for core infrastructure and convenience methods that are useful across all templates (especially HTML-output templates).
    • Cheetah.Utils: Use this for mixin classes or objects required by any part of Cheetah's core. If a method is too long for the Template class, move it to a mixin in Cheetah.Utils and inherit it.
    • Cheetah.Tools: Use this for completely optional routines or problem-specific domains. This ensures that Cheetah.Tools can be deleted without breaking core services.

    Important Integration Rule: If a core method needs to access an attribute defined in Cheetah.Tools, it must use hasattr() and provide a default value to handle cases where the user has not imported that subsystem.

  5. Use single-line and multi-line comments in Cheetah templates

    master

    Comments in Cheetah are used for notes, explanations, or decorative text that should not appear in the final output. Cheetah preserves these comments in the generated Python module.

    Single-line comments

    Use two hash characters ({##}) at the start of a line or after code to comment out the rest of the line. To use literal hash characters in a comment, escape them with a backslash.

    Multi-line comments

    Use {#* to start a multi-line comment block and *# to end it.

    Handling blank lines

    Blank lines in a template are output as-is. To prevent blank lines between method definitions or loops from appearing in the output, enclose the blank lines within a comment block.

    ##=============================  this is a decorative comment-bar
    $var    ## this is an end-of-line comment
    ##=============================
    
    #* 
       This is a 
       multi-line comment 
    *#
  6. How the Containment approach works in Webware

    master

    In the Containment approach, your servlet is a standard Python class (not a template) that manages template objects internally.

    Key implementation details:

    • Manual invocation: The servlet must explicitly call the template object's .respond() or .__str__() method to generate output.
    • Sending output: The servlet is responsible for sending the generated string to the user using self.response().write().
    • Thread Safety: Template objects are NOT thread-safe. You should instantiate a new template object within each servlet request. However, template classes are thread-safe and can be stored in module-level global variables.
    • Template sourcing: You can load templates from strings, files, or databases using Cheetah.Template.Template, or compile .tmpl files into .py modules using cheetah compile and then import them.
    # Conceptual example of Containment approach
    import my_compiled_template
    
    class MyServlet(WebKit.HTTPServlet):
        def respond(self):
            # Instantiate template object per request for thread safety
            tmpl_obj = my_compiled_template.Template()
            output = tmpl_obj.respond()
            self.response().write(output)
  7. Define the main method name with #implements

    master

    By default, the top-level content of a template (text/placeholders outside any #def or #block) is wrapped in a method named .respond(). Use #implements METHOD to change this name to something else (e.g., .send_output()).

    Important Behavior with Inheritance: When you use #extends, Cheetah automatically renames the template's main method to .writeBody() to prevent it from overriding the base template's .respond() method.

    Troubleshooting: If you use #extends and your template produces no output, it is likely because the method you intended to call was renamed. You may need to add #implements respond to your template to restore the default method name.

    #implements send_output
  8. How Cheetah templates inherit from Python classes

    master

    By default, every Cheetah template is compiled into a Python class that subclasses Cheetah.Template.Template. You can customize this behavior by defining a custom base class in a Python module and using the #extends directive in your Cheetah template to inherit from it instead of the default.

    # In a Python module (e.g., cookbook.py)
    import Cheetah.Template
    
    class CookbookTemplate(Cheetah.Template.Template):
        _page = 'Cookbook'
        author = 'R. Tyler Ballance'
        def pageName(self):
            return self._page or 'Unknown'
    # In a Cheetah template (e.g., recipe1.tmpl)
    #import cookbook
    #extends cookbook.CookbookTemplate
    #attr author = 'Tavis Rudd'
    
    ## Template content goes here
  9. How the Inheritance approach works in Webware

    master

    In the Inheritance approach, your template object is the servlet (often called a template-servlet). This is the recommended approach for new sites due to its simplicity and scalability.

    Key implementation details:

    • Servlet structure: A servlet is a subclass of WebKit.HTTPServlet contained in a module with the same name as the servlet. cheetah compile automatically generates these valid Webware servlets.
    • Method requirements: The servlet must implement a .respond() method (or specific HTTP method handlers like .respondToGet(), .respondToPut(), etc.).
    • Separating logic from presentation: To keep algorithmic logic separate from display logic, your template class can inherit from a pure Python class. You can achieve this using the #extends directive in the .tmpl file or via a standard Python class statement.
    • Testing: If WebKit.HTTPServlet is unavailable, Cheetah uses a dummy class to allow command-line testing. Note that accessing web-specific data like form input will fail in this mode because the request object is None.
    # Conceptual template-servlet using #extends
    #extends MyLogicClass
    
    <html>
    <body>
        <h1>Hello, $name!</h1>
    </body>
    </html>
  10. Understand the Cheetah development workflow

    master

    Cheetah development primarily uses two branches to manage releases and upcoming features:

    • next: The branch where development for the upcoming Cheetah release takes place.
    • maint: The branch used for backporting fixes and patches to the current release. It is common to apply a single patch to both maint and next simultaneously.

    Before a release is finalized, all tests must pass on the next branch before it is merged into the master branch to create the release tarball.

  11. Use Autocalling to simplify method calls

    master

    Cheetah automatically detects and calls functions or methods in $variables if the parentheses () are omitted. This is known as Autocalling.

    Rules for Autocalling:

    • Arguments: Autocalling only works for functions/methods with no arguments (or those with default values for all arguments). If arguments are required, you must use ().
    • Targets: Only functions and methods are autocalled. Classes and other callable objects are not autocalled to prevent accidental memory allocation or side effects.
    • Disabling: You can disable this via the useAutocalling compiler setting, or for a specific placeholder using $getVar('varName', 'default value', False). (Note: .getVar() only works with searchList values).

    Example: If b is a method of object a:

    $a.b    # Equivalent to $a.b()

    If b() returns a dictionary with key 'c':

    $a.b.c   # Autocalls b() and accesses key 'c'
    $a.b().c # Explicit call
    $a.b()['c']
    $a.b
  12. Understand how Cheetah generates code from placeholders

    master

    When a Cheetah template is compiled into a Python module, placeholders are translated into specific code patterns within the respond method:

    1. Regular Text: Translated into direct write('literal text') calls.
    2. Standard Placeholders: Translated into nested function calls that look up the value in the search list (SL) and apply a filter. The pattern is: write(filter(VFS(SL, "name", 1))).
      • VFS (from Cheetah.NameMapper) performs the lookup in the search list.
      • 1 indicates autocalling.
      • filter applies the current output filter (e.g., converting to string).
    3. Built-in Placeholders: Placeholders referring to Python built-ins (e.g., $xrange) generate a bare variable name wrapped in the filter: write(filter(xrange)).
    # Example of what the generated code looks like for: 'Hello, $what'
    # (Simplified representation)
    
    write('Hello, ')
    write(filter(VFS(SL, "what", 1)))