NOTE: This is outdated information that applies only to Tapestry 4. For current information see http://tapestry.apache.org/layout-component.html. |
In \[Mid 2005 I was\] bitten by the HTML/CSS standards bug. I wanted to write semantically rich HTML code that would validate with validator.w3.org (except for the minor jwcids), I could look at direct in my browser of choice, and that Tapestry would take and generate similarily good HTML. |
The standard HTML page example is the one in section 6.6.3 of Tapestry in Action:
<html> <head> <title>Tapestry Hangman</title> <link rel="stylesheet" type="text/css" href="css/hangman.css"/> </head> <body jwcid="$content$"> <span jwcid="@Border"> . . . </span> </body> </html> |
My solution is to move the $content$ up to html tag, and the Border component moves to the body tag:
<html jwcid="$content$"> <head> <title>Tapestry Hangman</title> <link rel="stylesheet" type="text/css" href="css/hangman.css"/> </head> <body jwcid="@Border"> . . . </body> </html> |
My full version adds the following bells and whistles:
Here's what a standard html page looks like:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en" jwcid="$content$"> <head jwcid="$remove$"> <meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1"> <title>Login</title> <link rel="stylesheet" type="text/css" href="css/emv2.css"/> <!--[if IE 6]> <link rel="stylesheet" type="text/css" href="css/ie6.css"/> <![endif]--> <!--[if IE 7]> <link rel="stylesheet" type="text/css" href="css/ie7.css"/> <![endif]--> <![if !IE]> <link rel="stylesheet" type="text/css" href="css/nonIE.css"/> <![endif]> </head> <body jwcid="@Border" baseStylesheet="ognl:assets.baseStylesheet"> . . . </body> </html> |
My Border component html looks like this:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html jwcid="@Shell" title="ognl:page.pageTitle" doctype="" stylesheet="ognl:stylesheet" delegate="ognl:headerDelegate" xmlns="http://www.w3.org/1999/xhtml" lang="ognl:page.locale.language" xml:lang="ognl:page.locale.language"> <head jwcid="$remove$"> <meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1"> <link rel="stylesheet" type="text/css" href="css/base.css"/> <!--[if IE 6]> <link rel="stylesheet" type="text/css" href="css/ie6.css"/> <![endif]--> <!--[if IE 7]> <link rel="stylesheet" type="text/css" href="css/ie7.css"/> <![endif]--> <![if !IE]> <link rel="stylesheet" type="text/css" href="css/nonIE.css"/> <![endif]> <title>Border Component</title> </head> <body jwcid="@Body"> <div id="header"> </div> <div id="contentBlock"> <span jwcid="@RenderBody"> Body content goes here. </span> </div> <div id="footer"> </div> </body> </html> |
My IRender to do the conditional comments in the head tag takes 4 stylesheet assets:
Here is the code:
package de.xcom.emv.tapestry; import org.apache.tapestry.IAsset; import org.apache.tapestry.IMarkupWriter; import org.apache.tapestry.IRender; import org.apache.tapestry.IRequestCycle; /** * This delegate is invoked before the </head> tag of the rendering @Shell component. * It is used to write out the correct styleheets using conditional comments. * * It also supports calling additional delegates to continue the good work. * * @author joconnor */ public class StylesheetDelegate implements IRender { private IRender nextDelegate; private IAsset ie6Stylesheet; private IAsset ie7Stylesheet; private IAsset nonIEStylesheet; private IAsset baseStylesheet; public StylesheetDelegate(IAsset ie6, IAsset ie7, IAsset nonIE, IAsset base, IRender nextDelegate) { this.ie6Stylesheet = ie6; this.ie7Stylesheet = ie7; this.nonIEStylesheet = nonIE; this.baseStylesheet = base; this.nextDelegate = nextDelegate; } public void render(IMarkupWriter writer, IRequestCycle cycle) { writeStylesheetLink(writer, cycle, baseStylesheet); writeStylesheetLink(writer, cycle, "<!--[if IE 6]>\n", ie6Stylesheet, "<![endif]-->\n"); writeStylesheetLink(writer, cycle, "<!--[if IE 7]>\n", ie7Stylesheet, "<![endif]-->\n"); writeStylesheetLink(writer, cycle, "<![if !IE]>\n", nonIEStylesheet, "<![endif]>\n"); if (nextDelegate != null) { nextDelegate.render(writer, cycle); } } private void writeStylesheetLink(IMarkupWriter writer, IRequestCycle cycle, String ifCond, IAsset stylesheet, String endIf) { if (stylesheet != null) { writer.printRaw(ifCond); writeStylesheetLink(writer, cycle, stylesheet); writer.printRaw(endIf); } } private void writeStylesheetLink(IMarkupWriter writer, IRequestCycle cycle, IAsset stylesheet) { if (stylesheet != null) { writer.beginEmpty("link"); writer.attribute("rel", "stylesheet"); writer.attribute("type", "text/css"); writer.attribute("href", stylesheet.buildURL(cycle)); writer.println(); } } } |