Scala / Lift - 试图理解 Lift 同时声称使用有效 html 和提升倾向:渲染中的标签和标签重写

Posted

技术标签:

【中文标题】Scala / Lift - 试图理解 Lift 同时声称使用有效 html 和提升倾向:渲染中的标签和标签重写【英文标题】:Scala / Lift - Trying to understand Lift's simultaneous claim to use valid html and propensity for lift: tags and tag rewriting in render 【发布时间】:2011-09-20 16:49:31 【问题描述】:

所有七件事 (http://seventhings.liftweb.net/) 都很好,但我对模板 (http://seventhings.liftweb.net/templates) 中声称“Lift 支持设计师友好的模板”特别感兴趣。

作为学习 Lift 做事方式的步骤之一,我尝试创建一个简单的对象创建表单:获取一些参数,将它们用作构造函数参数,然后将对象存放起来。经过一些研究和实验,我有两个担忧:

    似乎有相当大的倾向在 sn-ps 中显着重写/修饰模板标记。 表单似乎没有使用有效或可识别的 html 元素。

我的依据是:

表单示例/文档似乎都是关于特殊提升:标签。 Exploring Lift 建议表单应如下所示:(http://exploring.liftweb.net/master/index-6.html)

<lift:Ledger.add form="POST">
  <entry:description />
  <entry:amount /><br />
  <entry:submit />
</lift:Ledger.add>

我什至不确定这是否是有效的 html5,虽然它可能是有效的 xhtml,但对于我们的设计师朋友来说,这并不符合让您的模板看起来像真正的 html 的精神。我在其他地方读到(无法再找到它)我们确实可以选择使用实际输入标签,但是我们不会得到 Lift 的花哨形式接线或类似的某些部分,段落不是很清楚关于我究竟会错过什么,并且这些示例似乎对我编写一个普通的 html 表单制作一个普通的 html 帖子不感兴趣。

demo.liftweb.net 示例 (1) 的代码表明您的模板应如下所示 (2)

<lift:surround with="default" at="content">
  <div class="lift:PersonScreen"></div>
</lift:surround>

PersonScreen sn-p 的代码也不是很清楚 (3)。还有其他几个模板示例,例如只有在特定位置的 ul 标记才会生成一系列复杂的 li,其中包含 sn-p 中的嵌套元素。当然,您可以在 Scala 中使用 xml 并且它的读取效果还不错,但它仍然会将您的标记分散到各处。这似乎违背了“设计师友好模板”的精神。

我想了解的内容。

长期以来,我在 webapp 开发中严格遵循两条规则:

    “代码”(控制器、业务模型)中没有标记。 模板中没有任何业务逻辑。

Idiomatic Lift 似乎完全放弃了第一条规则,完全忽略了第二条规则的价值。这些规则对我很有帮助,我还没有准备好跟随那些似乎违反它们的例子,而不理解为什么它不会造成混乱。我想了解为什么在 Lift 中可以在 Snippets 中生成如此多的显示代码。我还想了解为什么模板中的标记很少反映输出是可以的。

我(认为我)想要什么:

我希望我的所有标记都包含在我的模板中,如果有的话,例外情况很少。我希望我的 sn-ps 做最少的模板修改,通常只替换“叶子”标签上的元素文本并可能调整属性值。我想我已经为一个相当复杂的显示示例做了这个,我怀疑我可以使用相同的技术来生成一个普通的 html 表单,然后自己处理参数。如果我希望我的模板看起来像最终结果表单,我需要这样做吗?

非常感谢您的回复和任何其他想法,尤其是关于了解 Lift 对这些东西的心态。

谢谢!

    http://demo.liftweb.net/simple_screen?F674431078927QJVVYD=_ https://github.com/lift/examples/blob/master/combo/example/src/main/webapp/simple_screen.html https://github.com/lift/examples/blob/master/combo/example/src/main/scala/net/liftweb/example/snippet/Wizard.scala#L94

编辑

回应@OXMO456。 (感谢您的回复。)

我有,他们似乎只是证实了我的担忧:例如我们开始:

Lift 模板不包含可执行代码。它们是纯粹的、原始的、有效的 HTML。

这太棒了。后来:

后两种调用 sn-ps 的机制不会产生有效的 Html5 模板。

然而每个人似乎都使用这两种机制中的第一种。此外,它说:

第三,设计者不必担心为了设计 HTML 页面而学习编程,因为程序执行是从 HTML 中抽象出来的,而不是嵌入在 HTML 中。

但与我在 OP 中引用的示例 sn-ps 完全一致,它完全以编程方式生成标记。这似乎与以下目标背道而驰:(a) 拥有对设计师友好的模板,这样设计师就不必为 Freemarker 标记所困扰,以及 (b) 将显示逻辑与业务逻辑分开。

第二个链接很有帮助且具有启发性,但它清楚地表明这不是 The Lift Way。然而,The Lift Way 似乎也将整个标记生成负载拖到了 sn-ps 中,(我认为)这是标记和业务逻辑的巨大复合。那是电梯道吗?

【问题讨论】:

嗨,你看过simply.liftweb.net/index-3.4.html#toc-Section-3.4(模板)和simply.liftweb.net/index-4.1.html#toc-Section-4.1(表单)吗? 【参考方案1】:

那些是旧式标签,不是设计师友好的标签。

<lift:MySnippet>
  <b:field />
</lift:MySnippet>

变成

<div class="lift:MySnippet">
  <div class="field"></div>
</div>

旧式 Lift 模板是有效的 XML,而不是 XHTML - 所以你不能有未封闭的标签或任何东西 - 这使 Lift 与大多数框架不同,后者将模板视为原始字符串,其中包含一些相互交织的代码,而不考虑标签或结构。

顺便说一句,在旧式标签中,这些字段都是虚构的 - 它们不是某些标准 Lift 标签集的一部分。我也可以轻松做到:

<lift:MySnippet>
  <frobnicate:blorb />
</lift:MySnippet>

只要我的 sn-p 代码正在寻找那个特定的标签。

Lift 不允许在您的模板中使用 任何 逻辑。所有逻辑都发生在您的 Snippet 类中。所以对于上面对设计者友好的例子,我可能有一个像这样的 sn-p 类:

 class MySnippet  
   def render(in: NodeSeq): NodeSeq = ".field" #> Text("some text here")
 

这会产生这个结果:

 <div>
   <div class="field">some text here</div>
 </div>

不可能在 Lift 模板中添加任何逻辑 - 他们所能做的就是调用 Lift sn-ps,这是所有工作都在其中发生的常规 Scala 类。

Lift 放弃了在实际代码中不应有任何显示逻辑的规则。为什么?因为它可以生成更多可重用的代码,因为 Scala 在语言中嵌入了强大的 XML 支持,而且您的所有逻辑现在都被视为普通的旧 Scala 代码。

如果我定义了一个名为 CurrentTime 的 Lift sn-p,我可以简单地将其放入任何模板中,它会显示当前时间 - 对于老式 MVC 框架,每个操作方法都需要将时间设置为page 变量,然后我的模板需要修改才能打印出来。对于更复杂的逻辑,老式框架可能需要在模板中添加条件。 Lift 不允许这样做 - 您的所有逻辑都是常规 Scala 代码,符合重构条件、易于测试并与现代 IDE 兼容。

【讨论】:

优秀的答案。然而,Lisp 的模板机制是 Lisp 的一种变体(非常冗长)......所以可以添加一些 sn-ps 来使 Lift 的模板机制图灵完备......但是 sssshhhh...... 不要告诉任何人. ;-)【参考方案2】:

在回答您“我认为我想要什么”的问题时,请确保您可以毫无问题地做到这一点。 Lift 真的是关于选择和理解你的用例。您看到的示例通常与 Lift 混合代码和标记,这当然是次优的。需要注意的重要一点是,从概念上讲,sn-ps 仅用于生成标记和渲染视图。

此外,由于 Lift 遵循其视图第一范式,视图实际需要的唯一内容是概述您希望在哪个渲染 sn-ps 中处理标记的哪些部分。有几种方法,如 OP 和“Bill”所示,但我个人更喜欢:

<div lift="YourSnippet.method">
  <p>Some other code</p>
</div>

这是更可取的,因为这样您就不会培养 (IMO) 可能会让设计师感到困惑的类属性。 Lift 可能对设计师非常友好,但我认为这里的主要问题是,在编写 sn-ps 时必须遵守纪律,同时忽略当今可用的许多混合 Scala 和标记的示例。

您可能也对这篇文章感兴趣(http://blog.getintheloop.eu/2011/04/11/using-type-classes-for-lift-snippet-binding/);使用这种模式,您可以定义渲染逻辑的解耦、可重用部分,同时将您的业务逻辑安全地排除在 sn-ps 之外。

最后,并不想无耻地推广我自己的产品,但我特意在我的 Lift in Action 示例代码中不使用任何混合的 Scala xml 文字(除了说明它的可能),所以如果您正在查看 Lift (http://manning.com/perrett/),也许它可能会有所帮助

【讨论】:

以上是关于Scala / Lift - 试图理解 Lift 同时声称使用有效 html 和提升倾向:渲染中的标签和标签重写的主要内容,如果未能解决你的问题,请参考以下文章

您能否为使用 Scala 的 Lift 框架制作的 webapp 推荐一个好的共享托管服务提供商? [关闭]

框架比较:Lift、Play 和 Wicket

Scalaz(32)- Free :lift - Monad生产线

什么Scala Web框架可用? [关闭]

Monad 在从 Lift 移植到 Yesod 的 Persistent 时遇到了麻烦

深度学习特征检测LIFT,learnd invariant feature transform