2012-07-09 4 views
6

Je suis assez nouveau à Flask, pour ce que ça vaut. J'utilise des blueprints pour décomposer mon code et j'essaie d'utiliser Flask-Assets pour servir les liens d'assets. Pour une raison quelconque, cependant, je ne peux pas faire fonctionner Flask-Assets dans un plan.Ressources propres à Blueprint dans Flask à l'aide de Flask-Assets?

structure code

:

/modules 
    /base 
     __init__.py 
    __init__.py 
/static 
    # ... stuff 
/templates 
    /layout.html 

En /modules/base/__init__.py:

from flask import Blueprint, render_template, request 
from flask.ext.sqlalchemy import SQLAlchemy 
from flask.ext.assets import Environment, Bundle 
from flask import current_app as app 

default = Blueprint('base', __name__) 

assets = Environment(app) 

css = Bundle('css/bootstrap.min.css') 
assets.register('css_all', css) 

js = Bundle('js/jquery-1.7.2.min.js', 'js/bootstrap.min.js') 
assets.register('js_all', js) 

@default.route('/') 
def index(): 

    return render_template('index/index.html') 

Et la mise en page de base a cela il:

{% assets "css_all" %} 
    <link rel="stylesheet" href="{{ ASSET_URL }}" /> 
{% endassets %} 
{% assets "js_all" %} 
    <script type="text/javascript" src="{{ ASSET_URL }}"></script> 
{% endassets %} 

En fait ce que je avoir dans /modules/base/__init__.py maintenant ne fonctionne même pas, car il lance "RuntimeError: travailler en dehors de l'application co ntext ". Si je déplace le code des actifs dans la fonction d'index, cela fonctionne, mais il semble bizarre d'avoir à répéter ce code chaque fois que je veux ajouter des actifs. Y a-t-il une meilleure manière de faire cela? Est-ce que je manque quelque chose?

Edit: Mis à jour par /modules/base/__init__.py commentaire de codecool, mais maintenant il jette un "TemplateSyntaxError: tag inconnu Rencontrés 'actifs'" erreur. Je pense que celui-ci est parce que l'objet d'actifs n'est pas transmis à l'application.

Edit 2: Donc, en prenant quelques conseils de la façon dont SQLAlchemy fait des choses, je suis arrivé à ce genre de travail avec les éléments suivants:

Dans mon principal __init__.py:

from flask import Flask 
from modules.base import default, assets as base_assets 
from flask.ext.assets import Environment, Bundle 

app = Flask(__name__) 
app.register_blueprint(default) 

base_assets.init_app(app) 

In base/__ init__.py: à partir de flask import Blueprint, render_template, demande à partir de flask.ext.assets import Environment, Bundle à partir de flask import current_app comme application

default = Blueprint('base', __name__) 

assets = Environment(app) 

css = Bundle('css/bootstrap2.min.css') 
assets.register('css_all', css) 

js = Bundle('js/jquery-1.7.2.min.js', 'js/bootstrap.min.js') 
assets.register('js_all', js) 

L'astuce consiste ici à créer des éléments dans le plan, à l'importer dans l'initialisation de base, puis à y appeler .init_app. Lorsque cela tombe en panne, cependant, est d'avoir deux plans qui le font. Le dernier appelé gagne toujours. Peut-être qu'il serait possible de tirer cela dans un module commun ou quelque chose ..

+0

J'ai édité ma réponse avec la solution de votre nouveau problème. – codecool

Répondre

7

Vous n'avez pas besoin d'appeler la méthode _get_current_object sur current_app et c'est pourquoi vous obtenez l'erreur. current_app est en fait un proxy pour l'application. Code devrait ressembler à ceci:

app = current_app 
    assets = Environment(app) 

Enfait, vous n'avez pas besoin d'assigner comme variable. Pour ce faire:

 from flask import current_app as app 

    assets = Environment(app) 

Vous obtenez RuntimeError parce que _get_current_object est disponible uniquement lorsqu'une demande est en cours sinon vous devez utiliser current_app. Lorsque vous avez déplacé des éléments en initialisant du code dans la vue index, il a commencé à fonctionner comme dans une requête.

_get_current_object L'utilisation de la fonctionnalité Signals dans Flask est disponible et vous pouvez la lire ici http://flask.pocoo.org/docs/signals/#sending-signals.

Edit:

Ce qui se passe parce que ce n'est pas le bon endroit pour initialiser les actifs Flask. Il doit être initialisé en modules/__init__.py où l'environnement jinja est configuré lors de la création de l'application. Rappelez-vous que le code des plans est exécuté uniquement lorsque vous y accédez. Toutes les initialisations globales doivent être effectuées dans le module où votre application est définie, où ce code est présent:

app = Flask(__name__) 
    assets = Environment(app) 
+0

à droite. current_object n'existe que dans le contexte de la requête. – Brent81

+0

qui résout le problème de celui-ci ne se charge pas, mais maintenant il renvoie une erreur: 'jinja2.exceptions.TemplateSyntaxError TemplateSyntaxError: tag inconnu Rencontrés « assets'.' Je pense que c'est parce que l'objet-actifs Flask ISN » t en cours d'ajout à l'objet d'application Flask. – greggilbert

+0

J'ai aussi essayé d'initialiser des assets dans la base init, et cela ne change rien. Voulez-vous dire, alors, qu'il n'est pas possible d'avoir des plans directeurs qui définissent leurs propres actifs? – greggilbert

Questions connexes