Created
January 30, 2012 09:49
-
-
Save dph01/1703611 to your computer and use it in GitHub Desktop.
TBUtils
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package code.snippet | |
import scala.xml._ | |
import net.liftweb.util.Helpers._ | |
import scala.xml.transform._ | |
import net.liftweb.common.Logger | |
object TBUtils extends Logger { | |
/* Transforms the XML produced by Menu.build such that any menus defined as: | |
Menu("Test") / "test" >> LocGroup("test") >> PlaceHolder submenus ( | |
Menu("Test 2") / "test2", | |
Menu("Test 3") / "test3" | |
), | |
or | |
Menu("Test") / "test" >> LocGroup("test") >> submenus ( | |
Menu("Test 2") / "test2", | |
Menu("Test 3") / "test3" | |
), | |
will be transformed into Twitter Bootstrap dropdown menus | |
*/ | |
def menuToTBNav( in: NodeSeq ) : NodeSeq = { | |
object t1 extends RewriteRule { | |
override def transform(n: Node): Seq[Node] = n match { | |
// removes the white space which appears between elements | |
case Text(text) if ( text.matches("\\s+") ) => NodeSeq.Empty | |
/* matches xml of the format: | |
*<li> | |
<span>Test</span> | |
<ul> | |
<li> | |
<a href="/test2">Test 2</a> | |
</li> | |
<li> | |
<a href="/test3">Test 3</a> | |
</li> | |
</ul> | |
</li> | |
and transforms it to: | |
<li class="dropdown" data-dropdown="dropdown"> | |
<a class="dropdown-toggle">Test</a> | |
<ul class="dropdown-menu"> | |
<li> | |
<a href="/test2">Test 2</a> | |
</li> | |
<li> | |
<a href="/test3">Test 3</a> | |
</li> | |
</ul> | |
</li> | |
*/ | |
case li @ Elem(liPrefix, "li", liAttribs, liScope, | |
span @ Elem(spanPrefix,"span",spanAttribs,spanScope,spanChildren @ _*), | |
ul @ Elem(ulPrefix,"ul",ulAttribs,ulScope,ulChildren @ _*), | |
other @ _* ) => { | |
val newLiAttribs = appendToClass(liAttribs,"dropdown").append("data-dropdown" -> "dropdown") | |
val newAAttribs = appendToClass(spanAttribs,"dropdown-toggle") | |
val newUlAttribs = appendToClass(ulAttribs,"dropdown-menu") | |
Elem(liPrefix,"li",newLiAttribs,liScope, | |
Elem(spanPrefix, "a", newAAttribs, spanScope, spanChildren: _*) ++ | |
Elem(ulPrefix, "ul", newUlAttribs, ulScope, ulChildren: _*) ++ | |
other: _*) | |
} | |
/* matches xml of the format: | |
*<li> | |
<a href="">Test</a> | |
<ul> | |
<li> | |
<a href="/test2">Test 2</a> | |
</li> | |
<li> | |
<a href="/test3">Test 3</a> | |
</li> | |
</ul> | |
</li> | |
and transforms it to: | |
<li class="dropdown" data-dropdown="dropdown"> | |
<a class="dropdown-toggle">Test</a> | |
<ul class="dropdown-menu"> | |
<li> | |
<a href="/test2">Test 2</a> | |
</li> | |
<li> | |
<a href="/test3">Test 3</a> | |
</li> | |
</ul> | |
</li> | |
*/ | |
case li @ Elem(liPrefix, "li", liAttribs, liScope, | |
a @ Elem(aPrefix,"a",aAttribs,aScope,aChildren @ _*), | |
ul @ Elem(ulPrefix,"ul",ulAttribs,ulScope,ulChildren @ _*), | |
other @ _* ) => { | |
val newLiAttribs = appendToClass(liAttribs,"dropdown").append("data-dropdown" -> "dropdown") | |
val newAAttribs = appendToClass(aAttribs,"dropdown-toggle") | |
val newUlAttribs = appendToClass(ulAttribs,"dropdown-menu") | |
Elem(liPrefix,"li",newLiAttribs,liScope, | |
Elem(aPrefix, "a", newAAttribs, aScope, aChildren: _*) ++ | |
Elem(ulPrefix, "ul", newUlAttribs, ulScope, ulChildren: _*) ++ | |
other: _*) | |
} | |
case other @ _ => other | |
} | |
} | |
debug("menuToTBNav received: " + new PrettyPrinter(80,3).formatNodes(in)) | |
object rt1 extends RuleTransformer(t1) | |
val out = rt1.transform(in) | |
debug("menuToTBNav out: " + new PrettyPrinter(80,3).formatNodes(out)) | |
out | |
} | |
// append a new value to the class attribute if one already exists, otherwise create a new class | |
// with the given value | |
def appendToClass(attribs: MetaData, newClass: String ) : MetaData = { | |
// Note that MetaData.get("class") returns a Option[Seq[Node]] , not Option[Node] as might be expected | |
// for an explanation of why see the scala-xml book: | |
val oldClass : Option[String] = attribs.get("class").map(_.mkString).filterNot(_ == "") | |
val resultingClass = oldClass.map( _.trim + " ").getOrElse("") + newClass | |
attribs.append("class" -> resultingClass) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment