61

默认情况下,flask 使用存储在“模板”目录中的模板文件:

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

有没有办法根据用户登录动态选择模板目录?这就是我想要的目录结构:

/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

现在如果我有登录用户的用户名和用户激活的模板名称,是否可以动态选择目录来加载模板文件?例如,

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

而不是固定的

/templates/

我想要实现的是一个类似 wordpress 的主题系统,用于我的 Web 应用程序,用户可以为他的网站上传/选择主题。

4

3 回答 3

110

您可以向 Flask 构造函数传递一个“template_folder”参数。

像这样...

Flask(__name__, template_folder="wherever")

这是文档: http: //flask.pocoo.org/docs/api/

于 2012-11-28T05:46:33.853 回答
48

还有可能覆盖 Jinja 加载器并设置 Jinja 查找模板的路径。喜欢:

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

目录按照 Jinja 需要首先开始查找的顺序排列。然后从视图中,您可以像这样呈现用户特定的模板:

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

您可以在视图中动态更改用户名的位置。当然,您也可以在那里选择要渲染的模板(1 或 2)。但基本上你真正想念的是这个带有自定义路径的自定义 Jinja 加载器。

希望能帮助或给出想法:)

于 2012-11-28T06:06:53.030 回答
1

我是 Python 新手,但我已经遇到过这个问题。我不知道我的解决方案是否正确,但它有效:

首先,您必须为每个用户创建模块

/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              

在 application.py init Flask app 中,添加全局方法 render_page_from 并注册蓝图

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)

在每个模块(user1、user2 等)中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

最后像这样将视图(动作)方法添加到views.py

from LocalHub.client import controller
@controller.route('/hello')
def hello():
    """Renders the page"""
    return render_page_from(controller.name, 'hello.html', title='hello')
于 2016-10-25T20:15:32.950 回答