You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Jochen Frey <jo...@jochenfrey.com> on 2012/01/31 06:50:49 UTC

URL Rewriting

Hi!

I am looking for a clean way to generically rewrite URLs as follows:

Publicly we want to have an account name to be the first part of the path in URLs like so:  /SomeAccount/settings/page1.  Since (I believe) that in Tapestry I can't bind the first part of the path to a variable,  I would like to rewrite it to something like this: /settings/page1?account=SomeAccount

I would want it to be a generic rewrite along the lines of "if the path doesn't start with /login then rewrite the url".  The effect would be that what was a path element becomes a variable (whether query variable or context I don't really know or care).

I have seen Igor's blog post (http://blog.tapestry5.de/index.php/2010/09/06/new-url-rewriting-api/).  I have two conceptual hurdles that I can't overcome and would love some help with:

After doing the path manipulation (by way of String manipulation), I need to find the Page class by way of a String that looks like "/settings/page1".
How do I pass newly created variable (account) into the PageRenderRequestParameters (I guess if knew the Java class from step 1, I could check if it implements an interface and if so, typecast it and ask the receiving page to generate a link ... but that wouldn't help much either.

It's pretty clear to me how I'd have done it in TS 5.1 (http://tapestry.apache.org/url-rewriting.html), but URLRewriterRule is not supported any more.

Alternatively I could roll my own RequestFilter (like the TimingFilter), but it seems there'd have to be a better way?

Any suggestions?

Thanks!
Jochen
---
  jochen@jochenfrey.com
  +1.415.366.0450
  @jochen_frey


Re: URL Rewriting

Posted by Jochen Frey <jo...@jochenfrey.com>.
OK - so I resolved conceptual problem #1:

	String pageName = componentClassResolver.canonicalizePageName(newPath);

	where "newPath" is the manipulated pass (after removing the "SomeAccount").


Remains problem #2:  How do I generically pass a parameter in a page URL (that the page may or may not care about)?

Any hints?

Thanks so much!
Jochen


On Jan 30, 2012, at 9:50 PM, Jochen Frey wrote:

> Hi!
> 
> I am looking for a clean way to generically rewrite URLs as follows:
> 
> Publicly we want to have an account name to be the first part of the path in URLs like so:  /SomeAccount/settings/page1.  Since (I believe) that in Tapestry I can't bind the first part of the path to a variable,  I would like to rewrite it to something like this: /settings/page1?account=SomeAccount
> 
> I would want it to be a generic rewrite along the lines of "if the path doesn't start with /login then rewrite the url".  The effect would be that what was a path element becomes a variable (whether query variable or context I don't really know or care).
> 
> I have seen Igor's blog post (http://blog.tapestry5.de/index.php/2010/09/06/new-url-rewriting-api/).  I have two conceptual hurdles that I can't overcome and would love some help with:
> 
> After doing the path manipulation (by way of String manipulation), I need to find the Page class by way of a String that looks like "/settings/page1".
> How do I pass newly created variable (account) into the PageRenderRequestParameters (I guess if knew the Java class from step 1, I could check if it implements an interface and if so, typecast it and ask the receiving page to generate a link ... but that wouldn't help much either.
> 
> It's pretty clear to me how I'd have done it in TS 5.1 (http://tapestry.apache.org/url-rewriting.html), but URLRewriterRule is not supported any more.
> 
> Alternatively I could roll my own RequestFilter (like the TimingFilter), but it seems there'd have to be a better way?
> 
> Any suggestions?
> 
> Thanks!
> Jochen
> ---
>   jochen@jochenfrey.com
>   +1.415.366.0450
>   @jochen_frey
> 

---
  jochen@jochenfrey.com
  +1.415.366.0450
  @jochen_frey


Re: URL Rewriting

Posted by Jochen Frey <jo...@jochenfrey.com>.
Thanks Thiago!

On Jan 31, 2012, at 10:52 AM, Thiago H. de Paula Figueiredo wrote:

> On Tue, 31 Jan 2012 15:53:29 -0200, Jochen Frey <jo...@jochenfrey.com> wrote:
> 
>> Excellent!
>> 
>> But what let's say there's a 2nd link transformer, what happens to the PageRenderRequestParameters that the two transformers return?  Would the second one just inject an EventContext
> 
> The PageRenderRequestParameters returned by the first will be passed to the next. I haven't looked at the code, but that's what I expect it to do. That's what the old URL rewriter code did: the Request returned by one rule was passed to the next rule until all rules were executed.
> 
> -- 
> Thiago H. de Paula Figueiredo
> Independent Java, Apache Tapestry 5 and Hibernate consultant, developer, and instructor
> Owner, Ars Machina Tecnologia da Informação Ltda.
> http://www.arsmachina.com.br

---
  jochen@jochenfrey.com
  +1.415.366.0450
  @jochen_frey


Re: URL Rewriting

Posted by Jochen Frey <jo...@jochenfrey.com>.
So I dug through the source code, and the custom link transformation is spliced in by way of an interceptor pattern (in TapestryModule):

    @Match("ComponentEventLinkEncoder")
    public ComponentEventLinkEncoder decorateLinkTransformer(LinkTransformer linkTransformer,
                                                             ComponentEventLinkEncoder delegate)
    {
        return new LinkTransformerInterceptor(linkTransformer, delegate);
    }

Where the linkTransformer splices in a Chain of Command that can be configured as per Igor's blog post.

The problem I am wrestling with is that when I implement a LinkTransformer myself in which I only want to rewrite the basepath and leave activation contexts etc alone, I still have to replicate all functionality that the original ComponentEventLinkEncoderImpl has (I could copy the source code, but that seems unclean at best).

Alternatively (and that's what I am trying to figure out how to do), I could do something like this in my own LinkTransformer:


    public PageRenderRequestParameters decodePageRenderRequest(Request request)
	{
		PageRenderRequestParameters original = originalComponentEventLinkEncoder.decodePageRenderRequest(request);
		
		// build my own based on the original one ...


So how do I get the "original" ComponentEventLinkEncoderImpl?  When I @Inject or @InjectService, I get the interceptor (see all the way on top of this mail), which results in an endless loop (my code keeps calling the interceptor, which in turn calls my code).  It seems like the only way of doing this is actually doing a:

	ComponentEventLinkEncoder myPrivateEncoder = new ComponentEventLinkEncoderImpl( .... )

... which seems to be unclean ... or is that the way to do it?

Thanks!
Jochen


On Jan 31, 2012, at 10:52 AM, Thiago H. de Paula Figueiredo wrote:

> On Tue, 31 Jan 2012 15:53:29 -0200, Jochen Frey <jo...@jochenfrey.com> wrote:
> 
>> Excellent!
>> 
>> But what let's say there's a 2nd link transformer, what happens to the PageRenderRequestParameters that the two transformers return?  Would the second one just inject an EventContext
> 
> The PageRenderRequestParameters returned by the first will be passed to the next. I haven't looked at the code, but that's what I expect it to do. That's what the old URL rewriter code did: the Request returned by one rule was passed to the next rule until all rules were executed.
> 
> -- 
> Thiago H. de Paula Figueiredo
> Independent Java, Apache Tapestry 5 and Hibernate consultant, developer, and instructor
> Owner, Ars Machina Tecnologia da Informação Ltda.
> http://www.arsmachina.com.br

---
  jochen@jochenfrey.com
  +1.415.366.0450
  @jochen_frey


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


Re: URL Rewriting

Posted by "Thiago H. de Paula Figueiredo" <th...@gmail.com>.
On Tue, 31 Jan 2012 15:53:29 -0200, Jochen Frey <jo...@jochenfrey.com>  
wrote:

> Excellent!
>
> But what let's say there's a 2nd link transformer, what happens to the  
> PageRenderRequestParameters that the two transformers return?  Would the  
> second one just inject an EventContext

The PageRenderRequestParameters returned by the first will be passed to  
the next. I haven't looked at the code, but that's what I expect it to do.  
That's what the old URL rewriter code did: the Request returned by one  
rule was passed to the next rule until all rules were executed.

-- 
Thiago H. de Paula Figueiredo
Independent Java, Apache Tapestry 5 and Hibernate consultant, developer,  
and instructor
Owner, Ars Machina Tecnologia da Informação Ltda.
http://www.arsmachina.com.br

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


Re: URL Rewriting

Posted by Jochen Frey <jo...@jochenfrey.com>.
Excellent!

But what let's say there's a 2nd link transformer, what happens to the PageRenderRequestParameters that the two transformers return?  Would the second one just inject an EventContext

@Inject
private EventContext eventContext;

and use it to generate the new EventContext? As well, would the 2nd transformer get an adjusted path in the Request ... (or how else would I do additional path munging?)

    public PageRenderRequestParameters decodePageRenderRequest(Request request)
    {


Thanks!
Jochen


On Jan 31, 2012, at 9:42 AM, Thiago H. de Paula Figueiredo wrote:

> On Tue, 31 Jan 2012 15:35:13 -0200, Jochen Frey <jo...@jochenfrey.com> wrote:
> 
> 
>> Let's say there's a page /SomeAccount/profile/SomeOtherVar, where "SomeOtherVar" is supposed to go into the activation context as well ... how would I handle that?  Do I have the shot of augmenting the activation context somewhere on a per-page basis, or do I need to handle all possible Activate Context variations in the LinkTransformer?  In other words, is there some chain where more processing of the URL is done?
> 
> Don't forget that you can have more than one LinkTransformer. They're chained, so you need to ensure they're contributed in the right order.
> 
> -- 
> Thiago H. de Paula Figueiredo
> Independent Java, Apache Tapestry 5 and Hibernate consultant, developer, and instructor
> Owner, Ars Machina Tecnologia da Informação Ltda.
> http://www.arsmachina.com.br

---
  jochen@jochenfrey.com
  +1.415.366.0450
  @jochen_frey


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


Re: URL Rewriting

Posted by "Thiago H. de Paula Figueiredo" <th...@gmail.com>.
On Tue, 31 Jan 2012 15:35:13 -0200, Jochen Frey <jo...@jochenfrey.com>  
wrote:


> Let's say there's a page /SomeAccount/profile/SomeOtherVar, where  
> "SomeOtherVar" is supposed to go into the activation context as well ...  
> how would I handle that?  Do I have the shot of augmenting the  
> activation context somewhere on a per-page basis, or do I need to handle  
> all possible Activate Context variations in the LinkTransformer?  In  
> other words, is there some chain where more processing of the URL is  
> done?

Don't forget that you can have more than one LinkTransformer. They're  
chained, so you need to ensure they're contributed in the right order.

-- 
Thiago H. de Paula Figueiredo
Independent Java, Apache Tapestry 5 and Hibernate consultant, developer,  
and instructor
Owner, Ars Machina Tecnologia da Informação Ltda.
http://www.arsmachina.com.br

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


Re: URL Rewriting

Posted by Jochen Frey <jo...@jochenfrey.com>.
On Jan 31, 2012, at 2:39 AM, Thiago H. de Paula Figueiredo wrote:

> On Tue, 31 Jan 2012 03:50:49 -0200, Jochen Frey <jo...@jochenfrey.com> wrote:
> 
>> Hi!
> 
> Hi!
> 
>> I am looking for a clean way to generically rewrite URLs as follows:
>> 
>> Publicly we want to have an account name to be the first part of the path in URLs like so:  /SomeAccount/settings/page1.  Since (I believe) that in Tapestry I can't bind the first part of the path to a variable,  I would like to rewrite it to something like this: /settings/page1?account=SomeAccount
> 
> Why not as the first page activation context value?

Activation context sounds fine.  However, I will want to have flexibility to add other Activation Contexts values for some of the pages (and not for others).  Currently the code in LinkTransformer does something like this (based on :

    public PageRenderRequestParameters decodePageRenderRequest(Request request)
    {

        String path = request.getPath();
	// do some path munging here
	String newPath = someMagic(path);
        String pageName = componentClassResolver.canonicalizePageName(newPath);
        
        PageRenderRequestParameters ret = new PageRenderRequestParameters(
                pageName, new EmptyEventContext(), false
        );
        return ret;
    }

Let's say there's a page /SomeAccount/profile/SomeOtherVar, where "SomeOtherVar" is supposed to go into the activation context as well ... how would I handle that?  Do I have the shot of augmenting the activation context somewhere on a per-page basis, or do I need to handle all possible Activate Context variations in the LinkTransformer?  In other words, is there some chain where more processing of the URL is done?

Thanks so much!
Jochen

---
  jochen@jochenfrey.com
  +1.415.366.0450
  @jochen_frey


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


Re: URL Rewriting

Posted by "Thiago H. de Paula Figueiredo" <th...@gmail.com>.
On Tue, 31 Jan 2012 03:50:49 -0200, Jochen Frey <jo...@jochenfrey.com>  
wrote:

> Hi!

Hi!

> I am looking for a clean way to generically rewrite URLs as follows:
>
> Publicly we want to have an account name to be the first part of the  
> path in URLs like so:  /SomeAccount/settings/page1.  Since (I believe)  
> that in Tapestry I can't bind the first part of the path to a variable,   
> I would like to rewrite it to something like this:  
> /settings/page1?account=SomeAccount

Why not as the first page activation context value?

> How do I pass newly created variable (account) into the  
> PageRenderRequestParameters (I guess if knew the Java class from step 1,  
> I could check if it implements an interface and if so, typecast it and  
> ask the receiving page to generate a link ... but that wouldn't help  
> much either.

What do you mean by variable?

> It's pretty clear to me how I'd have done it in TS 5.1  
> (http://tapestry.apache.org/url-rewriting.html), but URLRewriterRule is  
> not supported any more.
> Alternatively I could roll my own RequestFilter (like the TimingFilter),  
> but it seems there'd have to be a better way?

If you don't want to user LinkTransformer, I'd just copy the URL rewriting  
support from Tapestry 5.1 sources. It's basically a RequestFilter and some  
helper classes. Not much code and it uses nothing that would cause  
problems in 5.3.

-- 
Thiago H. de Paula Figueiredo
Independent Java, Apache Tapestry 5 and Hibernate consultant, developer,  
and instructor
Owner, Ars Machina Tecnologia da Informação Ltda.
http://www.arsmachina.com.br

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