RSS Feed
19
July
2004

How to generate META tags in Tapestry

Though the Shell component in Tapestry has no parameters for setting META tags it features delegate parameter. The deletage must be of type IRender. When Tapestry renders the Shell component it invokes the following method:

void render(IMarkupWriter writer,  IRequestCycle cycle)

According to the documentation of the Shell component everything you write through the writer will be placed before the tag. Therefore it perfectly serves our needs for writing custom META tags! First thing you have to do is to write a simple custom class that implements the IRender interface:

public class MetaGenerator implements IRender
{
    private IAsset propertiesFile;

    public IAsset getPropertiesFile()
    {
        return propertiesFile;
    }

    public void setPropertiesFile(IAsset propertiesFile)
    {
        this.propertiesFile = propertiesFile;
    }

    public void render(IMarkupWriter writer, IRequestCycle cycle)
    {
        if (cycle.isRewinding())
            return;

        Properties p = new Properties();
        try
        {
            InputStream in = propertiesFile.getResourceAsStream(cycle);
            p.load(in);
            in.close();
        }
        catch(Exception ex)
        {
            log.error("Could not read properties file :" + propertiesFile, ex);
        }

        for (Iterator it = p.keySet().iterator(); it.hasNext(); )
        {
            String name = (String)it.next();
            String content = p.getProperty(name);
            writer.begin("meta");
            writer.attribute("name", name);
            writer.attribute("content", content);
        }
    }

    private final static Log log = LogFactory.getLog(MetaGenerator.class);
}

As you can see the class MetaGenerator has a property propertiesFile of type IAsset. This property can be specified in the decleration of the page:

<?xml version="1.0"?>
<!DOCTYPE component-specification PUBLIC 
    "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
    "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">

<component-specification class="net.acidware.jtwaddle.presentation.component.Border" 
  allow-body="yes" allow-informal-parameters="no">
   <bean name="metaGenerator"
     class="net.acidware.jtwaddle.presentation.bean.MetaGenerator"
     lifecycle="page">
     <set-property name="propertiesFile" expression="assets.metaProperties"/>
   </bean>
...
  <context-asset name="metaProperties" path="meta.properties"/>
</component-specification>

That's it! :-)

Comments

1. Howard M. Lewis Ship
Nice comments and dead on. You should update the Tapestry Wiki FAQ and point it here. Any reason you don't cache the contents of the properties file?

2. Lars Hoss
Hi Howard! Thanks for your feedback :-) First I need to implement the cominbed view (weblog entry + comments). Then I can make a link in the Tapestry Wiki FAQ. Regarding caching: it was just prototyping code ;-)