Then in your XSLT you can create a template which will build your url up. If you put this in a XSLT include you can use it through out your site with easy and keep your design all DRY.
Then in your render-car.aspx template you can do something like:
Many thanks for your reply, however I won't be able to use virtualUrl="^~/.*-cars/.*/(.*).aspx" as there is no guarantee in this case that -cars will be in the URL.
I'm guessing without something consistent in the URL (which there will not be in my case) then rewriting is not going to work?
hmm, maybe the solution is to just to call the missing page (website.com/german-cars/audi/audi-rs4) and trap the error and try to render it from there?
But its exactly what it is designed for. I think the part you are missing is maybe the building up of the urls. Let me give you a sample and maybe that might give you some ideas.
If you had something like this to build up your urls instead of using umbraco.library:NiceUrl the UrlRewritting would be perfect:
<!-- Pass in each segment of a url to have it tidied up -->
<xsl:template name="Helpers.toSEOFriendly">
<xsl:param name="input" select="''" />
<xsl:variable name="dodgyChars" select="' ,.#_-'" />
<xsl:variable name="replacementChar" select="'-----'" />
<xsl:variable name="lowercased"><xsl:call-template name="Helpers.toLowerCase"><xsl:with-param name="input" select="$input" /></xsl:call-template></xsl:variable>
<xsl:variable name="escaped"><xsl:value-of select="translate( $lowercased, $dodgyChars, $replacementChar )" /></xsl:variable>
<xsl:variable name="cleaned"><xsl:value-of select="umbraco.library:Replace( $escaped, '--', '-' )" /></xsl:variable>
<xsl:value-of select="umbraco.library:UrlEncode($cleaned)" />
</xsl:template>
<xsl:template match="Car" mode="linkTo">
<!-- we want to build up a link link /cars/country_of_origin/make/model.aspx -->
<xsl:text>/cars/</xsl:text>
<!-- country_of_origin (ish) -->
<xsl:call-template>
<xsl:with-param name="input" select="../../@nodeName" />
</xsl:call-template>
<xsl:text>/</xsl:text>
<!-- make -->
<xsl:call-template>
<xsl:with-param name="input" select="../@nodeName" />
</xsl:call-template>
<xsl:text>/</xsl:text>
<!-- model -->
<xsl:call-template>
<xsl:with-param name="input" select="@nodeName" />
</xsl:call-template>
<xsl:text>.aspx</xsl:text>
</xsl:template>
Then from ANY car doc type (I've assumed here that you are using the new 4.5 XML format and that your car doctype will be rendered as "Car" in the XML) assuming its under the nodes as shown in the screen shot should work like this:
<xsl:template match="/">
Why not read more about the
<a>
<xsl:attribute name="href">
<!-- Assuming here that we are on a Car page? -->
<xsl:apply-templates select="$currentPage" more="linkTo" />
</xsl:attrbute>
<xsl:value-of select="@nodeName" />
</a>.
</xsl:template>
Now if you are not sure where your car might be in the tree, ie a car "could" appear anywhere or in multiple places then surely there should be one place in the tree where you can define each individual car which could then allow users to "select" a car if they need to add one below a garage (I'm guessing here so forgive me). That way you "could" enforce the nesting of the parents to give you the urls you want using the above. If you really don't know where they are then you "could" cheat and change the url a little: "something/whatever/another/makes/audi-r3" and have your UrlRewriter look for "/.*/.*/.*/make/(.*).aspx for instance?
Really appreciate your reply, right now there is no way for me to work out which nodes should be rewritten, there are no guarantees about node names as the client creates these.
I used cars as an example to illustrate a point, however in reality we are building a system where the client use it for any purpose, not just cars, so this makes it hard to have a unique piece of text in the URL.
All we know is the doc types which we need to rewrite.
So to make sure I understand, unless there is something unique about the URL (name, character or even number of paths) there is no way to work out which nodes to rewrite?
then just look for .*/(\d*)/.*\.aspx (or there abouts) in your url and you can rewrite anything as node id'd are unique.
Side note: Ideally you should have 1 url to get to each page, this way will give you lots of possibles so ideally you should check on each redirected page if the "1 true url" for that page was used to get there or not. If not then do a 301 redirect to the "1 true url" so you SEO does not suffer.
It's late and my brain is not in gear so forgive me, I'm a bit lost.
I thought the reason I would need something unique in my url was so that I could add a rule to the virtualUrl parameter? If I'm using the node ID then I can't see how this is going to help as I'm not going to know the node id either.
Maybe I need to get some sleep and read this again in the morning, have I completely misunderstood your point?
I thought that the following link would get rendered to the page (using your xslt) 'http://website.com/german-cars/audi/audi-rs4' and the url rewrite rule return the destinationUrl="~/render-car.aspx?name=$1" which I could use to render the correct info?
Maybe or I've said it all wrong. I'm shattered too so certainly a possibility. Ping me a tweet in the morning if your head clears and we can have another go. Sorry I didn't make your weekend ;)
Custom URL rewriting help please
Hi,
Here's a mock set up, usually I would add the cars under their make, so the URL would be
website.com/german-cars/audi/audi-rs4
However in this case the cars must be under a owner node (for reasons I won't go into) so I pick them via MNTP.
But this will give a car a URL of
website.com/cars/MOT-station/audi-rs4
and I would like to retain
website.com/german-cars/audi/audi-rs4
How can I keep this structure and also keep the URL?
Rich
Should say I need to make the solution automatic, so manually entering the url into UmbracoURLAlias won't do on this occasion.
Cheers
Rich
Edit your UrlRedirect.config file like so:
<add name="carDetails"
virtualUrl="^~/.*-cars/.*/(.*).aspx"
rewriteUrlParameter="ExcludeFromClientQueryString"
destinationUrl="~/render-car.aspx?name=$1"
ignoreCase="true"
/>
Then in your XSLT you can create a template which will build your url up. If you put this in a XSLT include you can use it through out your site with easy and keep your design all DRY.
Then in your render-car.aspx template you can do something like:
Something like that?
Hi Peter,
Many thanks for your reply, however I won't be able to use virtualUrl="^~/.*-cars/.*/(.*).aspx" as there is no guarantee in this case that -cars will be in the URL.
I'm guessing without something consistent in the URL (which there will not be in my case) then rewriting is not going to work?
hmm, maybe the solution is to just to call the missing page (website.com/german-cars/audi/audi-rs4) and trap the error and try to render it from there?
Rich
Can't you stick a /cars/ in the url somewhere? Would make it much easier:
/cars/german/audi/audi-r3
Without going into too much detail, I won't know that this (cars) will be as the user can edit or create it.
This is for a generic (and rather complicated) site.
It seems that URL rewriting is not going to be able to help in this case.
Rich
But its exactly what it is designed for. I think the part you are missing is maybe the building up of the urls. Let me give you a sample and maybe that might give you some ideas.
If you had something like this to build up your urls instead of using umbraco.library:NiceUrl the UrlRewritting would be perfect:
Then from ANY car doc type (I've assumed here that you are using the new 4.5 XML format and that your car doctype will be rendered as "Car" in the XML) assuming its under the nodes as shown in the screen shot should work like this:
Now if you are not sure where your car might be in the tree, ie a car "could" appear anywhere or in multiple places then surely there should be one place in the tree where you can define each individual car which could then allow users to "select" a car if they need to add one below a garage (I'm guessing here so forgive me). That way you "could" enforce the nesting of the parents to give you the urls you want using the above. If you really don't know where they are then you "could" cheat and change the url a little: "something/whatever/another/makes/audi-r3" and have your UrlRewriter look for "/.*/.*/.*/make/(.*).aspx for instance?
Hi Peter,
Really appreciate your reply, right now there is no way for me to work out which nodes should be rewritten, there are no guarantees about node names as the client creates these.
I used cars as an example to illustrate a point, however in reality we are building a system where the client use it for any purpose, not just cars, so this makes it hard to have a unique piece of text in the URL.
All we know is the doc types which we need to rewrite.
So to make sure I understand, unless there is something unique about the URL (name, character or even number of paths) there is no way to work out which nodes to rewrite?
Rich
Well to make it easy you could just write out the node id into the url and just look for that?
/something/anything/not/interested/what/1234/some/more/stuff.aspx
then just look for .*/(\d*)/.*\.aspx (or there abouts) in your url and you can rewrite anything as node id'd are unique.
Side note: Ideally you should have 1 url to get to each page, this way will give you lots of possibles so ideally you should check on each redirected page if the "1 true url" for that page was used to get there or not. If not then do a 301 redirect to the "1 true url" so you SEO does not suffer.
Peter,
It's late and my brain is not in gear so forgive me, I'm a bit lost.
I thought the reason I would need something unique in my url was so that I could add a rule to the virtualUrl parameter? If I'm using the node ID then I can't see how this is going to help as I'm not going to know the node id either.
Maybe I need to get some sleep and read this again in the morning, have I completely misunderstood your point?
I thought that the following link would get rendered to the page (using your xslt) 'http://website.com/german-cars/audi/audi-rs4' and the url rewrite rule return the destinationUrl="~/render-car.aspx?name=$1" which I could use to render the correct info?
Rich
Maybe or I've said it all wrong. I'm shattered too so certainly a possibility. Ping me a tweet in the morning if your head clears and we can have another go. Sorry I didn't make your weekend ;)
Pete
No worries, really appreciate you giving it a go!
I've learnt a thing or two from this post, just wish this project was more straight forward...
cheers, Rich
is working on a reply...