Flask - Jinja环境中的魔法蓝图

时间:2013-07-26 01:37:09

标签: python flask

在jinja模板中:

  1. 提供给{%extends xxx_string%}和{%include xxx_string%}的字符串是如何解决的?
  2. 这是相对于实际文件系统还是生成的命名空间(例如使用Flask.url_for函数时)?
  3. 最终,我想在我的模板中使用相对导入(我不想在每个模板中更新文件系统位置,相对于蓝图)。我希望能够:

    1. 将实际的Blueprint包及其嵌套的静态/模板资源存储在任意文件系统路径下。 ( '/鲍勃/项目/ 2013_07 / marketanalysis')
    2. 在python Blueprint包中,定义一个单独的'slugname'来引用蓝图实例及其所有资源。在应用程序上注册此slugname以获取全局引用。 (没有全球名称冲突或竞争条件)
    3. 具有提供'千篇一律'布局的通用视图功能,具体取决于蓝图的使用方式(标题,封面,介绍,全文,引文)
    4. 在蓝图包的文件系统内部,在解析模板内的extends()/ include()时使用相对路径名(在引用相对蓝图视图时类似于url_for快捷方式)。
    5. 这个想法是,当蓝图包与其所有资源捆绑在一起时,它不知道它将在何处部署,并且可能在不同的 slug-names 下多次重新定位。 python 接口对于每个“bundle”应该是相同的,但html内容,css,javascript和images / downloads对于每个bundle都是唯一的。


      我已经提出了相当多的问题。我认为这是应该在这个线程上进行的。

3 个答案:

答案 0 :(得分:0)

在我看来,使用文件夹而不是前缀使它更加干净。示例应用程序结构:

yourapplication
|- bp143
   |- templates
      |- bp143
         |- index.jinja
         |- quiz.jinja
         |- context.jinja
|- templates
   |- base.jinja
   |- index.jinja
   |- bp143
      |- context.jinja

使用上述结构,您可以按如下方式引用模板:

base.jinja --> comes from the application package
index.jinja --> comes from the application package
bp143/index.jinja --> comes from the blueprint
bp143/context.jinja --> comes from the application package (the app overrides the template of the same name in the blueprint)

答案 1 :(得分:0)

使用... (未测试)

显式加载模板
@blueprint.route('/summarize_article')
def summarize():
    fd = blueprint.open_resource('/blueprint/relative/pathid/section/introductions.jinja')    
    relative_ctx['article_intro'] = flask.render_template_string(fd.read(), **context)

    fd = blueprint.open_resource('/blueprint/relative/pathid/section/citations.jinja')    
    relative_ctx['article_citations'] = flask.render_template_string(fd.read(), **context)

    fd = blueprint.open_resource('/blueprint/relative/pathid/summarized_layout.jinja')
    return flask.render_template_string(fd.read(), **relative_ctx)

根据需要为每个视图手动加载这些模板。我确信这可以清理多个视图,但我相信这是预期的行为。

我不确定你是否可以{% extend context_kword_key %},但它应该适用于嵌入式includes()/ imports()。

答案 2 :(得分:0)

对于我的“资源捆绑”似乎最合适的解决方案应该使用Jinja加载器处理(参见Jinja Docs on Loaders)。马上,jinja2.PackageLoaderjinja2.PrefixLoader和jinja2.DictLoader似乎很有趣。

Similar Thread的已接受答案提供了如何在Flask中处理装载程序的想法。在大多数情况下,我们可以保持默认的应用级DispatchingJinjaLoader

默认情况下,我相信蓝图最终会以self.jinja_loader结束......

jinja2.FileSystemLoader(os.path.join(self.root_path,
                                     self.template_folder)) 

这有助于我们了解默认分辨率算法的简单程度,以及我们如何轻松扩展蓝图特定功能。 Subclassed / Custom Loaders的巧妙组合将让我们创造更智能的装载机,并让我们潜入一些可以帮助我们作弊的魔法。

真正的力量将来自重写CustomBaseLoader.list_templates()和一个快速的小型ProxyLoader,它连接到应用程序的DispatcherJinjaLoader,它将优先于正常查找。