thijsferyn / edgestash-twig-bundle
EdgestashTwig Symfony 扩展包为 Twig 添加了 Edgestash 支持。Edgestash 是一个 Varnish Enterprise 模块,用于在边缘处理 Mustache 模板。
Requires
- php: ^7.2
- symfony/dependency-injection: ^4.2
- symfony/twig-bundle: ^4.2
README
ThijsFerynEdgestashTwigBundle 是一个 Symfony 扩展包,为 Twig 添加了 Edgestash 支持。
Edgestash 是一个 Varnish Enterprise 模块,用于在边缘处理 Mustache 模板。
Edgestash 允许使用 Mustache 语法将 JSON 数据组合到响应中,例如:{{variable}}
。每个响应都可以分配自己的 JSON 对象,实现真正的动态响应。JSON 可以从后端获取或通过 VCL 生成,可以为模板分配任意数量的 JSON。
此扩展包提供了一些自定义的 Twig 函数和过滤器,以方便无干扰地使用 Edgestash,从而高效地缓存个性化数据。
安装 ThijsFerynEdgestashTwigBundle
ThijsFerynEdgestashTwigBundle
可在 Packagist 上找到,并可以使用以下命令通过 Composer 安装
composer require thijsferyn/edgestash-twig-bundle
Edgestash 如何工作?
Edgestash 文档页面上的 VCL 示例 展示了 Mustache 模板和 JSON 数据是如何分别缓存的。
VCL 代表 Varnish 配置语言,是控制 Varnish 行为的领域特定编程语言。
edgestash.parse_response()
方法将处理模板并识别需要解析的占位符。
Edgestash 提供了 3 种不同的方式来摄取用于替换模板占位符的 JSON 数据
- add_json_url:传递一个指向 JSON 端点的 URL
- add_json_url_csv:传递一个包含指向多个 JSON 端点的 CSV 风格的 URL 列表
- add_json:传递 JSON 字符串
一旦注入了 JSON,就会执行 edgestash.execute()
方法,将 JSON 和模板转换为个性化的输出。
如何从 Twig 模板触发 Edgestash?
Edgestash 函数
自定义的 edgestash
Twig 函数将发出未解析的 Mustache 变量,与 Varnish 进行内容协商,并自动提供 JSON 端点。
以下是一个示例
<div>{{ edgestash('username','/session') }}</div>
此示例将发出一个 {{ username }}
变量。尽管 Twig 与 Mustache 有类似的语法,但该变量不会由 Twig 解析。
包含 JSON 数据的 /session
端点将被发送到 Varnish。Varnish 将处理这些 JSON 数据,查找 username
属性,并将其解析为 {{ username }}
变量。
Edgestash 过滤器
edgestash
函数也作为自定义 Twig 过滤器提供。这意味着您可以将数据传递给它。
以下是一个示例
<div>{{ username | edgestash('username','/session') }}</div>
在这个例子中,如果Symphony包没有检测到Edgestash支持的Varnish服务器,Twig将解析{{ username }}
变量。
然而,如果此包检测到Edgestash支持的Varnish服务器,它将输出{{ username }}
并将/session
端点发送到Varnish。
isEdgestash
函数
虽然edgestash
过滤器是一种在不干扰的情况下引入Edgestash的理想方式,但不幸的是,有时Edgestash集成需要一些自定义模板代码。
幸运的是,isEdgestash()
Twig函数允许您检测应用程序是否位于Edgestash支持的Varnish服务器之后。这与edgestash
过滤器和函数内部用于检测的逻辑相同。
以下是一个示例
<div>
{% if isEdgestash() %}
//Edgestash-supported logic
{% else %}
//Regular Twig logic
{% endif %}
</div>
条件和循环
Edgestash支持完整的Mustache语法并可以处理条件和循环。
以下是一个使用Edgestash的if-else语句的例子
{{ edgestash('#username', '/session') }}
Welcome {{ edgestash('username') }}
{{ edgestash('/username') }}
{{ edgestash('^username') }}
Welcome guest
{{ edgestash('/username') }}
所以如果检测到JSON数据中的username
属性,将打印用户名。如果没有,我们将把用户称为访客。
请注意,JSON端点只能注册一次。随后,可以留空
url
参数。但是,如果相同端点注册多次,不会造成损害,因为重复项将被删除。
以下是一个使用Edgestash的循环的例子
<ul>
{{ edgestash('#.', '/users') }}
<li>{{ edgestash('username') }}</li>
{{ edgestash('/.') }}
</ul>
在这个例子中,我们遍历用户对象集合并列出用户名。输出/users
端点可能看起来像这样
[
{"username":"user 1"},
{"username":"user 2"},
{"username":"user 3"}
]
最终输出将是
<ul>
<li>user 1</li>
<li>user 2</li>
<li>user 3</li>
</ul>
多个JSON端点
此Edgestash集成允许有多个JSON端点。重复值将被删除,所有端点的输出将合并成一个JSON对象。
以下是一个示例
<div>{{ username | edgestash('username','/session') }}</div>
<div>{{ items_in_cart | edgestash('items_in_cart','/cart') }}</div>
ThijsFerynEdgestashTwigBundle
如何与Varnish交互?
如前所述,edgestash
过滤器以一种不干扰的方式进行工作。这意味着它可以检测是否位于Edgestash支持的Varnish服务器之后。
Edgestash检测
为了宣布Edgestash支持,Varnish将发送以下请求头到您的源服务器,包含应用程序
Surrogate-Capability: edgestash="EDGESTASH/2.1"
此Symphony包会查找此头,如果找到它,则表示支持Edgestash。
在返回的过程中,Varnish需要知道何时应将输出视为Mustache模板。ThijsFerynEdgestashTwigBundle
包通过向Varnish发送以下响应头来实现这一点
Surrogate-Control: edgestash="EDGESTASH/2.1"
当Varnish检测到这个响应头时,它将内部执行edgestash.parse_response()
方法。
检测是自动发生的,头部协商是在EdgestashTwigSubscriber.php中完成的
处理JSON端点
当使用有效的URL参数调用edgestash
函数或过滤器时,该URL被添加到TwigExtension.php中的内部HTTP请求参数。
该参数由EdgestashTwigSubscriber.php处理,并通过Link
头公开URL(或URLs)。
以下是一个此类Link
头的例子
Link: </session>; rel=edgestash
此链接头具有rel=edgestash
属性,使得在Link
头包含其他非相关数据时易于查找。
当注册多个JSON端点时,它将看起来像这样
Link: </session>; rel=edgestash, </cart>; rel=edgestash
当Varnish检测到Edgestash输出并解析Link
头时,它将触发edgestash.add_json_url_csv
方法通过端点检索JSON数据。最后,执行edgestash.execute()
方法解析JSON并将其添加到缓存的模板占位符中。
Varnish要求
Edgestash 是由 Varnish Software 开发和维护的专有 VMOD。当您注册 Varnish Enterprise 时,此模块将自动打包。
如果您没有 Varnish Enterprise 许可证,您也可以通过我们在 AWS、Azure 或 Google Cloud 上的云镜像尝试 Varnish Enterprise 和 Edgestash。
使用 ThijsFerynEdgestashTwigBundle
所需的最小 VCL 存储在 Resources/Config/default.vcl