views:

949

answers:

2

In Grails, there are two mechanisms for modularity in the view layers : template and taglib.

While I am writing my own Grail app, I am often facing the same question when I need to write an UI component : do I need to use a template or a tagLib ?After searching the web, I didn't find a lot of best practices or rules of thumb concerning this design decision.

So basically, can you help me and tell me:

  1. What is the main difference between the two mechanisms?
  2. In which scenarios, do you use a TagLib instead of a Template (and vice versa) ?

Thanks,

Fabien.

A: 

As for us...

A coder is supposed to see specific object presentation logic in template, not anywhere else.

We use taglibs only for isolated page elements, not related to business logic at all. Actually, we try to minimize their usage: it's too easy to write business logic in a taglib.

Templates are the conventional way to go; for instance, they support Layouts (btw, they can be named a third mechanism)

Victor Sergienko
+6  A: 

There is definitely some overlap, but below are several things to think about. One way to think about it is that Template is like a method-level reuse, while TagLibs are more convenient for API-level reuse.

  • Templates are great for when you have to format something specific for display. For example, if you wan to display a domain object in a specific way, typically it's easier to do it in a template, since you are basically just writing HTML with some . It's reusable, but I think its reusability in a bit limited. I.e. if you have a template, you'd use it in several pages, not in hundreds of pages.

  • On the other hand, taglibs is a smaller unit of functionality, but one you are more likely to use in many places. In it you are likely to concatenate strings, so if you are looking to create a hundred lines of HTML, they are less convenient. A key feature taglibs allow is ability to inject / interact with services. For example, if you need a piece of code that calls up an authentication service and displays the current user, you can only do that in a TagLib. You don't have to worry about passing anything to the taglib in this case - taglib will go and figure it out from the service. You are also likely to use that in many pages, so it's more convenient to have a taglib that doesn't need parameters.

  • There are also several kinds of taglibs, including ones that allow you to iterate over something in the body, have conditional, etc - that's not really possible with templates. As I said above, a well-crafted taglib library can be used to create a re-usable API that makes your GSP code more readable. Inside the same *taglib.groovy you can have multiple tag definitions, so that's another difference - you can group them all in once place, and call from one taglib into another.

Also, keep in mind that you can call up a template from inside a taglib, or you can call taglibs withing templates, so you can mix and match as needed.

Hope this clears it up for you a bit, though really a lot of this is what construct is more convenient to code and how often it will be reused.

Jean Barmash
Great !! Exactly the kind of answers I was expecting ! You have put in words and barely formalized what I was only feeling from intuition. Thank you.
fabien7474
"iterate over something in the body, have conditional, etc - that's not really possible with templates" - er, sorry?You can write arbitrary Groovy code in template. And template can iterate over array and do conditionals even without Groovy code.Though, it's better to do so at a minimum.
Victor Sergienko
Victor - I meant that inside taglib body you can run additional code, that has nothing to do with your taglib, not that you can't run code in the templates. I probably should have qualified more.
Jean Barmash
I typically use a mix of the two. I'll create a taglib that handles preparing any sort of model then render a template with the prepared model. The rule of thumb I try to follow is that the bulk of the HTML should be in a template and the bulk of the Groovy code should be in a taglib.
Matt Lachman