Skip to content Skip to sidebar Skip to footer

Insert Static Files Literally Into Jinja Templates Without Parsing Them

I'm trying to insert file into a page using Jinja 2.6 using the include tag. This worked fine until I started using characters in the file that are reminiscent of the Jinja syntax,

Solution 1:

You can define a function to load the text file and render it in the template:

import jinja2

def include_file(name):
    return jinja2.Markup(loader.get_source(env, name)[0])

loader = jinja2.PackageLoader(__name__, 'templates')
env = jinja2.Environment(loader=loader)
env.globals['include_file'] = include_file

def render():
    return env.get_template('page.html').render()

if __name__ == '__main__':
    print render()

In the template, call it like this:

{{ include_file('file.txt') }}

Solution 2:

If you are using Flask it can be written like this:

from jinja2 import Markup

...

app.jinja_env.globals['include_raw'] = lambda filename : Markup(app.jinja_loader.get_source(app.jinja_env, filename)[0])

And used like this:

{{ include_raw('js-inline/modernizr.min.js') }}

Path of the included file is relative to your template folder as for normal includes.

Solution 3:

Try putting the syntax in the other files in {% raw %} {% endraw %}

You can use jQuery if you dont want to edit the external files: Make a dive to contain the content <div id="contentoffile"></div>

and use jquery to load the file : $("#contentoffile").load("url to file") << the url can be relative

Solution 4:

Here's a solution in the form of a tag, which looks more like the standard "include" when you're writing templates. (This is how I do it for a static site generator called Combine.)

from jinja2 import nodes
from jinja2.ext import Extension
from jinja2 import Markup


classIncludeRawExtension(Extension):
    tags = {"include_raw"}

    defparse(self, parser):
        lineno = parser.stream.expect("name:include_raw").lineno
        filename = nodes.Const(parser.parse_expression().value)
        result = self.call_method("_render", [filename], lineno=lineno)
        return nodes.Output([result], lineno=lineno)

    def_render(self, filename):
        return Markup(self.environment.loader.get_source(self.environment, filename)[0])

# Use the extension when setting up Jinja
your_jinja_env = jinja2.Environment(
    extensions=[IncludeRawExtension],
)

Functionally it's the same as other answers here, but I think it helps to keep the same {% syntax as the regular "include" tag.

{% include "template.html" %}
{% include_raw "template.html" %}

Solution 5:

As an update to @Alex's answer, you can use Jinja's @contextfunction decorator to remove some of the reliance on global variables. The updated code would look like:

import jinja2                                                                                                                                                                                                  

@jinja.contextfunction                                                                                                                                                                                         definclude_file(ctx, name):                                                                                                                                                                                   
    env = ctx.environment                                                                                                                                                                                      
    return jinja2.Markup(env.loader.get_source(env, name)[0])                                                                                                                                                  


defmain():                                                                                                                                                                                                    
    loader = jinja2.PackageLoader(__name__, 'templates')                                                                                                                                                       
    env = jinja2.Environment(loader=loader)                                                                                                                                                                    
    env.globals['include_file'] = include_file                                                                                                                                                                 

    env.get_template('page.html').render()                                                                                                                                                                     


if __name__ == '__main__':                                                                                                                                                                                     
    print main()

And just as before, call it from your template like:

{{ include_file('file.txt') }}

Post a Comment for "Insert Static Files Literally Into Jinja Templates Without Parsing Them"