Ejemplo n.º 1
0
def render(content="hello world",
           stream=None,
           filename=None,
           path=None,
           context={},
           lexers={},
           delimiters=('{{', '}}'),
           writer='response.write'):
    """
    Generic render function

    Args:
        content: default content
        stream: file-like obj to read template from
        filename: where to find template
        path: base path for templates
        context: env
        lexers: custom lexers to use
        delimiters: opening and closing tags
        writer: where to inject the resulting stream

    Example::
        >>> render()
        'hello world'
        >>> render(content='abc')
        'abc'
        >>> render(content="abc'")
        "abc'"
        >>> render(content=''''a"'bc''')
        'a"'bc'
        >>> render(content='a\\nbc')
        'a\\nbc'
        >>> render(content='a"bcd"e')
        'a"bcd"e'
        >>> render(content="'''a\\nc'''")
        "'''a\\nc'''"
        >>> render(content="'''a\\'c'''")
        "'''a\'c'''"
        >>> render(content='{{for i in range(a):}}{{=i}}<br />{{pass}}', context=dict(a=5))
        '0<br />1<br />2<br />3<br />4<br />'
        >>> render(content='{%for i in range(a):%}{%=i%}<br />{%pass%}', context=dict(a=5),delimiters=('{%','%}'))
        '0<br />1<br />2<br />3<br />4<br />'
        >>> render(content="{{='''hello\\nworld'''}}")
        'hello\\nworld'
        >>> render(content='{{for i in range(3):\\n=i\\npass}}')
        '012'

    """
    # here to avoid circular Imports
    try:
        from gluon.globals import Response
    except ImportError:
        # Working standalone. Build a mock Response object.
        Response = DummyResponse

        # Add it to the context so we can use it.
        if not 'NOESCAPE' in context:
            context['NOESCAPE'] = NOESCAPE

    if isinstance(content, unicodeT):
        content = content.encode('utf8')

    # save current response class
    if context and 'response' in context:
        old_response_body = context['response'].body
        context['response'].body = StringIO()
    else:
        old_response_body = None
        context['response'] = Response()

    # If we don't have anything to render, why bother?
    if not content and not stream and not filename:
        raise SyntaxError("Must specify a stream or filename or content")

    # Here for legacy purposes, probably can be reduced to
    # something more simple.
    close_stream = False
    if not stream:
        if filename:
            stream = open(filename, 'rb')
            close_stream = True
        elif content:
            stream = StringIO(to_native(content))

    # Execute the template.
    code = str(
        TemplateParser(stream.read(),
                       context=context,
                       path=path,
                       lexers=lexers,
                       delimiters=delimiters,
                       writer=writer))

    try:
        exec(code, context)
    except Exception:
        # for i,line in enumerate(code.split('\n')): print i,line
        raise

    if close_stream:
        stream.close()

    # Returned the rendered content.
    text = context['response'].body.getvalue()
    if old_response_body is not None:
        context['response'].body = old_response_body
    return text
Ejemplo n.º 2
0
def render(content="hello world",
           stream=None,
           filename=None,
           path=None,
           context={},
           lexers={},
           delimiters=('{{', '}}'),
           writer='response.write'
           ):
    """
    Generic render function

    Args:
        content: default content
        stream: file-like obj to read template from
        filename: where to find template
        path: base path for templates
        context: env
        lexers: custom lexers to use
        delimiters: opening and closing tags
        writer: where to inject the resulting stream

    Example::
        >>> render()
        'hello world'
        >>> render(content='abc')
        'abc'
        >>> render(content="abc'")
        "abc'"
        >>> render(content=''''a"'bc''')
        'a"'bc'
        >>> render(content='a\\nbc')
        'a\\nbc'
        >>> render(content='a"bcd"e')
        'a"bcd"e'
        >>> render(content="'''a\\nc'''")
        "'''a\\nc'''"
        >>> render(content="'''a\\'c'''")
        "'''a\'c'''"
        >>> render(content='{{for i in range(a):}}{{=i}}<br />{{pass}}', context=dict(a=5))
        '0<br />1<br />2<br />3<br />4<br />'
        >>> render(content='{%for i in range(a):%}{%=i%}<br />{%pass%}', context=dict(a=5),delimiters=('{%','%}'))
        '0<br />1<br />2<br />3<br />4<br />'
        >>> render(content="{{='''hello\\nworld'''}}")
        'hello\\nworld'
        >>> render(content='{{for i in range(3):\\n=i\\npass}}')
        '012'

    """
    # here to avoid circular Imports
    try:
        from gluon.globals import Response
    except ImportError:
        # Working standalone. Build a mock Response object.
        Response = DummyResponse

        # Add it to the context so we can use it.
        if 'NOESCAPE' not in context:
            context['NOESCAPE'] = NOESCAPE

    if isinstance(content, unicodeT):
        content = content.encode('utf8')

    # save current response class
    if context and 'response' in context:
        old_response_body = context['response'].body
        context['response'].body = StringIO()
    else:
        old_response_body = None
        context['response'] = Response()

    # If we don't have anything to render, why bother?
    if not content and not stream and not filename:
        raise SyntaxError("Must specify a stream or filename or content")

    # Here for legacy purposes, probably can be reduced to
    # something more simple.
    close_stream = False
    if not stream:
        if filename:
            stream = open(filename, 'rb')
            close_stream = True
        elif content:
            stream = StringIO(to_native(content))

    # Execute the template.
    code = str(TemplateParser(stream.read(
    ), context=context, path=path, lexers=lexers, delimiters=delimiters, writer=writer))

    try:
        exec(code, context)
    except Exception:
        # for i,line in enumerate(code.split('\n')): print i,line
        raise

    if close_stream:
        stream.close()

    # Returned the rendered content.
    text = context['response'].body.getvalue()
    if old_response_body is not None:
        context['response'].body = old_response_body
    return text
Ejemplo n.º 3
0
def render(content=None,
           stream=None,
           filename=None,
           path=None,
           context=None,
           lexers=None,
           delimiters='{{ }}',
           writer='response.write',
           reader=None):
    """
    Generic render function

    Args:
        content: default content
        stream: file-like obj to read template from
        filename: where to find template
        path: base path for templates
        context: env
        lexers: custom lexers to use
        delimiters: opening and closing tags
        writer: where to inject the resulting stream

    Example::
        >>> render()
        'hello world'
        >>> render(content='abc')
        'abc'
        >>> render(content="abc'")
        "abc'"
        >>> render(content=''''a"'bc''')
        'a"'bc'
        >>> render(content='a\\nbc')
        'a\\nbc'
        >>> render(content='a"bcd"e')
        'a"bcd"e'
        >>> render(content="'''a\\nc'''")
        "'''a\\nc'''"
        >>> render(content="'''a\\'c'''")
        "'''a\'c'''"
        >>> render(content='{{for i in range(a):}}{{=i}}<br />{{pass}}', context=dict(a=5))
        '0<br />1<br />2<br />3<br />4<br />'
        >>> render(content='{%for i in range(a):%}{%=i%}<br />{%pass%}', context=dict(a=5),delimiters=('{%','%}'))
        '0<br />1<br />2<br />3<br />4<br />'
        >>> render(content="{{='''hello\\nworld'''}}")
        'hello\\nworld'
        >>> render(content='{{for i in range(3):\\n=i\\npass}}')
        '012'

    """

    # If we don't have anything to render, why bother?
    if content is None and stream is None and filename is None:
        raise SyntaxError("Must specify a stream or filename or content")

    # handle defaults
    if context is None:
        context = {}
    if lexers is None:
        lexers = {}
    if isinstance(delimiters, basestring):
        delimiters = delimiters.split(' ', 1)
    if not reader:
        reader = file_reader

    # allow optional alternative delimiters
    if hasattr(context.get('response', None), 'delimiters'):
        if context['response'].delimiters is not None:
            delimiters = context['response'].delimiters

    # here to avoid circular Imports
    try:
        from gluon.globals import Response
    except ImportError:
        # Working standalone. Build a mock Response object.
        Response = DummyResponse

        # Add it to the context so we can use it.
        if 'NOESCAPE' not in context:
            context['NOESCAPE'] = NOESCAPE

    if isinstance(content, unicodeT):
        content = content.encode('utf8')

    # save current response class
    if context and 'response' in context:
        old_response_body = context['response'].body
        context['response'].body = StringIO()
    else:
        old_response_body = None
        context['response'] = Response()

    if content is None:
        if stream is not None:
            content = stream.read()
        elif filename is not None:
            content = reader(filename)
        else:
            content = '(no template found)'

    # Execute the template.
    code = str(
        TemplateParser(text=content,
                       context=context,
                       path=path,
                       lexers=lexers,
                       delimiters=delimiters,
                       writer=writer,
                       reader=reader))

    try:
        exec(code, context)
    except Exception:
        # for i,line in enumerate(code.split('\n')): print i,line
        raise

    # Returned the rendered content.
    text = context['response'].body.getvalue()
    if old_response_body is not None:
        context['response'].body = old_response_body
    return text
Ejemplo n.º 4
0
def render(content=None,
           stream=None,
           filename=None,
           path=None,
           context=None,
           lexers=None,
           delimiters='{{ }}',
           writer='response.write',
           reader=None
           ):
    """
    Generic render function

    Args:
        content: default content
        stream: file-like obj to read template from
        filename: where to find template
        path: base path for templates
        context: env
        lexers: custom lexers to use
        delimiters: opening and closing tags
        writer: where to inject the resulting stream

    Example::
        >>> render()
        'hello world'
        >>> render(content='abc')
        'abc'
        >>> render(content="abc'")
        "abc'"
        >>> render(content=''''a"'bc''')
        'a"'bc'
        >>> render(content='a\\nbc')
        'a\\nbc'
        >>> render(content='a"bcd"e')
        'a"bcd"e'
        >>> render(content="'''a\\nc'''")
        "'''a\\nc'''"
        >>> render(content="'''a\\'c'''")
        "'''a\'c'''"
        >>> render(content='{{for i in range(a):}}{{=i}}<br />{{pass}}', context=dict(a=5))
        '0<br />1<br />2<br />3<br />4<br />'
        >>> render(content='{%for i in range(a):%}{%=i%}<br />{%pass%}', context=dict(a=5),delimiters=('{%','%}'))
        '0<br />1<br />2<br />3<br />4<br />'
        >>> render(content="{{='''hello\\nworld'''}}")
        'hello\\nworld'
        >>> render(content='{{for i in range(3):\\n=i\\npass}}')
        '012'

    """

    # If we don't have anything to render, why bother?
    if content is None and stream is None and filename is None:
        raise SyntaxError("Must specify a stream or filename or content")

    # handle defaults
    if context is None:
        context = {}
    if lexers is None:
        lexers = {}
    if isinstance(delimiters, basestring):
        delimiters = delimiters.split(' ',1)
    if not reader:
        reader = file_reader

    # allow optional alternative delimiters
    if hasattr(context.get('response', None), 'delimiters'):
        if context['response'].delimiters is not None:
            delimiters = context['response'].delimiters

    # here to avoid circular Imports
    try:
        from gluon.globals import Response
    except ImportError:
        # Working standalone. Build a mock Response object.
        Response = DummyResponse

        # Add it to the context so we can use it.
        if 'NOESCAPE' not in context:
            context['NOESCAPE'] = NOESCAPE

    if isinstance(content, unicodeT):
        content = content.encode('utf8')

    # save current response class
    if context and 'response' in context:
        old_response_body = context['response'].body
        context['response'].body = StringIO()
    else:
        old_response_body = None
        context['response'] = Response()


    if content is None:
        if stream is not None:
            content = stream.read()
        elif filename is not None:
            content = reader(filename)
        else:
            content = '(no template found)'

    # Execute the template.
    code = str(TemplateParser(text=content,
                              context=context,
                              path=path,
                              lexers=lexers,
                              delimiters=delimiters,
                              writer=writer,
                              reader=reader))

    try:
        exec(code, context)
    except Exception:
        # for i,line in enumerate(code.split('\n')): print i,line
        raise

    # Returned the rendered content.
    text = context['response'].body.getvalue()
    if old_response_body is not None:
        context['response'].body = old_response_body
    return text