Panels and 404

We encourage users to post events happening in the community to the community events group on https://www.drupal.org.
escoles's picture

I'm using Panels 2 on a site that I'm working on right now, and I've discovered that paths to non-existent pages that begin with the URL of the panel page do not produce a 404.

For example, let's say that this is a page that doesn't exist:

[1] http://example.com/melvin

If I go to that page, I get a 404 Page Not Found response code, and a 404 page is displayed.

Let's say I have a panel page with this URL:

[2] http://example.com/panel1

Now let's say I try to browse to this URL:

[3] http://example.com/panel1/melvin

... where this refers to a page that does not exist. What's happening now is that I get a 200 OK response code, and what loads is a broken version of the page at [2].

Anybody have a clue what's going on with this, or how I could work around it?

Pre-emptive: I know of one workaround, and that's to give the panel page URLs fake file extensions. (It also works just to give them names that will never occur in the path to child pages.) This is a solution I don't want to use, but will have to if I can't find a different solution in the next three days at the outside. I don't want to use it because it leaves the defect still in place and exposed.

Comments

One workaround, slightly less ugly...

escoles's picture

OK, here's a slightly less ugly version of the workaround.

If I give the panel page a name with a extension -- say, 'services.htm' -- and then create a URL alias that redirects that alias to a path that doesn't end in an extension -- say, 'services' -- the problem goes away except for one case. (Where a trailing slash is added to the URL, e.g. 'services/' -- as though it's a directory -- and that can be eliminated using the GlobalRedirect module.)

That still leaves me wondering why this happens, and whether I'm the only person seeing it.

If you go to node/1 and it

merlinofchaos's picture

If you go to node/1 and it exists, and you go to node/1/melvin you will also find that it exists. This isn't a Panels behavior, it's a standard Drupal behavior.

That's really user-hostile standard behavior

escoles's picture

OK, I realize this probably wasn't your design decision, but it's a really bad design. It's both user-hostile and potentially very SEO-hostile as well. I also understand that it may be something that's inherent in the Clean URLs design; that doesn't mean we should rationalize it as being good because it facilitates having something else that's good.

Point 1: node/1/melvin doesn't exist, and you shouldn't find it. What you're finding at node/1/melvin is not what you're looking for, it's just another instance of node/1. It's the system lying to the user -- hiding errors from them, saying "nope, everything's fine here! This is really what you want, trust me!" From a semiotic perspective, a user interaction perspective, that is absolutely what the system is doing when it shows the same page for node/1 and node/1/melvin.

I can tell you that all the users I've ever seen getting the output from node/1 when they browse to node/1/melvin, they think they site is broken. This is not speculation; I've seen it, many times. On the site in question alone, I had two people submit defects on that and both of the people we've had look at it at the client site commented on that failure mode as a failure, not an expected behavior. And I can't think of a reason why they shouldn't see it as a system failure. They are not getting feedback. This is a violation of a really important core principal of user-interaction design: Users should get accurate feedback within the range of their understanding. If a mistake has been made, they should be informed, and they should be told if it's something they can correct. That is the purpose of the 404 code. That node/1/melvin (which does not exist) does not return 404 constitutes a design flaw, and it's behavior that should be changed.

On the charge of SEO-hostility, I can personally attest (after seeing my usual link checker go into what looked like an endless recursion) its failure mode can be deeply ugly from a spider's perspective. Think this through: If you have relative links that are incorrect on a page that behaves in this manner, you'll get a recursive propagation of links to the same page with a different address. Just a few days ago, I watched a link checker (Xenu, as it happens) chase that particular rabbit down a recursive hold that ended up over 5,000 links deep before I killed the crawl. Yesterday when I used Xenu on the same site with the same content, corrected links and my hacks applied, it found 200 links. No recursion. Presumably, search spiders are smart enough not to recurse infinitely through that kind of morass; but why should we expect them to compensate for bad design, when simply passing a 404 (as would normally be done in non-Drupal, non-clean-URLs implementations) would be sufficient to efficiently stop them right at the start of the rabbit hole?

This is potentially very very SEO-hostile because it gives the illusion of repeated content, which is a big, big no-no. It can get you banned.

This is user-hostile because it contradicts the directory-path metaphor that everyday computer users have worked hard to inculcate. What people are used to is the idea of browsing into deeper directory spaces and finding more detail. That's how the vast majority of information architectures are designed. But this breaks that assumption, because you browse "deeper" and find the same thing. What you should find is nothing where there's nothing, not the same thing where there should be nothing.

This is also user-hostile in the sense that it expects people to think like the machine -- it tacitly expects them to think in terms of passing parameters instead of browsing into directory structures. This is a slightly different point -- it's not merely that the behavior works against their assumptions, it's that it expects of them to develop new assumptions. And what's more, with nothing to guide them toward those assumptions: The information architecture, even if its underlying structure as the machine understands it is all about getting new slash-delimited parameters, still looks like browsing a directory path to the user. And it's the user that matters, not the machine.

Finally, it requires people designing information architectures and their supporting system architectures to think in ways that allow people to get something that makes sense to them when they browse to node/1/melvin. I can't even begin to think about how that would work from an IA perspective, without hacking to get past the "expected behavior" of browsing to a deeper structure and getting the same thing happily presented to me. When designing an IA and an interaction design to go along with it, you are still stuck having to deal with what people will expect. If you want to make something that's usable and useful, you have to go with what they'll expect -- otherwise you're making art. I have no objection to art, but that kind of art is not useful in providing results for my clients.

bug report

catch's picture

Please post a bug report against Drupal 7 at: http://drupal.org/node/add/project-issue/drupal/bug

I wanted to see what this

escoles's picture

I wanted to see what this looked like in practice, so I browsed to this address:

http://groups.drupal.org/node/13878/melvin

What I get is just the top level story, with no affordance for viewing the comments.

So it may be expected behavior, and may be as-designed, but it looks to me as though it breaks important things more or less wherever it occurs. It should be changed.

I'll note that Drupal.org seems to have patched around this behavior:

http://drupal.org/upgrade/melvin
http://drupal.org/upgrade/tutorial-introduction/melvin

Well, in some places at least:

http://drupal.org/project/issues/melvin

You've got to be careful;

merlinofchaos's picture

You've got to be careful; what you're seeing is the difference between URL aliases (which can't accept arguments) and normal Drupal paths (which can).

Your very long post is pretty much in the wrong place. I have no opinion on it, and I don't really care. This group is a discussion about Panels; if you have problems with Drupal's URL system, then there are appropriate places to bring up that discussion, and this isn't it.

I know that's the difference

escoles's picture

I know that's the difference I'm seeing; that was my (tacit) point: The behavior is inconsistent. (It also tends to break things. For fun, sometime, when you're logged-in, follow the "issues/melvin" and then change a filter parameter on the issues view. You'll get what looks like a session ID appended with a querystring argument. It doesn't break function hard, but it sure looks like a potential vulnerability.)

I realize this "isn't the place"; I find this "not the place" attitude I encounter in the Drupal discussion areas to be frustrating. People like you (and I believe you absolutely have the best motives for making this observation, I really respect your work and for all I can remember you behave like a human being in discussions) will be quick to enforce this idea of topic-appropriateness, but it's most often violated without comment. I realize that doesn't make it right when they do that.

My point on that is that sometimes it's important to bring things up when and where they have an effect. This has an effect here. We have a situation where the behavior of what looks to a user like a normal page alias (the Panel URL), but it's actually behaving like an application root URL that accepts additional parameters. Except when the URL happens to have children, and sometimes then it shows a page, and sometimes it just shows the same page. Finding something where they should find nothing.

appropriateness

catch's picture

While it has an effect in Panels, it can't be fixed in Panels. While you might find the 'not the place' mantra frustrating, I can guarantee that those of us spending a lot of time on Drupal.org find it even more frustrating when perfectly good bug/usability reports like yours get lost in completely the wrong places. People currently working on the menu system don't look in this group, so the post is pretty much wasted. You can choose to take our advice or not, but not everyone reads every post everywhere on all the sub-sites, so if you'd actually like this fixed (or at least an explanation why it works the way it does), then bug reports against core are more effective.

You're wasting my reading

dilvish's picture

You're wasting my reading time.

Education is a wonderful thing, provided you always remember that nothing worth knowing can ever be taught. Oscar Wilde

Education is a wonderful thing, provided you always remember that nothing worth knowing can ever be taught. Oscar Wilde

Your post reminds me of another Wilde quote

christefano's picture

Your post reminds me of another Wilde quote:

When one pays a visit, it's for the purpose of wasting other people's time and not one's own.

Please don't tell people that they're wasting your time. It's rude and unhelpful. Just move on.

What's the solution?

xsean's picture

anyone know what is the solution for this issue as i tested some of website using drupal solve it?

In Panels 3, the solution is

merlinofchaos's picture

In Panels 3, the solution is to add an optional argument as a string context, and then have an access rule that uses the context exists rule and requires that the optional context does not exist.

The context exists feature

merlinofchaos's picture

The context exists feature may only exist in the current -dev version of CTools, though. I hope to release a new one in the next week or two.

Attempt to WorkAround - ALMOST working

webthingee's picture

Based on this here's what I am trying...

case is -
panel is located at /paneltest
I type in a url such as /paneltest/someurlthatisntreal
-> returns the /paneltest page.

so....

in the panels menu,
under settings: variants: panel: selection rules
I added php code

if (arg(1)==NULL) {
return FLASE;
}

if my panel is at /foo/paneltest I changed the argument to (2)

result -
panel is located at /paneltest
I type in a url such as /paneltest/someurlthatisntreal
-> returns a 404/403

It seems to be working for now... the site I am working in has a dozen or so panels... not looking forward to coding them all... and looking to use panels everywhere soon.... if there's an override, or a better way to do this please chime in...

This is the best/easiest

locomo's picture

This is the best/easiest solution I've found so far - thanks!

Yes - some kind of setting in panels seems ideal.

Typ0

webthingee's picture

Leave it to me to typo an important post...

if (arg(1)==NULL) {
return FALSE;
}

This also worked great in Views :)

This code still looks wrong

mr.j's picture

This code still looks wrong to me. It should return TRUE if there are no arguments.

I used this:
return arg(1) == NULL;

We were having the same

bwporter's picture

We were having the same problem. The code from mr.j solved the issue.

How do you...

l-laziz's picture

1 How do you get this to response as 404? So far it's showing only "Access denied"(403) which isn't correct since path doesn't exist...

2 How can i apply it in views pages? Thanks.

How do you...

l-laziz's picture

1 How do you get this to response as 404? So far it's showing only "Access denied"(403) which isn't correct since path doesn't exist...

2 How can i apply it in views pages? Thanks.

As for a taxonomy term

capellic's picture

As for a taxonomy term template solution, add a validator for the vocabulary you're trying to override:

Taxonomy: vocabulary = Term being viewed vocabulary is "Topic category"

Was this issue ever logged in the right place?

Actually, what I found I had

capellic's picture

Actually, what I found I had to do is this:

Put in following pane selection criteria for the three category panes:

<?php
$args
= explode('/', $_GET['q']); 
return (
count($args) > 3) ? FALSE : TRUE;
?>

Then put in a variant for the last pane that simply executed the durpal_not_found function.

Code shouldnt be stored in the DB

ecrown's picture

it is generally not best practice to store code in the db

so instead of using php code. you should create a ctools plugin through a custom module you can find sample code below for this based off #comment-225323
https://www.drupal.org/sandbox/crownemmanuel/2382149

How do you...

l-laziz's picture

Hi ecrown,
I see that you created module to return 404... but it returns 403 (Access denied) for invalid arguments. I would really want it to return 404 (Page not Found) instead. Is there any control over it? If so, please advice. Thank you!

Panels

Group organizers

Group notifications

This group offers an RSS feed. Or subscribe to these personalized, sitewide feeds: