- 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:
- 測試驅(qū)動開發(fā):入門、實戰(zhàn)與進(jìn)階
- 程序員面試筆試寶典
- C#完全自學(xué)教程
- 大學(xué)計算機(jī)基礎(chǔ)(第2版)(微課版)
- Hands-On Microservices with Kotlin
- 區(qū)塊鏈底層設(shè)計Java實戰(zhàn)
- Yii Project Blueprints
- C++從入門到精通(第5版)
- 編程菜鳥學(xué)Python數(shù)據(jù)分析
- 現(xiàn)代C++編程實戰(zhàn):132個核心技巧示例(原書第2版)
- 匯編語言編程基礎(chǔ):基于LoongArch
- Learning Material Design
- Python自然語言理解:自然語言理解系統(tǒng)開發(fā)與應(yīng)用實戰(zhàn)
- 計算機(jī)應(yīng)用技能實訓(xùn)教程
- Python全棧開發(fā):基礎(chǔ)入門