pythonflaskmakowebassets

Using Flask-Assets with Flask-Mako


I would like to use flask-assets to organize my webassets and mako for templating. Flask-assets normally uses jinja in the following way:

{% assets "js_all" %}
    <script type="text/javascript" src="{{ ASSET_URL }}"></script>
{% endassets %}

The Mako equivalent (as far as I know) would be the following:

    % assets 'coffee':
        <script type="text/javascript" src="{{ ASSET_URL }}"></script>
    % endassets

However this causes a compile error:

mako.exceptions.CompileException
CompileException: Unsupported control keyword: 'assets' in file '/index.html' at line: 8 char: 1

Is there any way to use custom control keywords (like 'assets') in Mako?

Here is my app.py for the record:

import os
from flask import Flask, render_template
from flask.ext import assets
from flask import config
from flask.ext.mako import MakoTemplates
from flask.ext.mako import render_template

app = Flask(__name__)
app.config['ASSETS_DEBUG'] = True

mako = MakoTemplates(app)
env = assets.Environment(app)

# Tell flask-assets where to look for our coffeescript and sass files.
env.load_path = [
    os.path.join(os.path.dirname(__file__), 'js'),
    os.path.join(os.path.dirname(__file__), 'styles'),
]

coffee = assets.Bundle('**/*.coffee', filters='coffeescript', output="app.js")
env.register('coffee', coffee)

@app.route("/")
def index():
    return render_template('index.html', name='mako')


if __name__ == "__main__":
    app.run(debug=True)

Solution

  • Well, I came up with a solution. You can make it work by importing the environment into your base template and acting on that.

    assets.py:

    import os
    from flask.ext import assets
    from app import app
    
    env = assets.Environment(app)
    
    # Tell flask-assets where to look for our coffeescript and sass files.
    env.load_path = [
        os.path.join(os.path.dirname(__file__), 'js'),
        os.path.join(os.path.dirname(__file__), 'styles'),
    ]
    
    coffee = assets.Bundle('**/*.coffee', filters='coffeescript', output="app.js")
    env.register('coffee', coffee)
    

    Template:

    <%!
      from assets import env
    %>
    
    <!doctype html>
    
    <html>
        <head>
            <title>Hello Flask</title>
        <head>
        <body>
            <h1>Hello Flask</h1>
    
            % for url in env['coffee'].urls():
                <script src="${url}"></script>
            % endfor
    
        </body>
    </html>
    

    There might be way to avoid the import by using the MAKO_IMPORTS config parameter but I haven't played with it.