[stringtemplate-interest] ST4: Directory STGroups, common templates, relative template names?
Udo Borkowski
ub at abego-software.de
Wed Apr 20 00:44:02 PDT 2011
Hi Barrie,
you can simplify your templates by using both the "template group directory" and "template group file" feature of ST4.
ST4 allows you to create template groups in two ways:
- create a directory (the "template group directory") and put all template files (extension ".st") of that group into the directory.
- create a template group file (extension ".stg") containing all template definitions of that group (for syntax see http://www.antlr.org/wiki/display/ST4/Group+file+syntax)
E.g. your "common" directory is already a perfect template group, called "common":
> - mytemplate.st
> - common/HelloWorld.st
> - common/Hello.st
> - common/World.st
It contains three templates "HelloWorld", "Hello" and "World". As "Hello" and "World" belong to the same group as "HelloWorld" you don't need to the "common" prefix (<common/Hello()>) to call them from "HelloWorld.". I.e. your "HelloWorld.st" just looks like this:
HelloWorld() ::= <<
<Hello()> <World()>
>>
("Hello.st" and "World.st" need no change)
To use the "common" group and call its templates from outside the group you need to import the group. Therefore make "mytemplate.st" a template group file by changing the extension to ".stg". Add the import statement for the "common" group. I.e.
mytemplate.stg
----------------------
import "common"
mytemplate() ::= <<
<HelloWorld()>
>>
----------------------
Again you don't need the "common" prefix when referencing the template.
Now you can load the group "mytemplate.stg", get a "mytemplate" template and render it.
Here a complete example:
package org.stringtemplate.v4.debug;
import org.junit.Assert;
import org.junit.Test;
import org.stringtemplate.v4.ST;
import org.stringtemplate.v4.STGroup;
import org.stringtemplate.v4.STGroupFile;
public class TreloarTest extends BaseTest {
/**
* see http://www.antlr.org/pipermail/stringtemplate-interest/2011-April/003445.html
*
* @throws Exception
*/
@Test
public void testIt() throws Exception {
String subdir = tmpdir + "/common";
writeFile(tmpdir, "mytemplate.stg",
"import \"common\"\n\nmytemplate() ::= <<\n<HelloWorld()>\n>>\n");
writeFile(subdir, "Hello.st", "Hello() ::= <<\nHello\n>>");
writeFile(subdir, "World.st", "World() ::= <<\nWorld\n>>");
writeFile(subdir, "HelloWorld.st",
"HelloWorld() ::= <<\n<Hello()> <World()>\n>>");
STGroup group = new STGroupFile(tmpdir+ "/mytemplate.stg");
ST st = group.getInstanceOf("mytemplate");
String s = st.render();
Assert.assertEquals("Hello World", s);
}
}
You may also want to have a look at chapter "Import statements" in http://www.antlr.org/wiki/display/ST4/Group+file+syntax
Hope this helps.
Udo
On 20.04.2011, at 04:17, Barrie Treloar wrote:
> I've built my ST3 process around not having a single group file
> (*.stg) but using a directory instead.
> I've ported this wholesale into ST4 and have a couple of questions.
>
> I'm finding that when a template needs to invoke another template then
> the template name must be specified as a relative path from the Group.
> e.g.
> <STGroup.dir>/
> - mytemplate.st
> - common/HelloWorld.st
> - common/Hello.st
> - common/World.st
>
> In:
> * mytemplate.st -> <common/HelloWorld()>
> * common/HelloWorld -> <common/Hello()> and <common/World()>
>
> This makes sense when I look at the code, but I had naively expected
> that in common/HelloWorld to be able to reference <Hello()> and
> <World()>
> Having relative paths is making my templates a bit uglier than I
> thought when I started separating out the files into multiple
> directories, but that is better than having 60+ templates living in
> the one directory.
> It gets a bit more worse when you have multiple directories.
>
> Does anyone have advice for me?
>
> Should I move to using a *.stg file instead? I've not used a *.stg
> file before, but since I can import templates from a directory, ala
> import "test" // import a directory of templates
> (http://www.antlr.org/wiki/display/ST4/Group+file+syntax)
> Perhaps that will do what I want...
> Can I import "*" somehow?
>
> Should directory based groups have similar functionality some how?
>
> (As an aside, if you make a typo [in either the filename or
> templatename] then ST will not be able to find your template and will
> give you an error because the template does not exist. From what I
> can tell you can not also define other template names within the
> template file either. In java terminology the *.st must match the
> name of the single public template within the file and no
> package/private templates may also live inside that file
> Is this expected behaviour?)
>
> Cheers
> _______________________________________________
> stringtemplate-interest mailing list
> stringtemplate-interest at antlr.org
> http://www.antlr.org/mailman/listinfo/stringtemplate-interest
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.antlr.org/pipermail/stringtemplate-interest/attachments/20110420/771aa276/attachment.html
More information about the stringtemplate-interest
mailing list