### Start Lift Server with sbt (~jetty:start)
Source: https://github.com/lift/framework/blob/main/README.md
Navigate to your application folder and run this command in the SBT prompt to start the development server. The application will recompile and restart on code changes.
```bash
~jetty:start
```
--------------------------------
### Setup for User Data
Source: https://github.com/lift/framework/blob/main/docs/css-selectors.adoc
Defines a case class for User and an instance of it for use in examples.
```scala
case class User(name: String)
val user = User("Benedict Cumberbatch")
```
--------------------------------
### Quickstart Lift Server with sbt (jetty:quickstart)
Source: https://github.com/lift/framework/blob/main/README.md
Use this command for a faster server restart when primarily working on frontend assets like CSS or HTML. It serves directly from the src directory, but manual Scala compilation is required.
```bash
jetty:quickstart
```
--------------------------------
### Lift 2.6 Simple Pagination Example
Source: https://github.com/lift/framework/blob/main/docs/migration/2.6-to-3.0-paginator.adoc
Illustrates the old bind-style pagination structure using nav:* elements.
```html
```
--------------------------------
### Create New Lift Project with sbt (Basic)
Source: https://github.com/lift/framework/blob/main/README.md
Use this command to create a new, basic Lift application with example code using sbt and Giter8.
```bash
sbt new lift/basic-app.g8
```
--------------------------------
### Lift 2.6 Pagination Example with All Pages
Source: https://github.com/lift/framework/blob/main/docs/migration/2.6-to-3.0-paginator.adoc
Demonstrates the use of nav:allpages in Lift 2.6 for displaying all page links with a delimiter.
```html
|
```
--------------------------------
### Lift REST handler example
Source: https://github.com/lift/framework/blob/main/docs/simply_lift.md
An example of a REST handler within Lift, showcasing how 'for' comprehensions and Box types are used to process request parameters and handle potential errors gracefully.
```scala
serve {
case Req("user" :: "info" :: Nil, "xml", GetRequest) =>
for {
id <- S.param("id") ?~ "id param missing"
user <- User.find(id.toLong) ?~ userNotFoundMessage(id)
} yield
toXml(user)
}
```
--------------------------------
### Lift 3.0 Simple Pagination Example
Source: https://github.com/lift/framework/blob/main/docs/migration/2.6-to-3.0-paginator.adoc
Shows the new CSS selector transform approach for pagination, replacing nav:* elements with CSS classes.
```html
First
Previous
Next
Last
```
--------------------------------
### Lift 3.0 Pagination Example with All Pages
Source: https://github.com/lift/framework/blob/main/docs/migration/2.6-to-3.0-paginator.adoc
Shows how to use the 'all-pages' CSS class in Lift 3.0 to specify the delimiter for all page links.
```html
First
Previous
|
Next
Last
```
--------------------------------
### Lift 3.0 Pagination Example with Zoomed Pages
Source: https://github.com/lift/framework/blob/main/docs/migration/2.6-to-3.0-paginator.adoc
Illustrates the use of the 'zoomed-pages' CSS class in Lift 3.0 for displaying a scaled subset of page links with a delimiter.
```html
First
Previous
|
Next
Last
```
--------------------------------
### Lift 'for' comprehension with Box
Source: https://github.com/lift/framework/blob/main/docs/simply_lift.md
Demonstrates using a 'for' comprehension with Lift's Box type, which can be Full, Empty, or a Failure. This example shows handling missing parameters and potential errors.
```scala
for {id <- S.param("id") ?~ "id param missing"
```
--------------------------------
### RESTful Endpoints Based on Request Suffix
Source: https://github.com/lift/framework/blob/main/docs/simply_lift.md
This example demonstrates how to serve different response types based on the request suffix (e.g., .xml, .json). Lift inspects the request's Accept header to determine the appropriate response format.
```scala
serve {
case Req("api" :: "static" :: Nil, "xml" ==: Suffix, _) =>
Response("Hello, world!", List(("Content-Type", "text/xml")))
case Req("api" :: "static" :: Nil, "json" ==: Suffix, _) =>
Response("{\"message\": \"Hello, world!\"}", List(("Content-Type", "application/json")))
}
```
```scala
serve {
case "api" :: "static" :: _ =>
// If you want to navigate your Web Service, you must remember to add a *.xml or *.json (depending in what you have implemented) at the end of the URL: http://localhost:8080/XXX/api/static/call.json http://localhost:8080/XXX/api/static/call.xml
serveJaxrs
}
```
--------------------------------
### Lift Dependency Injection with Scalatest Fixtures
Source: https://github.com/lift/framework/blob/main/docs/dependency-injection-liftweb-scala.adoc
This example shows how to integrate custom dependency injection with ScalaTest using a trait that overrides the `withFixture` method. This allows tests to run with a specific DependencyFactory instance.
```scala
trait DependencyOverrides extends SuiteMixin {
self: Suite =>
protected def dependencyFactory: Vendor[DependencyFactory] = DependencyFactory.instance
abstract override def withFixture(test: NoArgTest): Outcome = {
DependencyFactory.instance.doWith(dependencyFactory.vend) {
super.withFixture(test)
}
}
}
```
```scala
class SomeSpec extends ... with DependencyOverrides {
override val dependencyFactory: Vendor[DependencyFactory] = new DependencyFactory {
override def cardServiceVendor: Vendor[CardService] = mock[CardService]
// other overrides
...
}
}
```
--------------------------------
### Injecting Dependencies in a Class
Source: https://github.com/lift/framework/blob/main/docs/dependency-injection-liftweb-scala.adoc
This example shows how to inject dependencies managed by a FactoryMaker into a Scala class. It illustrates accessing singleton dependencies directly and using inject to retrieve other types, with error handling for missing instances.
```scala
class SomeClass {
private val emailService = DependencyFactory.emailService()
// Or alternatively, if you don't have the FactoryMaker for a given type
private val someType =
DependencyFactory.inject[SomeType]
.openOrThrowException("No instance of SomeType found")
}
```
--------------------------------
### Lift 2.6 Global Error Markup
Source: https://github.com/lift/framework/blob/main/docs/migration/2.6-to-3.0-lift-screen.adoc
Example of global error markup in Lift 2.6 using wizard: elements.
```html
```
--------------------------------
### Handle Hashchange Event
Source: https://github.com/lift/framework/blob/main/core/util/src/test/resources/net/liftweb/util/Html5ParserSpec.page2.html
Listens for the `hashchange` event, which fires when the URL fragment identifier changes. This example logs the event type but does not process hash changes.
```javascript
addEvent(window, 'hashchange', function (event) { reportEvent(event); // we won't do this for now - let's stay focused on states /\* if (event.newURL) { urlhistory.innerHTML = event.oldURL; } else { urlhistory.innerHTML = "no support for event.newURL/oldURL"; } \*/ });
```
--------------------------------
### Add Module Menus to SiteMap with Mutators
Source: https://github.com/lift/framework/blob/main/docs/simply_lift.md
SiteMap mutators allow modules to inject their menu items into the application's SiteMap. This example shows how to add custom menus using markers and applying the mutator during SiteMap registration.
```scala
/**
The module also makes a SiteMap mutator available, this can either be returned from the module's init method or via some other method on the module. ProtoUser makes the sitemapMutator method available which returns a SiteMap => SiteMap.
The application can add the marker to the appropriate menu item:
Menu("Home") / "index" >> User.AddUserMenusAfter
And when the application registers the SiteMap with LiftRules, it applies the mutator:
LiftRules.setSiteMapFunc(() => User.sitemapMutator(sitemap()))
Because the mutators are composable:
val allMutators = User.sitemapMutator andThen FruitBat.sitemapMutator
For each module, the implementation of the mutators is pretty simple:
private lazy val AfterUnapply = SiteMap.buildMenuMatcher(_ == AddUserMenusAfter)
We've defined some extractors that help with pattern matching. SiteMap.buildMenuMatcher is a helper method to make building the extractors super-simple. Then we supply a PartialFunction[Menu, List[Menu]] which looks for the marker LocParam and re-writes the menu based on the marker. If there are no matches, the additional rule is fired, in this case, we append the menus at the end of the SiteMap.
```
--------------------------------
### Overriding Default DependencyFactory Instance
Source: https://github.com/lift/framework/blob/main/docs/dependency-injection-liftweb-scala.adoc
This example shows how to override the default DependencyFactory instance for testing purposes. It's important to reset the default after use to avoid issues in parallel test runs.
```scala
class SomeSpec {
override def beforeAll = DependencyFactory.instance.default.set({
new DependencyFactory {
override def cardServiceVendor: Vendor[CardService] = mock[CardService]
}
})
override def afterAll: Unit = DependencyFactory.resetDefault
}
```
--------------------------------
### Handle Click Events for History Push
Source: https://github.com/lift/framework/blob/main/core/util/src/test/resources/net/liftweb/util/Html5ParserSpec.page2.html
Intercepts click events on anchor tags within the 'examples' element. Prevents default navigation, extracts data, and pushes a new state to the browser history using `history.pushState`.
```javascript
addEvent(examples, 'click', function (event) { var title; event.preventDefault(); if (event.target.nodeName == 'A') { title = event.target.innerHTML; data[title].url = event.target.getAttribute('href'); // slightly hacky (the setting), using getAttribute to keep it short history.pushState(data[title], title, event.target.href); reportData(data[title]); } });
```
--------------------------------
### Scala Option Type Example
Source: https://github.com/lift/framework/blob/main/docs/simply_lift.md
Demonstrates the Scala Option type, which provides a type-safe way to handle potentially missing values, contrasting with Java's null and Ruby's nil. The Option[T] type has two subclasses: Some(T) for a value and None for absence.
```Scala
def findUser(name: String): Option[User] = {
```
--------------------------------
### Create New Lift Project with sbt (Blank)
Source: https://github.com/lift/framework/blob/main/README.md
Use this command to create a new, entirely blank Lift application using sbt and Giter8.
```bash
sbt new lift/blank-app.g8
```
--------------------------------
### Build Lift from Source
Source: https://github.com/lift/framework/blob/main/README.md
Clone the Lift framework repository and use the `liftsh` script to build components. Ensure you are in the framework directory before running the script.
```bash
git clone https://github.com/lift/framework.git
cd framework
./liftsh +update +publish
```
--------------------------------
### Content Negotiation by Accept Header
Source: https://github.com/lift/framework/blob/main/docs/simply_lift.md
Shows how to configure Lift to respond based on the `Accept` header of the HTTP request.
```APIDOC
## Content Negotiation by Accept Header
### Description
Lift can also negotiate the response type by inspecting the `Accept` header sent by the client.
### Method
Use the `serve` block and specify the desired response types.
### Endpoint
Any endpoint handled by the `serve` block.
### Request Example
```scala
serve {
case Req("api" :: "static" :: "call" :: Nil, _, _) =>
// Lift checks the Accept header and responds with the most appropriate type
// (e.g., application/json or application/xml)
OkResponse() // Placeholder for actual response
}
```
### Response
#### Success Response (200)
Response content type is determined by the client's `Accept` header.
```
--------------------------------
### HTML5 History API Initialization and Event Handling
Source: https://github.com/lift/framework/blob/main/core/util/src/test/resources/net/liftweb/util/Html5ParserSpec.page3.html
Sets up event listeners for clicks on links to trigger `pushState` and for `popstate` events to handle browser navigation. It also checks for History API support.
```javascript
var $ = function (s) { return document.getElementById(s); }, state = $('status'), lastevent = $('lastevent'), urlhistory = $('urlhistory'), examples = $('examples'), output = $('output'), template = '
URL: **{url}**, name: **{name}**, location: **{location}**
', data = { // imagine these are ajax requests :) first : { name: "Remy", location: "Brighton, UK" }, second: { name: "John", location: "San Francisco, USA" }, third: { name: "Jeff", location: "Vancover, Canada" }, fourth: { name: "Simon", location: "London, UK" } }; function reportEvent(event) { lastevent.innerHTML = event.type; } function reportData(data) { output.innerHTML = template.replace(/(:?\{(.\*?)\})/g, function (a,b,c) { return data[c]; }); } if (typeof history.pushState === 'undefined') { state.className = 'fail'; } else { state.className = 'success'; state.innerHTML = 'HTML5 History API available'; } addEvent(examples, 'click', function (event) { var title; event.preventDefault(); if (event.target.nodeName == 'A') { title = event.target.innerHTML; data[title].url = event.target.getAttribute('href'); // slightly hacky (the setting), using getAttribute to keep it short history.pushState(data[title], title, event.target.href); reportData(data[title]); } }); addEvent(window, 'popstate', function (event) { var data = event.state; reportEvent(event); reportData(event.state || { url: "unknown", name: "undefined", location: "undefined" }); }); addEvent(window, 'hashchange', function (event) { reportEvent(event); // we won't do this for now - let's stay focused on states /* if (event.newURL) { urlhistory.innerHTML = event.oldURL; } else { urlhistory.innerHTML = "no support for `event.newURL/oldURL`"; } */ }); addEvent(window, 'pageshow', function (event) { reportEvent(event); }); addEvent(window, 'pagehide', function (event) { reportEvent(event); });
```
--------------------------------
### Customize CSS Class Bindings in Lift 3.0
Source: https://github.com/lift/framework/blob/main/docs/migration/2.6-to-3.0-lift-screen.adoc
Override the cssClassBinding in your LiftScreen subclass to customize CSS class names, for example, to use dasherized names instead of camelCase.
```scala
protected override lazy val cssClassBinding = new CssClassBinding {
override val screenInfo = "screen-info"
override val screenNumber = "screen-number"
override val totalScreens = "total-screens"
override val wizardTop = "wizard-top"
override val screenTop = "screen-top"
override val wizardBottom = "wizard-bottom"
override val screenBottom = "screen-bottom"
override val globalErrors = "global-errors"
override val fieldContainer = "field-container"
}
```
--------------------------------
### Add Page to SiteMap
Source: https://github.com/lift/framework/blob/main/docs/getting-started-tutorial/2-the-lift-menu-system.adoc
Define a menu item for the 'Chat' page, linking it to the 'chat.html' template. The string passed to 'i' is the menu name, and the path after '/' specifies the template location.
```scala
...
Menu.i("Chat") / "chat"
...
```
--------------------------------
### Basic Transformation with String
Source: https://github.com/lift/framework/blob/main/docs/css-selectors.adoc
Demonstrates a basic transformation using a String as the transformation function. The `CanBind[String]` is implicitly used, and the function is applied to each matched element.
```scala
"input" #> "Hello"
with the HTML ,
an instance of `CanBind[String]` is used, and is called twice; first as
stringBind("Hello")() and then as
stringBind("Hello")(). Note that a `CanBind[String]` is
already provided by default.
```
--------------------------------
### Setting Session-Scoped Dependency in Boot.scala
Source: https://github.com/lift/framework/blob/main/docs/dependency-injection-liftweb-scala.adoc
Configure a new instance of a dependency to be created for each session using Lift's lifecycle hooks in Boot.scala.
```scala
class Boot {
LiftSession.afterSessionCreate = ((_: LiftSession, req: Req) => {
DependencyFactory.awesomeService.session.set(new AwesomeService {})
}) :: LiftSession.afterSessionCreate
...
}
```
--------------------------------
### Add Lift and Logback Dependencies to sbt
Source: https://github.com/lift/framework/blob/main/README.md
Add the necessary Lift webkit and Logback dependencies to your existing sbt project's libraryDependencies.
```scala
libraryDependencies ++= {
val liftVersion = "3.3.0"
Seq(
"net.liftweb" %% "lift-webkit" % liftVersion % "compile",
"ch.qos.logback" % "logback-classic" % "1.2.3"
)
}
```
--------------------------------
### Enable JettyPlugin in sbt
Source: https://github.com/lift/framework/blob/main/README.md
Enable the JettyPlugin in your existing sbt project's build.sbt file to integrate with the xsbt-web-plugin.
```scala
enablePlugins(JettyPlugin)
```
--------------------------------
### Type Conversion of Path Parameters
Source: https://github.com/lift/framework/blob/main/docs/simply_lift.md
Demonstrates how to automatically convert extracted path parameters to specific types (e.g., Long) and handle conversion failures.
```APIDOC
## Type Conversion of Path Parameters
### Description
Extracted path parameters can be automatically converted to a desired type (e.g., `Long`). The pattern match only succeeds if the conversion is successful.
### Method
Use type annotations in the pattern match within the `serve` block.
### Endpoint
Example: `/api/items/456` where `456` is converted to a `Long`.
### Request Example
```scala
serve {
case Req("api" :: "items" :: id :: Nil, _, _) if id.toLongOption.isDefined =>
// 'id' is successfully converted to a Long
val itemId: Long = id.toLong
println(s"Item ID: $itemId")
OkResponse() // Placeholder for actual response
}
// Alternative using extractors for cleaner conversion:
serve {
case Req("api" :: "items" :: id(itemId) :: Nil, _, _) =>
// 'itemId' is already a Long due to the extractor
println(s"Item ID: $itemId")
OkResponse() // Placeholder for actual response
}
```
### Response
#### Success Response (200)
Successful dispatch and processing when the path parameter can be converted to the target type.
```
--------------------------------
### Implement a Basic Chat Actor
Source: https://github.com/lift/framework/blob/main/docs/getting-started-tutorial/7-using-actors-for-chat.adoc
Create a singleton LiftActor to store chat messages. The messageHandler processes incoming MessagePosted events by adding the new message to an internal list.
```scala
package code
package actor
import net.liftweb.actor._
case class ChatMessage(poster: String, body: String)
case class MessagePosted(message: ChatMessage)
object ChatActor extends LiftActor {
private var messageEntries = List[ChatMessage]()
def messageHandler = {
case MessagePosted(newMessage) =>
messageEntries ::= newMessage
}
}
```
--------------------------------
### Define basic Lift snippet methods
Source: https://github.com/lift/framework/blob/main/docs/getting-started-tutorial/3-adding-snippet-bindings.adoc
Define the 'messages' and 'sendMessage' methods in the 'Chat' object. These methods accept a NodeSeq and return it unchanged, serving as placeholders for future behavior.
```scala
package code
package snippet
import scala.xml._
object Chat {
def messages(contents: NodeSeq) = contents
def sendMessage(contents: NodeSeq) = contents
}
```
--------------------------------
### Setting Request-Scoped Dependency in Boot.scala
Source: https://github.com/lift/framework/blob/main/docs/dependency-injection-liftweb-scala.adoc
Configure a new instance of a dependency to be created for each request using Lift's lifecycle hooks in Boot.scala.
```scala
class Boot {
LiftSession.onBeginServicing = ((sess: LiftSession, req: Req) => {
DependencyFactory.awesomeService.request.set(new AwesomeService {})
}) :: LiftSession.onBeginServicing
...
}
```
--------------------------------
### Define RESTful Endpoints with RestHelper
Source: https://github.com/lift/framework/blob/main/docs/simply_lift.md
Extend RestHelper to create RESTful web services. Define URL patterns and corresponding response logic within the 'serve' block.
```scala
import net.liftweb.http._
LiftRules.dispatch.append(MyRest) // stateful -- associated with a servlet container session
serve {
case Req("api" :: "static" :: Nil, _) =>
Response("Hello, world!")
}
```
--------------------------------
### Basic Chat HTML Structure
Source: https://github.com/lift/framework/blob/main/docs/getting-started-tutorial/1-view-first-development.adoc
This HTML provides the initial structure for a chat application's user interface. It includes a list for displaying messages and a form for users to post new messages. This serves as a high-fidelity mockup for user testing before backend integration.
```html
Chat!
Hi!
Oh, hey there.
How are you?
Good, you?
```
--------------------------------
### Content Negotiation by Suffix
Source: https://github.com/lift/framework/blob/main/docs/simply_lift.md
Demonstrates how Lift can automatically determine the response type (e.g., JSON, XML) based on the request URL suffix.
```APIDOC
## Content Negotiation by Suffix
### Description
Lift can serve different response types (JSON, XML) based on the suffix of the request URL.
### Method
Use the `serve` block with pattern matching on the request.
### Endpoint
Example: `/api/static/call.json` or `/api/static/call.xml`
### Request Example
```scala
serve {
case Req("api" :: "static" :: "call" :: Nil, _, _) =>
// Logic to determine response type based on suffix
// For example, if the suffix is .json, return JSON
// If the suffix is .xml, return XML
// Lift handles the content type negotiation automatically
OkResponse() // Placeholder for actual response
}
```
### Response
#### Success Response (200)
Response content type (e.g., `application/json`, `application/xml`) is determined by the request suffix.
```
--------------------------------
### FactoryMaker vs Inject Declaration
Source: https://github.com/lift/framework/blob/main/docs/dependency-injection-liftweb-scala.adoc
Illustrates the declaration of dependencies using both FactoryMaker and Inject. Both can be used identically, but Inject is preferred when session/request scoped dependencies are not needed due to lower overhead.
```scala
object cardServiceFactoryMaker extends FactoryMaker(cardServiceVendor)
object cardServiceInject extends Inject(cardServiceVendor)
```
--------------------------------
### Applying Multiple Transforms Sequentially with `apply`
Source: https://github.com/lift/framework/blob/main/docs/css-selectors.adoc
Apply multiple transformations to a NodeSeq by passing the result of each transformation to the next. This method explicitly shows the sequential application.
```scala
val textReplaced = ("a *" #> "Mozilla") apply nodes
val final result = ("a [href]" #> "https://mozilla.org") apply textReplaced
```
--------------------------------
### Extracting Path Parameters
Source: https://github.com/lift/framework/blob/main/docs/simply_lift.md
Illustrates how to extract variables from the request URI using Scala's pattern matching.
```APIDOC
## Extracting Path Parameters
### Description
Path elements from the request URI can be extracted and used as variables within the `serve` block.
### Method
Use Scala's pattern matching within the `serve` block.
### Endpoint
Example: `/api/users/123` where `123` is an extracted ID.
### Request Example
```scala
serve {
case Req("api" :: "users" :: id :: Nil, _, _) =>
// 'id' is a String representing the extracted path element
println(s"User ID: $id")
OkResponse() // Placeholder for actual response
}
```
### Response
#### Success Response (200)
Successful dispatch and processing of the request.
```
--------------------------------
### Using serveJx for JSON/XML Conversion
Source: https://github.com/lift/framework/blob/main/docs/simply_lift.md
Introduces `serveJx` for scenarios where business logic produces a value that needs to be converted to JSON or XML based on the request type.
```APIDOC
## Using serveJx for JSON/XML Conversion
### Description
The `serveJx` method is useful when your business logic returns a value that needs to be automatically converted to either JSON or XML based on the request's `Accept` header or suffix.
### Method
Use `serveJx` in conjunction with conversion patterns (e.g., `JxCvtPF`).
### Endpoint
Endpoints configured with `serveJx`.
### Request Example
```scala
// Define a trait for convertible types
trait Convertable {
def toJson: String // Or appropriate JSON representation
def toXml: String // Or appropriate XML representation
}
// Define an implicit conversion pattern
implicit def cvt: JxCvtPF[Convertable] = {
case (JsonSelect, c, _) => c.toJson
case (XmlSelect, c, _) => c.toXml
}
// Define the REST service using serveJx
serveJx {
case Req("data" :: Nil, _, _) =>
// Business logic that returns a Box[Convertable]
Full(new Convertable { // Example implementation
def toJson = "{ \"message\": \"Hello JSON\" }"
def toXml = "Hello XML"
})
}
```
### Response
#### Success Response (200)
Lift automatically uses the `cvt` pattern to convert the `Convertable` object to JSON or XML based on the request context.
```
--------------------------------
### Registering a Custom Instance
Source: https://github.com/lift/framework/blob/main/docs/dependency-injection-liftweb-scala.adoc
Register a custom instance of a type with the DependencyFactory. This is useful for providing singletons or pre-configured objects.
```scala
class SomeOtherClass {
private val someTypeInstance = new SomeType
DependencyFactory.registerInjection[SomeType](() => someTypeInstance)
}
```
--------------------------------
### Basic REST Service
Source: https://github.com/lift/framework/blob/main/docs/simply_lift.md
Defines a basic REST service by extending RestHelper and appending it to LiftRules.dispatch.
```APIDOC
## Basic REST Service
### Description
This example shows how to create a simple REST service by extending `RestHelper` and registering it with Lift.
### Method
Append to `LiftRules.dispatch`
### Endpoint
Defined within the `serve` block.
### Request Example
```scala
import net.liftweb.http._
object MyRest extends RestHelper {
serve {
case Req("api" :: "static" :: Nil, _, _) =>
OkResponse()
}
}
// In Boot.scala:
// LiftRules.dispatch.append(MyRest)
```
### Response
#### Success Response (200)
An `OkResponse` is returned in this basic example.
```
--------------------------------
### Safe Dependency Overrides with doWith
Source: https://github.com/lift/framework/blob/main/docs/dependency-injection-liftweb-scala.adoc
Demonstrates a safer way to override dependencies using DependencyFactory.doWith, which avoids global state issues and is suitable for parallel test execution.
```scala
private val customDepFactory = new DependencyFactory {
override def cardServiceVendor: Vendor[CardService]
= mock[CardService]
}
DependencyFactory.instance.doWith(customDepFactory) {
// write all your tests here
}
```
--------------------------------
### Check HTML5 History API Support
Source: https://github.com/lift/framework/blob/main/core/util/src/test/resources/net/liftweb/util/Html5ParserSpec.page2.html
Checks if the browser supports the HTML5 History API by looking for the `history.pushState` method. Updates the UI to reflect availability.
```javascript
var $ = function (s) { return document.getElementById(s); }, state = $('status'), lastevent = $('lastevent'), urlhistory = $('urlhistory'), examples = $('examples'), output = $('output'), template = '
URL: {url}, name: {name}, location: {location}
', data = { // imagine these are ajax requests :) first : { name: "Remy", location: "Brighton, UK" }, second: { name: "John", location: "San Francisco, USA" }, third: { name: "Jeff", location: "Vancover, Canada" }, fourth: { name: "Simon", location: "London, UK" } }; function reportEvent(event) { lastevent.innerHTML = event.type; } function reportData(data) { output.innerHTML = template.replace(/(:?\{(.\*?)\})/g, function (a,b,c) { return data\[c\]; }); } if (typeof history.pushState === 'undefined') { state.className = 'fail'; } else { state.className = 'success'; state.innerHTML = 'HTML5 History API available'; }
```
--------------------------------
### Lift WebKit Factory for Scoped Injection
Source: https://github.com/lift/framework/blob/main/docs/simply_lift.md
Lift's WebKit extends SimpleInjector with Factory, enabling injection scoping based on HTTP requests or container sessions.
```scala
object MyInjector extends Factory
```
--------------------------------
### Serve JSON and XML with serveJx
Source: https://github.com/lift/framework/blob/main/docs/simply_lift.md
The serveJx function allows for a single business logic to generate a response that can be converted to either JSON or XML based on the request type. This requires defining conversion patterns.
```scala
trait Convertable {
def toJson: String
def toXml: String
}
implicit def cvt: JxCvtPF[Convertable] = { case (JsonSelect, c, _) => c.toJson case (XmlSelect, c, _) => c.toXml }
serveJx {
case Req("api" :: "convert" :: Nil, _, _) =>
// Assume this returns a Box[Convertable]
Box(Some(new Convertable { // Dummy implementation
def toJson = "{\"message\": \"converted to JSON\"}"
def toXml = "converted to XML"
}))
}
```
```scala
// extract the parameters, create a user
serveJx {
case Req("api" :: "user" :: Nil, _, _) =>
// Logic to create a user and return it as a Box[Convertable]
Box(Some(new Convertable { // Dummy implementation
def toJson = "{\"user\": \"created\"}"
def toXml = "created"
}))
}
```
--------------------------------
### Define Managed Dependencies with FactoryMaker
Source: https://github.com/lift/framework/blob/main/docs/dependency-injection-liftweb-scala.adoc
This snippet demonstrates how to define managed dependencies using the FactoryMaker trait. It shows how to create singleton and prototype scoped dependencies, with the emailService adapting its implementation based on the application's run mode.
```scala
object DependencyFactory extends Factory {
private val seq = new AtomicLong(0)
object emailService extends FactoryMaker(emailServiceImpl)
object sequenceNumberService extends FactoryMaker(seq.incrementAndGet _)
private def emailServiceImpl: EmailService = Props.mode match {
case Props.RunModes.Production => new RealEmailService
// A stub for local development
case _ => new TestEmailService
}
}
```
--------------------------------
### Update HTML for Displaying Usernames
Source: https://github.com/lift/framework/blob/main/docs/getting-started-tutorial/6-adding-usernames.adoc
Modify the index.html file to include spans with 'poster' and 'body' classes for displaying usernames and message content.
```html
...
AntonioHi!
DavidOh, hey there.
AntonioHow are you?
AntonioGood, you?
...
```
--------------------------------
### ChatServer Singleton in Lift
Source: https://github.com/lift/framework/blob/main/docs/simply_lift.md
A singleton object that manages the chat messages. It holds the list of messages as private state, provides a method to generate updates for listeners, and handles incoming String messages by appending them and notifying listeners.
```scala
object ChatServer extends LiftActor with ListenerManager {
private var msgs: Vector[String] = Vector()
override def createUpdate(listener: LiftActor): Unit = {
listener ! msgs
}
override def lowPriority : PartialFunction[Any,Unit] = {
case x: String => {
msgs = msgs :+ x
updateListeners()
}
}
}
```
--------------------------------
### Bind Message List to HTML
Source: https://github.com/lift/framework/blob/main/docs/getting-started-tutorial/4-css-selector-transforms.adoc
Use Lift's CSS selector transform to bind the contents of the `messageEntries` list to `li` elements. Lift repeats the matched element for each item in the list.
```scala
import net.liftweb.util.Helpers._
def messages = {
"li *" #> messageEntries
}
```
--------------------------------
### Lift First Selected Element to Root with '^^'
Source: https://github.com/lift/framework/blob/main/docs/css-selectors.adoc
The '^^' rule lifts the first matched element to the root of the NodeSeq, ignoring the transformation result. This is useful for selecting specific template elements based on external conditions.
```scala
".admin-user ^^" #> "ignored"
when applied to the markup ,
will produce .
```
--------------------------------
### Lift Form Binding with SHtml
Source: https://github.com/lift/framework/blob/main/docs/getting-started-tutorial/5-basic-forms.adoc
Binds a text input and a submit button to server-side logic using Lift's SHtml helpers. Use this to capture user input and trigger actions on form submission.
```scala
import net.liftweb.http.SHtml
def sendMessage = {
var message: String = ""
"#new-message" #> SHtml.text(message, message = _) &
"type=submit" #> SHtml.submitButton(() => {
messageEntries ::= message
})
}
```
--------------------------------
### Google Analytics Tracking Code
Source: https://github.com/lift/framework/blob/main/core/util/src/test/resources/net/liftweb/util/Html5ParserSpec.page1.html
This snippet includes the standard JavaScript code for integrating Google Analytics tracking. It dynamically loads the `ga.js` script and initializes the page tracker.
```javascript
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
try {
var pageTracker = _gat._getTracker("UA-1656750-18");
pageTracker._trackPageview();
} catch(err) {}
```
--------------------------------
### Handle PageShow and PageHide Events
Source: https://github.com/lift/framework/blob/main/core/util/src/test/resources/net/liftweb/util/Html5ParserSpec.page2.html
Listens for `pageshow` and `pagehide` events, which are fired when a page is loaded or unloaded, respectively. These events are reported to track page lifecycle.
```javascript
addEvent(window, 'pageshow', function (event) { reportEvent(event); }); addEvent(window, 'pagehide', function (event) { reportEvent(event); });
```
--------------------------------
### Accessing and Modifying data-* Attributes
Source: https://github.com/lift/framework/blob/main/core/util/src/test/resources/net/liftweb/util/Html5ParserSpec.page1.html
This JavaScript code demonstrates how to access and modify `data-*` attributes using the `element.dataset` property. It also shows how to update the HTML content to reflect these changes. This is useful for storing custom data directly on HTML elements.
```javascript
(function () {
function show() {
code.innerHTML = test.outerHTML.replace(/[\[<>\]]/g, function (m) {
return {
'<': '<',
'>': '>'
}[m];
});
for (var prop in test.dataset) {
code.innerHTML += '\nel.dataset.' + prop + ' = "' + test.dataset[prop] + '"';
}
}
var state = document.getElementById('status'),
code = document.getElementById('element');
var test = window.element = document.getElementById('test');
if (test.dataset === undefined) {
state.innerHTML = 'dataset not supported';
state.className = 'fail';
} else {
state.className = 'success';
state.innerHTML = 'element.dataset supported';
}
addEvent(document.getElementById('show'), 'click', function () {
show();
});
addEvent(document.getElementById('change1'), 'click', function () {
test.dataset.name = 'via el.dataset';
show();
});
addEvent(document.getElementById('change2'), 'click', function () {
test.setAttribute('data-name', 'via setAttribute');
show();
});
})();
```
--------------------------------
### Chaining Transforms with `andThen`
Source: https://github.com/lift/framework/blob/main/docs/css-selectors.adoc
Chain multiple transformation functions into a single function using `andThen`. This provides a more concise way to apply a series of transformations.
```scala
("a *" #> "Mozilla" andThen
"a [href]" #> "https://mozilla.org") apply nodes
```
--------------------------------
### HTML Form Structure
Source: https://github.com/lift/framework/blob/main/docs/getting-started-tutorial/5-basic-forms.adoc
This is the basic HTML structure for a form that will be processed by Lift.
```html
```
--------------------------------
### Define ChatMessage and MessagePosted Case Classes
Source: https://github.com/lift/framework/blob/main/docs/getting-started-tutorial/7-using-actors-for-chat.adoc
Define case classes for chat messages and for posting messages to the actor. Case classes are preferred for actor messages due to easy pattern matching and immutability.
```scala
case class ChatMessage(poster: String, body: String)
case class MessagePosted(message: ChatMessage)
```
--------------------------------
### Add Message on Render
Source: https://github.com/lift/framework/blob/main/docs/getting-started-tutorial/4-css-selector-transforms.adoc
Modify the `messages` method to prepend a new message to the `messageEntries` list before rendering. This ensures the list is updated on each page load.
```scala
messageEntries :+= "It is now " + formattedTimeNow
"li *" #> messageEntries
```
--------------------------------
### Basic Username Field with ajaxText
Source: https://github.com/lift/framework/blob/main/docs/getting-started-tutorial/8-customizable-usernames.adoc
Use SHtml.ajaxText to create an input field that updates a SessionVar when the user changes the text. The initial value is taken from the SessionVar.
```scala
...
def nameField = {
"input" #> SHtml.ajaxText(username.is, username.set _)
}
...
```
--------------------------------
### Lift Children of First Selected Element with '^\*'
Source: https://github.com/lift/framework/blob/main/docs/css-selectors.adoc
The '^\*' rule lifts the children of the first matched element to the root of the NodeSeq, ignoring the transformation result. This is useful for extracting specific content from within a matched element.
```scala
"#power-user ^*" #> "ignored"
when applied to the markup
Admin
Power User
,
will produce
Power User
.
```
--------------------------------
### Combining Selectors with Space Combinator
Source: https://github.com/lift/framework/blob/main/docs/css-selectors.adoc
Use the space combinator to select descendants. This allows you to target elements that are nested within other selected elements.
```scala
".user-form input [value]"
```
--------------------------------
### Extracting JSON/XML from POST/PUT Requests
Source: https://github.com/lift/framework/blob/main/docs/simply_lift.md
Shows how Lift can parse JSON or XML payloads from POST or PUT requests and dispatch only if the payload is valid.
```APIDOC
## Extracting JSON/XML from POST/PUT Requests
### Description
Lift's REST helper can automatically extract and validate JSON or XML data from the body of POST or PUT requests, dispatching the request only if the data is well-formed.
### Method
Use the `serve` block with patterns that attempt to parse JSON or XML.
### Endpoint
POST or PUT endpoints that expect a JSON or XML body.
### Request Example
```scala
serve {
case req @ (POST | PUT) if req.request.contentType.contains("application/json") =>
// Attempt to parse JSON from the request body
req.parseJson match {
case Full(json) =>
// Process the valid JSON payload
println(s"Received JSON: $json")
OkResponse() // Placeholder for actual response
case Failure(msg, _, _) =>
// Handle JSON parsing error
BadRequestResponse(msg)
case _ =>
// Handle other parsing issues
InternalServerErrorResponse()
}
case req @ (POST | PUT) if req.request.contentType.contains("application/xml") =>
// Attempt to parse XML from the request body
req.parseXml match {
case Full(xml) =>
// Process the valid XML payload
println(s"Received XML: $xml")
OkResponse() // Placeholder for actual response
case Failure(msg, _, _) =>
// Handle XML parsing error
BadRequestResponse(msg)
case _ =>
// Handle other parsing issues
InternalServerErrorResponse()
}
}
```
### Response
#### Success Response (200)
Returned when the JSON or XML payload is successfully parsed and processed.
#### Error Responses
- `BadRequestResponse`: If JSON or XML parsing fails.
- `InternalServerErrorResponse`: For other unexpected parsing issues.
```
--------------------------------
### Define Message Types for ChatActor
Source: https://github.com/lift/framework/blob/main/docs/getting-started-tutorial/7-using-actors-for-chat.adoc
Defines the case classes and objects used for communication with the ChatActor.
```scala
case class MessagePosted(message: ChatMessage)
case object GetMessages
```
--------------------------------
### Request-Scoped Injection for DocType
Source: https://github.com/lift/framework/blob/main/docs/simply_lift.md
Dynamically set the docType based on the current HTTP request. This allows for request-specific rendering rules.
```scala
if (isMobileReqest) LiftRules.docType.request.set((r: Req) => Full(DocType.xhtmlMobile))
```
--------------------------------
### Define Message Entries List
Source: https://github.com/lift/framework/blob/main/docs/getting-started-tutorial/4-css-selector-transforms.adoc
Declare a mutable list to store chat message entries. This variable will be used to dynamically populate the message list.
```scala
object Chat {
var messageEntries = List[String]()
}
```
--------------------------------
### Session-Scoped Injection for Max Concurrent Requests
Source: https://github.com/lift/framework/blob/main/docs/simply_lift.md
Adjust the maximum concurrent requests based on session rules. This can be used to manage resource usage per user session.
```scala
if (browserIsSomethingElse) LiftRules.maxConcurrentRequests.session.set((r: Req) => 32)
```
--------------------------------
### Replace Element Content with Text
Source: https://github.com/lift/framework/blob/main/docs/css-selectors.adoc
Replaces the content of all 'a' elements with the specified text. Useful for standardizing text across multiple elements.
```html
```
--------------------------------
### Set formName in Lift 3.0
Source: https://github.com/lift/framework/blob/main/docs/migration/2.6-to-3.0-lift-screen.adoc
In Lift 3.0, you must provide a formName to your screen. Setting it to an empty string ensures compatibility with the current form implementation.
```scala
val formName = ""
```
--------------------------------
### Lift 3.0 Global Error Markup
Source: https://github.com/lift/framework/blob/main/docs/migration/2.6-to-3.0-lift-screen.adoc
In Lift 3.0, wizard:* elements are replaced with CSS classes like 'globalErrors' for global error markup.
```html
placeholder text, will be replaced by the error message