如何动态选择要在烧瓶中使用的模板目录?
Posted
技术标签:
【中文标题】如何动态选择要在烧瓶中使用的模板目录?【英文标题】:How to dynamically select template directory to be used in flask? 【发布时间】:2012-11-15 21:47:39 【问题描述】:默认情况下,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 应用程序,用户可以在其中上传/选择他的网站的主题。
【问题讨论】:
【参考方案1】:您可以向 Flask 构造函数传递一个“template_folder”参数。
就这样……
Flask(__name__, template_folder="wherever")
这是文档: http://flask.pocoo.org/docs/api/
【讨论】:
而且如果你要使用蓝图,它们也可以有自定义模板目录。 @IgnasButėnas 使用蓝图也不适用于两个不同的路径,但render_template
相同的模板名称【参考方案2】:
还可以覆盖 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 加载器。
希望有所帮助或提供想法:)
【讨论】:
您不必在 Python 中的列表或字典声明中转义换行符。 如果有人遇到问题:这在 Heroku 中不起作用。您必须通过没有第一个/
的路径(如'flaskapp/userdata'
)。
排除app.jinja_loader
行以仅使用提到的两个文件夹
感谢这项工作。我想在这里建议一个编辑:当你编写这段代码时,Flask 仍然会查看默认的“模板”文件夹,但也会查看新添加的文件夹。【参考方案3】:
我是 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)
在init.py中的每个模块(user1、user2等)初始化蓝图中
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')
【讨论】:
不起作用,它打印出正确的搜索路径但呈现错误的模板。以上是关于如何动态选择要在烧瓶中使用的模板目录?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Jinja2 模板在烧瓶中解码 ' [重复]