Hi Norm,

Below is text from a CustomHead I wrote. It does header/splash/icon images for 
appfuse css-framework. Integrated to trails features I developed of course.

It will give you some insights for the shell derivative.

I am a trails developer. So anything trails you might want to tailor.

Can't help you with the menu.

Best regards
Ken in nashua

Customhead.java
-------------------------------------
package org.trails.demo.components;

import java.util.Date;
import java.util.Iterator;

import org.apache.hivemind.HiveMind;
import org.apache.tapestry.IAsset;
import org.apache.tapestry.IMarkupWriter;
import org.apache.tapestry.IPage;
import org.apache.tapestry.IRender;
import org.apache.tapestry.IRequestCycle;
import org.apache.tapestry.IScript;
import org.apache.tapestry.Tapestry;
import org.apache.tapestry.annotations.Asset;
import org.apache.tapestry.annotations.ComponentClass;
import org.apache.tapestry.annotations.InjectObject;
import org.apache.tapestry.annotations.InjectScript;
import org.apache.tapestry.annotations.InjectState;
import org.apache.tapestry.annotations.Parameter;
import org.apache.tapestry.coerce.ObjectArrayToIteratorConverter;
import org.apache.tapestry.engine.ILink;
import org.apache.tapestry.html.Shell;
import org.apache.tapestry.json.IJSONWriter;
import org.apache.tapestry.spec.IApplicationSpecification;
import org.trails.component.blob.BlobDownloadService;
import org.trails.component.blob.TrailsBlobAsset;
import org.trails.demo.AdminLayout;

/**
 * Background Usage...
 * 
 * <html jwcid="@Shell" title="Trails" stylesheet="ognl:assets.stylesheet">
 * 
 * The <html> tag is basically the shell to a page. It encompasses <head><body>
 * 
 * @Shell is a tapestry component that intercepts <html> parameters and renders
 *        according to it's semantics. We can do whatever we like in
 * @Shell according to it's defined parameters.
 * 
 * This component is an extension to
 * @Shell. We instrument additional features with the main purpose of rendering
 *         a custom <head>
 * 
 * In short...This guy reaches into the database and applies logo, header and
 * background to default css within the <html> shell. internally, tedius
 * renderings will occur to override specific css-framework fragments and
 * styles.
 * 
 * @author kenneth.colassi        [EMAIL PROTECTED]
 * 
 */
@ComponentClass(allowBody = true, allowInformalParameters = true)
public abstract class CustomHead extends Shell
{
    @InjectState("adminLayout")
    public abstract AdminLayout getLayout();
    public abstract void setLayout(AdminLayout layout);

    @InjectObject("service:trails.core.BlobService")
    public abstract BlobDownloadService getDownloadService();

    private static final String generatorContent = "Tapestry Application 
Framework, version " + Tapestry.VERSION;

    @Asset("/js/dojo-0.4.3/dojo.js")
    public abstract IAsset getDefaultDojoSource();

    @Asset("/dojo-0.4.3/")
    public abstract IAsset getDefaultDojoPath();

    @Asset("/tapestry/core.js")
    public abstract IAsset getDefaultTapestrySource();

    @Asset("/tapestry/")
    public abstract IAsset getDefaultTapestryPath();

    @Asset("/styles/tapestryskin/theme.css")
    public abstract IAsset getTheme();

    /**
     * Injected via jwc - readonly, yes that means no setter
     */
    public abstract IApplicationSpecification getApplicationSpecification();

    /**
     * Injected via jwc - readonly, yes that means no setter
     */
    @InjectScript("CustomHead.script")
    public abstract IScript getScript();

    @Parameter(required = true, cache = true)
    public abstract IAsset getStylesheet();

    public abstract void setStylesheet(IAsset stylesheet);

    @Parameter(required = true, cache = true)
    public abstract String getTitle();
    public abstract void setTitle(String title);

    public abstract IRender getDelegate();

    public abstract IRender getAjaxDelegate();

    public void renderComponent(IJSONWriter writer, IRequestCycle cycle)
    {
    }

    @Override
    protected void prepareForRender(IRequestCycle cycle)
    {
        getLayout();
        super.prepareForRender(cycle);
    }

    @Override
    protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle)
    {
        long startTime = 0;

        boolean rewinding = cycle.isRewinding();

        if (!rewinding)
        {
            startTime = System.currentTimeMillis();

            writeDocType(writer, cycle);

            IPage page = getPage();

            writer.comment("Application: " + 
getApplicationSpecification().getName());
            writer.comment("Page: " + page.getPageName());
            writer.comment("Generated: " + new Date());

            writer.begin("html");
            renderInformalParameters(writer, cycle);
            writer.println();
            writer.begin("head");
            writer.println();

            writer.beginEmpty("meta");
            writer.attribute("name", "generator");
            writer.attribute("content", generatorContent);
            writer.println();

            if (getRenderContentType())
            {
                /**
                 * This should not be necessary (the HTTP content type should be
                 * sufficient), but some browsers require it for some reason
                 */
                writer.beginEmpty("meta");
                writer.attribute("http-equiv", "Content-Type");
                writer.attribute("content", writer.getContentType());
                writer.println();
            }

            if (getLayout() != null)
            {
                writer.begin("title");
                writer.print(getLayout().getTitle());
                writer.end(); // title
                writer.println();
            }

            IAsset stylesheet = getStylesheet();

            if (stylesheet != null)
            {
                writeStylesheetLink(writer, cycle, stylesheet.buildURL());
            }

            ObjectArrayToIteratorConverter conv = new 
ObjectArrayToIteratorConverter();
            if (getStylesheets() != null)
            {
                Iterator i = (Iterator) conv.convertValue((Object[]) 
getStylesheets());
                if (i != null)
                {
                    while (i.hasNext())
                    {
                        stylesheet = (IAsset) i.next();
                        writeStylesheetLink(writer, cycle, 
stylesheet.buildURL());
                    }
                }
            }

            writeRefresh(writer, cycle);

            if (getLayout() != null && 
getLayout().getBackground().getFileName() != null)
            {
                writeStyleOverride(writer, cycle);
            }

            writer.end();
            writer.flush();
        }

        // Render the body, the actual page content
        renderBody(writer, cycle);

        if (!rewinding)
        {
            writer.end(); // html
            writer.println();

            long endTime = System.currentTimeMillis();

            writer.comment("Render time: ~ " + (endTime - startTime) + "ms");
        }

    }

    private void writeDocType(IMarkupWriter writer, IRequestCycle cycle)
    {
        String doctype = getDoctype();
        if (HiveMind.isNonBlank(doctype))
        {
            writer.printRaw("<!DOCTYPE " + doctype + ">");
            writer.println();
        }
    }

    private void writeRefresh(IMarkupWriter writer, IRequestCycle cycle)
    {
        int refresh = getRefresh();

        if (refresh <= 0)
        {
            return;
        }

        // Here comes the tricky part ... have to assemble a complete URL
        // for the current page.

        String pageName = cycle.getPage().getPageName();
        ILink link = getPageService().getLink(false, new String[] { pageName });

        StringBuffer buffer = new StringBuffer();
        buffer.append(refresh);
        buffer.append("; URL=");
        buffer.append(link.getAbsoluteURL());

        // Write out the <meta> tag

        writer.println();
        writer.println();
        writer.beginEmpty("meta");
        writer.attribute("http-equiv", "Refresh");
        writer.attribute("content", buffer.toString());
        writer.println();
        writer.println();
    }

    private void writeStylesheetLink(IMarkupWriter writer, IRequestCycle cycle, 
String stylesheetBase)
    {
        writer.beginEmpty("link");
        writer.attribute("rel", "stylesheet");
        writer.attribute("type", "text/css");
        writer.attribute("title", "don't select");
        String sessionStrippedURL = getTheme().buildURL();
        if (sessionStrippedURL.contains(";"))
            sessionStrippedURL = sessionStrippedURL.substring(0, 
sessionStrippedURL.indexOf(";"));
        writer.attribute("href", sessionStrippedURL);
        writer.println();
        writer.println();
    }

    private void writeStyleOverride(IMarkupWriter writer, IRequestCycle cycle)
    {
        writer.begin("style");
        writer.attribute("type", "text/css");

        writer.println();
        writer.comment("Checkout these Custom <HEAD> widget...Style Overrides");

        doBodyOverride(writer, cycle);

        doMainOverride(writer, cycle);

        doSplashOverride(writer, cycle);

        doPageOverride(writer, cycle);

        writer.end(); // style
        writer.println();
        writer.println();
    }

    private void writeJavaScript(IMarkupWriter writer, IRequestCycle cycle, 
IAsset javascript)
    {
        writer.beginEmpty("script");
        writer.attribute("type", "text/javascript");
        writer.attribute("src", javascript.buildURL());
        writer.closeTag();
        writer.println();
        writer.println();
    }

    private void doBodyOverride(IMarkupWriter writer, IRequestCycle cycle)
    {
        writer.println();
        writer.printRaw("\tbody {");
        writer.println();
        writer.printRaw("\t\tpadding: 5;");
        writer.println();
        writer.printRaw("\t\tmargin: 5;");
        writer.println();
        String blobRenderString = "/BlobService.svc?class=" + 
getLayout().getClass().getCanonicalName()
                + "&contentType=" + 
getLayout().getBackground().getContentType().toString() + "&fileName="
                + getLayout().getBackground().getFileName().toString() + "&id=" 
+ getLayout().getId().toString()
                + "&property=background";
        writer.printRaw("\t\tbackground: #fff url( " + blobRenderString + " ) 
top left repeat;");
        writer.println();
        writer.printRaw("\t}");
        writer.println();
    }

    private void doSplashOverride(IMarkupWriter writer, IRequestCycle cycle)
    {
        writer.println();
        writer.printRaw("\tdiv#splash {");

        writer.println();
        String blobRenderString = "/BlobService.svc?class=" + 
getLayout().getClass().getCanonicalName()
                + "&contentType=" + 
getLayout().getSplash().getContentType().toString() + "&fileName="
                + getLayout().getSplash().getFileName().toString() + "&id=" + 
getLayout().getId().toString()
                + "&property=splash";
        writer.printRaw("\t\tbackground: #fff url( " + blobRenderString + " ) 
top left no-repeat;");
        writer.println();
        writer.printRaw("\t}");
        writer.println();
    }

    private void doMainOverride(IMarkupWriter writer, IRequestCycle cycle)
    {
        writer.println();
        writer.printRaw("\tdiv#main {");
        writer.println();
        writer.printRaw("\t}");
        writer.println();
    }

    private void doPageOverride(IMarkupWriter writer, IRequestCycle cycle)
    {
        writer.println();
        writer.printRaw("\tdiv#page {");
        writer.println();

        writer.println();
        String blobRenderString = "/BlobService.svc?class=" + 
getLayout().getClass().getCanonicalName()
                + "&contentType=" + 
getLayout().getBackground().getContentType().toString() + "&fileName="
                + getLayout().getBackground().getFileName().toString() + "&id=" 
+ getLayout().getId().toString()
                + "&property=background";
        writer.printRaw("\t}");
        writer.println();
    }

    private void doHeaderOverride(IMarkupWriter writer, IRequestCycle cycle)
    {
        writer.println();
        writer.printRaw("\tdiv#header  {");
        writer.println();
        writer.printRaw("\t\theight: 94px;");
        writer.println();
        writer.printRaw("\t\twidth: 740px;");
        writer.println();
        String blobRenderString = "/BlobService.svc?class=" + 
getLayout().getClass().getCanonicalName()
                + "&contentType=" + 
getLayout().getHeader().getContentType().toString() + "&fileName="
                + getLayout().getHeader().getFileName().toString() + "&id=" + 
getLayout().getId().toString()
                + "&property=header";
        writer.printRaw("\t\tbackground: #fff url( " + blobRenderString + " ) 
top left no-repeat;");
        writer.println();
        writer.printRaw("\t}");
        writer.println();
    }

    private void doHeaderImgOverride(IMarkupWriter writer, IRequestCycle cycle)
    {
        writer.println();
        writer.printRaw("\tdiv#header img background {");
        writer.println();
        writer.printRaw("\t\twidth:    740px;");
        writer.println();
        writer.printRaw("\t\theight:    94px;");
        writer.println();
        writer.printRaw("\t}");
        writer.println();
    }

    public IAsset getHeaderAsset()
    {
        String contentType = getLayout().getHeader().getContentType();
        String fileName = getLayout().getHeader().getFileName();

        return new TrailsBlobAsset(getDownloadService(),
                AdminLayout.class.getName(),
                getLayout().getId().toString(),
                "header", contentType,
                fileName);
    }

    public IAsset getLogoAsset()
    {
        String contentType = getLayout().getLogo().getContentType();
        String fileName = getLayout().getLogo().getFileName();

        return new TrailsBlobAsset(getDownloadService(),
                AdminLayout.class.getName(),
                getLayout().getId().toString(),
                "logo", contentType,
                fileName);
    }
}



CustomHead.jwc
-------------------------------------
<!DOCTYPE component-specification PUBLIC "-//Apache Software 
Foundation//Tapestry Specification 4.1//EN" 
"http://jakarta.apache.org/tapestry/dtd/Tapestry_4_1.dtd";>
<component-specification class="org.trails.demo.components.CustomHead"
                         allow-body="yes"
                         allow-informal-parameters="no">

    <inject property="applicationSpecification" 
object="infrastructure:applicationSpecification"/>

</component-specification>


CustomHead.html
-------------------------------------
<span jwcid="$content$">
    <span jwcid="customhead"/>
</span>


Border.html (shows custom head usage)
-------------------------------------
<span jwcid="@ScriptIncludes" />

<html
    jwcid="[EMAIL PROTECTED]:CustomHead"
    title="ognl:layout.title"
    stylesheet="ognl:assets.stylesheet"    >

<body jwcid="@Body">
.... snip...

_________________________________________________________________
Windows Live Hotmail and Microsoft Office Outlook – together at last.  Get it 
now.
http://office.microsoft.com/en-us/outlook/HA102225181033.aspx?pid=CL100626971033

Reply via email to