以下是在捆绑的 Example
项目中使用的 Reparse
语法示例 (为了简洁,删除了一些行)
<r-require name="context" type="[String]" label="superheroes" />
<r-extend name="base" />
<r-extend name="body" />
<r-eval line='req.logger.info("Index Debug Message")' />
<main>
<h1>
<r-set name="class" value=" red" append r-if="context.isEmpty" />
Hello
<r-include name="components.world" r-if="!context.isEmpty">
Ultra Heroes!
</r-include>
<r-block r-else> World?</r-block>
</h1>
<ol>
<li r-for-every="context" r-with-item r-with-index>
<p>
<r-include name="components.hello-me">\(item)</r-include>
</p>
<p>Index: \(index)</p>
</li>
<li r-else>No more heroes...</li>
</ol>
<p><r-value of="req.url.string" /> or \(req.url.string)</p>
</main>
<title r-add-to-slot="head">Hero List</title>
以下是手动构建示例页面的默认命令:swift run reparse ./Resources/Pages ./Sources/Example --parameters req:Request --imports Vapor
然后使用以下命令运行 Example 项目:swift run ReparseExample
如果您想在自己的项目中使用它,首先,像这样将其添加到您的 package 依赖项中
.package(url: "https://github.com/RussBaz/experimental-reparse-html.git", from: "0.0.19"),
然后像这样将 ReparseRuntime
作为依赖项添加到您的 target 中
.product(name: "ReparseRuntime", package: "experimental-reparse-html"),
要将其用作独立工具,您需要 git clone
此仓库,然后像这样编译该工具:swift build -c release
。然后将构建的工具从 build 文件夹复制到您想要的任何位置并运行它。否则,您可以只需从该项目文件夹内部调用 swift run reparse
,并提供有效的参数和选项。
这是该工具的帮助页面
USAGE: reparse <location> <destination> [--file-name <file-name>] [--file-extension <file-extension>] [--enum-name <enum-name>] [--imports <imports> ...] [--parameters <parameters> ...] [--protocols <protocols> ...] [--dry-run]
ARGUMENTS:
<location> The target data folder location.
<destination> The destination folder for the output file.
OPTIONS:
--file-name <file-name> Output file name (default: pages.swift)
--file-extension <file-extension>
The file extension to be searched for (default: html)
--enum-name <enum-name> The name of the generated enum (default: Pages)
--imports <imports> List of global imports
--parameters <parameters>
List of shared parameters (parameters to be added to
every 'include' function) in a form of
'[?][label:]name:type[=default]' where the optional
parts are in square brackets. The question mark at the
beginning indicates that the parameter will be
overriden by a local requirement if it is present.
--protocols <protocols> A list of protocols to apply to enums with render
functions in them in a form of
'name[:associatedName:associatedType]' where the
optional parts are in square brackets. Optional part
can be repeated any number of times.
--dry-run Write the output to the console instead of file
-h, --help Show help information.
您还可以从终端将其作为命令插件运行。您只需按照安装说明进行操作即可使其自动可用。
列出可用插件
swift package plugin --list
要使用自动 Vapor 设置,请使用
swift package plugin reparse --preset vapor
注意:每个基于 Vapor 的预设都会将 'req: Request' 作为第一个参数添加到生成的函数中。
或者如果您正在使用 VaporHX
swift package plugin reparse --preset vaporhx
注意:如果要将其与 VaporHX 一起使用,那么您只能 'require' context
变量,因为否则生成的代码将不再符合 HXTemplateable
协议,这是自动使用生成的模板所必需的。
除了来自 Vapor 预设的 'req: Request' 之外,它还添加了 'isPage: Bool' 和 'context: Context' 参数。当模板预期返回整个页面时,'isPage' 为 true;当预期返回页面片段(就地更新)时,'isPage' 为 false。然后 'Context' 类型默认为 EmptyContext
结构体,由 VaporHX 提供。但是,如果您使用 'r-require' 标签指定 'context',那么它将被替换为您自己的类型,而不会破坏与 VaporHX 的兼容性。
如果您不使用任何预设,那么所有相对路由都将指向项目根文件夹。
您可以传递的所有选项都是相同的,除了 location 和 destination 参数被以下选项替换
--source
用于指定与项目根文件夹不同的根文件夹
--target
用于从 package targets 中选择一个 target 作为生成文件的目标
--destination
作为路径组件列表,用于为 target 提供相对于源根文件夹(或如果未选择则为项目根)的不同输出文件夹
所有特殊属性和标签都将在编译时删除,并且不得出现在 render 函数的输出中。如果它们出现,那就是一个 bug。
您可以使用标准的 swift 语法进行字符串插值 \(expression)
,将任何 swift 表达式插入到 html 模板的文本部分 - 属性值内部和标签之间的文本。
有几种类型的控制属性,可以分为 3 组
大多数 html 标签都可以配备条件控制属性之一
如果条件(必须是有效的 Swift 表达式)满足,则渲染 html 标签及其内容。
如果条件满足,则一个名为 previousUnnamedIfTaken
的特殊变量将被设置为 true。否则,它将被设置为 false。
可选地,您可以使用附加属性将条件的结果保存到不同的变量
<r-extend name="template-name" />
(必须在任何标签之前,除了 r-require) 将当前模板包装到指定模板的默认插槽中<r-require label="optional-label" name="var-name" type="var-type" default="optional-default" />
(必须在任何标签之前,除了 r-extend) 定义一个必须从调用者传递到模板的变量<r-require label="optional-label" name="var-name" type="var-type" default="optional-default" mutable />
或者如果您需要将其重映射到同名的可变变量local-only
属性以防止它在外部作用域中被 require。在这种情况下,您必须为此参数提供自己的参数。警告!这将禁用具有 local-only
属性的枚举的所有协议一致性。<r-include name="template-name" />
包含另一个模板,或者<r-include name="template-name"> 默认插槽 </r-include>
包含一个提供默认插槽的模板<r-block> 一些数据 </r-block>
对模板的某些部分进行分组,例如,用它包装一些文本,现在您可以对其应用控制属性。<r-set name="attr-name" value="attr-value" />
替换前一个标签中的属性 (跳过其他 set/unset 标签),或者<r-set name="attr-name" value="attr-value" append />
改为附加到它<r-unset name="attr-name" />
从前一个标签中删除属性 (跳过其他 set/unset 标签)<r-var name="var-name" line="expression" />
将表达式的结果赋值给变量<r-value of="name" default="optional-val" />
粘贴指定变量的值,或者如果该值为 nil
,则粘贴提供的默认值<r-eval line="expression" />
将表达式按原样粘贴到生成的代码中<r-slot name="optional-name" />
标记一个要由传入的外部插槽填充的区域。如果未提供名称,则它将被称为 'default',或者<r-slot name="optional-name"> 默认插槽 </r-slot>
声明一个插槽并提供默认内容,如果在传入的外部插槽中未找到匹配的插槽它分两个阶段运行。编译阶段和运行时阶段。