I am working through the menu entries for one rather large site, making sure that all entries have unique URL aliases. I had encountered a given URL alias being used in multiple menu entries which was confusing Drupal.
To untangle I created a new URL alias "Issues_Addiction_Shopping" pointing at the same Taxonomy query as the old alias which had been used twice which is "Issues_MentalHealth_OCD_Shopping".
In the /admin interface the Menu entries look correct, verify that the parent menu entry is correct, etc...
When verifying the site, however, the menu entries each have the other's URL alias.
We tried deleting one of the menu entries and re-creating it, the reversal still happens in the run-time environment whereas the /admin interface remains looking correct.
Finally I tried forcing the issue and added the string "Test" to the menu entry which I created the new URL Alias for. Indeed via the /admin interface the "Test" entry has the newly created URL alias. In the run-time with the web browser refreshed, the Menu entry does say "Test", however the link target is the old URL alias.
I tried emptying the cache* tables... initially it clears the problem up, however shortly it once again reverses itself.
I have verified using my usual Firefox 3.6 browser logged into the site, and also with Opera while not logged in. Also using a second computer with Firefox 3.6, the same thing is happening.
Server stats are as follows:
MySQL database 5.0.81 - mysqli:// type connection
PHP 5.2.12 - CGI
Apache/1.3.34 web server - last known version, since then the provider has eliminated showing the exact version
PHP.INI as follow, which configures PHP when run as a CGI (Just by uploading a custom php.ini file, doing so sets the MemoryLimit to 128M which we clearly did not specify one)
;Equiv of .htaccess that Drupal provided
magic_quotes_gpc = 0
register_globals = 0
session.auto_start = 0
mbstring.http_input = pass
mbstring.http_output = pass
mbstring.encoding_translation = 0
;Per http://gallery.menalto.com/node/68598
session.save_handler = files
allow_call_time_pass_reference = Off
;Per http://www.alphaone-tech.com/tech-support/index.php?_m=knowledgebase&_a=viewarticle&kbarticleid=70
;register_globals = 0
track_vars = 1
short_open_tag = 1
;magic_quotes_gpc = 0
magic_quotes_runtime = 0
magic_quotes_sybase = 0
arg_separator.output = "&"
session.cache_expire = 200000
session.gc_maxlifetime = 200000
session.cookie_lifetime = 604800
;session.auto_start = 0
;session.save_handler = user
session.cache_limiter = none
;allow_call_time_pass_reference = On
;Adjusted to allow larger files to be uploaded / downloaded
post_max_size = 10M
upload_max_filesize = 10M
| Comment | File | Size | Author |
|---|---|---|---|
| #14 | drupal-7.x-1.x-path_system-multiple_separate_aliases-1.patch | 8.05 KB | thekevinday |
Comments
Comment #1
mdlueck commentedCorrecting Component, I did not see "menu system" when I first filed this report.
Comment #2
mdlueck commentedUpdating this ticket after doing further research...
It appears that there is something in the Drupal menu system which is checking ultimate destinations of URL Aliases, and SEO optimizes the site by stacking all menu entries onto the first URL Alias for that particular destination.
The problem with that logic is that Drupal has no idea which menu entry to open the twisties to, since then multiple menu entries have the same URL Alias.
Further, a site might need to have a consistent URL Alias of "FeaturedProduct" which changes. With URL Alias stacking, the product's dedicated URL Alias ends up going missing when said product is the "FeaturedProduct".
The way it is working:
Menu Entry 1 -> URL Alias "FeaturedProduct" -> xyz
Featured Product Menu Entry -> URL Alias "FeaturedProduct" -> xyz
The way it SHOULD work:
Menu Entry 1 -> URL Alias 1 -> xyz
Featured Product Menu Entry -> URL Alias "FeaturedProduct" -> xyz
This behavior is the same in both D5 and D6, but I updated the ticket to reflect the latest version which this appears in.
I am looking for where to adjust D5 core code, and once found would gladly attach a patch to this ticket.
Comment #3
damien tournoud commentedThis is by design. The menu system stored internal paths, not aliases.
Comment #4
mdlueck commentedHang on... not so fast please...
For larger sites that have "multiple paths to the same content", we purposely make unique URL Aliases so that the menu system would have something unique to open to the correct leaf on the menu tree.
Compacting / Stacking multiple URL aliases at run-time causes the menu system to "go nuts" and not open sequential menu leafs properly.
I understand that multiple aliases for the same content is bad in search engine's mind... but we are developing sites for real people, not the applauds of search engines!
Please provide a counter solution to accomplish the site navigation we are trying to arrive at, else if there is none, then the bug still stands.
Possible menu system:
In the above example, each menu entry has a unique URL Alias. However some entries run exactly the same taxonomy query (term 1+2+3) so that is where we are seeing this stacking behavior, and it drives the menu system crazy.
Comment #5
mdlueck commentedThe code in this area does not happen to first convert URL Aliases to Destinations, then later reverse look up URL Aliases for Destinations if one exists, does it?
That type of logic would explain "criss crossing" URL Aliases / nodes that I have also observed.
Comment #6
mdlueck commentedPicture to explain what I asked in #5:
Is that what goes on in Drupal core?
Comment #7
subspaceeddy commentedHi - recently ran into this issue:
Basically I have content at node/10 which I alias to '/content/whatever' and also to '/more_content/whatever', basically so that I can add some extra blocks at the bottom of the content if the path is '/more_content/*'
However, internally, the menu system stores '/more_content/whatever' as 'node/10' which is then replaced at render by '/content/whatever' - the first alias - meaning I cannot have a menu entry pointing to '/more_content/whatever'.
There is an easy workaround, however, and that is to alias '/more_content/whatever' as 'node/10/display' - note that whatever comes after '10/' is arbitrary - but make sure you don't use 'edit' or some other term that is being used by a module you may have installed.
Now, in the menu system I can add 'more_content/whatever' and it stays as this - it doesn't get altered since internally it appears a different url.
Hope that helps...
Comment #8
dman commentedCurious work-around. Taking advantage of Drupals URL-resolution 'bug' that allows you to have many names for one piece of content - that SEO witch-doctors hate! Well, it should work, though it's certainly a bit odd!
In D4 & 5 (IIRC) this flattening to one true path didn't happen, and I pulled some similar trick to get menus to behave right - in cases where a page was both a menu parent and the first item in that menu.
Comment #9
subspaceeddy commentedYeah I know. It's odd and it made me both shudder and smile when I thought of it - the instinct is to be repulsed at quick and dirty work arounds like this - but hey - time is pressing, and it works for d6. It also frees up a lot of other menu-related stuff that has been bogging down the project I'm currently working on. I'd be curious to find out how d7 handles all this, but I guess that's for the future when I have more time.
Comment #10
curtaindog commentedThank you subspaceeddy, just when I was gearing up to hack menu.inc you saved me.
Comment #11
BogdanN commentedHas anyone ever noticed the schema change in the system module, for url_alias table? Why put the pid in the unique key dst_language_pid. This makes our site unstable with a lot of identical urls pointing to different things. If you have a primary key column, you don't use that column in an unique key, because there should be no point in that.
Comment #12
BrentRoger commentedI'm using this work-around in a D7 site I'm currently working on.
From what I've seen it messes up menu_tree_page_data so when you get to the actual hybrid node (node/##/whatever) it's not being recognized as valid and therefore not building the appropriate tree structure. I haven't looked at a work-around for this just yet but wanted let you know it in essence works the same in D7 as you described it working in D6.
Comment #13
jyg commentedBrentRoger, what is the user-identifiable effect of "not building the appropriate tree structure"?
Comment #14
thekevinday commentedI think the real problem is in the path system and is unrelated to the menu module.
As I came up with a solution to this on drupal 7, I am bumping this to drupal 7, then somebody can potentially backport the fix.
Also, I don't see a "Path System" component, so I am selecting "Base System" instead.
I have multiple url aliases pointing to a single node.
As visualized in number #6, lets say I have 3 url aliases pointing to a single node (aka real path).
Lets say the aliases are as follows:
The following is what I see happening:
(1) User goes to: http://example.com/url_alias_2
(2) drupal initializes _GET[q] and translate "url_alias_2" to "node/1"
(3) drupal loads alias for "node/1"
(4) drupal rewrites the url as http://example.com/url_alias_1
What is expected to happen:
(1) User goes to: http://example.com/url_alias_2
(2) drupal initializes _GET[q] and translate "url_alias_2" to "node/1"
(3) drupal loads alias for "node/1"
(4) drupal rewrites the url as http://example.com/url_alias_2
My Solution
The immediate problem is that the original path gets lost and then replaced.
Inside of drupal_path_initialize(), I saved the original path before it gets replaced by drupal_get_normal_path().
This is stored as 'original_path' inside of a drupal_static variable called 'drupal_path_initialize'.
Inside of drupal_lookup_path(), when loading the 'alias', I replaced database fetchField() calls with database fetchAll() calls.
Then I have to process each of the array values.
The next problem that must be solved is that the 'source' is used as the unique key instead of the 'alias'.
The existing design generates the path cache like this:
To solve this so that all aliases are cached, I swap the key and value when generating the array.
This produces:
Doing this produces the desired behavior and fixes the problem.
Additional References:
(1) #1865384: Multiple alias for single node
(2) http://drupal.org/node/673890
(3) http://drupal.org/node/368907