Skip to content

Instantly share code, notes, and snippets.

@hectorgool
Last active August 29, 2015 14:11
Show Gist options
  • Save hectorgool/2020b8f27ff3d7a0fcb3 to your computer and use it in GitHub Desktop.
Save hectorgool/2020b8f27ff3d7a0fcb3 to your computer and use it in GitHub Desktop.
Snippet Scala Lift
<div id="main" class="lift:surround?with=default&at=content">
<div class="row">
<div class="col-xs-12 col-md-8">
<div class="panel panel-default">
<div class="panel-body">
<h3>
<span class="glyphicon glyphicon-pencil"></span>
<lift:loc>add.post</lift:loc>
</h3>
<p data-lift="Msg?id=postError"></p>
<form role="form" data-lift="form.ajax">
<div data-lift="PostSnip.add">
<div class="form-group">
<label for="name">
<lift:loc>Name</lift:loc>
</label>
<!--<p data-lift="Msg?id=name"></p>-->
<p id="name_error" class=""></p>
<input id="name" name="name" class="form-control" placeholder="Enter a name">
</div>
<div class="form-group">
<label for="description">
<lift:loc>Description</lift:loc>
</label>
<!--<p data-lift="Msg?id=description"></p>-->
<p id="description_error" class=""></p>
<textarea class="form-control"
name="description"
placeholder="Enter a description">
</textarea>
</div>
<button type="submit" class="btn btn-default">
<!--<span class="glyphicon glyphicon-send"></span>-->
<lift:loc>send.post</lift:loc>
</button>
<a href="/" class="btn btn-default">
<!--<span class="glyphicon glyphicon-remove-circle"></span>-->
<lift:loc>cancel.button</lift:loc>
</a>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
package code
package snippet
import net.liftweb._
import common._
import common.Full
import http._
import http.RequestVar
import http.S._
import http.js.JsCmds._
import lib._
import model._
import mongodb.{Skip, Limit}
import scala.xml._
import sitemap._
import util._
import util.Helpers._
import com.mongodb._
import net.liftweb.util.Helpers._
import net.liftweb.http.SHtml._
import net.liftweb.http.js._
import JsCmds._
import com.foursquare.rogue.Rogue._
import com.foursquare.rogue.LiftRogue._
import com.foursquare.rogue.Iter._
import net.liftweb.json._
import net.liftweb.json.JsonDSL._
import org.joda.time.format.DateTimeFormat
import code.comet._
class PostSnip extends StatefulSnippet with PaginatorSnippet[Posts] with UserHelper{
private var name = ""
private var description = ""
private var seoUrl = ""
private val whence = S.referer openOr "/"
private var editingPosts = Posts.createRecord
private val fmt = DateTimeFormat.forPattern("dd MMMM yy, HH:mm:ss")
override def offsetParam = "d"
override def count = Posts.count
override def itemsPerPage = 5
override def page = Posts.findAll(QueryBuilder.start().get(), Limit(itemsPerPage), Skip(curPage*itemsPerPage))
override def prevXml: NodeSeq = Text(?("<"))
override def nextXml: NodeSeq = Text(?(">"))
override def firstXml: NodeSeq = Text(?("<<"))
override def lastXml: NodeSeq = Text(?(">>"))
override def currentXml: NodeSeq = Text("Displaying records "+(first+1)+"-"+(first+itemsPerPage min count)+" of "+count)
def dispatch = {
case "add" => add _
case "displayDocuments" => displayDocuments _
//case "editForm" => editForm _
//case "manageDocuments" => manageDocuments _
case "myPosts" => myPosts _
case "paginate" => paginate _
case "metaTagContents" => metaTagContents _
case "displayTopPosts" => displayTopPosts _
}
def add( xhtml: NodeSeq ): NodeSeq = User.currentUser match {
case Full(user) => {
def doProcess(): JsCmd = {
val post : Posts = Posts.createRecord
.name(name)
.seoUrl(SEOTransform.toSEOFriendly(name))
.description(description)
.userId( user.id.is )
.timecreated(millis)
.published(true)
assert( post.userId.obj.map(_.id.is) == Full( user.id.is ) )
post.validate match{
case Nil =>
S.notice("post is add")
post.save
indexPost( post ) //beta
S.redirectTo("/")
case errors : List[FieldError] =>
S.error("postError", <span class="glyphicon glyphicon-warning-sign"></span> <lift:loc>post.errors</lift:loc>)
//S.error("name", <lift:loc>post.errors</lift:loc>)
//S.error("description", <lift:loc>post.errors</lift:loc>)
S.error(errors)
}
}
def check_name(in:String, field: String, errorFieldId: String) = {
val name= in.trim
val post : Posts = Posts.createRecord.name(name)
post.name.validate match{
case Nil =>
<p class="success" id={errorFieldId}><i class="icon-ok"></i></p>
case errors : List[FieldError] =>
S.error(errors)
<p id={errorFieldId}> <span class="glyphicon glyphicon-warning-sign"></span> <lift:Msg id="name" /></p>
}
}
def check_description(in:String, field: String, errorFieldId: String) = {
val description = in.trim
val post : Posts = Posts.createRecord.description(description)
post.description.validate match{
case Nil =>
<p class="success" id={errorFieldId}><i class="icon-ok"></i></p>
case errors : List[FieldError] =>
S.error(errors)
<p id={errorFieldId}> <span class="glyphicon glyphicon-warning-sign"></span> <lift:Msg id="description" /></p>
}
}
def cssSel =
"name=name" #> ajaxLiveText( "", name => Replace( "name_error", check_name( name,"Firstname: ", "name_error" ) ),"type" -> "text" ) andThen
"name=name" #> SHtml.text(name, name = _) andThen
"name=description" #> ajaxLiveText( "", description => Replace( "description_error", check_description( description,"Lastname: ", "description_error" ) ),"type" -> "text" ) andThen
"name=description" #> SHtml.textarea(description, description = _ ) andThen
"type=submit" #> ( SHtml.submit( S.?("post.send"), doProcess _ , "class" -> "btn btn-default" ) ++ SHtml.hidden( doProcess _ ) ) //beta
cssSel.apply(xhtml)
}
case _ =>
(<div class="alert alert-danger"><lift:loc>user.not.found</lift:loc></div>)
S.redirectTo("/")
}
def displayDocuments(xhtml: NodeSeq): NodeSeq = {
page.flatMap(post => {
(
"#post *" #> post.name &
"#post [href]" #> "/post/%s".format(post.seoUrl) &
"#timecreated" #> fmt.print(post.timecreated.is) &
"#description" #> Text(post.description.is) &
"#username" #> post.userId.obj.map(_.nickname.is)
).apply(xhtml)
})
}
def displayTopPosts(xhtml: NodeSeq): NodeSeq = {
def page = Posts.where(_.published eqs true).limit(50).fetch()
page.flatMap( post => {
(
"#post *" #> post.name &
"#post [href]" #> "/post/%s".format(post.seoUrl) &
"#timecreated" #> fmt.print(post.timecreated.is) &
"#description" #> Text(post.description.is) &
"#username" #> post.userId.obj.map(_.nickname.is)
).apply(xhtml)
})
}
/*
def editForm(xhtml: NodeSeq): NodeSeq = {
( "#editName" #> editingPosts.name.toForm &
"#editDescription" #> editingPosts.description.toForm &
"type=submit" #> SHtml.submit(S.?("Save"), () => save )
).apply(xhtml)
}
def manageDocuments(xhtml: NodeSeq): NodeSeq = {
page.flatMap(post => {
( ".postEdit *" #> link("edit", () => edit(post), Text("Edit")) &
".postDelete *" #> link("", () => delete(post), Text("Delete")) &
".postName *" #> post.name
).apply(xhtml)
})
}
*/
def myPosts( xhtml: NodeSeq ): NodeSeq = User.currentUser match {
case Full(user) => {
def page = Posts.findAll( "userId", user.id.is )
page.flatMap(post => {
( "a *" #> post.name &
"a [href]" #> "/post/%s".format(post.seoUrl) &
"#timecreated" #> toInternetDate(post.timecreated.is) &
"#description" #> Text(post.description.is) &
"#username" #> post.userId.obj.map(_.nickname.is)
).apply(xhtml)
})
}
case _ => {
Text("error")
S.redirectTo("/")
}
}
def edit(post : Posts ) = {
editingPosts = post
}
def delete(post : Posts ) = {
post.delete_!
redirectToHome
}
def save = {
editingPosts.seoUrl(SEOTransform.toSEOFriendly(name))
editingPosts.save
redirectToHome
}
def redirectToHome = {
editingPosts = Posts.createRecord
redirectTo("/post")
}
def metaTagContents(xhtml: NodeSeq): NodeSeq = {
def cssSel =
"@keywords [content]" #> "santo content"//beta
cssSel.apply(xhtml)
}
//beta
def indexPost(post : Posts ) = {
val indexTerm =
("name" -> post.name.toString )~
("description" -> post.description.toString )~
("userId" -> post.userId.toString )~
("timecreated" -> post.timecreated.defaultValue )~
("published" -> post.published.defaultValue )
ElasticSearch.mongoindexSave( List( "siteindex", "posts", post.id.toString ), indexTerm )
}
}
// capture the page Posteter information
case class PostInfo(thePost: String)
// a snippet that takes the page Posteter information
class ViewPost(pi: PostInfo) extends StatefulSnippet with Loggable with UserHelper {
private val whence = S.referer openOr "/"
private var editingPost = Posts.createRecord
private val fmt = DateTimeFormat.forPattern("dd MMMM yy, HH:mm:ss")
def dispatch = {
case "view" => view _
case "editForm" => editForm _
}
def view( xhtml: NodeSeq ): NodeSeq = User.currentUser match {
case Full(user) if user.confirmed.is == true => {
Posts.find( "seoUrl", pi.thePost ) match{
case Full(post) if post.published.is == true => {
val editLink: NodeSeq = {
if( user.id.is == post.userId.is ){
link( "/editpost",() => edit(post), Text(S.?("edit.post")))//beta
}
else{
NodeSeq.Empty
}
}
def cssSelectors =
"title *" #> post.name &
"#name" #> post.name &
"#timecreated" #> fmt.print(post.timecreated.is) &
"#description" #> Text(post.description.is) &
"#username" #> post.userId.obj.map(_.nickname.is) &
"#edit" #> editLink
cssSelectors.apply(xhtml)
}
case _ =>{
logger.info("\n\n\n pi.thePost: "+pi.thePost+" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\n\n\n")//depurar
Text(S.?("document.not.found"))
}
}
}
case _ => {
S.redirectTo("/")//login
}
}
def editForm(xhtml: NodeSeq): NodeSeq = {
(
"#editName" #> editingPost.name.toForm &
"#editDescription" #> (( editingPost.description.toForm) ++ SHtml.hidden( save _ ) )
).apply(xhtml)
}
def edit(post : Posts ) = {
editingPost = post
}
def save = {
editingPost.seoUrl(SEOTransform.toSEOFriendly(editingPost.name.is))
editingPost.save
S.redirectTo("/")
}
}
object Post {
// Create a menu for /Post/somedata
val postId = Menu.param[PostInfo]("Post", "Post",
s => Full(PostInfo(s)),
pi => pi.thePost) / "post"
lazy val loc = postId.toLoc
def render = "*" #> loc.currentValue.map(_.thePost)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment