To help me output XHTML ... here are 3 classes. Most of the code below came
from the wiki.

I updated a few generic class references. You'll want to put these in the
(root)**.services package.

-Luther




import java.io.IOException;

import org.apache.tapestry5.*;
import org.apache.tapestry5.ioc.Configuration;
import org.apache.tapestry5.ioc.MappedConfiguration;
import org.apache.tapestry5.ioc.OrderedConfiguration;
import org.apache.tapestry5.ioc.ServiceBinder;
import org.apache.tapestry5.ioc.annotations.InjectService;
import org.apache.tapestry5.services.AliasContribution;
import org.apache.tapestry5.services.MarkupWriterFactory;
import org.apache.tapestry5.services.Request;
import org.apache.tapestry5.services.RequestFilter;
import org.apache.tapestry5.services.RequestHandler;
import org.apache.tapestry5.services.Response;
import org.slf4j.Logger;

/**
 * This module is automatically included as part of the Tapestry IoC
Registry, it's a good place to
 * configure and extend Tapestry, or to place your own service definitions.
 */
public class TapestryModule
{
    public static void bind(ServiceBinder binder)
    {
        // binder.bind(MyServiceInterface.class, MyServiceImpl.class);

        // Make bind() calls on the binder object to define most IoC
services.
        // Use service builder methods (example below) when the
implementation
        // is provided inline, or requires more initialization than simply
        // invoking the constructor.
    }

    public static void
contributeAlias(Configuration<AliasContribution<MarkupWriterFactory>>
configuration)
    {

configuration.add(AliasContribution.create(MarkupWriterFactory.class, new
XhtmlMarkupWriterFactory()));
    }

    public static void contributeApplicationDefaults(
            MappedConfiguration<String, String> configuration)
    {
        // Contributions to ApplicationDefaults will override any
contributions to
        // FactoryDefaults (with the same key). Here we're restricting the
supported
        // locales to just "en" (English). As you add localised message
catalogs and other assets,
        // you can extend this list of locales (it's a comma seperated
series of locale names;
        // the first locale name is the default when there's no reasonable
match).

        configuration.add(SymbolConstants.SUPPORTED_LOCALES, "en");

        // The factory default is true but during the early stages of an
application
        // overriding to false is a good idea. In addition, this is often
overridden
        // on the command line as -Dtapestry.production-mode=false
        configuration.add(SymbolConstants.PRODUCTION_MODE, "false");
    }


    /**
     * This is a service definition, the service will be named
"TimingFilter". The interface,
     * RequestFilter, is used within the RequestHandler service pipeline,
which is built from the
     * RequestHandler service configuration. Tapestry IoC is responsible for
passing in an
     * appropriate Log instance. Requests for static resources are handled
at a higher level, so
     * this filter will only be invoked for Tapestry related requests.
     *
     * <p>
     * Service builder methods are useful when the implementation is inline
as an inner class
     * (as here) or require some other kind of special initialization. In
most cases,
     * use the static bind() method instead.
     *
     * <p>
     * If this method was named "build", then the service id would be taken
from the
     * service interface and would be "RequestFilter".  Since Tapestry
already defines
     * a service named "RequestFilter" we use an explicit service id that we
can reference
     * inside the contribution method.
     */
    public RequestFilter buildTimingFilter(final Logger log)
    {
        return new RequestFilter()
        {
            public boolean service(Request request, Response response,
RequestHandler handler)
                    throws IOException
            {
                long startTime = System.currentTimeMillis();

                try
                {
                    // The responsibility of a filter is to invoke the
corresponding method
                    // in the handler. When you chain multiple filters
together, each filter
                    // received a handler that is a bridge to the next
filter.

                    return handler.service(request, response);
                }
                finally
                {
                    long elapsed = System.currentTimeMillis() - startTime;

                    log.info(String.format("Request time: %d ms", elapsed));
                }
            }
        };
    }

    /**
     * This is a contribution to the RequestHandler service configuration.
This is how we extend
     * Tapestry using the timing filter. A common use for this kind of
filter is transaction
     * management or security.
     */
    public void contributeRequestHandler(OrderedConfiguration<RequestFilter>
configuration,
            @InjectService("TimingFilter")
            RequestFilter filter)
    {
        // Each contribution to an ordered configuration has a name, When
necessary, you may
        // set constraints to precisely control the invocation order of the
contributed filter
        // within the pipeline.

        configuration.add("Timing", filter);
    }
}




import org.apache.tapestry5.ContentType;
import org.apache.tapestry5.MarkupWriter;
import org.apache.tapestry5.dom.MarkupModel;
import org.apache.tapestry5.internal.services.MarkupWriterImpl;
import org.apache.tapestry5.services.MarkupWriterFactory;

/**
 * @author luther.baker
 */
public class XhtmlMarkupWriterFactory implements MarkupWriterFactory
{
    // private
    private final MarkupModel xmlModel = new ImprovedXhtmlMarkupModel();

    /**
     * @see
org.apache.tapestry5.services.MarkupWriterFactory#newMarkupWriter(org.apache.tapestry5.ContentType)
     */
    @Override
    public MarkupWriter newMarkupWriter(ContentType contentType)
    {
        return new MarkupWriterImpl(xmlModel,
contentType.getParameter("charset"));
    }

    /**
     * @see
org.apache.tapestry5.services.MarkupWriterFactory#newMarkupWriter(java.lang.String)
     */
    @Override
    public MarkupWriter newMarkupWriter(String pageName)
    {
        // TODO Auto-generated method stub
        return null;
    }

}




import java.util.HashSet;
import java.util.Set;

import org.apache.tapestry5.dom.DefaultMarkupModel;
import org.apache.tapestry5.dom.EndTagStyle;

/**
 * @author luther.baker
 */
public class ImprovedXhtmlMarkupModel extends DefaultMarkupModel
{
    private static final Set<String> DONT_ABRV = newSet("script", "div",
"span", "p");

    @Override
    public EndTagStyle getEndTagStyle(String element)
    {
        boolean isDontAbr = DONT_ABRV.contains(element);
        return isDontAbr ? EndTagStyle.REQUIRE : EndTagStyle.ABBREVIATE;
    }

    @Override
    public boolean isXML()
    {
        return true;
    }

    private static final Set<String> newSet(String a, String b, String c,
String d)
    {
        Set<String> set = new HashSet<String>();
        set.add(a);
        set.add(b);
        set.add(c);
        set.add(d);
        return set;
    }

}





2008/9/9 Luther Baker <[EMAIL PROTECTED]>

> I do remember the generics being a bit tricky but not too bad.
>
> I will post what I have a bit later tonite.
>
> -Luther
>
>
>
>
>
> On Tue, Sep 9, 2008 at 12:24 PM, ProAdmin Dariusz Dwornikowski <
> [EMAIL PROTECTED]> wrote:
>
>> And it wokred for you ?
>>
>> public static void contributeAlias(Configuration<AliasContribution>
>> configuration) {
>>
>>  configuration.add(AliasContribution.create(MarkupWriterFactory.class,
>> new XhtmlMarkupWriterFactoryImpl()));
>>            }
>>
>>
>> I get error after insering that in AppModule. Eclipse says:
>>
>>
>> The method create(Class<X>, X) in the type AliasContribution is not
>> applicable for the arguments
>> (Class<MarkupWriterFactory>,XhtmlMarkupWriterFactoryImpl)
>>
>>
>>
>> W dniu 9 września 2008 19:18 użytkownik Luther Baker
>> <[EMAIL PROTECTED]> napisał:
>> >
>> > I followed the wiki instructions and the other posts here and yes, I am
>> > generating correct XHTML now.
>> >
>> > I haven't attempted to remove the superfluous tapestry css file nor have
>> I
>> > convinced the library to put the Content-Type meta tag first - but I'm
>> > satisfied with valid XHTML.
>> >
>> > The only other style *thing* I've been been disappointed with is that
>> things
>> > like the provided beaneditform template (from the tutorial) include
>> > Javascript files within the html body tags. Although it generally works
>> in
>> > most browsers, I don't think script tags are legal body tag children ..
>> ie:
>> > not XHTML compliant. I loved to be proved wrong but as far as I know, it
>> is
>> > generally considered poor practice to include Javascript in the body
>> tags of
>> > the html.
>> >
>> > That said, I'm not sure whether this component just needs to be tweaked
>> or
>> > if this is inherent in component html frameworks since the Javascript is
>> > relevant to the component being referenced. The
>> > [EMAIL PROTECTED] makes me think that it is also
>> > possible to do the same for
>> > Javascript files - but I've not written or tried to fix the provided
>> > beaneditform. I found this:
>> > [EMAIL PROTECTED]("${tapestry.scriptaculous}/dragdrop.js")
>> > but I have to assume it is being used in the beaneditform - and in that
>> > case, it is NOT pushing these script includes into HEAD ... but I
>> suppose
>> > it'd be best to look at the source in this case.
>> >
>> > All in all - these are minor style points - it really is a fantastic
>> > framework.
>> >
>> > -Luther
>> >
>> >
>> >
>> > On Tue, Sep 9, 2008 at 11:18 AM, ProAdmin Dariusz Dwornikowski <
>> > [EMAIL PROTECTED]> wrote:
>> >
>> > > Did you manage to achieve it in 5.0.14 ? Im very curious, how to do
>> the
>> > > Wiki
>> > > method in 5.0.14.
>> > >
>> > > 2008/9/1 Luther Baker <[EMAIL PROTECTED]>
>> > >
>> > > > Is there a way to adjust the html that is generated - especially in
>> the
>> > > > header?
>> > > >
>> > > > Specifically, the generated head section does not appear to be xhtml
>> > > > compliant.
>> > > >
>> > > > Here is what I'm including in my own custom "wrapping" component:
>> > > >
>> > > > <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
>> > > >  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd";>
>> > > > <html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd
>> "
>> > > > lang="en">
>> > > >    <head>
>> > > >        <meta http-equiv="Content-Type" content="text/html;
>> > > charset=UTF-8"/>
>> > > >        <title>${pageTitle}</title>
>> > > >        <link rel="stylesheet" href="css/styles.css"
>> type="text/css"/>
>> > > >    </head>
>> > > >
>> > > >
>> > > > *A few points:
>> > > > *
>> > > > a) The xhtml strict DOCTYPE should be pretty straightforward
>> > > > b) I want the Content-Type first in the <head> tag
>> > > > c) The meta tag *MUST* have a closing slash - otherwise the document
>> is
>> > > not
>> > > > well formed.
>> > > > d) The same goes for the two <link tags. XHTML dictates that all
>> tags
>> > > must
>> > > > be well formed.
>> > > >
>> > > >
>> > > > *Unfortunately, my application ends up generating
>> > > > *
>> > > > <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
>> > > >               "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd";>
>> > > > <html lang="en" xmlns="http://www.w3.org/1999/xhtml";>
>> > > > <head>
>> > > > <link href="assets/tapestry/5.0.14/default.css" rel="stylesheet"
>> > > > type="text/css">
>> > > > <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
>> > > > <title>Home</title>
>> > > > <link href="css/styles.css" rel="stylesheet" type="text/css">
>> > > > </head>
>> > > >
>> > > >
>> > > > For the most part - this is fine ... but in the details, I believe
>> my
>> > > > problem is two fold:
>> > > >
>> > > > 1) I would really like the "Content-Type" to be the first tag in
>> head.
>> > > > 2) The link and meta tags are not properly closed. Unfortunately,
>> this
>> > > > code-gen is just not valid xhtml.
>> > > >
>> > > > I do have one last (not so terrible) issue with the EXTRA <link tag
>> > > > (tapestry specific css) that is showing up in the head as well. I'm
>> sure
>> > > it
>> > > > is nice for exceptions (which the final user should never see) but
>> it has
>> > > a
>> > > > few more problems:
>> > > >
>> > > > 1) It tells everyone what version of a particular library I am
>> using. I'd
>> > > > rather not do that.
>> > > > 2) The tag appears before my Content-Type tag - which as I
>> mentioned, I'd
>> > > > prefer FIRST in the hierarchy.
>> > > > 3) Finally, the tapestry stylesheet is not well formed. Again,
>> proper
>> > > xhtml
>> > > > demands that tags be balanced/closed.
>> > > >
>> > > > I know Code Gen is hard -- but I generally pay extra attention to
>> ensure
>> > > I
>> > > > produce valid, well formed xhtml documents and the codegen going on
>> > > behind
>> > > > the scenes here is making that a bit hard.
>> > > >
>> > > > Thoughts?
>> > > >
>> > > > I'm not sure how to close the tags - maybe I can set a flag or pass
>> > > > something else in as an xml attribute of the root tag of my
>> templates?
>> > > > Regarding the extra tapestry css file inserted ... maybe the
>> Tapestry
>> > > > library has a DEBUG and a RELEASE mode? Maybe there a flag to turn
>> off
>> > > the
>> > > > DEBUG mode and put this library into RELEASE mode? I really don't
>> want
>> > > that
>> > > > tapestry specfiic css page requested everytime I serve up a page. I
>> > > > understand the filter takes care of it ... but it still shows up in
>> my
>> > > > request logs, on user pages, in proxies, etc ...
>> > > >
>> > > > Is it even wise to consider opening up the tapestry JARs and see if
>> the
>> > > > components implementeing this section of code can simply be tweaked
>> to
>> > > have
>> > > > proper xhtml balance.
>> > > >
>> > > > On a positive note, the library is working well and I enjoy the
>> general
>> > > > programming model. I think convention is great - but it needs to be
>> valid
>> > > > in
>> > > > this case. Thanks again in advance for any thoughts.
>> > > >
>> > > > -Luther
>> > > >
>> > >
>> > >
>> > >
>> > > --
>> > > Pozdrawiam,
>> > > Dariusz Dwornikowski
>> > > ------------------------------------
>> > > ProAdmin
>> > > ul. Królowej Jadwigi 44/2
>> > > 61-872 Poznań
>> > > tel: 061 623-20-92
>> > > kom: 0601 59-64-74
>> > > fax: 061 623-20-93
>> > > www.proadmin.com.pl
>> > > [EMAIL PROTECTED]
>> > >
>>
>>
>>
>> --
>> Pozdrawiam,
>> Dariusz Dwornikowski
>> ------------------------------------
>> ProAdmin
>> ul. Królowej Jadwigi 44/2
>> 61-872 Poznań
>> tel: 061 623-20-92
>> kom: 0601 59-64-74
>> fax: 061 623-20-93
>> www.proadmin.com.pl
>> [EMAIL PROTECTED]
>>
>
>

Reply via email to