On 5/8/07, Alexandru Popescu ☀ <the.mindstorm.mailinglist@...> wrote:
On 5/4/07, kawczynski <sitemesh-users@...> wrote:
> I need to implement a solution to 60+ websites to account for new reporting requirements. The solution needs to be able to perform the following:
>
> - add onclick event handlers to <a href> tags that are external to the current site
> - include different <meta> tags based on the URI (using database-driven configuration)
> - include <script src> tags if they didn't already exist on the page.
>
> I read that SiteMesh does decoration, but I have yet to find documentation on it being able to perform low-level body element insertion or modification. Can someone tell me it this is possible, and point me in the direction of a howto?
>
Sitemesh is a decoration tool and not an HTML parser, so some of the
things you need to accomplish are not possible.
Well actually it *is* an extensible HTML parser :)
1/ add onclick event handlers to <a href> tags that are external to
the current site
To do this, you can extend SiteMesh's HTML parser and add a new tag rule for processing <a> tags.
public class MyParser extends HTMLPageParser {
// override default rulest
protected void addUserDefinedRules(State html, PageBuilder page) {
super.addUserDefinedRules(html, page);
// Add a rule.
// Rules allow the parser to do custom things when encountering HTML tags.
html.addRule(new LinkRewritingRule()); // see below
}
}
class LinkRewritingRule extends BasicRule {
public LinkRewritingRule() {
super("a"); // Handles all <a> tags.
}
public void process(Tag tag) { // Called when parser encounters <a>
CustomTag newTag = new CustomTag(tag); // Allows tag modification
// modify href attribute
boolean caseSensitive = false; // allow HREF or href or HrEf
String oldHref = newTag.getAttributeValue("href", caseSensitive);
if (oldHref != null) {
String newHref = // do something;
newTag.setAttributeValue("href", caseSensitive, newHref);
}
// write the new tag bag to the page
newTag.writeTo
(currentBuffer());
}
}
}
To enable this, edit sitemesh.xml and update the <page-parser> tag to point to your new parser class.
2/ include different <meta> tags based on the URI (using
database-driven configuration)
Your decorator is a standard executable page (probably a JSP or Velocity page), so you can include code to output the necessary meta tags there (which can look at the URI).
3/ include <script src> tags if they didn't already exist on the page.
You could create another tag rule, that looks out for <script src> tags and adds them to the page properties. (If you've ever accessed the meta tag properties from a SiteMesh page this works the same way):
class ScriptSrcExtractingRule extends BasicRule {
private PageBuilder page;
public ScriptSrcExtractingRule(PageBuilder page) {
super("script"); // Handles all <script> tags.
this.page = page;
}
public void process(Tag tag) { // Called when parser encounters <script>
String src = newTag.getAttributeValue("src", caseSensitive);
if (src != null) {
// we found a <script src>. Make it available as a page property.
page.addProperty("script." + src);
}
tag.writeTo(currentBuffer()); // ensure original <script> tag is still written out.
}
}
}
Add this to your parser class (above).
Then from decorators, you can do:
<decorator:usePage id="myPage" />
<% if (!myPage.hasProperty("script.something.js")) { %>
<script src="something.js"></script>
<% } %>
cheers
-Joe