Comment sélectionner dynamiquement le répertoire de modèles à utiliser dans flask?

Par défaut, flask utilise les fichiers template stockés dans le répertoire "template":

/flaskapp
    /application.py
    /templates
        /hello.html

Existe-t-il un moyen de choisir dynamiquement le répertoire du modèle en fonction de l'utilisateur connecté? Voici comment je veux que la structure du répertoire soit:

/flaskapp
    /application.py
    /templates (default template goes here)
        /hello.html
    /userdata
        /user1
            /template1
                 hello.html
            /template2
                 hello.html
        /user2
            /template1
                 hello.html
            /template2
                 hello.html

Maintenant, si j'ai le nom d'utilisateur de l'utilisateur connecté et le nom du modèle activé par l'utilisateur, est-il possible de sélectionner dynamiquement le répertoire pour charger les fichiers de modèle? Par exemple,

/userdata/<username>/<activated template name>/

Au Lieu de fixe

/templates/

Ce que je suis essayer de réaliser est un système de thème wordpress comme pour mon application web où les utilisateurs peuvent télécharger / sélectionner des thèmes pour son site web.

41
demandé sur anujkk 2012-11-28 09:22:30

3 réponses

Il y a aussi la possibilité d'écraser Jinja loader et de définir les chemins où Jinja recherchera les modèles. Comme:

my_loader = jinja2.ChoiceLoader([
        app.jinja_loader,
        jinja2.FileSystemLoader(['/flaskapp/userdata', 
                                 '/flaskapp/templates']),
    ])
app.jinja_loader = my_loader

Les répertoires sont disposés dans l'ordre où Jinja doit commencer à le chercher. Ensuite, à partir de la vue, vous pouvez rendre un modèle spécifique à l'utilisateur comme ceci:

render_template('%s/template1/hello.html' % username)

Où nom d'utilisateur vous pouvez changer dinamically dans la vue. Bien sûr, vous pouvez également choisir le modèle (1 ou 2) à rendre. Mais fondamentalement ce qui vous manque vraiment est cette coutume Chargeur Jinja avec les chemins personnalisés.

J'espère que cela a aidé ou donné les idées:)

36
répondu Ignas Butėnas 2017-01-10 20:33:34

Vous pouvez passer au constructeur Flask un argument "template_folder".

Comme ça...

Flask(__name__, template_folder="wherever")

Voici la documentation: http://flask.pocoo.org/docs/api/

69
répondu nathan 2012-11-28 05:46:33

Je suis nouveau en Python, mais j'ai déjà fait face à ce problème. Je ne sais pas si ma solution est correcte, mais cela fonctionne:

Tout d'Abord, vous devez créer un module pour chaque utilisateur

/flaskapp
    /application.py
    /templates (default template goes here)
        __init__.py     # default module flaskapp
        views.py        # here you can define methods for default module (like Action in MVC)
        /hello.html
    /static
    /userdata
        /user1
            __init__.py # user1 module
            views.py    # here you can define methods for user1 module
            /template1
                 hello.html
            /template2
                 hello.html
        /user2
            __init__.py # user2 module
            views.py    # here you can define methods for user2 module
            /template1
                 hello.html
            /template2
                 hello.html              

Dans application.py init Flask app, ajouter la méthode globale render_page_from et enregistrer blueprints

app = Flask(__name__)
def render_page_from(controller_name, template_name_or_list, **context):
    # here you can choose any controller or use default
    app.jinja_loader.searchpath.clear()
    blueprint = app.blueprints[controller_name]
    app.jinja_loader.searchpath.append(blueprint.template_folder)
    return render_template(template_name_or_list, context=context)

from flaskapp.user1 import controller as user1_controller
from flaskapp.user2 import controller as user2_controller

app.register_blueprint(user1_controller)
app.register_blueprint(user2_controller)

Dans chaque module (user1, user2, etc) init plan dans init.py

templates_folder = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'templates')

controller = Blueprint('user1', __name__, url_prefix='/user1', template_folder = templates_folder)

import flaskapp.user1.views

Enfin ajouter vue (action) méthodes à views.py comme ça

from LocalHub.client import controller
@controller.route('/hello')
def hello():
    """Renders the page"""
    return render_page_from(controller.name, 'hello.html', title='hello')
2
répondu Egor 2016-10-25 20:15:32