wheezy.html / src / wheezy / html / ext / tenjin.py

""" ``tenjin`` extension module.
"""

import re

from wheezy.html.ext.lexer import InlinePreprocessor
from wheezy.html.ext.lexer import Preprocessor
from wheezy.html.ext.lexer import WhitespacePreprocessor


class TenjinPreprocessor(Preprocessor):

    def __init__(self):
        super(TenjinPreprocessor, self).__init__(
            r'(?P<expr_filter>[#\$])\{((?P<expr>.+?)\.'
            r'(?P<widget>%(widgets)s){1}'
            r'\((?P<params>.*?)\)\s*)\}')

    EXPRESSION = '%(expr_filter)s{%(expr)s}'

    ERROR_CLASS0 = """\
<?py #pass ?>
<?py if '%(name)s' in errors: ?>
 class="error"<?py #pass ?>
<?py #endif ?>"""

    ERROR_CLASS1 = """\
<?py #pass ?>
<?py if '%(name)s' in errors: ?>
 class="error %(class)s"<?py #pass ?>
<?py else: ?>
 class="%(class)s"<?py #pass ?>
<?py #endif ?>"""

    MULTIPLE_HIDDEN = """\
<?py #pass ?>
<?py for item in %(value)s: ?>
<input type="hidden" name="%(name)s" value="%(expr_filter)s{item}" />\
<?py #pass ?>
<?py #endfor ?>"""

    INPUT = """\
<input id="%(id)s" name="%(name)s" type="%(type)s"%(attrs)s%(class)s\
<?py if %(value)s%(condition)s: ?>
 value="${%(func)s}" /><?py #pass ?>
<?py else: ?>
 /><?py #pass ?>
<?py #endif ?>"""

    CHECKBOX = """\
<input id="%(id)s" name="%(name)s" type="checkbox" \
value="1"%(attrs)s%(class)s\
<?py if %(value)s: ?>
 checked="checked"<?py #pass ?>
<?py #endif ?>
 />"""

    MULTIPLE_CHECKBOX = """\
<?py #pass ?>
<?py for key, text in %(choices)s: ?>
<label%(attrs)s%(class)s><input id="%(id)s" name="%(name)s" type="checkbox" \
value="1"%(attrs)s%(class)s<?py #pass ?>
<?py if key in %(value)s: ?>
 checked="checked"<?py #pass ?>
<?py #endif ?>
 />%(expr_filter)s{text}</label><?py #pass ?>
<?py #endfor ?>"""

    RADIO = """\
<?py #pass ?>
<?py for key, text in %(choices)s: ?>
<label%(attrs)s%(class)s>\
<input type="radio" name="%(name)s"%(attrs)s \
value="%(expr_filter)s{key}"%(class)s
<?py if key == %(value)s: ?>
 checked="checked"<?py #pass ?>
<?py #endif ?>
 />%(expr_filter)s{text}</label><?py #pass ?>
<?py #endfor ?>"""

    SELECT = """\
<?py #pass ?>
<select id="%(id)s" name="%(name)s"%(select_type)s%(attrs)s%(class)s>\
<?py #pass ?>
<?py for key, text in %(choices)s: ?>
<option value="%(expr_filter)s{key}"<?py #pass ?>
<?py if key == %(value)s: ?>
 selected="selected"<?py #pass ?>
<?py #endif ?>
>%(expr_filter)s{text}</option><?py #pass ?>
<?py #endfor ?>\
</select>"""

    ERROR = """\
<?py #pass ?>
<?py if '%(name)s' in errors: ?>
<span%(attrs)s>%(expr_filter)s{errors['%(name)s'][-1]}</span>\
<?py #pass ?>
<?py #endif ?>"""

    MESSAGE = """\
<?py #pass ?>
<?py if %(value)s: ?>
<span%(attrs)s>%(info)s</span><?py #pass ?>
<?py #endif ?>"""


widget_preprocessor = TenjinPreprocessor()
whitespace_preprocessor = WhitespacePreprocessor(rules=[
    (re.compile(r'^ \s+|\s+$', re.MULTILINE),
     r''),
    (re.compile(r'(?<!\?)>\s+<(?!\?)'),
     r'><'),
])


RE_INLINE = re.compile(r'<\?py\s+inline\(("|\')(?P<path>.+?)\1\)\s*\?>',
                       re.MULTILINE)


def inline_preprocessor(directories, fallback=False):
    """ Inline preprocessor. Rewrite <?py inline("...") ?> tag with
        file content. If fallback is ``True`` rewrite to
        <?py include("...") ?> tag.

        >>> t = '1 <?py inline("master.html") ?> 2'
        >>> m = RE_INLINE.search(t)
        >>> m.group('path')
        'master.html'
        >>> t[:m.start()], t[m.end():]
        ('1 ', ' 2')
        >>> m = RE_INLINE.search(' <?py inline("shared/footer.html") ?>')
        >>> m.group('path')
        'shared/footer.html'
    """
    strategy = fallback and (
        lambda path: '<?py include("' + path + '") ?>') or None
    return InlinePreprocessor(RE_INLINE, directories, strategy)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.