### 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 ``` -------------------------------- ### 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 ``` -------------------------------- ### 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 ``` -------------------------------- ### 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!
  1. Hi!
  2. Oh, hey there.
  3. How are you?
  4. 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 ...
  • Antonio Hi!
  • David Oh, hey there.
  • Antonio How are you?
  • Antonio Good, 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
    John Doe
    ``` ```scala "a *" #> "Mozilla" ``` ```html
    John Doe
    ``` -------------------------------- ### 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
    ```