how to solve following snippet implementation?

88 views
Skip to first unread message

Christian Thomas

unread,
Nov 18, 2012, 4:54:26 AM11/18/12
to lif...@googlegroups.com
Hello,

currently I have started to reimplement my existing blog (it is a JSF app : www.chr-thomas.de) with Lift to learn it (I can simply use my existing services via jndi lookup do get the appropriate content for the page). 

I want to create a side bar, which should show a listing of all existing main-categories including its sub-categories (if you visit my page, you can see it on the right side under the header "Kategorien"). The visitor can click such a sub-category to the filter the result of article-previews on that page.

Kategorien
Administration ( main-category )
  • JDK :: 1 ( sub-category )
Softwareentwicklung ( main-category )

Okay, if have startet to write for that part following html conent

<section>
<header><h3>Kategorien</h3></header>
<section class="lift:Categories.mainCategories">
<header><h4><span lift:bind="row:name">main category name</span></h4></header>
<ul>
<li class="lift:Categories.subCategories"><a subrow:link=""><span lift:bind="subrow:name">sub category name</span></a> :: <span lift:bind="subrow:count">count</span></li>
</ul>
</section>
</section>

Here the snippet class:

class Categories {
def mainCategories(html: NodeSeq) : NodeSeq = {
val resource = new BlogResource // know's how to access the java services
val mainCategories = resource.getAllMainCategories
return mainCategories.flatMap(category => bind("row", html,        "name" -> {category.getName + " : " + category.getId}))
}

def subCategories(html: NodeSeq) : NodeSeq = {
val resource = new BlogResource // know's how to access the java services
val parentId : Long = 1 // for the first test a static id is set
val subCategories = resource.getAllChildCategories(parentId)
return subCategories.flatMap(category => bind("subrow", html,       FuncAttrBindParam("link", {ns : NodeSeq => Text("/blog/category/" + category.getName.toLowerCase)}, "href"),
      "name" -> {category.getName},
"count" -> {resource.getNoOfArticlesForCategory(category.getId)}))
}
}




Christian Thomas

unread,
Nov 18, 2012, 5:00:16 AM11/18/12
to lif...@googlegroups.com
oops, I have accidentally post it...

Okay, here my question:

How can I solve it in Lift:

I have to pass the id of each main-category to the snippet, which generates the entries for the sub-categories ( currently a static known parentId
val parentId : Long = 1 //in method subCategories
 is set to see, I the rest of the code works ) ?

Can give someone me a hint, example?

Thanks!

Kind regards!

Christian

AGYNAMIX Torsten Uhlmann

unread,
Nov 18, 2012, 5:19:09 AM11/18/12
to lif...@googlegroups.com
Hi Christian,

so you basically want to support a URL like "/blog/<xyz>/list" where xyz is a category or ID or whatever narrows down the elements to show?

Then Menu.param is one (preferred) solution to do it. Have a look at: https://github.com/d6y/london_class_march_2011_sitemap_css

You might need to put the source code into a new sbt skeleton project, but it still works with the latest Lift libs. There is an example David did with a list of forums and a list of threads per forum.

Does that help?

Torsten.

-- 
AGYNAMIX(R). Passionate Software.
Inh. Torsten Uhlmann | Buchenweg 5 | 09380 Thalheim
Phone:       +49 3721 273445
Fax:             +49 3721 273446
Mobile:       +49 151 12412427
Web:           http://www.agynamix.de

--
--
Lift, the simply functional web framework: http://liftweb.net
Code: http://github.com/lift
Discussion: http://groups.google.com/group/liftweb
Stuck? Help us help you: https://www.assembla.com/wiki/show/liftweb/Posting_example_code
 
 
 

David Pollak

unread,
Nov 18, 2012, 12:07:43 PM11/18/12
to lif...@googlegroups.com
Also, please use the CSS Selector Transforms rather than the bind() syntax... the CSS Selector Transforms lead to more readable and understandable code.
--
Telegram, Simply Beautiful CMS https://telegr.am
Lift, the simply functional web framework http://liftweb.net

Christian Thomas

unread,
Nov 18, 2012, 1:46:01 PM11/18/12
to lif...@googlegroups.com
@Torsten big thanks for your help via mail :thumbsup:

@Torsten, @David: yes, the css selector transforms is the better way. This also simply solved my problem.

Now the html look's like:

<section class="lift:Categories">
  <header><h4><span name="main-category-name">main category name</span></h4></header>
  <ul>
    <li name="sub-category"><a href="todo"><span name="sub-category-name">sub category name</span></a> :: <span name="sub-category-count">count</span></li>
  </ul>
</section>

and the snippet code:

class Categories {

def render = {
val resource = new BlogResource // know's how to access the java service
val mainCategories = resource.getAllMainCategories

"* *" #> mainCategories.map {mainCategory =>
"@main-category-name" #> mainCategory.getName &
"@sub-category *" #> resource.getAllChildCategories(mainCategory.getId).map {subCategory =>
"@sub-category-name" #> subCategory.getName &
"@sub-category-count" #> resource.getNoOfArticlesForCategory(subCategory.getId)
}
}
}
}

and I really like it : )

Now I have to check, how to use the Menu.param to append the dynamic link's...

David Pollak

unread,
Nov 19, 2012, 6:20:14 PM11/19/12
to lif...@googlegroups.com
Please take a look at the project that Torsten pointed you to. Specifically, the ForumStuff.scala file which contains the logic to create a menu link based on a parameter:

class AForum(f: Forum) {
  def render = "li *" #>
  ForumThread.all(f).map(t =>
    "a *+" #> t.name & "a [href]" #> AThread.menu.calcHref(f -> t))

Christian Thomas

unread,
Nov 20, 2012, 3:06:28 PM11/20/12
to lif...@googlegroups.com
Currently I'm trying to find out, how it work's. But at this first time it is really hard to understand, what there happens (the concrete impl) !

In my example I have got a page blog.html. This contains the snippet above to show the existing categories. Each rendered sub-category is clickable to filter the summary of listed blog-articles.

For instance:
/blog <-- has to show all existing blog-article-previews on the blog.html page
/blog/category/example <-- has to show all blog-article-previews in relation to the category "example" on the blog.html page
/blog/article/example-article <-- has to show the complete article on the article page ( I think I have to create an article folder containing a star.html file )



I have created a small mvn project (contains a lift-app and a tiny Java-Service (in real world it should be an EJB or something else...) ), which shows the current state of my test-project.

Please feel free to have a look on it: https://github.com/Chris81T/learning-lift.git

This version is still running without error's. May someone can support me to solve my current problem by giving some hints / example code (with may some short comments) appropriate to the small project. 

For instance I really don't understand following code:

object AForum {
  lazy val menu = 
    Menu.param[Forum]("AForum", // for what is this string good for? Simply a label
                      Loc.LinkText(f => Text(S.?("Forum") +": "+f.name)), // ?????
                      (s: String) => { // is this an anonymous function ??
                        println("Looking up forum "+s)
                        val ret = Forum.find(s)
                        println("Found "+ret)
                        ret // where will the return ret value be used ??
                        },
                      (f: Forum) => f.id) / "forums" / * // this defines the dynamic url. the id will be replaced for the *
}




Thank's in advance!

Christian

Christian Thomas

unread,
Nov 21, 2012, 2:29:02 PM11/21/12
to lif...@googlegroups.com
Okay, now I have continued implementing my example project.

First of all I simply want to create the article navigation:
  • behind the "read..." link an appropriate url for the article is requested
  • after clicking the "read..." link the article page has to be called and has to show the whole article instead of the article-preview on the blog page
  def render = {

/*
TODO:
- adapt class to support filtering by category
- add dynamic href article url
*/


/*
it is not necessary to return all real articles including content. It should be overhead. Only the complete
article is requested, if the visitor wants to read the article

--> An articlePreview knows the id of the article
*/
val articles = asScalaList(BlogJavaService.getAllArticlePreviews)
"* *" #> articles.map {article =>
"@article-title" #> article.getTitle &
"a [href]" #> Article.menu.calcHref(BlogJavaService.getArticle(article.getArticleId)) // TODO this is a first test to see, if something at all will work !!! Normally I do not want to call each article! I'm not really shure, how the Menu.param work's !!!
}
  }

this is the render function of the ArticlePreviews snippet. This is used to show on the blog page all existing article-previews (or all previews appropriate to a selected category ( filter function ))

Here is the Article object:
object Article {
/*
*  sealed trait MenuSingleton extends AnyRef
   * def param[T <: AnyRef](name: String, linkText: LinkText[T], parser: (String) ⇒ Box[T], encoder: (T) ⇒ String): PreParamMenu[T]
*/
lazy val menu = Menu.param[de.java.entities.Article]("Article",
"Reading an article",
                                                    articleId => findArticleById(articleId),
                                                    article => getIdForArticle(article)
) / "article" / *


def findArticleById(articleId: String) : Box[de.java.entities.Article] = {
val article = BlogJavaService.getArticle(articleId.toLong)

/* TODO I dont think, that is the best solution to get the box instance - source:
*/
val map = Map(articleId -> article)
println("Found article=" + article + " for given id=" + articleId)
val box = map.get(articleId)
println("Returning created box=" + box)
box
}

def getIdForArticle(article: de.java.entities.Article) : String = {
val id = article.getId.toString
println("Returning requested id=" + id + " of article=" + article)
id
}

}

This code will create the required dynamic url's for each "read..." link on the blog page (my first success for that topic). But another solution should be better:
I think I have only to handle the articleId of each article-preview instance to create the url's. And if the user will click the "read..." link, then the whole article has to be loaded.

How do I have to change the Article.menu to solve this? 


To see the complete code, please clone my repository: https://github.com/Chris81T/learning-lift.git

Christian
Reply all
Reply to author
Forward
0 new messages