Skip to content

Instantly share code, notes, and snippets.

@fanf
Created December 5, 2010 16:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fanf/729195 to your computer and use it in GitHub Desktop.
Save fanf/729195 to your computer and use it in GitHub Desktop.
package net.liftweb.http
import net.liftweb.common._
/**
* That class allow to load and register a snippet for the context of
* a Lift request.
*
*
* Such snippet should not be reachable directly from the application,
* and so should not be placed in the "snippet" package.
*
* We could call these local snippets "components".
*
* This is useful to split a big page into sub part, especially when some of
* these part are (complex) forms based on some user action on other part of
* the page (and so, forms are contextualized).
*
*
* How to use it:
*
* <pre>
* MyPage.scala
*
* class MyPage extends DispatchSnippet {
*
* val myComponentHolder : LocalSnippet[MyComponent] = new LocalSnippet[MyComponent]
*
* def dispatch = {
* case "myComponent" => displayComponent _
* }
*
* def displayComponent(xml:NodeSeq) : NodeSeq = {
* myComponentHolder.is match {
* case Failure(m,_,_) =>
* //error with the component loading or update, display an error message
* //here, <lift:MyComponent.renderComponent /> will lead to Lift saying it does not know that class
* <span class="error">Error: {m}</span>
* case Empty =>
* //the component was not initialize for that request, show an error message or a way to initialize it (by ajax)
* //here too, <lift:MyComponent.renderComponent /> will lead to Lift saying it does not know that class
* <span><a href="#" ...>Please click here to init the component</a></span>
* case Full(myComponent) =>
* //render component, as it is now registered
* <lift:MyComponent.renderComponent />
* }
* }
*
* //to register the component, you just have to set a value to LocalSnippet
* def initComponent : Unit = {
* myComponentHolder.set( new MyComponent(context, param, for, that, component) )
* }
* }
*
* MyComponent.scala
*
* class MyComponent(some:Context, param:For, that:Componenent) extends DispatchSnippet {
*
* def dispatch = {
* case "renderComponent" => renderComponent _
* }
*
* def renderComponent(xml:NodeSeq) : NodeSeq = { // render component }
* }
*
* </pre>
*
*/
class LocalSnippet[T <: DispatchSnippet](implicit m: ClassManifest[T]) {
private[this] var _snippet : Box[T]= Empty
val name = m.erasure.getSimpleName
def is = _snippet
def set(snippet:Box[T]) : Unit = {
_snippet = snippet
snippet match {
case _:EmptyBox => S.unsetSnippetForClass(name)
case Full(s) => S.overrideSnippetForClass(name, s)
}
}
}
@fanf
Copy link
Author

fanf commented Dec 5, 2010

That LocalSnippet can be used to build reusable components in Lift.
I'm not sure about the Box, it makes the Snippet use less direct (especially to access to component methods, like initJs(), getComponentState, etc), but it's a good way to force the component user to check if the component is initialized (not Empty) without error (not Failure).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment