# Relative Linking in Radiant

**URL:** <https://www.ruby-forum.com/t/relative-linking-in-radiant/106585>\
**Category:** Radiant CMS\
**Created:** [June 12, 2007, 7:30am UTC](https://www.ruby-forum.com/t/relative-linking-in-radiant/106585 "2007-06-12T07:30:03Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![mahadewa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/9e8a1a/32.png) [@mahadewa](https://www.ruby-forum.com/u/mahadewa)\
**Post date:** [June 12, 2007, 7:30am UTC](https://www.ruby-forum.com/t/relative-linking-in-radiant/106585/1 "2007-06-12T07:30:03Z")

</div>

My apologies if this has already been discussed…

I’m converting a website which uses relative links into Radiant.  
Relative links are a bit screwy in Radiant because Radiant has done away  
with folders.

I like this convention – that pages can have children – but browsers  
still think in terms of folders. The issue is the trailing slash.

In the following example:  
root  
|- A  
| |- C  
| |- D  
|- B

In Radiant, I can render page A in my browser with either:

- [http://root/a](http://root/a)
- [http://root/a/](http://root/a/)

This makes perfect sense since page A is both a child of root/ and the  
parent of other pages.

However, if in page A I have a relative link: , the target  
page depends on the address used. In the first case, I will be directed  
to [http://root/b](http://root/b) because the browser thinks I’m in the root/ folder. In  
the second case, I’m sent to [http://root/a/b](http://root/a/b) because it thinks I’m in  
the root/a/ folder.

Has anyone else run into this? If so, how are you solving it? Is there  
a best practice here or some Radiant tag, or is everyone just using  
absolute URLs?

---

<div class="post-metadata">

**Author:** ![mahadewa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/9e8a1a/32.png) [@mahadewa](https://www.ruby-forum.com/u/mahadewa)\
**Post date:** [June 12, 2007, 11:15am UTC](https://www.ruby-forum.com/t/relative-linking-in-radiant/106585/2 "2007-06-12T11:15:19Z")

</div>

I am not really sure what your problem is here. Parents act like  
folders as far as the browser is concerned, so nothing has really  
changed. Ithink your only problem is the leading slash, which will  
tell the browser to look at the root. So in your example, instead of  
writing , you need to write [.](https://www.ruby-forum.com/b)

[ 

So basically, you need to put the slash not behind “a”, but in front  
of “b”. This isn’t anything that has to do with Radiant specifically,  
but is typical of most content management systems. I know Textpattern  
works similarly.

 

Is this what you are asking?

 ](https://www.ruby-forum.com/b)

[Keith B.  
Tel: +49-7731-79838380  
removed\_email\_address@domain.invalid  
 ](https://www.ruby-forum.com/b)[http://keithbingman.com](http://keithbingman.com)

---

<div class="post-metadata">

**Author:** ![mahadewa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/9e8a1a/32.png) [@mahadewa](https://www.ruby-forum.com/u/mahadewa)\
**Post date:** [June 12, 2007, 11:31am UTC](https://www.ruby-forum.com/t/relative-linking-in-radiant/106585/3 "2007-06-12T11:31:24Z")

</div>

On 6/12/07, Chris P. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> However, if in page A I have a relative link: , the target  
> page depends on the address used. In the first case, I will be directed  
> to [http://root/b](http://root/b) because the browser thinks I’m in the root/ folder. In  
> the second case, I’m sent to [http://root/a/b](http://root/a/b) because it thinks I’m in  
> the root/a/ folder.

This is normal behavior and not something you can “fix”.

Simply normalize your URLs - choose a convention for trailing slashes  
and  
stick to it.

---

<div class="post-metadata">

**Author:** ![mahadewa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/9e8a1a/32.png) [@mahadewa](https://www.ruby-forum.com/u/mahadewa)\
**Post date:** [June 12, 2007, 4:10pm UTC](https://www.ruby-forum.com/t/relative-linking-in-radiant/106585/4 "2007-06-12T16:10:36Z")

</div>

When I worked on kckcc.edu, we had a pretty deep structure in some  
places. If I wanted quasi-relative URLs I took to using \<r:url/\> or  
\<r:parent:url/\> where necessary to cut down the typing errors.

Sean

---

<div class="post-metadata">

**Author:** ![mahadewa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/9e8a1a/32.png) [@mahadewa](https://www.ruby-forum.com/u/mahadewa)\
**Post date:** [June 12, 2007, 3:45pm UTC](https://www.ruby-forum.com/t/relative-linking-in-radiant/106585/5 "2007-06-12T15:45:19Z")

</div>

Keith B. wrote:

> I am not really sure what your problem is here. Parents act like  
> folders as far as the browser is concerned, so nothing has really  
> changed. Ithink your only problem is the leading slash, which will  
> tell the browser to look at the root. So in your example, instead of  
> writing , you need to write [.](https://www.ruby-forum.com/b)
> 
> [](https://www.ruby-forum.com/b)

[ 

Starting with a leading slash makes the URL absolute rather than  
relative (not relative to the current page, anyway). I am beginning to  
think that this is the only real solution.

 

If you have a hierarchy where the pages can get quite deep, this can be  
a bit of a challenge to remember and type every time, though.

](https://www.ruby-forum.com/b)

---

<div class="post-metadata">

**Author:** ![mahadewa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/9e8a1a/32.png) [@mahadewa](https://www.ruby-forum.com/u/mahadewa)\
**Post date:** [June 12, 2007, 4:03pm UTC](https://www.ruby-forum.com/t/relative-linking-in-radiant/106585/6 "2007-06-12T16:03:47Z")

</div>

Mislav Marohniï¿½? wrote:

> On 6/12/07, Chris P. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > However, if in page A I have a relative link: , the target  
> > page depends on the address used. In the first case, I will be directed  
> > to [http://root/b](http://root/b) because the browser thinks I’m in the root/ folder. In  
> > the second case, I’m sent to [http://root/a/b](http://root/a/b) because it thinks I’m in  
> > the root/a/ folder.
> 
> This is normal behavior and not something you can “fix”.
> 
> Simply normalize your URLs - choose a convention for trailing slashes  
> and  
> stick to it.

The problem with this approach is two-fold:  
1.) People make mistakes and if my convention is to always link to page  
A as ‘root/a/’ and some time down the road, a writer mistakenly links to  
that page as ‘root/a’ their link will still appear to work. It wouldn’t  
be apparent to them, however, that they just broke all the relative  
links inside page A. In a traditional website, this could never happen  
– the writer would have immediate feedback that their link to page A is  
wrong.

2.) Even if I could foolproof (enforce) #1, I would still have cases  
where the user may manually type the URL (either marketing materials  
tell them to go to: ‘[www.website.com/path](http://www.website.com/path)’ or someone guides them via  
phone). Again, no matter which way they type it,everything will appear  
to work to them… until they follow links. And then they just think my  
site is broken.

The only way I think that this premise could work is if you could tell  
Radiant to enforce a trailing slash on all pages (or no trailing slash  
on all pages). That way if the user typed (or a link sent them to)  
‘[www.website.com/root/a](http://www.website.com/root/a)’ Radiant would automatically redirect to  
‘[www.website.com/root/a/](http://www.website.com/root/a/)’

Then a writer could be sure that their pages would work as intended no  
matter how the user got there.

I’m not sure everyone would want this convention or would agree to which  
way it should work (always or never a slash). Perhaps it could be  
configurable. Thoughts anyone?

---

<div class="post-metadata">

**Author:** ![mahadewa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/9e8a1a/32.png) [@mahadewa](https://www.ruby-forum.com/u/mahadewa)\
**Post date:** [June 12, 2007, 5:02pm UTC](https://www.ruby-forum.com/t/relative-linking-in-radiant/106585/7 "2007-06-12T17:02:08Z")

</div>

Chris P. wrote:

> The only way I think that this premise could work is if you could  
> tell  
> configurable. Thoughts anyone?  
> I agree and support the idea of generally redirecting URLs without a  
> trailing slash to URLs with trailing slash. I know it is easily done  
> with every Web server in front of Radiant, but I think this should be  
> part of Radiant. My only concern about generally enforcing this is that  
> other document types (images, PDFs, etc.) end up with a trailing slash  
> as well. Some context-based redirect would solve that, by asking the  
> addressed page/object to redirect to its canonical URL.

Cheers,  
Oliver

---

<div class="post-metadata">

**Author:** ![mahadewa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/9e8a1a/32.png) [@mahadewa](https://www.ruby-forum.com/u/mahadewa)\
**Post date:** [June 12, 2007, 5:05pm UTC](https://www.ruby-forum.com/t/relative-linking-in-radiant/106585/8 "2007-06-12T17:05:13Z")

</div>

Sean C. wrote:

> When I worked on kckcc.edu, we had a pretty deep structure in some  
> places. If I wanted quasi-relative URLs I took to using \<r:url/\> or  
> \<r:parent:url/\> where necessary to cut down the typing errors.
> 
> Sean

So all your URLs wound up as absolute (href="/path/to/the/new/page") but  
you only had to input them in a relative-ish fashion  
(href="\<r:url\>/new/page"). Interesting.

It’s beginning to look like true relative links are unworkable (or  
untrustworthy).

---

<div class="post-metadata">

**Author:** ![mahadewa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/9e8a1a/32.png) [@mahadewa](https://www.ruby-forum.com/u/mahadewa)\
**Post date:** [June 12, 2007, 5:12pm UTC](https://www.ruby-forum.com/t/relative-linking-in-radiant/106585/9 "2007-06-12T17:12:11Z")

</div>

They’re not unworkable, you just have to be very careful about how you  
use them. In general, I found that you had to prepend the current level  
of nesting in order to get children of the current page; i.e. if I’m in  
a page with the “links” slug, I would do href=“links/rails” to get the  
“rails” child page. So I guess if you’re not using virtual pages, you  
might be able to get away with \<r:slug/\>. YMMV. I just did \<r:url/\>  
because I was lazy and didn’t want to figure out which way it would go.

Sean

---

<div class="post-metadata">

**Author:** ![mahadewa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/9e8a1a/32.png) [@mahadewa](https://www.ruby-forum.com/u/mahadewa)\
**Post date:** [June 12, 2007, 6:32pm UTC](https://www.ruby-forum.com/t/relative-linking-in-radiant/106585/10 "2007-06-12T18:32:33Z")

</div>

Mislav MarohniÄ‡ wrote:

> On 6/12/07, Oliver B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > I agree and support the idea of generally redirecting URLs without a  
> > trailing slash to URLs with trailing slash. I know it is easily done  
> > with every Web server in front of Radiant, but I think this should be  
> > part of Radiant.
> 
> I don’t. It’s much better to do on the server (speed-wise). Radiant doesn’t  
> need such options.

Speed-wise it is better on the server, but the server does not know  
anything about the context. It clearly is the job of the application,  
otherwise it would be like having Squid decide whether Apache redirects  
to canonical URLs for directories or not.

Also, you can still do it on the server if you want to, even if Radiant  
has that option.

Oliver

---

<div class="post-metadata">

**Author:** ![mahadewa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/9e8a1a/32.png) [@mahadewa](https://www.ruby-forum.com/u/mahadewa)\
**Post date:** [June 12, 2007, 5:20pm UTC](https://www.ruby-forum.com/t/relative-linking-in-radiant/106585/11 "2007-06-12T17:20:12Z")

</div>

On 6/12/07, Oliver B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> I agree and support the idea of generally redirecting URLs without a  
> trailing slash to URLs with trailing slash. I know it is easily done  
> with every Web server in front of Radiant, but I think this should be  
> part of Radiant.

I don’t. It’s much better to do on the server (speed-wise). Radiant  
doesn’t  
need such options.

---

<div class="post-metadata">

**Author:** ![mahadewa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/9e8a1a/32.png) [@mahadewa](https://www.ruby-forum.com/u/mahadewa)\
**Post date:** [June 12, 2007, 8:37pm UTC](https://www.ruby-forum.com/t/relative-linking-in-radiant/106585/12 "2007-06-12T20:37:05Z")

</div>

Sean C. wrote:

> They’re not unworkable, you just have to be very careful about how  
> you use them.

> I’m in a page with the “links” slug, I would do href=“links/rails”  
> to get the “rails” child page.

Actually, the example above, it only works if your browser is pointed  
to: ‘[example.com/links](http://example.com/links)’ (i.e. the browser ‘thinks’ its opening the links  
file in the root directory).

If, instead, your browser is pointed to: ‘[example.com/links/](http://example.com/links/)’ (i.e. the  
browser ‘thinks’ its opening the default file in the links directory),  
the link sends the browser looking for ‘[example.com/links/links/rails](http://example.com/links/links/rails)’

My point about ‘unworkable’ is that, there is no way to guarantee that  
user’s browser is always at the address with (or without) trailing  
slash. And so, if your href’s don’t give the full address from the  
root, your links may not work.

The problem is that Radiant gives feedback that the user’s at the  
“right” page even when, in fact, they may have the slash wrong for the  
relative links to work.

As for the ability to limit this issue by forcing a trailing slash on  
every page (or preventing it everywhere), I never considered using the  
server. I like that.

I also agree with Oliver that it fits well in Radiant (I would certainly  
configure it within Radiant if given that option). But it’s also not  
something you’d change regularly, so I could make do with Apache.

---

<div class="post-metadata">

**Author:** ![mahadewa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/9e8a1a/32.png) [@mahadewa](https://www.ruby-forum.com/u/mahadewa)\
**Post date:** [June 13, 2007, 12:11am UTC](https://www.ruby-forum.com/t/relative-linking-in-radiant/106585/13 "2007-06-13T00:11:43Z")

</div>

Oliver B. wrote:

> I agree and support the idea of generally redirecting URLs without a  
> trailing slash to URLs with trailing slash. I know it is easily done  
> with every Web server in front of Radiant, but I think this should be  
> part of Radiant. My only concern about generally enforcing this is that  
> other document types (images, PDFs, etc.) end up with a trailing slash  
> as well. Some context-based redirect would solve that, by asking the  
> addressed page/object to redirect to its canonical URL.

I would accept a patch that implements this in the following fashion:

- URLs without file extensions automatically get redirected to URLs with  
trailing slashes
- URLs with extensions (like .css or .xml) are left alone
- There is a configuration variable that turns this behavior on or off

Don’t forget unit tests.

–  
John

---

<div class="post-metadata">

**Author:** ![mahadewa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/9e8a1a/32.png) [@mahadewa](https://www.ruby-forum.com/u/mahadewa)\
**Post date:** [June 12, 2007, 10:15pm UTC](https://www.ruby-forum.com/t/relative-linking-in-radiant/106585/14 "2007-06-12T22:15:26Z")

</div>

> My point about ‘unworkable’ is that, there is no way to guarantee that  
> user’s browser is always at the address with (or without) trailing  
> slash. And so, if your href’s don’t give the full address from the  
> root, your links may not work.
> 
> The problem is that Radiant gives feedback that the user’s at the  
> “right” page even when, in fact, they may have the slash wrong for the  
> relative links to work.

Right – which is why I went with the \<r:url/\> route in the first  
place. It’s a pain to try to control the existence or absence of that  
slash.

Sean

---

<div class="post-metadata">

**Author:** ![mahadewa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/9e8a1a/32.png) [@mahadewa](https://www.ruby-forum.com/u/mahadewa)\
**Post date:** [June 13, 2007, 4:52am UTC](https://www.ruby-forum.com/t/relative-linking-in-radiant/106585/15 "2007-06-13T04:52:08Z")

</div>

On 12/06/07 07:10 PM, John W. Long was heard to say:

> - URLs without file extensions automatically get redirected to URLs with  
> trailing slashes
> - URLs with extensions (like .css or .xml) are left alone
> - There is a configuration variable that turns this behavior on or off

Hi John,

thanks for your input. I do not think that the file extension is in  
the general case a good indication for whether a URL should have a  
trailing slash or not [1]. The canonical URL of a resource should be  
determined by its corresponding model. ATM, everything in Radiant is a  
page whether it is HTML or CSS. I would suggest the site controller  
uses Page#url to determine the canonical URL of a page and redirects  
accordingly. Page#url or any derived form of it is then responsible of  
deciding if a trailing slash should be added. If we then want to have  
CSS and XML without trailing slashes, we can just add a new derived  
page model that computes the canonical URL differently.

[1] [Hypertext Style: Cool URIs don't change.](http://www.w3.org/Provider/Style/URI)

Cheers,  
Oliver

---

<div class="post-metadata">

**Author:** ![mahadewa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/9e8a1a/32.png) [@mahadewa](https://www.ruby-forum.com/u/mahadewa)\
**Post date:** [June 13, 2007, 5:51am UTC](https://www.ruby-forum.com/t/relative-linking-in-radiant/106585/16 "2007-06-13T05:51:54Z")

</div>

Chris P. wrote:

> My point about ‘unworkable’ is that, there is no way to guarantee that  
> user’s browser is always at the address with (or without) trailing  
> slash. And so, if your href’s don’t give the full address from the  
> root, your links may not work.

Sure there is. Just set up an apache rewrite rule to remove trailing  
slashes from any url handled by radiant. Why make this so hard?

---

<div class="post-metadata">

**Author:** ![mahadewa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/9e8a1a/32.png) [@mahadewa](https://www.ruby-forum.com/u/mahadewa)\
**Post date:** [June 13, 2007, 5:25am UTC](https://www.ruby-forum.com/t/relative-linking-in-radiant/106585/17 "2007-06-13T05:25:43Z")

</div>

Oliver B. wrote:

> On 12/06/07 07:10 PM, John W. Long was heard to say:
> 
> > - URLs without file extensions automatically get redirected to URLs with  
> > trailing slashes
> > - URLs with extensions (like .css or .xml) are left alone
> > - There is a configuration variable that turns this behavior on or off
> 
> Hi John,
> 
> thanks for your input. I do not think that the file extension is in  
> the general case a good indication for whether a URL should have a  
> trailing slash or not [1]. The canonical URL of a resource should be  
> determined by its corresponding model. ATM, everything in Radiant is a  
> page whether it is HTML or CSS. I would suggest the site controller  
> uses Page#url to determine the canonical URL of a page and redirects  
> accordingly. Page#url or any derived form of it is then responsible of  
> deciding if a trailing slash should be added. If we then want to have  
> CSS and XML without trailing slashes, we can just add a new derived  
> page model that computes the canonical URL differently.
> 
> [1] [Hypertext Style: Cool URIs don't change.](http://www.w3.org/Provider/Style/URI)
> 
> Cheers,  
> Oliver

The interesting thing with Radiant is that it eliminates possible the  
namespace confusion of something like:  
root  
|- A (folder)  
| |- index (file)  
|- A (file)

which made distinguishing between [example.com/a](http://example.com/a) and [example.com/a/](http://example.com/a/)  
necessary for browsers in the first place.

So, you can safely choose to add slashes or not for EVERY file and know  
that it’ll all work out.

That said, I’d prefer to represent each page as a file to the browser  
(i.e. [example.com/a](http://example.com/a)) unless someone has a compelling reason it should be  
treated like a folder. In addition, this method cleans up the whole  
extension parsing (who cares if it’s a CSS file – nothing gets a  
slash).

@John,  
So, how about a Radiant configuration setting to either “strip all  
trailing slashes” or “don’t mess with my slashes dude (current  
behavior)”?

I guess a third option could be ‘force trailing slashes’ (but someone  
else can contribute that one 😛 ).

-Chris

---

<div class="post-metadata">

**Author:** ![mahadewa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/9e8a1a/32.png) [@mahadewa](https://www.ruby-forum.com/u/mahadewa)\
**Post date:** [June 13, 2007, 4:39pm UTC](https://www.ruby-forum.com/t/relative-linking-in-radiant/106585/18 "2007-06-13T16:39:24Z")

</div>

Chris P. wrote:

> I guess a third option could be ‘force trailing slashes’ (but someone  
> else can contribute that one 😛 ).

I prefer this one because it makes relative linking easier.

–  
John L.  
[http://wiseheartdesign.com](http://wiseheartdesign.com)

---

<div class="post-metadata">

**Author:** ![mahadewa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/9e8a1a/32.png) [@mahadewa](https://www.ruby-forum.com/u/mahadewa)\
**Post date:** [June 13, 2007, 4:41pm UTC](https://www.ruby-forum.com/t/relative-linking-in-radiant/106585/19 "2007-06-13T16:41:24Z")

</div>

Oliver B. wrote:

> thanks for your input. I do not think that the file extension is in  
> the general case a good indication for whether a URL should have a  
> trailing slash or not [1]. The canonical URL of a resource should be  
> determined by its corresponding model. ATM, everything in Radiant is a  
> page whether it is HTML or CSS. I would suggest the site controller  
> uses Page#url to determine the canonical URL of a page and redirects  
> accordingly. Page#url or any derived form of it is then responsible of  
> deciding if a trailing slash should be added. If we then want to have  
> CSS and XML without trailing slashes, we can just add a new derived  
> page model that computes the canonical URL differently.

I’m fine with it being implemented through Page#url, but I would suggest  
that the default implementation check the file extension to determine if  
the trailing slash is necessary.

–  
John L.  
[http://wiseheartdesign.com](http://wiseheartdesign.com)

---

<div class="post-metadata">

**Author:** ![mahadewa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/9e8a1a/32.png) [@mahadewa](https://www.ruby-forum.com/u/mahadewa)\
**Post date:** [June 13, 2007, 5:08pm UTC](https://www.ruby-forum.com/t/relative-linking-in-radiant/106585/20 "2007-06-13T17:08:12Z")

</div>

John W. Long wrote:

> I prefer this one because it makes relative linking easier.

You lost me on that one. John. In the example:

root  
|- A  
| |- F  
| |- G  
|- B  
|- C

To get to a child page (say, page F), the trailing slash is more  
intuitive:

- from [example.com/a/](http://example.com/a/) → href=“f/” (you could =“f” too)
- from [example.com/a](http://example.com/a) → href=“a/f” (a bit weird)

Is this what you were referring to?

Of course, when accessing siblings (say page B), the trailing slash is  
less intuitive:

- from [example.com/a/](http://example.com/a/) → href=“…/b/” (also weird)
- from [example.com/a](http://example.com/a) → href=“b”

If this is what you meant, I don’t see which way is easier.

The implementation of no trailing slash is simpler, though.

[Next page](https://www.ruby-forum.com/t/relative-linking-in-radiant/106585.md?page=2)
