- Lift Application Development Cookbook
- Gilberto T. Garcia Jr.
- 752字
- 2021-08-04 10:05:44
Nesting snippets
Snippets are lazily evaluated, which means that the Inner
snippet will not be invoked until the Outer
snippet is evaluated. By using this neat feature, we can nest snippet invocations in our HTML templates, and thus gain a powerful tool to dynamically generate HTML with a fine-grained control. For example, you can use this feature to show different things to your users depending on whether they are logged in or not and on their authorization level. We'll learn how to do this in this recipe.
Getting ready
Create a new project and add the following designer-friendly HTML code into the index.html
file to invoke the snippet and trigger all of the mechanisms to render snippets recursively:
<div data-lift="Outer.choose"> <div class="inner-div"></div> </div>
How to do it...
Nesting snippets can be done by following these steps:
- Create a file called
Outer.scala
in thesnippet
package with the following content:import net.liftweb.util.Helpers._ import net.liftweb.http.S import net.liftweb.util.BasicTypesHelpers._ import net.liftweb.common.Full object Outer { def choose = { val loggedIn = S.param("loggedin").flatMap(asBoolean) loggedIn match { case Full(b) if b => ".inner-div [class+]" #> "lift:Inner.logged" case _ => ".inner-div [class+]" #> "lift:Inner.nonlogged" } } }
After building the
Outer
snippet, we'll build theInner
one. - Create a file called
Inner.scala
in thesnippet
package with the following content:import net.liftweb.util.Helpers._ object Inner { def logged = { "div *" #> "Should only be visible when user is logged in" } def nonlogged = { "div *" #> "Should only be visible when user is not logged in" } }
- Access the following URLs to test this example:
http://localhost:8080?loggedin=true
http://localhost:8080?loggedin=false
http://localhost:8080
You will see the following output, as shown in the following screenshot:
How it works...
As you can see, the only snippet invocation in the HTML file is the invocation of the Outer
snippet; the rest of the HTML is just plain HTML markup—nothing special or new. But we have two snippets and only one invocation in the HTML file. As it turns out, when Lift starts to process HTML, it will find the snippet invocation and will pass the HTML code to it.
The Outer
snippet will check for the presence of the loggedin
parameter. It does this by using the param
method of the S
object; it then uses this parameter to choose which snippet will be rendered next.
Note
S
is an object that holds the HTTP requests/responses and HTTP session state.
When we invoke the S
object's param
method, it will try to get a query string—having the key passed as parameter to the param
method—from the URL.
The S.param
method returns Box[String]
; it will return Full[String]
if it successfully gets the query string, or Empty
if the key doesn't exist.
Box
is a container class that can be empty or full. If Box
contains a value different from null
, the box's value is Full(value)
; otherwise, the value of Box
will be Empty
. Other possible values for an empty box are Failure
and ParamFailure
, which can include the reason why the box is empty.
If the parameter is true, it will append lift:Inner.logged
to the class
attribute of the div
tag with inner-div
as value of the class
attribute; if the parameter is false or non-existent, it will append lift:Inner.nonlogged
to the class
attribute.
Note
How does Lift know that we want to append something to the class
attribute of a tag? By using the [attr+]
selector, we tell Lift to append the result of the right-hand side of the #>
operator to the tag
attribute. Since we used [class+]
, we told Lift to append lift:...
to the class
attribute.
You can read more about CSS Selector Transforms at http://simply.liftweb.net/index-7.10.html.
Once the Outer
snippet finishes its job, the transformed HTML—if the value of the loggedin
parameter is true
—will look like the following code:
<div> <div class="inner l:Inner.logged"></div> </div>
We no longer have the invocation of the Outer
snippet. The HTML will now invoke the Inner
snippet, which is a snippet that will render some text inside the div
tag. The final HTML will look the following code:
<div> <div class="inner"> Should only be visible when user is logged in </div> </div>
What we did is:
- Invoke the
Outer
snippet. - Choose which snippet should be called, based on some condition.
- Return HTML that contains in itself an invocation to another snippet—the
Inner
snippet. - Process the HTML in the
Inner
snippet. - Return the transformed HTML.
That's all you need to create nested calls to snippets in Lift.
See also
You can read more about snippets at:
- C和C++安全編碼(原書(shū)第2版)
- 我的第一本算法書(shū)
- Mastering Unity Shaders and Effects
- Java應(yīng)用開(kāi)發(fā)技術(shù)實(shí)例教程
- The HTML and CSS Workshop
- Kotlin從基礎(chǔ)到實(shí)戰(zhàn)
- 批調(diào)度與網(wǎng)絡(luò)問(wèn)題的組合算法
- Getting Started with Eclipse Juno
- .NET Standard 2.0 Cookbook
- MySQL程序員面試筆試寶典
- 深入解析Java編譯器:源碼剖析與實(shí)例詳解
- Learning Grunt
- 從零開(kāi)始學(xué)UI設(shè)計(jì)·基礎(chǔ)篇
- HTML5程序開(kāi)發(fā)范例寶典
- 深入理解Zabbix監(jiān)控系統(tǒng)