I would like to use the [menupath-raw] in the pathauto module like [menupath-raw]/[title-raw] but [menupath-raw] contains the current node's menu title so there will be duplicated information in the url about current node: menuparent1/menuparent2/currentnodemenuitemtitle/currentnodetitle

I woult like to get in the url (after menu parent titles) one of the node's title or node's menu title.
e.g:
menuparent1/menuparent2/currentnodetitle
or
menuparent1/menuparent2/currentnodemenuitemtitle

I can't use only [menupath-raw] because nodes which doesn't have menu entry will not have path because [menupath-raw] returns nothing.

How can I create a token like [menupath-raw] without the last (current) item?
Or.. Any other solution welcomed.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

alison’s picture

subscribing... would love to get help with this as well!!

svihel’s picture

Subscribing

jweowu’s picture

Title: [menupath-raw] without current node » A variant of [menupath-raw] which excludes the current node, or a token which provides [title-raw] when [menupath-raw] is empty
Category: support » feature

+1 for either some kind of [titleless-menupath-raw] token (so that we can use [titleless-menupath-raw][title-raw] -- the absence of a slash between the tokens is important for when there is no menu item), or else something like the following (which I have as a separate pathauto_titletoken.module, but would be much better if integrated into token_node.inc)

It might even be nice to have both tokens, because the title used when [menupath-raw] is populated could be different to the [title-raw] title.

/**
 * @file
 *   Provides [title-or-menupath-raw] token for pathauto titles.
 */

/**
 * Implementation of hook_token_list().
 */
function pathauto_titletoken_token_list($type = 'all') {
  if ($type == 'node' || $type == 'all') {
    $tokens['node']['title-or-menupath-raw'] = t("A path-auto token returning [menupath-raw] if applicable, and [title-raw] if not.");
    return $tokens;
  }
}

/**
 * Implementation of hook_token_values().
 *
 * Replacement for ['title-or-menupath-raw'], for use with pathauto.
 * The 'path-raw' suffix is important: @see pathauto_clean_token_values().
 * Otherwise the '/'s are stripped from the alias.
 *
 * Code is adapted from node_token_values() in token_node.inc
 */
function pathauto_titletoken_token_values($type, $object = NULL) {
  $values = array();
  if ($type == 'node') {
    $node = $object;
    if (!empty($node->menu['mlid'])) {
      if ($menu_link = menu_link_load($node->menu['mlid'])) {
        $trail_raw = _menu_titles($menu_link, $node->nid);
        $menupath_raw = implode('/', $trail_raw);
      }
    }
    $values['title-or-menupath-raw'] = !empty($menupath_raw) ? $menupath_raw : $node->title;
  }
  return $values;
}
peterjmag’s picture

Title: A variant of [menupath-raw] which excludes the current node, or a token which provides [title-raw] when [menupath-raw] is empty » [menupath-raw] without current node
Category: feature » support

Subscribing, so I can link people with the same question to this issue. I also wrote a custom module to achieve the same thing, but jweowu's code in #3 is much more elegant. :)

jweowu’s picture

FileSize
4.12 KB

Here's a patch for token_node.inc to integrate [title-or-menupath] and [title-or-menupath-raw] (which is completely trivial, done this way).

peterjmag: Was there a particular reason you reverted the issue title and category? It's definitely a feature request, and the other title seemed rather more descriptive.

jweowu’s picture

Category: support » feature
Status: Active » Needs review
peterjmag’s picture

Title: [menupath-raw] without current node » A variant of [menupath-raw] which excludes the current node, or a token which provides [title-raw] when [menupath-raw] is empty

jweowu: My apologies, I don't know how that happened!

jweowu’s picture

Cross-linking to #640136: [menupath] / [menupath-raw] omits menu link title of new node in some circumstances in case it helps anyone.

There's an updated version of the module code from #3 in that issue.

ddanier’s picture

Subscribing

vadimk’s picture

@jweowu - the code for [title-or-menupath-raw] above does not work when doing "Bulk generate aliases for nodes that are not aliased". $node->menu is not in $node in this case.
I modified it.

/**
* @file
*   Provides [title-or-menupath-raw] token for pathauto titles.
*/

/**
* Implementation of hook_token_list().
*/
function pathauto_titletoken_token_list($type = 'all') {
  if ($type == 'node' || $type == 'all') {
    $tokens['node']['title-or-menupath-raw'] = t("A path-auto token returning [menupath-raw] if applicable, and [title-raw] if not.");
    return $tokens;
  }
}

/**
* Implementation of hook_token_values().
*
* Replacement for ['title-or-menupath-raw'], for use with pathauto.
* The 'path-raw' suffix is important: @see pathauto_clean_token_values().
* Otherwise the '/'s are stripped from the alias.
*
* Code is adapted from node_token_values() in token_node.inc
*/
function pathauto_titletoken_token_values($type, $object = NULL) {
  $values = array();
  if ($type == 'node') {
    $node = $object;
    $mlid = db_result(db_query_range("SELECT mlid FROM {menu_links} WHERE link_path = 'node/%d' AND module = 'menu' ORDER BY mlid ASC", $node->nid, 0, 1));
    if (!empty($mlid)) {
      if ($menu_link = menu_link_load($mlid)) {
        $trail_raw = _menu_titles($menu_link, $node->nid);
        $menupath_raw = implode('/', $trail_raw);
      }
    }
    $values['title-or-menupath-raw'] = !empty($menupath_raw) ? $menupath_raw : $node->title;
  }
  return $values;
}

vadimk’s picture

#5: token-519834-5.patch queued for re-testing.

vadimk’s picture

Automatic alias is not taking into account the new menu title when updating the node. Really annoying. Seems like an issue with the pathauto module or the order of modules being executed. I fixed it by getting the menu link title from $_POST. Not sure if there is a better solution.

<?php
function pathauto_titletoken_token_values($type, $object = NULL) {
  $values = array();
  if ($type == 'node') {
    $node = $object;
    $mlid = $node->menu['mlid'];
    if (empty($mlid)) {
      $mlid = db_result(db_query_range("SELECT mlid FROM {menu_links} WHERE link_path = 'node/%d' AND module = 'menu' ORDER BY mlid ASC", $node->nid, 0, 1));
    }
    if (!empty($mlid)) {
      if ($menu_link = menu_link_load($mlid)) {
        $trail_raw = _menu_titles($menu_link, $node->nid);
        $menu_link_title = isset($_POST['menu']['link_title']) ? $_POST['menu']['link_title'] : null;
        if (!empty($menu_link_title)) {
          $trail_raw[count($trail_raw) - 1] = $menu_link_title;
        }
        $menupath_raw = implode('/', $trail_raw);
      }
    }
    $values['title-or-menupath-raw'] = !empty($menupath_raw) ? $menupath_raw : $node->title;
  }
  return $values;
}
?>
Poieo’s picture

Subscribing...

grendzy’s picture

subscribing

arcaneadam’s picture

Status: Needs review » Reviewed & tested by the community

Any chance of getting this patch added to a new release? It works. I've been doing the exact same thing through an extra module forever. I'd say it's RTBC.

xjm’s picture

Tracking. I think I submitted a patch for this one back in 5.x... will test the current patch.

j-worker’s picture

#5: token-519834-5.patch queued for re-testing.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, token-519834-5.patch, failed testing.

xjm’s picture

Looks like the patch needs to be re-rolled against the current dev branch.

gooddesignusa’s picture

subscribing

Dave Reid’s picture

Marked #566326: Add support for menu path without the title as a duplicate of this issue.

askibinski’s picture

FileSize
637 bytes

Just a quick patch against latest 1.x-dev which just replaces the existing menupath token output instead of introducing a new token.
Maybe not the most elegant solution, but probably what most people need.

jweowu’s picture

askibinski: that can't actually be merged into the 1.x branch, though -- it would break the behaviour of existing sites.

KhaledBlah’s picture

subscribing

zmove’s picture

#22 don't seems to work (with pathauto). I cleared all the aliases, regenerated them, but [menupath-raw] continue to include the node title.

KhaledBlah’s picture

First of all, thanks to all contributors!

I have edited the code from #3 and #10 according to my needs. Maybe this is useful to somebody else. The pathauto and the transliteration modules are needed for this.

My goal was:

  • to make sure that pathauto settings like transliteration and lower cases are taken into account. Also pathauto seems to ignore the node language while transliteration which leads to German umlaute like 'ö' to be transliterated to 'o' instead of 'oe'.
  • the alias to be lower case only which might not be what you want.

comments welcome!

/**
 *  helper function for hook_token_values which cleans up a string
 *  according to pathauto settings
 */
function _my_cleanstring($string, $object = NULL) {
  $output = $string;

  if ( function_exists('transliteration_get') ) {
    if ( !empty($object) && !empty($object->language) ) {
      $output = transliteration_get($output, '?', $object->language);
    }
    else {
      $output = transliteration_get($output);
    }
  }
 
  if ( function_exists('pathauto_cleanstring') ) {
    return pathauto_cleanstring($output);
  }

  return $output;
}

/**
* Implementation of hook_token_values().
*
* Replacement for ['title-or-menupath-raw'], for use with pathauto.
* The 'path-raw' suffix is important: @see pathauto_clean_token_values().
* Otherwise the '/'s are stripped from the alias.
*
* Code is adapted from node_token_values() in token_node.inc
*/
function <yourmodule>_token_values($type, $object = NULL, $options = array()) {
  $values = array();
  if ($type == 'node') {
    $node = $object;
    $mlid = $node->menu['mlid'];
    $menupath_raw = '';

    if ( $node->status ) {
      if ( empty($mlid) ) {
        $mlid = db_result(db_query_range("SELECT mlid FROM {menu_links} WHERE link_path = 'node/%d' AND module = 'menu' ORDER BY mlid ASC", $node->nid, 0, 1));
      }

      if ( !empty($mlid) ) {
        if ($menu_link = menu_link_load($mlid)) {
          $trail_raw = _menu_titles($menu_link, $node->nid);

          // use pathauto cleanup for all path components
          foreach($trail_raw as $key => $trail) {
            $trail_raw[$key] = _my_cleanstring($trail, $node);
          }

          $menupath_raw = implode('/', $trail_raw);
        }
      }
    }

    $values['title-or-menupath-raw'] = !empty($menupath_raw) ? $menupath_raw : _my_cleanstring($node->title, $node);
  }

  return $values;
}
xjm’s picture

Status: Needs work » Needs review
FileSize
4.66 KB

Reroll of #5 that actually applies.

xjm’s picture

butler360’s picture

This is exactly what I've been looking for. Subscribing.

Dave Reid’s picture

Status: Needs review » Needs work

How about we make this [node-menu-parent-path] so that it only uses the menu path of the node's parent menu item, so that way you're free to use [node-menu-parent-path]/[title] ?

butler360’s picture

Sounds fine to me as long as it accomplishes the same: just [title] if the node isn't part of a menu, and the entire menu path/title if it's part of a menu.

jweowu’s picture

Which it wouldn't do, surely. You'd get /[title] instead of [title]

xjm’s picture

Hm. Seems like a double slash or a slash at the beginning of a URL alias is something our cleanup should fix.

I personally use the token in #289630: Add [node-menu-parent-alias] token because it accurately reflects the implied menu hierarchy even if I've customized the alias of a parent page. I just tested it and creating a page entitled "Moo Cows" that has no menu item gives the page the URL https://example.com/moo-cows. No double slash. I'm not sure if it's token, core, or pathauto that's fixing that, but it seems to work fine, so maybe we can call this a dup of #289630: Add [node-menu-parent-alias] token?

Edit: I can think of two other cases to consider:

  1. Patterns like content/[node-menu-parent-alias]/[title] (is there a double slash in the middle?), or
  2. Using that token pattern with something other than pathauto/URL alias generation (I can't think of a use case, but it's possible that the behavior might be different).
Jackinloadup’s picture

Subscribe. This is great! Thanks all!

dave_robinson’s picture

The title values are the wrong way around in #27s patch

        $values['title-or-menupath-raw'] = $values['title'];
        $values['title-or-menupath']     = $values['title-raw'];

Should probably be

        $values['title-or-menupath-raw'] = $values['title-raw'];
        $values['title-or-menupath']     = $values['title'];
welly’s picture

It seems that this patch doesn't clean the title if the token doesn't match a path so while a node that sits in a menu the url alias generated may be 'about-us/testing-title' - if this same node DOESN'T live in a menu, the alias generated becomes 'Testing title'. I'll try and fix the patch but if anyone gets to this before me, that would be great too!

ericbroder’s picture

Patch #22 works for me when I run Pathauto. It fixes the problem "I can't use only [menupath-raw] because nodes which doesn't have menu entry will not have path because [menupath-raw] returns nothing."

Comment #23 may still be a valid point though. Other comments also seem to imply that patch #22 doesn't solve the problem.

I think comment #25 is a misunderstanding, the expected behavior of the patch is for [menupath-raw] to include the node title.

Dave Reid’s picture

While patching #333590: Node menu token fails (node grants not saved yet, menu access checking, oh my!) I notice that the [bookpath] token excludes the current node title, but our [menupath] tokens do include it. So we have a fairly fundamental difference in functionality between the two tokens. The Pathauto-provided [catpath] also does include the current term in the path. :/

Dave Reid’s picture

Priority: Normal » Major
modernaut’s picture

FileSize
4.78 KB

Dave Reid had an excellent point in #30; My initial thoughts were on this as well.

I worked up a solution, and proposed two new tokens, [menupath-parents] and [menupath-parents-raw].

For example, you can place this text in your URL alias settings:
[menupath-parents-raw]/[title-raw]

And you should have the desired behavior in your URLs now.

Note:
At first, I created an exception to handle whether or not the '/' character should be provided at the end, which would handle some people's worries that [menupath-parents-raw]/[title-raw] would return /[title-raw] if no parent was present (i.e. you'd simply place [menupath-parents-raw][title-raw] in there, and the code will handle the rest). However, I noticed that there's already some error checking to remove any unwanted '/' characters.

Let me know if there's any issues with this..

modernaut’s picture

FileSize
5.09 KB

I've added some new changes to the patch to assess a thrown error when menupath values are strings..

I've built two sites thus far with these tokens - works like a charm for me.

Let me know how this looks to you.

modernaut’s picture

Status: Needs work » Patch (to be ported)
jweowu’s picture

Status: Patch (to be ported) » Needs review

Fixing invalid status change.

Status: Needs review » Needs work

The last submitted patch, menupath-parents.patch, failed testing.

modernaut’s picture

FileSize
5.09 KB

Let's try this one..

Jackinloadup’s picture

Status: Needs work » Needs review

started testing

modernaut’s picture

I'm clearly not writing the patch correctly, although the code I'm trying to apply should work fine.. Maybe one of you guys could take a stab at it.

Status: Needs review » Needs work

The last submitted patch, menupath-parents.patch, failed testing.

jweowu’s picture

Instructions for creating patches can be found under the Git instructions menu tab on the main page of every drupal.org project. Follow those, and you'll be fine.

modernaut’s picture

Just a note... With the new upgrade to the Token module ( 6.x-1.16 ), it looks like using [menu-link-parent-path-raw]/[title-raw] will achieve the behavior we're looking for.

Details can be found here:
http://drupal.org/node/289630

Nonetheless, please let me know if there's any issues with that method.

amitgarg’s picture

Hi,

put the below line in path & put your desire title

http://#

Thanks,
Amit Garg
amit@highpixel.in
http://highpixel.in

Anonymous’s picture

I can confirm that simply using [menu-link-parent-path-raw]/[title-raw] achieves the desired result

jweowu’s picture

modernaut, jackocnr: how can a string with a hard-coded '/' in it achieve the desired result? (i.e. surely that approach breaks whenever [menu-link-parent-path-raw] is empty?)

Anonymous’s picture

Nope - it works fine when [menu-link-parent-path-raw] is empty (i.e. there is no extra slash in the resulting URL). I couldn't tell you why tho - maybe pathauto automatically removes it, or maybe it's the fact that I have global redirect on, and that automatically removes redundant slashes?

Dave Reid’s picture

Priority: Major » Normal
bluegeek9’s picture

Issue summary: View changes
Status: Needs work » Closed (outdated)