How to dynamically select template directory to be used in flask?

后端 未结 3 1362
生来不讨喜
生来不讨喜 2020-11-30 03:06

By default flask uses template files stored in \"template\" directory :

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

Is

相关标签:
3条回答
  • 2020-11-30 03:16

    You can pass the Flask constructor a "template_folder" argument.

    Like so...

    Flask(__name__, template_folder="wherever")
    

    Here's the documentation: http://flask.pocoo.org/docs/api/

    0 讨论(0)
  • 2020-11-30 03:32

    There is also the possibility to overwrite Jinja loader and set the paths where Jinja will look for the templates. Like:

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

    Directories are arranged in the order where Jinja needs to first start looking for it. Then from the view you can render user specific template like this:

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

    where username you can dinamically change in the view. Of course you can also there choose which template (1 or 2) to render. But basically what you really miss is this custom Jinja loader with the custom paths.

    Hope that helped or gave the ideas :)

    0 讨论(0)
  • 2020-11-30 03:41

    I'm new to Python, but I have already faced with this problem. I don't know if my solution is right, but it works:

    First of all you have to create module for each user

    /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              
    

    in application.py init Flask app, add global method render_page_from and register 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)
    

    in each module (user1, user2 etc) init blueprint in 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
    

    finally add view (action) methods to views.py like this

    from LocalHub.client import controller
    @controller.route('/hello')
    def hello():
        """Renders the page"""
        return render_page_from(controller.name, 'hello.html', title='hello')
    
    0 讨论(0)
提交回复
热议问题