Locating Templates in Modules

55 views
Skip to first unread message

Peter Robinett

unread,
Dec 23, 2010, 9:18:45 PM12/23/10
to lif...@googlegroups.com
Hi all,

I'm putting together a Hello World Lift Module and I ran into a stumbling block which hopefully someone here has the solution to. The problem is this: I'd like to provide a template with my module and have the app using the module correctly find it. Thanks to David's work a few weeks ago I can now add a SiteMap Menu entry referring to my template to the main app's SiteMap from within my module's init method. The template is in my module's src/main/webapp directory. However, when I launch the example app using the module I see the Menu listed correctly but clicking on it leads to a 404 error, as the app doesn't see my template. Do you know how I can tell the app to check my module for the file?

Thanks,
Peter

Timothy Perrett

unread,
Dec 24, 2010, 7:37:54 AM12/24/10
to Lift
You dont say specifically how you have tried to load it, but you'd
want to look at TemplateFinder object, as that handles the actual
template resolution.

Have a play around with that I would, off the top of my head i cant
remember if it only looks in webapp for .html templates, or if it
checks the whole classpath. It certainly checks the classpath when
looking for views, but I think html templates may be confined to the
WAR at the moment. Like i said, have a play around with the "places"
argument in template finder and you should get your answer fairly
quickly.

Cheers, Tim

Peter Robinett

unread,
Dec 24, 2010, 9:13:05 AM12/24/10
to lif...@googlegroups.com
Thanks, Tim. I was just trying to load it by accessing the url (ie SiteMap Menu) corresponding to the template. TemplateFinder definitely looks to be where the action is but unfortunately it does seem to just look in the WAR right now. I guess that makes sense, since how else can it find them? Templates aren't objects within the classpath hierarchy...

Maybe they can be treated similar to how CSS and JS resource files are treated? Or perhaps modules could load their templates and then add them to LiftRules.templateCache, since TemplateFinder.findAnyTemplate first checks the cache for the template.

I'll defer to others who know more, particularly David, as he put a scary warning in the source on findAnyTemplate. ;-)

Peter

David Pollak

unread,
Dec 24, 2010, 9:58:42 AM12/24/10
to lif...@googlegroups.com
On Thu, Dec 23, 2010 at 6:18 PM, Peter Robinett <pe...@bubblefoundry.com> wrote:
Hi all,

I'm putting together a Hello World Lift Module and I ran into a stumbling block which hopefully someone here has the solution to. The problem is this: I'd like to provide a template with my module and have the app using the module correctly find it. Thanks to David's work a few weeks ago I can now add a SiteMap Menu entry referring to my template to the main app's SiteMap from within my module's init method. The template is in my module's src/main/webapp directory. However, when I launch the example app using the module I see the Menu listed correctly but clicking on it leads to a 404 error, as the app doesn't see my template. Do you know how I can tell the app to check my module for the file?

Lift ultimately does a ServletContext.getResource (see http://download.oracle.com/docs/cd/E17802_01/products/products/servlet/2.3/javadoc/javax/servlet/ServletContext.html#getResource%28java.lang.String%29 ) on the path of the URL.  So, the call will be ServletContext.getResource("/foo/bar.html") and however that gets resolved to your JAR by the J/EE Container is how you have to package the static file.

Alternatively, you can use LiftRules.viewDispatch http://scala-tools.org/mvnsites/liftweb-2.2-RC4/framework/scaladocs/net/liftweb/http/LiftRules$object.html#viewDispatch

You can match on the List[String] representing the path to return Either[() => Box[NodeSeq], LiftView]

Oh, and the comment in TemplateFinder is about programming style... I did some serious turning of findAnyTemplate, I know it's ugly, but it's fast and fast matters.
 

Thanks,
Peter

--
You received this message because you are subscribed to the Google Groups "Lift" group.
To post to this group, send email to lif...@googlegroups.com.
To unsubscribe from this group, send email to liftweb+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/liftweb?hl=en.



--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Blog: http://goodstuff.im
Surf the harmonics

Timothy Perrett

unread,
Dec 24, 2010, 11:29:09 AM12/24/10
to Lift
Ok, so what about using the view dispatch system to load your NodeSeq
from the template in your other JAR? Views are content generators, so
where its coming from is kind of irrelevant - its simply () =>
NodeSeq. Seems like you could load that template in your other JAR and
integrate it that way.

By the by, in this regard you may what to look at the CMS dpp was
working on, as that does something similar (if memory recalls) where
it just loads templates from the filesystem external to the web
application... you want to do the inverse, so it should be even
simpler. Might be worth a scootch anyway.

Cheers, Tim

Peter Robinett

unread,
Dec 24, 2010, 1:23:21 PM12/24/10
to lif...@googlegroups.com

On Friday, December 24, 2010 3:58:42 PM UTC+1, David Pollak wrote:
Lift ultimately does a ServletContext.getResource (see http://download.oracle.com/docs/cd/E17802_01/products/products/servlet/2.3/javadoc/javax/servlet/ServletContext.html#getResource%28java.lang.String%29 ) on the path of the URL.  So, the call will be ServletContext.getResource("/foo/bar.html") and however that gets resolved to your JAR by the J/EE Container is how you have to package the static file.

Hmm, ok. Do you know how Jetty works? I'd like to poke around from the sbt console, but I'm not having a lot of luck.
 
Alternatively, you can use LiftRules.viewDispatch http://scala-tools.org/mvnsites/liftweb-2.2-RC4/framework/scaladocs/net/liftweb/http/LiftRules$object.html#viewDispatch

You can match on the List[String] representing the path to return Either[() => Box[NodeSeq], LiftView]

That sounds good, but how would I load the template file from my module's JAR? That seems be the the tricky part, once I can find it I can load it into a NodeSeq, add it to the template cache, all sorts of things.
 
Oh, and the comment in TemplateFinder is about programming style... I did some serious turning of findAnyTemplate, I know it's ugly, but it's fast and fast matters.

Yep, I know. I just thought it was a good sign that Here Be Dragons. =)

In the end I think just using a Template LocParam and setting the template in code is simpler and better for what I want to achieve. That being said, it would still be great if I could do something simple, along the lines of the LiftRules.addToPackages("my.module.name") command I use to enable Lift to find my module's snippets and the like.

Thanks,
Peter 

Timothy Perrett

unread,
Dec 24, 2010, 7:04:11 PM12/24/10
to Lift
Peter, all the tools you need are in Lift already I think - its simply
a case of knitting it together correctly. For example, I think you
could load the template from the other JAR using the existing template
parsing using net.liftweb.util.PCDataXmlParser which only needs a
Source; without looking at it in more detail I cant say exactly, but
it certainly wouldn't be too difficult. The question probably is, what
do you actually gain from having it in a template file specifically.
If its not much, probably just easier to do it with inline code.

Cheers, Tim

On Dec 24, 6:23 pm, Peter Robinett <pe...@bubblefoundry.com> wrote:
> On Friday, December 24, 2010 3:58:42 PM UTC+1, David Pollak wrote:
>
> > Lift ultimately does a ServletContext.getResource (see
> >http://download.oracle.com/docs/cd/E17802_01/products/products/servle...) on the path of the URL.  So, the call will be
> > ServletContext.getResource("/foo/bar.html") and however that gets resolved
> > to your JAR by the J/EE Container is how you have to package the static
> > file.
>
> Hmm, ok. Do you know how Jetty works? I'd like to poke around from the sbt
> console, but I'm not having a lot of luck.
>
> > Alternatively, you can use LiftRules.viewDispatch
> >http://scala-tools.org/mvnsites/liftweb-2.2-RC4/framework/scaladocs/n...

David Pollak

unread,
Dec 27, 2010, 1:44:50 PM12/27/10
to lif...@googlegroups.com
On Fri, Dec 24, 2010 at 10:23 AM, Peter Robinett <pe...@bubblefoundry.com> wrote:

On Friday, December 24, 2010 3:58:42 PM UTC+1, David Pollak wrote:
Lift ultimately does a ServletContext.getResource (see http://download.oracle.com/docs/cd/E17802_01/products/products/servlet/2.3/javadoc/javax/servlet/ServletContext.html#getResource%28java.lang.String%29 ) on the path of the URL.  So, the call will be ServletContext.getResource("/foo/bar.html") and however that gets resolved to your JAR by the J/EE Container is how you have to package the static file.

Hmm, ok. Do you know how Jetty works? I'd like to poke around from the sbt console, but I'm not having a lot of luck.

Try looking at lift-widgets.  Look at the directory structure and see how it's mapped to ServletContext.getResource (it'll be pretty obvious).

Put another way, I could give you the answer, but pointing you at examples will, I hope, help you understand by doing and spelunking through code that does similar things.  That should give you a more solid grounding rather than just being able to be told the answer.
 
 
Alternatively, you can use LiftRules.viewDispatch http://scala-tools.org/mvnsites/liftweb-2.2-RC4/framework/scaladocs/net/liftweb/http/LiftRules$object.html#viewDispatch

You can match on the List[String] representing the path to return Either[() => Box[NodeSeq], LiftView]

That sounds good, but how would I load the template file from my module's JAR? That seems be the the tricky part, once I can find it I can load it into a NodeSeq, add it to the template cache, all sorts of things.

See above.  The best way is to use ServletContext.getResource.
 
 
Oh, and the comment in TemplateFinder is about programming style... I did some serious turning of findAnyTemplate, I know it's ugly, but it's fast and fast matters.

Yep, I know. I just thought it was a good sign that Here Be Dragons. =)

In the end I think just using a Template LocParam and setting the template in code is simpler and better for what I want to achieve. That being said, it would still be great if I could do something simple, along the lines of the LiftRules.addToPackages("my.module.name") command I use to enable Lift to find my module's snippets and the like.

Thanks,
Peter 

--
You received this message because you are subscribed to the Google Groups "Lift" group.
To post to this group, send email to lif...@googlegroups.com.
To unsubscribe from this group, send email to liftweb+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/liftweb?hl=en.
Reply all
Reply to author
Forward
0 new messages