Skip to content

Instantly share code, notes, and snippets.

@Shadowfiend
Created November 5, 2012 19:41
Show Gist options
  • Save Shadowfiend/4019866 to your computer and use it in GitHub Desktop.
Save Shadowfiend/4019866 to your computer and use it in GitHub Desktop.
Layout snippet that excludes the layout for AJAX requests + JS for retaining functions for AJAX loaded pages.
package com.openstudy { package snippet {
import scala.xml._
import net.liftweb.http.S
import net.liftweb.util.Helpers._
class Layout {
def render(xhtml:NodeSeq) = {
if (S.request.map(_.ajax_?) == Full(true)) {
S.skipXmlHeader = true
S.skipDocType = true
/**
* We add a data-gc-version attribute to the root element. This
* attribute is read client-side to send a __Lift_GC message back to
* the server to make sure we don't garbage collect fields associated
* with this page. This page is rendered under a different version than
* the original page itself, so we have to avoid garbage collecting
* this page's version in addition to the base page.
*/
val rendered = xhtml match {
case group:Group =>
group.find {
case e:Elem => true
case _ => false
}.map {
case e:Elem => e % ("data-gc-version" -> S.renderVersion)
} getOrElse group
case other => other
}
S.session.map { liftSession =>
liftSession.processSurroundAndInclude("xhr page", rendered)
} openOr rendered
} else {
val layoutFile =
S.attr("is").map { file =>
file.startsWith("/") ? file.substring(1) | ("layouts-hidden/" + file)
} openOr "default"
val insertionPoint = S.attr("at") openOr "content"
<lift:surround with={layoutFile} at={insertionPoint}>{xhtml}</lift:surround>
}
}
}
} }
# When we load entire pages via AJAX (for example, updates), Lift gives
# them a different GC id. Lift's GC throws away closures for fields and
# such after they haven't been seen on a page for a certain amount of
# time (10 minutes by default).
#
# Server-side, such renderings add an attribute to the base element,
# data-gc-version, that provide the Lift GC id for these pages. Here, we
# look for such ids and make sure to issue GC requests to Lift so that
# Lift doesn't erroneously clean up our closures.
if liftAjax?
lift_registerGC = liftAjax.lift_registerGC
lift_successRegisterGC = liftAjax.lift_successRegisterGC
lift_failRegisterGC = liftAjax.lift_failRegisterGC
successRegistered = false
failRegistered = false
liftAjax.lift_successRegisterGC = ->
unless successRegistered
successRegistered = true
lift_successRegisterGC()
liftAjax.lift_failRegisterGC = ->
unless failRegistered
failRegistered = true
lift_failRegisterGC()
liftAjax.lift_registerGC = ->
successRegistered = failRegistered = false
lift_originalPage = lift_page
lift_registerGC()
gcIds = {}
gcIds[$(elt).data('gc-version')] = true for elt in $('*[data-gc-version]')
for gcId of gcIds
lift_page = gcId
lift_registerGC()
lift_page = lift_originalPage
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment