#907690 changed the behaviour of items defined with type MENU_CALLBACK. Previously they created an entry in {menu_links table} and now they don't.

The same criteria used for inclusion in the menu_links table were also applied to whether the item was included when building the breadcrumb, hence the new type name MENU_VISIBLE_IN_BREADCRUMB. This had one problematic side effect - items created with type MENU_CALLBACK and no menu parents get "Home" as a title.

The title for a page is determined by taking the last item in the active path which is not a local task. The active path is seeded with a link to home and each item in the path with type MENU_VISIBLE_IN_BREADCRUMB is added to the list. At the end of this process the preferred link for the current item is added to the end of the breadcrumb

    // Make sure the current page is in the trail (needed for the page title),
    // if the link's type allows it to be shown in the breadcrumb. Also exclude
    // it if we are on the front page.
    $last = end($trail);
    if ($last['href'] != $preferred_link['href'] && ($preferred_link['type'] & MENU_VISIBLE_IN_BREADCRUMB) == MENU_VISIBLE_IN_BREADCRUMB && !drupal_is_front_page()) {

This leaves an item of type MENU_CALLBACK with no parent menu items returning only Home in it's breadcrumb, hence the unexpected page title.

The check for whether the current page's path should be in the breadcrumb is irrelevant since when the breadcrumb is displayed the current page is dropped from the end of the breadcrumb

    // Don't show a link to the current page in the breadcrumb trail.
    $end = end($active_trail);
    if ($item['href'] == $end['href']) {
      array_pop($active_trail);
    }

Since the breadcrumb display status of the current item is irrelevant (it's not displayed anyway) and it is required to set the title correctly the condition for its inclusion in the active trail should be dropped

    // Make sure the current page is in the trail (since its needed for the page
    // title), don't add it if we are on the front page (since it's already in
    // the trail).
    $last = end($trail);
    if ($last['href'] != $preferred_link['href'] && !drupal_is_front_page()) {
      $trail[] = $preferred_link;
    }

This also avoids the current situation of items ending up on {menu_links} just to get a title displayed.

Unless I've missed some knock-on effect somewhere ...

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Status: Needs review » Needs work

The last submitted patch, menu_callback_home_title.patch, failed testing.

bellHead’s picture

Status: Needs work » Needs review

menu_callback_home_title.patch queued for re-testing.

larowlan’s picture

sun’s picture

Status: Needs review » Needs work

Analysis seems to make sense. However, we should

1) improve and clarify the inline comment (moving some of the essentials in the analysis here into code).

2) Extend the existing breadcrumb test to also test a page of type MENU_CALLBACK.

larowlan’s picture

Status: Needs work » Needs review
FileSize
2.11 KB

Here it is again taking into account sun's comments

Island Usurper’s picture

Status: Needs review » Needs work

Test still hasn't been extended.

Also, small typo: it should read (since it's needed for the page, not its.

larowlan’s picture

Status: Needs work » Needs review

Here it is again with typo corrected and a new test testTitleOrphanMenuCallback which fetches path menu_callback_orphan defined in menu_test.module that is a MENU_CALLBACK item with no parents - and tests for the appropriate page title

larowlan’s picture

FileSize
4.04 KB

Status: Needs review » Needs work

The last submitted patch, issue-965272.patch, failed testing.

larowlan’s picture

Assigned: Unassigned » larowlan

hmm, test is no good, reviewing now

larowlan’s picture

Assigned: larowlan » Unassigned
Status: Needs work » Needs review

access denied on my callback, doh
here it is again

larowlan’s picture

FileSize
4.09 KB
sun’s picture

Status: Needs review » Needs work
+++ includes/menu.inc	14 Dec 2010 00:24:30 -0000
@@ -2303,11 +2303,25 @@ function menu_set_active_trail($new_trai
-    // Make sure the current page is in the trail (needed for the page title),
-    // if the link's type allows it to be shown in the breadcrumb. Also exclude
-    // it if we are on the front page.
+    // Make sure the current page is in the trail (since its needed for the page
+    // title), don't add it if we are on the front page (since its already in
+    // the trail).
+    //

1) Let's revert the addition(s) of "since it's".

2) Avoid abbreviations like "don't" and always spell them out instead.

3) The reasoning for not including the current page on the front page does not sound 100% correct to me. Since that is irrelevant for this issue in the first place, let's remove that reasoning.

4) Let's also remove the "blank comment line" (or rather, that entire separation of comments).

+++ includes/menu.inc	14 Dec 2010 00:24:30 -0000
@@ -2303,11 +2303,25 @@ function menu_set_active_trail($new_trai
+    // See #965272: The title for a page is determined by taking the last item in the
+    // active path which is not a local task. The active path is seeded with a
+    // link to home and each item in the path with type
+    // MENU_VISIBLE_IN_BREADCRUMB is added to the list.
+    // At the end of this process the preferred link for the current item is
+    // added to the end of the breadcrumb if it is flagged as
+    // MENU_VISIBLE_IN_BREADCRUMB or MENU_CALLBACK. If we don't do this,
+    // items of type MENU_CALLBACK without parents will result in the page title
+    // being Home- as this would be the only item in the active path. Adding the
+    // preferred link to the breadcrumb trail even if it is only a MENU_CALLBACK
+    // does not have an adverse affect on the breadcrumbs as the current page
+    // is always dropped from the breadcrumb trail anyway
     $last = end($trail);
-    if ($last['href'] != $preferred_link['href'] && ($preferred_link['type'] & MENU_VISIBLE_IN_BREADCRUMB) == MENU_VISIBLE_IN_BREADCRUMB && !drupal_is_front_page()) {
+    if ($last['href'] != $preferred_link['href'] && !drupal_is_front_page() &&
+        in_array($last['type'], array(MENU_CALLBACK, MENU_VISIBLE_IN_BREADCRUMB), TRUE)) {
       $trail[] = $preferred_link;

This type check is not correct.

1) MENU_VISIBLE_IN_BREADCRUMB is an internal menu system constant that is normally not specified directly. The menu system constants are bitmasks.

2) In D7, router items of type MENU_CALLBACK do not have a corresponding menu link.

In terms of code and logic, I think we can go back to the original patch and remove the additional condition altogether. The effect is that a MENU_CALLBACK (which can only originate from menu_get_item(), not menu_link_get_preferred()) is appended to the active trail, if it's not contained (last) yet, so we can use it for the page title elsewhere.

A side-effect of this change will be that menu links that are explicitly NOT visible in the breadcrumb will also be appended by this code. But again, the last item in the active trail does not actually appear in the breadcrumb, so that should be fine.

In turn, we can heavily shorten the entire code comment to clarify the situation.

(Note that we normally don't put issue numbers/URLs into code comments, comments should wrap at 80 chars, and always form proper sentences [trailing period, etc])

+++ modules/simpletest/tests/menu.test	14 Dec 2010 00:24:37 -0000
@@ -33,6 +33,16 @@ class MenuRouterTestCase extends DrupalW
+  ¶

Trailing white-space.

+++ modules/simpletest/tests/menu.test	14 Dec 2010 00:24:37 -0000
@@ -33,6 +33,16 @@ class MenuRouterTestCase extends DrupalW
+   * Test title is set correctly on orphan (no parents)
+   * items of type MENU_CALLBACK and not 'Home'

1) Wraps too early.

2) Can be shortened into:

"Tests page title of MENU_CALLBACKs."

+++ modules/simpletest/tests/menu.test	14 Dec 2010 00:24:37 -0000
@@ -33,6 +33,16 @@ class MenuRouterTestCase extends DrupalW
+   * @see http://drupal.org/node/965272

+++ modules/simpletest/tests/menu_test.module	14 Dec 2010 00:24:37 -0000
@@ -16,6 +16,13 @@ function menu_test_menu() {
+  //is set correctly - @see http://drupal.org/node/965272

Please remove those issue URLs.

+++ modules/simpletest/tests/menu.test	14 Dec 2010 00:24:37 -0000
@@ -33,6 +33,16 @@ class MenuRouterTestCase extends DrupalW
+    $this->assertText('Menu Callback Orphan', t('Raw text found on the page'));

+++ modules/simpletest/tests/menu_test.module	14 Dec 2010 00:24:37 -0000
@@ -16,6 +16,13 @@ function menu_test_menu() {
+    'title' => 'Menu Callback Orphan',

Let's change this title into:

"Menu callback title"

and afterwards, remove the custom assertion message (which isn't very informative); the default is "%text found."

Note that the menu router item title is passed through t() upon output, so t() must be used for assertText().

+++ modules/simpletest/tests/menu_test.module	14 Dec 2010 00:24:37 -0000
@@ -16,6 +16,13 @@ function menu_test_menu() {
+  //This item is of type MENU_CALLBACK with no parents to test title
+  //is set correctly - @see http://drupal.org/node/965272

Missing leading space and trailing period (full-stop). See http://drupal.org/node/1354 for comment coding style details.

+++ modules/simpletest/tests/menu_test.module	14 Dec 2010 00:24:37 -0000
@@ -16,6 +16,13 @@ function menu_test_menu() {
+    'page callback' => 'node_page_default',

If node_page_default() will change in the future, this test will break, even though it's technically completely unrelated. I think there should be an existing "null" page callback somewhere in menu_test.module already that we should use here instead. Otherwise, please create a new page callback function that simply returns an empty string.

Powered by Dreditor.

larowlan’s picture

Status: Needs work » Needs review
FileSize
3.48 KB

Here is another patch with these issues remedied.
Now we don't test the menu type at all?
Should we be testing that it is not of type MENU_LOCAL_TASK or MENU_DEFAULT_LOCAL_TASK as these items should not be used for the title?

Bakidok’s picture

How I can test this patch in my drupal instalation?

larowlan’s picture

please see http://drupal.org/patch/apply
but basically
*download the file
*on the command line

cd /path/to/drupal/install
patch -p0 < /path/to/patchfile
Bakidok’s picture

Thanks larowlan.

I tested the patch (issue-96527-2.patch) and works fine on my drupal installation.

Do I have to change the status to "reviewed & tested by the community"? (It's my first time that I test a patch, sorry)

bellHead’s picture

Status: Needs review » Reviewed & tested by the community

Newest patch works for me, works for Bakidok and answers all of the concerns Sun expressed (by my reading).

It's ready.

pillarsdotnet’s picture

Jaypan’s picture

The patch from #14, issue-96527-2.patch, solves the problem for me.

webchick’s picture

Status: Reviewed & tested by the community » Needs review

This could really use one more look from sun.

sun’s picture

Status: Needs review » Needs work
+++ includes/menu.inc	28 Dec 2010 06:04:05 -0000
@@ -2303,11 +2303,18 @@ function menu_set_active_trail($new_trai
-    // Make sure the current page is in the trail (needed for the page title),
-    // if the link's type allows it to be shown in the breadcrumb. Also exclude
-    // it if we are on the front page.
+    // Make sure the current page is in the trail (needed for the page title)
+    // The title for a page is determined by taking the last item in the active
+    // path which is not a local task. The active path is seeded with a link to
+    // home and each item in the path with type MENU_VISIBLE_IN_BREADCRUMB is
+    // added to the list. At the end of this process the preferred link for the
+    // current item is added to the end of the breadcrumb if it is not of type
+    // MENU_LOCAL_TASK. Adding the preferred link to the breadcrumb trail even
+    // if it is only a MENU_CALLBACK does not have an adverse affect on the
+    // breadcrumbs as the current page is always dropped from the breadcrumb
+    // trail anyway.

We can heavily shorten this, since most of the comment explains the behavior of other functions. Something along the lines of:

Make sure the current page is in the trail to build the page title, by appending either the preferred link or the menu router item for the current page. Exclude it if we are on the front page.

(Yes, I realize that the front page situation could be explained a bit more, but that's an entirely different, weird handling, off-topic for this issue, so let's just retain the current sentence about it.)

+++ modules/simpletest/tests/menu.test	28 Dec 2010 06:04:07 -0000
@@ -33,6 +33,14 @@ class MenuRouterTestCase extends DrupalW
+  ¶

Trailing white-space.

+++ modules/simpletest/tests/menu.test	28 Dec 2010 06:04:07 -0000
@@ -33,6 +33,14 @@ class MenuRouterTestCase extends DrupalW
+    $this->drupalGet('menu_callback_title');
+    $this->assertText(t('Menu Callback Title'));

Did we test that the menu item's title does not already appear in the navigation menu or somewhere else on the page, leading to a false positive?

Instead of testing this manually, prepend the following to those test lines:

// Verify that the menu router item title is not visible.
$this->drupalGet('');
$this->assertNoText(t('Menu Callback Title'));
// Verify that the menu router item title is output as page title.
...

Powered by Dreditor.

bellHead’s picture

FileSize
1.95 KB

Rerolled with suggested changes.

bellHead’s picture

Status: Needs work » Needs review
bellHead’s picture

FileSize
3.11 KB

Rerolled with -up

Status: Needs review » Needs work

The last submitted patch, 965272.patch, failed testing.

klaus66’s picture

I have two colorbox forms. They should not show as links.

The urls are cb/form/form1 and cb/form/form2.

What is the best way todo this in the menusystem:

1. Should I use a MENU_CALLBACK and then in the formfunction call drupal_set_title('My title')
2. Should I use MENU_VISIBLE_IN_BREADCRUMB
3. Should I use MENU_NORMAL_ITEM and deactivated it in the menu system.

sun’s picture

And now that single test failure is... guess what? ;)

"Menu Callback Title" not found	     MenuRouterTestCase->testTitleMenuCallback()

Apparently, 'type' => MENU_CALLBACK, is missing in the router item definition.

larowlan’s picture

Status: Needs work » Needs review
FileSize
3.13 KB

Added type => MENU_CALLBACK however this wasn't in the earlier tests either

Status: Needs review » Needs work

The last submitted patch, 965272_0.patch, failed testing.

larowlan’s picture

FileSize
3.03 KB

Reroll

larowlan’s picture

Status: Needs work » Needs review
larowlan’s picture

Ignore my comments from before, I understand what sun is saying about why nominating MENU_CALLBACK is important, without it the default of MENU_NORMAL_ITEM would be used and hence the text would show on all pages as a menu link in the navigation.

sun’s picture

+++ includes/menu.inc	4 Jan 2011 23:02:52 -0000
@@ -2303,11 +2303,11 @@ function menu_set_active_trail($new_trai
+    // appending either the preferred link or the menu router item for the ¶

Trailing white-space.

Powered by Dreditor.

pwolanin’s picture

Sun points out that this existing function also prevents displaying the title of a local task:

http://api.drupal.org/api/drupal/includes--menu.inc/function/menu_get_ac...

which seems to have been a main point of that check. Are we sure that we won't get a local action as a page title?

sun’s picture

@pwolanin: Thanks for having a look.

Local actions are also covered by the exclusion condition in menu_get_active_title(), since MENU_LOCAL_ACTION is also MENU_IS_LOCAL_TASK. Weird, but true.

larowlan’s picture

FileSize
3.03 KB

Whitespace removed, thanks sun

pwolanin’s picture

Status: Needs review » Reviewed & tested by the community

@sun, thanks for double checking.

longwave’s picture

Subscribing, as this affects Ubercart, and bumping in the hope it will get committed after two months at RTBC.

#994112: Page titles are not set on /cart/checkout/review and /cart/checkout
#1084432: Wrong page title on checkout pages

TR’s picture

I can confirm that the patch in #37 still applies cleanly to 7.x HEAD and fixes the problem. I would change status to RTBC, but it already is ...

chrisschaub’s picture

This patch did not fix

/user/login

still shows "Home". Using Bartik theme.

TR’s picture

@schaub123: Two things:

First, that is not relevant to this issue. user/login is not a MENU_CALLBACK, it is a MENU_DEFAULT_LOCAL_TASK. The reported problem and proposed fix have to do with improper titles on MENU_CALLBACK functions.

Second, I cannot reproduce what you report. When logged out, if I visit user/login (with Bartik) I see a page title of "User account". I suggest you open a new issue if you continue to have a problem, as the behavior report is not related to the subject of this thread.

daften’s picture

subscribe

rfay’s picture

Version: 7.x-dev » 8.x-dev
Status: Reviewed & tested by the community » Needs review

D8 first. Let's get these fixed on D8 and into D7.

TR’s picture

Status: Needs review » Reviewed & tested by the community
FileSize
2.55 KB

Patch in #37 still applies in Drupal 8.x, but I re-rolled it just for fun with the latest and greatest git format.

I tested this with Ubercart running under D8 (yes, you read that correctly); The original problem still exists in D8 and the patch still fixes the problem in D8.

I should also mention I ran the menu SimpleTests with the patch applied (patch adds tests for this issue), and they all ran green.

TR’s picture

Priority: Normal » Major

I'm going to take it upon myself to upgrade the priority. Here's why:

We can't make a non-beta release of Ubercart for Drupal 7 when a bunch of the page titles incorrectly read "Home", so we're stuck in beta until this (and other things, of course) gets fixed.

Drupal 7.1 is just around the corner, and if this fix doesn't get into 7.1 it's going to be many more months before it can get fixed in D7 core.

I'd like to point out that this patch is to restore functionality that was broken by #907690: Breadcrumbs don't work for dynamic paths & local tasks #2, way before D7 was released. Pushing the bar higher by insisting this gets fixed in D8 first is just delaying the resolution of a long-known bug inadvertently introduced into D7.

I understand why issues are being moved to D8, but I don't really agree that it's the correct move for *this* issue because this issue was RBTC before D7.0 was published. By moving the issue to D8 it's going to take that much longer to get it committed to D8 first then into D7. Nothing significant runs under D8 yet so a problem that is obvious with contribs in D7 can't necessarily be reproduced in D8 yet. This results in further delays to fixing a known bug in D7.

pillarsdotnet’s picture

sun’s picture

Still looking good to me. Should apply cleanly to D8 and D7.

timtunbridge’s picture

subscribe

jsenich’s picture

subscribe

Dries’s picture

Status: Reviewed & tested by the community » Fixed

Reviewed this patch and it looks good. Committed to 7.x and 8.x.

Jaypan’s picture

I'm glad to hear that. Good news definitely.

klaus66’s picture

Now I have a problem with MENU_LOCAL_TASK.
You can see it on the user site when your are logged out.

It shows always the same title ('User account') by all three paths:

-user/register
-user/login
-user/password

I have another multilanguage site and there it shows 'Home' as title.

sun’s picture

It shows always the same title ('User account') by all three paths:

-user/register
-user/login
-user/password

That's the expected behavior. IIRC, even covered by unit tests.

klaus66’s picture

I don't think so.

When you look in the user module you can see in the hook_menu different titles.

Therefore I can't understand why it is always the same title.

larowlan’s picture

These titles are for the tabs (ie local tasks) not the page title

Jaypan’s picture

Not really relevant to this thread though - it's a different issue.

Sunday Afternoon’s picture

Thanks for this fix - I was tearing my hair out trying to understand how to create menu items using the examples in the Drupal 7 Module books. The titles were not behaving as expected and the books make no mention of the bug.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

mdshields’s picture

Is this fix applied to D7? If so, which version of D7?

Also, for MENU_CALLBACK, I understand we cannot have that particular page show up in the Menu system or navigation, because essentially it is a call back from a REFERRER page.

Therefore, is it possible, that in any instance a web site user lands on a MENU_CALLBACK page, that we show the navigation... of the REFERRER page if that page that referred the MENU_CALLBACK page is a navigation menu item? This is how breadcrumbs work on checkout pages.