Relative Linking in Radiant

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:

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 because the browser thinks I’m in the root/ folder. In
the second case, I’m sent to 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?

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 .

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?

Keith B.
Tel: +49-7731-79838380
[email protected]
http://keithbingman.com

On 6/12/07, Chris P. [email protected] 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 because the browser thinks I’m in the root/ folder. In
the second case, I’m sent to 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.

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

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 .

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.

Mislav Marohni�? wrote:

On 6/12/07, Chris P. [email protected] 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 because the browser thinks I’m in the root/ folder. In
the second case, I’m sent to 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’ 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’ Radiant would automatically redirect to
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?

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

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).

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

Mislav Marohnić wrote:

On 6/12/07, Oliver B. [email protected] 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

On 6/12/07, Oliver B. [email protected] 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.

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’ (i.e. the browser ‘thinks’ its opening the links
file in the root directory).

If, instead, your browser is pointed to: ‘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

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.

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

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

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.

Cheers,
Oliver

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?

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.

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 and 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) 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 :stuck_out_tongue: ).

-Chris

Chris P. wrote:

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

I prefer this one because it makes relative linking easier.


John L.
http://wiseheartdesign.com

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

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:

Is this what you were referring to?

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

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

The implementation of no trailing slash is simpler, though.