Bellevue View Engine 入门 - 第一部分
一个用于 ASP.NET MVC 框架的新模板引擎的原型,它尊重 HTML 并使用类似 CSS 的语法进行模型绑定。

引言
Bellevue 是一个用于 ASP.NET MVC 框架的新开源模板引擎的原型。Bellevue 的核心使用纯 HTML - 不添加任何额外的标签或语法。然后,它使用类似 CSS 的语法将活动逻辑注入 HTML - 换句话说:将数据从模型绑定到视图。
在第一部分中,我将涵盖基础知识。
- 设计目标
- 简而言之的想法
- 路线图
- 在 Visual Studio 中入门
- 声明
- 相对定位
- 函数
- 调试器
第二部分 在此,它将深入探讨更高级的功能,并讨论设计和我计划的未来功能。
设计目标
这项新技术/视图引擎的设计目标是:
- 尊重 HTML 作为一等公民语言,而不是将其视为“仅仅是文本”。
- 不要弄乱我的 HTML! 数据绑定代码(Bellevue 代码)应与 HTML 分开。
- 强制实施 Terence Parr 在此所述的严格模型-视图分离。
简而言之的想法
几乎所有现有的模板引擎(MVC 视图引擎)都从 HTML 开始,但然后迫使开发人员修改此 HTML 以在 HTML 中插入活动内容。
例如,在 ASP.NET Web Forms 中,您会在想要显示活动内容的位置添加 <% ... %>
标签。

这些修改使得原始 HTML 在许多用途下都无法使用:它不再能在 Web 浏览器中独立显示,并且大多数 WYSIWYG 编辑器也无法正确显示它。
Bellevue 采取了不同的方法。它保持 HTML 的原始结构不变。

...然后使用独立的类似 CSS 的脚本将活动内容注入 HTML 中。

Bellevue View Engine 是一个完全兼容 ASP.NET MVC 的视图引擎:它将支持 ASP.NET MVC 的所有功能,您可以将其与 Web Forms 视图甚至其他视图引擎混合使用。它将以某种我尚未决定的许可证开源发布。我保留发布附加工具或商业许可证版本的道德权利,但基本视图引擎将是免费的。
路线图

在我们深入代码之前,让我们明确预期:这是一个演示该想法的预览。即使我发布了源代码,这篇文章的重点也是获得一些关于该想法的反馈 - 而不是真正关于实现。
如果您正在寻找可以在生产环境中实际使用的东西,请在一两个月后回来查看。我将开始进行大规模重写以修复粗糙的代码,并且我应该有望在五月至六月期间实现更具生产级别的实现。
有了这个免责声明,让我们深入代码...
在 Visual Studio 中入门
以下所有代码都位于下载包的 Ope.Bellevue.DemoWeb
项目中。
要在新的 Visual Studio ASP.NET MVC 项目中开始使用 Bellevue,您需要首先引用“Ope.Bellevue.dll”。然后,您需要将 Bellevue 视图引擎的注册添加到您的“Global.asax.cs”文件中。
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
// Uncomment this line, if you are not using aspx pages / ascx controls at all.
// ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new Ope.Bellevue.BellevueViewEngine());
}
现在您就可以添加 Bellevue 视图了。视图只是一个带有 .htm 或 .html 后缀的 HTML 文件。这里的示例是“/Views/Demo/Demo1_Intro_Bellevue.html”,其 body 的上半部分具有以下 HTML:
<div id="menucontainer">
<h1>Info about <b>Product 1</b></h1>
</div>
要将“Product 1
”文本更改为来自控制器(ViewData["Name"]
)的文本,我们将在 HTML 文件的 head
部分添加以下 Bellevue 脚本:
<script type="text/bellevue">
h1 b { text: data(Name); }
</script>
让我们来分析一下:script
标签就像 HTML 标准中的普通 script
标签一样。我们使用的 type 不是“text/JavaScript
”,而是“text/bellevue
”。这是 Bellevue 解析器识别其内容并在服务器端将该脚本应用于 HTML 文档的标记。如果页面未经过 Bellevue 视图引擎加载(例如,直接从文件系统到浏览器),浏览器将简单地忽略它不识别的 type 的 script
。
script
的语法就像 CSS 一样:我们有一个选择器“h1 b
”,它将选择目标元素并将声明“text: data(Name)
”应用于该元素。声明“text
”告诉系统用值替换内部文本,在这个例子中是函数“data(Name)
”。这将返回 ViewData["Name"]
或 ViewData.Model.Name
。
当然,script
也可以是一个 include
文件,就像在“Demo2_Intro_Bellevue.html”中一样。
<script type="text/bellevue" src="Demo2_Intro_Bellevue.bvue"></script>
include
文件必须具有 .bvue 后缀,但可以在 src
属性中省略后缀。Include 文件就像部分视图一样被搜索,所以它们也可以放在 Shared 文件夹中。
选择器可以更复杂,例如在“Demo2_Intro_Bellevue.bvue”中。
#main table tr:nth-child(1) td:nth-child(2) { text: data(Name); }
我目前正在使用 Fizzler CSS 选择器和 HTML Agility Pack,CSS 解析器来自 BoneSoft 在此 Code Project。它们都是优秀的项目,但它们有一些限制和 bug,所以你无法获得 CSS Level 3 选择器的所有功能。但总的来说,它们是一组强大的功能。
声明
仅仅替换文本并不算什么,但当然还有其他声明。这个预览版本有以下声明:
text
:如上所述,请注意文本是 HTML 编码的。attr
:替换属性的值,属性已编码。html
:替换内部 HTML,未编码。text-format
:将给定的string
格式应用于对象。text-replace
:将原始内部文本中指定的文本替换为新文本。checked
:设置输入的 checked 属性。style
:设置 style 属性。class
:设置 class 属性。value
:设置 value 属性。apply-template
:参见下面的模板。render-control
:渲染一个部分视图。- 可以是 Bellevue 部分视图,也可以是 ascx(或来自任何其他正确实现的 ASP.NET 视图引擎)。
action-link
:与 Web Forms 中的HtmlHelper.ActionLink()
相同。- 这是一个关于如何通过 Bellevue 使用 HTML 辅助方法的原型。
- 我计划实现其他辅助方法,但我需要仔细考虑所有这些重载并思考它们如何才能有意义。
要获取有关如何使用这些声明的更多详细信息,请参阅“Declarations.html”视图。其中包含一些示例。
相对定位
CSS 选择器始终匹配单个元素。默认情况下,大多数声明都以选择器匹配的元素的内部节点(或内部 HTML)为目标,例如 p { text: "foo" }
将把 <p>any html</p>
内部的 HTML 替换为 <p>foo</p>
。
有时这还不够,但您可以通过使用声明名称的标准后缀来获得更多控制。
-outer
:替换元素的外部 HTML。-add
:在元素内部附加一个新节点。-insert
:将一个新节点插入为元素中的第一个子节点。-before
:将一个新节点插入到元素正前方。-after
:将一个新节点插入到元素正后方。-inner
:明确指示目标为内部 HTML。添加此项是为了防止某些声明默认不以内部 HTML 为目标。可能在后续版本中移除。
有关更多信息和示例,请参阅演示项目中的“Demo5_RelativePosition.html”。
函数
我们上面已经使用了“data()
”函数,但当然还有其他函数。当前实现包含以下集合:
first(collection)
:集合中的第一个或唯一一个项。last(collection)
:集合中的最后一个或唯一一个项。rest(collection)
:集合中除了第一个项之外的所有项。trunc(collection)
:集合中除了最后一个项之外的所有项。strip(collection)
:去除null
值的集合。length(collection)
:集合的长度。join(collection, separator)
:连接集合中的所有项。item(property path)
:从传递给模板的当前项中获取数据对象。index(base)
:当前项的从零开始的索引号,加上基础编号。get(container, property path)
:从任何对象中获取属性。data(property path)
:从ViewData
对象中获取数据。model(property path)
:从ViewData.Model
对象中获取数据。concat(value1, value2, valueN)
:连接string
值。if(condition, value if true, value if false)
:类似于 C# 中的三元运算符(“?
”)。isnull(value, value if null)
:类似于 SQL。false()
:布尔值false
。null()
:Null
值。true()
:布尔值true
。
您可以嵌套函数,其中很多函数与 StringTemplate 中的函数相同。大多数函数可能都很明显,但有一个参考 在此 - 它也包含在演示项目中。
调试器
如果您查看了演示项目中的任何示例,您肯定会注意到每个页面的底部都有“Bellevue 调试器”。调试器显示可能的警告和错误、应用于元素的规则集以及模型(有限实现)和 ViewData
字典的内容。
调试器现在默认开启,但如果它打扰您,您可以通过修改 Global.asax.cs 来关闭它。
var engine = new Ope.Bellevue.BellevueViewEngine();
engine.ShowDebugger = false;
ViewEngines.Engines.Add(engine);
这当然只是一个临时实现。在最终版本中,您将对调试器有更多的控制,但在现阶段,您通常需要查看调试信息。
等等,还有更多...
这些就是基础知识。如果您对此感兴趣,第二部分将带您了解模板和母版页。演示已包含在此下载项目中。我还会提供有关未来开发想法的更多信息,并讨论设计和实现。