When setting pathauto to generate an alias based on the menu,[menu-trail-parents-path-raw]/[title-raw], the special menu item will not be transliterared.
I am not sure whether this should be passed to the pathauto issue queue.

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

Anonymous’s picture

for now I added a quick and dirty hook which is absolutely not solid because I have no idea how to check if a certain part of an alias belongs to a special menu item link.

function special_menu_items_pathauto_alias_alter(&$alias, $context) {
  // Check if we are using the menu-trail token
  if (strpos($context['pattern'], '[menu-trail-parents-path-raw]') !== false) {
    // Find the position of the pattern
    $patterns = explode('/', $context['pattern']);
    $alias_parts = explode('/', $alias);
    $key = array_search('[menu-trail-parents-path-raw]', $patterns);
    
    $alias_part = $alias_parts[$key];
    
    if (drupal_lookup_path('source', $alias_part) === false) {
      // This is not an existing alias
      // We can assume that thiis is a special menu item path
      // we should transliterate the alias
      $alias_parts[$key] = pathauto_cleanstring($alias_part);
      $alias = implode('/', $alias_parts);
    }
  }
}
gagarine’s picture

Category: bug » support
Status: Active » Closed (works as designed)

Special menu item are not link so they should note have aliases and should not passe trow transliterate

If I didn't understand please reopen.

Anonymous’s picture

Status: Closed (works as designed) » Active

Here is the usecase:
setup pathauto to generate node alias like:
[menu-trail-parents-path-raw]/[title-raw]

You will end up with non transliterated url-parts for the special menu items.
Again, I am not sure if this is a pathauto issue or a special menu items issue.

melissavdh’s picture

I have used the following:

<?php
function special_menu_items_pathauto_alias_alter(&$alias, &$context) {

  // split the alias into its components
  $url = explode('/', $alias);

  // get all the <nolink> link titles from the database
  $no_links = db_query('SELECT link_title FROM menu_links WHERE link_path = :nolink and menu_name = :mainmenu', array(':nolink' => '<nolink>', ':mainmenu' => 'main-menu'))->fetchCol();

  // if there are <nolink>s defined
  if (!empty($no_links)) {
    // define an array to hold the cleaned <nolink> titles
    $clean_no_link = array();
    // foreach <nolink>
    foreach ($no_links as $no_link) {
      // pathauto_cleanstring will output the title as it would appear in the URL
      $clean_no_link[] = pathauto_cleanstring($no_link);
    }
  }

  // now check if any of the cleaned <nolink> title strings appear in the current alias
  foreach ($url as $position => $argument) {
    if (in_array($argument, $clean_no_link)) {
      unset($url[$position]);
    }
  }
  // run url through array values to re-index in case we have removed one or more elements
  $url = array_values($url);

  // now implode the $url array back into an alias string
  $alias = implode('/', $url);

}
?>
noah’s picture

Version: 6.x-1.x-dev » 7.x-2.0

Not sure if I've misunderstood the problem, but none of the solutions above fixed the issue for me (in D7). I have a resolution that works (I think), so here it is in case it's useful to anyone.

The pattern I'm using in pathauto is:

[node:menu-link:parent:url:path]/[node:menu-link:title]

When a page is created that is a child of a special menu item, the generated URL looks like, e.g.:

<nolink>/about-us

The following function iterates through all possible parents, looks at the matching chunk of the alias, and transliterates it if it's equal to "<nolink>":

function example_module_pathauto_alias_alter(&$alias, &$context) {
  $alias_parts = explode('/', $alias);
  if (isset($context['data']['node']->menu)) {
    // iterate through all possible parents -- adding 1 for the "p" level, so stop $i at 8
    for ($i = 0; $i <= 8; $i++) {
      if (isset($alias_parts[$i]) && ($alias_parts[$i] == '<nolink>')) {
        $p = $i + 1;
        $mlid = $context['data']['node']->menu["p{$p}"];
        if (($mlid != 0) && ($item = db_query('SELECT link_title FROM menu_links WHERE mlid = :mlid', array(':mlid' => $mlid))->fetchField())) $alias_parts[$i] = pathauto_cleanstring($item);
      }
    }
  }
  $alias = implode('/', $alias_parts);
}

Note that this doesn't work for bulk updates, only when paths are generated automatically when creating or editing a node.

vrajak@gmail.com’s picture

@noah,

Not sure how to implement this? Do I need to make a custom module? Or a module & have this in my template.php ? Some direction would be great.

noah’s picture

It goes in a custom module.

aaronbauman’s picture

Category: Support request » Bug report
Issue summary: View changes

IMO this is a bug.
Special menu items should prevent this from happening - should not require a separate module.

seanb’s picture

It would be nice to be able to configure this somewhere. I think there are 2 options to handle this:
- Remove the part from the pathauto alias
- Replace the part with the display title

It would be nice to add this to the module. I will try to create a patch for both options.

seanb’s picture

Status: Active » Needs review
StatusFileSize
new2.12 KB
seanb’s picture

Added some extra code to always remove separator menu items from the alias (just in case, these probably wont have child menu items anyway).

Adamation’s picture

Hi SeanB I've applied this patch and I can see the new options:

Pathauto action for "nolink"
[] Replace by menu link title
[] Remove from alias
By default, Pathauto does not transliterate special menu items. Here you can specify how pathauto should handle "nolink" items.

However, when saving a node, the automatic URL alias still contains the title of the menu item.

For example my menu is as follows
- About Us {nolink}
-- Link 1
--- Link 1.1
--- Link 1.2
-- Link 2

When I assign a node to the menu I'd expect the PathAuto and your patch to make the URL become

www.mysite.com/link-1/link-11

However I'm still getting

www.mysite.com/about-us/link-1/link-11

Problem is About Us isn't a page, so we don't want it in the URL.

Thanks

Adam

gagarine’s picture

Status: Needs review » Needs work
spadxiii’s picture

Status: Needs work » Needs review

I just applied patch #11 to 7.x-2.0 and it works great. Not that existing aliases aren't updated (automatically), but that's outside this patch's scope.

Also note that I have this alias pattern set up: [node:menu-link:parent:url:path]/[node:title]
When using [node:menu-link:parents:join-path]/[node:title], the no-link menu items are joined in the url with their menu titles.

I'm setting this back to needs review so that someone else can have another look. From what I can see, the patch works fine.

euskarez’s picture

I have the same problem.
I need to exclude from url menu item that is nolink but I need also to have in the url all the parents of a node until the root of my site.
[node:menu-link:parent:url:path]/[node:title] work with tha patch but use only the direct parent of the node.
[node:menu-link:parents:join-path]/[node:title] creates url with all parents but not work with the patch.
someone have any solution?
thanks!

gagarine’s picture

+++ b/special_menu_items.module
@@ -161,6 +161,13 @@ function special_menu_items_admin_settings_form() {
+    '#options' => array('replace' => t('Replace by menu link title'), 'remove' => t('Remove from alias')),

I don't understand why we need two option. We can only have on checkbox "Use the special menu item title in pathauto" and by default removing it...

gagarine’s picture

Status: Needs review » Needs work
spadxiii’s picture

I just ran into an issue with this patch: after saving a new node, the user is redirected to the homepage.
I traced it back to node_access returning a FALSE when setting up the form-redirect. This is because during the node_save, a node_access call is made before the node is fully saved. This then stores a FALSE in the drupal_static of node_access.

The cause of this early node_access call is this line: $menu = menu_link_get_preferred($context['source']);

Attached is a patch where I delayed the call when it is actually needed. Other than this, it's the same patch as #11.

I'm leaving this on 'needs work' because I agree with @gagarine that there should only be a single option for replacing with the title and remove by default.

ps. I also fixed a query-mistake and added { } around the table name.

seanb’s picture

I agree that we really only need 1 checkbox. Since the default will then be removing the special menu items, do we need any update hooks or anything to make sure we don't break anything?
I'm not sure if the default behaviour should be removing special menu items, or if we should replace with the title by default.
Any ideas? When we make a choice I can update the patch accordingly...

seanb’s picture

Sorry, I see gagarine proposes to remove by default. I will update the patch!

gagarine’s picture

Version: 7.x-2.0 » 7.x-2.x-dev

Please work on the -dev version. When this one go in I will release a new stable version.

seanb’s picture

Status: Needs work » Needs review
StatusFileSize
new2.16 KB

New patch is attached, showing only a checkbox to choose if you want te replace special menu items in pathauto aliasses. The special menu items are removed by default.

gmaxwelled’s picture

The patch doesn't appear to work for me, I'm afraid. Have tried saving the configuration form with the box checked and without, and saving the nodes multiple times and creating a new node, but it always adds in the special menu item in the URL..

spadxiii’s picture

@gmaxwelled: did you clear the cache after applying the patch? The patch adds a new hook-implementation which would probably not be picked up without a cache clear.

ps. I haven't reviewed the patch myself. Hiding my patch-file because the last one should be better :)

aitala’s picture

I have applied Path #22 to -dev and it also does not work for me. Neither did Patch # 18.

I am using the token [node:menu-link:parents:join-path]/[node:title]

I have cleared all the caches and such.

Eric

timfletcher’s picture

I ran into this recently, the issue for me was in Pathauto. I ended up using this as a workaround: https://www.drupal.org/project/special_menu_items/issues/1485784#comment...

Update PathAuto to v2.0 and use the page path token:
[node:menu-link:parents:join-path]/[node:title] instead of
[node:menu-link:parent:url:path]/[node:title]

However, this can introduce new issues in some situations; Parent pages that have a custom-defined URL i.e. not relying on Pathauto, will show up in the URL path as a transliterated path, e.g.

My great page (great)
L My child page (child)

When visiting 'My child page', the URL should read mysite.com/great/child, but instead reads mysite.com/my-great-page/child

gagarine’s picture

Status: Needs review » Needs work

Uzdrupaller made their first commit to this issue’s fork.

Uzdrupaller’s picture

StatusFileSize
new2.62 KB

#11 patch was broken after 7.x-2.x-dev release 23 march. Adding patch that works with new version.