Skip to content

模板与资源

把模板与静态资源放在受控目录,并将最小目录加入resources.local_access.allowed_paths

plugins:
  htmlrender:
    provider: playwright
    resources:
      local_access:
        allowed_paths: [templates, assets]
from pathlib import Path

from entari_plugin_htmlrender import HtmlRenderer, TemplateRef
from entari_plugin_htmlrender.resources import FileResourceRef

async def render_card(renderer: HtmlRenderer, name: str):
    return await renderer.rasterize_template(
        TemplateRef(Path("templates"), "card.html"),
        {
            "name": name,
            "logo": FileResourceRef(Path("assets/logo.png")),
        },
    )

TemplateRef.root 和 HTML <base> 只影响相对引用解析,不会扩大访问白名单。locator 使用 FileResourceRef / PackageResourceRef / RemoteResourceRef;payload使用 ResourceContent / InlineResource,避免按字符串或 Path 的形状猜测语义。

需要把 payload 交给必须 fetch URL 的 consumer 时,通过 ResourceAccess.publish()建立显式 lease。PublishedResource 的 URL 与请求头只在 async with 内有效,不能返回 URL 后再使用。

对不可信文档可在 rasterize 调用传入ResourceMaterializationPolicy.STRICT,让不可解析资源确定性失败。自定义 Jinja filter 应使用稳定名称与稳定 callable identity;动态创建匿名函数会扩大 environment cache key 并降低 compiled-template cache 命中率。