Relative Linking in Radiant

Chris P. wrote:

|- C
Given the above if I am on A and want to link to F or G, I generally
use:

F or G

Granted the extra dot is more explicit, but it seems more semantic,
especially when you compare it to how you link to siblings:

B or C

But perhaps I’m strange.


John L.
http://wiseheartdesign.com

Back on track… I see three possible methods:
1.) Current behavior with trailing slashes (slash & no-slash are the
same)
2.) Force a trailing slash (redirect the user’s browser to address
ending in a slash) except for certain file types (CSS, JS, etc).
3.) Strip all trailing slashes (redirect to the address not ending in a
slash)

Which are acceptable for Radiant to support/permit?

If more than one way is permitted, we need some sort of configuration.
How would you like that done/named?

-Chris

P.S. your ./ thing is wild. If I ever learned that one, I’ve long
forgotten it. I don’t think I’ve ever seen it used.

Chris P. wrote:

Back on track… I see three possible methods:
1.) Current behavior with trailing slashes (slash & no-slash are the
same)
2.) Force a trailing slash (redirect the user’s browser to address
ending in a slash) except for certain file types (CSS, JS, etc).
3.) Strip all trailing slashes (redirect to the address not ending in a
slash)

I favor only 1 and 2. For configuration, I’d recommend an inherited
class attribute on Page:

Page.trailing_url_slash = true
StylesheetPage.trailing_url_slash = false

Combined with an attribute on SiteController:

SiteController.normalize_urls = true

Or something of that nature.


John L.
http://wiseheartdesign.com

John W. Long wrote:

F or G

Granted the extra dot is more explicit, but it seems more semantic,
especially when you compare it to how you link to siblings:

B or C

But perhaps I’m strange.


John L.
http://wiseheartdesign.com

Perhaps.

But you make up for it in not being opinionated like I am. :wink:

Brian G. wrote:

other-site host) will return “site.css”, which is horribly
incorrect.

I am not sure I understand this. If main.css is an alias page, its model
should make sure that it returns the alias’s canonical URL instead of
the destination page’s URL.

Cheers,
Oliver

On Jun 13, 2007, at 10:39 AM, John W. Long wrote:

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.

I’m not. It suggests that there is only one URL to access a page,
and that may not be the case.

My example:

/ (Virtual Domain Page)
/main-site
/main-site/site.css
/other-site
/other-site/site.css
/other-site/main.css (Alias Page) (to /main-site/site.css)

This would allow certain pages in the “other site” to look like the
main site (an organizational theme to override a site theme, for
example). However, doing Page.find_by_url(’/main.css’).url (from the
other-site host) will return “site.css”, which is horribly
incorrect. Perhaps I’m being overly cautious, but I don’t think that
Radiant should enforce a redirect to the “one true URL” anywhere. It
seems to seriously limit extensions.

That said, I do think that the trailing slash addition or removal is
useful. Personally, I think of a radiant page similarly to the
index.html of a directory in most cases. (So a sibling is actually
“…/sibling”.) YMMV. Adding .html to the slug of pages that
shouldn’t be directories (or a trailing slash to those that should)
isn’t a bad idea, I think.

~~ Brian

On Jun 13, 2007, at 2:00 PM, Oliver B. wrote:

example). However, doing Page.find_by_url(’/main.css’).url (from the
other-site host) will return “site.css”, which is horribly
incorrect.

I am not sure I understand this. If main.css is an alias page, its
model
should make sure that it returns the alias’s canonical URL instead of
the destination page’s URL.

Not in the way that I wrote the alias page. My Alias Page extension
simply returns the source page directly rather than attempting to re-
route and correct method calls. This was primarily done for
simplicity, as all I had to implement was find_by_url to return pages
from a different portion of the tree. But even if I did that, then
the children of the aliased page would be problematic.

The current design allows children of the AliasPage to override pages
of the source Page. The idea was for directories that contain mostly
the same information (CSS pages?) to be copied across sites but still
have local customizations. If I had to correct the url method of
these, I’d have to do some odd trickery with creating AliasPage
instances that don’t exist in the database.

The Alias Page I wrote is amazingly simple and useful. If the core
team decides that it’s fundamentally flawed in some method that
requires me to change it, I understand. But I simply used it as an
example near to my heart. Changing Radiant to have “One True URL”
for pages limits the power of virtual pages and extensions, and
that’s all I wish to speak against.

~~ Brian

Brian G. wrote:

The Alias Page I wrote is amazingly simple and useful. If the core
team decides that it’s fundamentally flawed in some method that
requires me to change it, I understand. But I simply used it as an
example near to my heart. Changing Radiant to have “One True URL”
for pages limits the power of virtual pages and extensions, and
that’s all I wish to speak against.

Hi Brian,

That is reasonable. I don’t suggest to force an entirely different URL
onto something that was addressed via an alias, virtual or other
abstract page. However, if you have a virtual page or an alias page, I
don’t think it is too much to ask for what its canonical URL should be.
Something similar is already done with the Archive page, that generates
URLs that are not only composed of the slug of the page and the slugs of
the page’s ancestors. All I am suggesting is to redirect if
clean_url(Page#url) != request url [1]. The model can then decide how to
compute the URL. I suspect your alias page model’s url method already
computes /other_site/alias_page instead of /first_site/source_page.

Cheers,
Oliver

[1] I believe clean_url currently adds a trailing slash, which has to be
fixed and left up to the model to do if necessary.

On Jun 13, 2007, at 4:37 PM, Oliver B. wrote:

All I am suggesting is to redirect if
clean_url(Page#url) != request url [1]. The model can then decide
how to
compute the URL. I suspect your alias page model’s url method already
computes /other_site/alias_page instead of /first_site/source_page.

Actually, it doesn’t. And I think that redirect is broken for any
site that has multiple ways to access the same page. And it sucks
from a performance point of view as we have to do find_by_url twice
for the page twice before displaying it.

~~ Brian

On 13/06/07 09:22 PM, Brian G. was heard to say:

On Jun 13, 2007, at 4:37 PM, Oliver B. wrote:

All I am suggesting is to redirect if
clean_url(Page#url) != request url [1]. The model can then decide
how to
compute the URL. I suspect your alias page model’s url method already
computes /other_site/alias_page instead of /first_site/source_page.

Actually, it doesn’t.

I think it should. I don’t see why not.

And I think that redirect is broken for any
site that has multiple ways to access the same page.

There is no reason for accessing the same page via multiple ways.
That’s just bad design. Compared to a Unix file system, there are
directory entries and there is data. Two directory entries may point
to the same data, but still are distinct directory entires. Asking
either of them for their path will return two different paths.

And it sucks from a performance point of view as we have to do find_by_url twice
for the page twice before displaying it.

Only if it actually needs to be redirected. Apache does not seem to
have a problem to stat a directory twice for the same reason.
Redirects should be fairly infrequent if the web-author is paying
attention.

Cheers,
Oliver

On Jun 13, 2007, at 11:27 PM, Oliver B. wrote:

I think it should. I don’t see why not.

Flat out simplicity. The AliasPage just has a find_by_url that
returns the other page. And since a page can have child pages, if I
didn’t just re-route the request I’d either have to have an alias for
each subchild (ugly) or do some complicated trickery involving
creating Page objects on the fly that don’t actually exist in the
database (which I don’t like, but can do if it becomes necessary).

I’ll admit the AliasPage extension is a dumb hack. But it works, and
I think it’s simplicity is an example of how the simple framework of
Radiant is powerful. I have no objection to altering the extension
to do these things so that the resulting page gives the correct URL,
if there is a compelling reason for it. But you haven’t given me one.

And I think that redirect is broken for any
site that has multiple ways to access the same page.

There is no reason for accessing the same page via multiple ways.
That’s just bad design. Compared to a Unix file system, there are
directory entries and there is data. Two directory entries may point
to the same data, but still are distinct directory entires. Asking
either of them for their path will return two different paths.

Hard Links. Symbolic Links. Used all the time in Unix to have the
same file in multiple places. And, AFAIK, you can’t ask “where is
this file” once you’ve opened it. The best you can get is “what path
did I open this file with”. Ext2 inodes don’t even know what their
parent is. Directory entries point back to their parents with the
“…” link, but files have no concept of where they are stored and it
makes links significantly easier.

My use of it is to have the same CSS file(s) across multiple sites.
But I could see an extension that publishes an address book with URLs
like /addresses//. If a person is in multiple groups,
should I have to update multiple pages when their contact information
changes? Or shouldn’t I be allowed to have a single page with their
information and a “groups” part the describes all the groups they are
in? What if we added authorization so that not everyone can see
every group? How do we handle your redirect now?

And it sucks from a performance point of view as we have to do
find_by_url twice
for the page twice before displaying it.

Only if it actually needs to be redirected. Apache does not seem to
have a problem to stat a directory twice for the same reason.
Redirects should be fairly infrequent if the web-author is paying
attention.

find_by_url is one of the biggest time issues in Radiant, as far as I
can tell. Avoiding it would be useful. And I don’t see what
redirecting to the “one true URL” would help. A site-wide setting
for “add a trailing slash” or “remove a trailing slash” (possibly
with don’t add slashes if there’s an extension on the URL), it would
be faster and solve the original problem without adding additional
cost or complication.

Doing what you suggest adds a limitation to Radiant and doesn’t
provide a significant bonus.

That’s my issue.

~~ Brian

Brian G. wrote:

On Jun 13, 2007, at 11:27 PM, Oliver B. wrote:

I think it should. I don’t see why not.

Flat out simplicity. The AliasPage just has a find_by_url that
returns the other page. And since a page can have child pages, if I
didn’t just re-route the request I’d either have to have an alias for
each subchild (ugly) or do some complicated trickery involving
creating Page objects on the fly that don’t actually exist in the
database (which I don’t like, but can do if it becomes necessary).

I see how this works now. It’s clever, but I don’t agree with that
choice. I think an AliasPage should be a separate entity and its
attributes, i.e. #url, should be consistent with how you access it. But
that’s just me.

this file" once you’ve opened it.
True, but you can ask a page where it is. Assume I am asking an
AliasPage for its path, you say it is alright to return a different path
than the one I used to find the page.

My use of it is to have the same CSS file(s) across multiple sites.
But I could see an extension that publishes an address book with URLs
like /addresses//. If a person is in multiple groups,
should I have to update multiple pages when their contact information
changes?

No, I think an AliasPage is a good extensions and I understand your
reasons for it. I don’t agree with those reasons, but that again is just
me. I just don’t think the AliasPage should not even be aware of its own
existence when accessed.

What if we added authorization so that not everyone can see
every group? How do we handle your redirect now?

I don’t know what you mean by that. If you are asking whether I think if
an AliasPage should delegate authorization to the target page, then
the answer is yes. In fact, I would have the AliasPage inherit the
authorization rules from the target page and provide the option to
overwrite/augment them.

And it sucks from a performance point of view as we have to do
find_by_url twice
for the page twice before displaying it.
Only if it actually needs to be redirected. Apache does not seem to
have a problem to stat a directory twice for the same reason.
Redirects should be fairly infrequent if the web-author is paying
attention.

find_by_url is one of the biggest time issues in Radiant, as far as I
can tell. Avoiding it would be useful.

I agree, but as mentioned before, duplicates occur rarely and only if
the “wrong” URL was used to begin with. Instead of redirecting we could
just produce a 404.

< And I don’t see what

redirecting to the “one true URL” would help. A site-wide setting
for “add a trailing slash” or “remove a trailing slash” (possibly
with don’t add slashes if there’s an extension on the URL), it would
be faster and solve the original problem without adding additional
cost or complication.

Also mentioned before, an extension is not a sufficient criteria to
decide whether something should have a trailing slash or not. If it
would, what extensions would you choose? Or do you treat everything
after the last dot as an extensions, thus limiting your choice of slug?
Only allowing up to 4 characters as extension?

Cheers,
Oliver

On Jun 14, 2007, at 1:58 PM, Oliver B. wrote:

I see how this works now. It’s clever, but I don’t agree with that
choice. I think an AliasPage should be a separate entity and its
attributes, i.e. #url, should be consistent with how you access it.
But
that’s just me.

The AliasPage extension falls into the category of “quick and dirty
hack.” It works. Nowhere will I claim that it’s implementation is
perfect. There are improvements that could be made (proxying the
desired page and it’s children in the way you describe, for example).

True, but you can ask a page where it is. Assume I am asking an
AliasPage for its path, you say it is alright to return a different
path
than the one I used to find the page.

It works so far and I don’t see a compelling reason why it’s not
alright. The url attribute should be a canonical way to access the
page but I don’t see why it has to be the only way, as you suggest.

But I could see an extension that publishes an address book with URLs
like /addresses//. If a person is in multiple groups,
should I have to update multiple pages when their contact information
changes? What if we added authorization so that not everyone can see
every group? How do we handle your redirect now?

At this point, I am discussing a hypothetical extension, not the
AliasPage in particular. This is a simple address book extension,
where the tree appears as:

/addresses/ (AddressBookPage)
/person
/person2
/person3

and each person page has two parts: main and groups. The groups part
is a list of what groups that person belongs to. The AddressBookPage
then gives the following URLs:

/addresses/
/addresses/group1/
/addresses/group1/person/
/addresses/group1/person2/
/addresses/group2/
/addresses/group2/person2/
/addresses/group2/person3/

Should we forbid person2 from being accessed from two different
URLs? Why? Perhaps there is additional logic in the display that
shows slightly different parts based on the group. Or there is an
authorization extension that only shows you certain groups. What
should person2.url return? Why should we redirect group2/person2 to
group1/person2 (or vice versa)?

find_by_url is one of the biggest time issues in Radiant, as far as I
can tell. Avoiding it would be useful.

I agree, but as mentioned before, duplicates occur rarely and only if
the “wrong” URL was used to begin with. Instead of redirecting we
could
just produce a 404.

I try to produce human-readable (and therefore typeable) URLs. I’d
argue that the URL would be mis-typed (regarding trailing slashes) on
a regular basis. And producing a 404 is wrong when we should be able
to easily correct it.

Also mentioned before, an extension is not a sufficient criteria to
decide whether something should have a trailing slash or not. If it
would, what extensions would you choose? Or do you treat everything
after the last dot as an extensions, thus limiting your choice of
slug?
Only allowing up to 4 characters as extension?

I don’t care. I’m all for adding a trailing slash to each and every
page. Or removing it from them all. Or making it based on the
page’s class or layout. (Although I’m less for that due to the
lookups required, but not against.) Actually, thinking about it now
I think that the presence or absence of the trailing slash is a
matter for the layout, not the page type. After all, a Page can be a
HTML or CSS file based on it’s layout. It would simply be a boolean
field on the layout.

But I’m still whole-heartedly against redirecting everything to
Page#url. It only seems to add limits without adding functionality.
And that’s my problem with it. I’m not arguing about it to keep my
extension from breaking. I’m arguing against it because I think it’s
wrong for Radiant to do conceptually.

~~ Brian