tapestry-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Josh Canfield <joshcanfi...@gmail.com>
Subject Re: URL Rewriting in Tapestry 5.2
Date Thu, 08 Jul 2010 00:22:54 GMT
> Hi,
> is the current replacement of the URLRewriter (LinkTransformer) the final new API for
> I would find some missing things quite useful:

Since it's still alpha software so there is room to make changes.
You'll have to get a commiter to on board with making the changes

> 1. A service that parses the request path.

String[] parts = request.getPath().split("/");

That's only partly tongue-in-check. You are able to rewrite urls to be
totally unrecognizable so there is no way for tapestry to know what
you've done or what parts go where.

> In 5.1 I found it frustrating that there was no proper API within Tapestry to read out
the locale (in an early stage of request processing), the page name and wether it's a component
request or not. The ComponentEventLinkEncoderImpl does lots of parsing to find out all of
these information but it doesn't share them. So to get the same information you'd have to
use the same code somehow...

You obviously can't pass in the actual request from a rewritten link
because it's not recognizable to tapestry. Since the
ComponentEventLinkEncoder only accepts a Request you'll have to
un-rewrite the url and use a wrapper request to pass it in. Something

   ComponentEventRequestParameters decodeComponentEventRequest(Request
request) {
       final String fixedPath = request.getPath().replace("dogs",
       return encoder.decodeComponentEventRequest(
                new DelegatingRequest() {
                    public String getPath() {
                        return fixedPath;

> 2. Mapping of rewrite rules.
> Other frameworks have some point where the user may configure a regex and provide a rewritten
path. Wouldn't it be nice if there would be some URLRewritingSource service that one could
contribute these mappings to?
> configuration.add("foo", new URLMapper("someregex", "${message:localizedPageName}"));
> Anything different from reinventing the wheel with each application you develop would
be great :)

I go back and forth about whether this should be in the system or if
it should be documented as a cookbook solution. Here is a very quick
implementation of something like this (minus regexp and symbol

public class StringMapperPageRenderLinkTransformer implements
PageRenderLinkTransformer {
    private List<Mapper> _mappers;
    private ComponentEventLinkEncoder _encoder;

    public StringMapperPageRenderLinkTransformer(List<Mapper> mappers,
ComponentEventLinkEncoder encoder) {
        _mappers = mappers;
        _encoder = encoder;

    public Link transformPageRenderLink(Link defaultLink,
PageRenderRequestParameters parameters) {
        for (Mapper mapper : _mappers) {
            if (defaultLink.getBasePath().contains(mapper.getFrom())) {
        return null;

    public PageRenderRequestParameters decodePageRenderRequest(Request
request) {
        for (Mapper mapper : _mappers) {
            if (request.getPath().contains(mapper.getTo())) {
                final String mapped =
request.getPath().replace(mapper.getTo(), mapper.getFrom());
                return _encoder.decodePageRenderRequest(
                        new DelegatingRequest(request) {
                            public String getPath() {
                                return mapped;
        return null;

    public static class Mapper {
        private String from;
        private String to;

        public Mapper(String from, String to) {
            this.from = from;
            this.to = to;

        public String getFrom() {
            return from;

        public void setFrom(String from) {
            this.from = from;

        public String getTo() {
            return to;

        public void setTo(String to) {
            this.to = to;

It's a service so bind it in your AppModule, and contribute it to the
   public static void contributePageRenderLinkTransformer(
            OrderedConfiguration<PageRenderLinkTransformer> configuration,
            StringMapperPageRenderLinkTransformer stringMapper) {
        configuration.add("StringMapper", stringMapper);

Then you can configure simple string replace patterns:

    public void contributeStringMapperPageRenderLinkTransformer(
configuration) {
        configuration.add("simple", new
StringMapperPageRenderLinkTransformer.Mapper("chicken", "turkey"));

> 3. Setting the locale according to the incoming request path.
> Again, the ComponentEventLinkEncoderImpl provides a very important feature that is hard
to modify. I've had the requirement to change the localization of the page according to the
language of the request path. I don't mean the /en/ persistent local thing, I mean a request
path like /home and /accueil or similar. The page's name can be found in a specific translation's
resource bundle. In 5.1, I rewrote the request path to /en/home or /fr/accueil or similar.
Then ComponentEventLinkEncoderImpl would read out the locale from the path correctly...

As I showed above you can use the ComponentEventLinkEncoder that the
system provides in your link transformer. If you want to make an
incoming path that starts with "/accueil" use the fr locale just
prepend "/fr" to the path before passing it on to the encoder.

I did a quick hack and made it so that anything that came in /german
was given the de locale.

> However, if I would just set the persistent locale by myself and leave the request path
ComponentEventLinkEncoderImpl tries to resolve /home as a locale, fails and sets some default
locale that it's got from the thread or the request.
> An extension to the LocalizationSetter could solve this maybe.
> Well, I hope my thoughts on that are not too far away from what you think Tapestry-Core
should contain :)

The API as written has a learning curve. Perhaps a mod_rewrite style
facade would make the curve a little more flat...

> Cheers,
> Christian
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: dev-help@tapestry.apache.org

http://www.bodylabgym.com - a private, by appointment only, one-on-one
health and fitness facility.
http://www.ectransition.com - Quality Electronic Cigarettes at a
reasonable price!
TheDailyTube.com. Sign up and get the best new videos on the internet
delivered fresh to your inbox.

To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
For additional commands, e-mail: dev-help@tapestry.apache.org

View raw message