1

在 jinja 模板中时:

  1. 提供给 {%extends xxx_string%} 和 {% include xxx_string%} 的字符串如何解析?
  2. 这是相对于实际文件系统还是生成的命名空间(例如使用 Flask.url_for 函数时)?

最终,我想在我的模板内使用相对导入(我不想更新每个模板内的文件系统位置,相对于蓝图)。我希望能够:

  1. 将实际的蓝图包及其嵌套的静态/模板资源存储在任意文件系统路径下。('/bob/projects/2013_07/marketanalysis')
  2. 在 python 蓝图包中,定义一个单独的“slugname”来引用蓝图实例及其所有资源。在应用程序上注册此 slugname 以供全局引用。(没有全局名称冲突或竞争条件)
  3. 具有提供“千篇一律”布局的通用视图功能,具体取决于蓝图的使用方式(标题、封面、介绍、全文、引文)
  4. 在内部,在蓝图包的文件系统中,在解析模板内的 extends()/include() 时使用相对路径名(类似于url_for引用相对蓝图视图时的快捷方式)。

这个想法是,当蓝图包与其所有资源捆绑在一起时,它不知道它将被部署在哪里,并且可能会在不同的 slug-names下多次重定位。每个“bundle”的 python界面应该是相同的,但是每个 bundle 的 html 内容、css、javascript 和图像/下载将是唯一的。


我已经把这个问题尖锐了很多。我认为这是该线程应有的内容。

4

3 回答 3

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)
于 2013-07-26T04:25:50.183 回答
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 %},但它应该适用于嵌入式 include()/imports()。

于 2013-08-01T19:56:23.827 回答
0

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

这个Similar Thread的公认答案给出了在 Flask 中如何处理 Loaders 的想法。在大多数情况下,我们可以避开默认的 application-level DispatchingJinjaLoader

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

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

这有助于我们了解默认分辨率算法的简单程度,以及扩展蓝图特定功能的容易程度。子类化/自定义加载器的巧妙组合将让我们创建更智能的加载器,并允许我们潜入一些帮助我们作弊的魔法。

真正的力量将来自覆盖 CustomBaseLoader.list_templates() 和一个快速的小 ProxyLoader 挂钩到应用程序的 DispatcherJinjaLoader 将优先于正常查找。

于 2013-08-02T04:43:39.140 回答