Problem/Motivation

We don't want nolink items to be added into our url path - presently, using the join path token adds the title for said items as an argument in the url path.

We also don't want our alias to be created from transliterated menu titles, rather, they should be created from menu parent paths.

Steps to reproduce

This occurs when bulk updating, or saving nodes individually.

Proposed resolution

Add two new tokens, ala:
1) join-path-exclude-no-links that omits item url args for continuing with transliterated menu title pattern

2) menu-path-use-parent-url that omits item url args for continuing with transliterated menu title pattern and uses menu parent path.

Issue fork pathauto-3214658

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:

  • 3214658-join-path-token-adds Comparecompare
  • 8.x-1.x Comparecompare

Comments

EthanT created an issue. See original summary.

ethant’s picture

StatusFileSize
new3.83 KB
ethant’s picture

Status: Active » Needs review
ethant’s picture

Issue summary: View changes
ethant’s picture

Title: join-path token adds <nolink> menu items to url path » join-path token adds <nolink> menu items to url path and path generated is created from menu titles, not parent path links
ethant’s picture

Issue summary: View changes
ethant’s picture

Adding patch that creates second token for using menu parent entity path instead of transliterated menu title path.

ethant’s picture

ethant’s picture

ethant’s picture

deaom’s picture

Hm, maybe I'm doing something wrong, so steps to reproduce would be appreciated.
I can see the reported issue with the url alias being as home/nolink/node but the patch does not correct that. I tested both tokens, and with the first one ([node:menu-link:parents:join-path-exclude-no-links]), I get the url alias as /homenolinknode
and with the second one ([node:menu-link:parents:menu-path-use-parent-url]), I get /homenolink-0. I assume intention was to be like home/node.
My menu items are

Home
   ->nolink
        ->Node
            ->Child

Not sure how it's suppose to work, so steps to reproduce and test would be great. Leaving it to needs review.

retiredpro’s picture

StatusFileSize
new5.83 KB

Thanks, EthanT. Patch #10 got me close but I ran into some issues. I'm on Drupal 9 if that matters.

Pattern setup was originally setup as:
[node:menu-link:parents:join-path]/[node:title]

After the patch, I updated it to:
[node:menu-link:parents:join-path-exclude-no-links]/[node:title]

$db = \Drupal::database();
// Get all the <nolink> link titles from our
// current menu (first in values array).
$query = $db->select('menu_link_content_data', 'mlcd')
  ->fields('mlcd', ['title']);
$or = $query->orConditionGroup()
  ->condition('link__uri', '%' . $db->escapeLike('internal:/nolink') . '%', 'LIKE')
  ->condition('link__uri', $db->escapeLike('route:') . '%', 'LIKE');
$query->condition($or)
  ->condition('menu_name', $values[0]);
$no_links = $query->execute()->fetchCol();
$values = [
  0 => 'more',
  1 => 'about',
]

$values[0] is the top parent path alias. Since this does not matches the menu_name, the last conditional is never met. I had to remove the following line.
->condition('menu_name', $values[0]);

In my testing, the following are picked up as the menu items

$clean_no_links = array_unique($clean_no_links_raw);

[
  0 => '/more',
  1 => '/plan-your-trip',
  2 => '/fares',
]

It is then str_replaced against

$alias_raw = implode('/', $values);
$alias = str_replace($clean_no_links, '/', $alias_raw);

The expected behavior is that '/more' is removed my URL but it actually does not match because the $alias_raw 'more' does not have a preceding forward slash.

$alias_raw = 'more/faqs';

Even if adjusted, theres a potential issue of targeting the wrong alias in the URL if duplicate alias used. For example, on my site I have the same page title listed under the parent with the nolink. So in the below example, both "about" would get removed.

About (nolink)
  - About (node/1)
  - Contact (node/2)

I attached a patch that approaches 'join-path-exclude-no-links' token in a different way. It loads the uuid of the menu link and checks to see if it is a nolink. If it is, then it's not included in the $values. This should prevent any potential issues removing non nolink aliases that share the same name.

I haven't the "tested menu-path-use-parent-url" token so I can't provide feedback on that one.

retiredpro’s picture

DeaOm, you may need to update your PathAuto module settings.
/admin/config/search/path/settings

I had to add "join-path-exclude-no-links" under the Safe Tokens textarea field. Otherwise the parent aliases ended up getting the forward slashes stripped out when on a page that is several layers nested on the menu.

rolandoscott’s picture

#12 patch works great.. its exactly what I needed.. along with the instructions on #13

such a lifesaver.. this should come by default.. if you have a menu item, theres a good chance you don't want that in the URL..

segx’s picture

I tested join-path-exclude-no-links. Patch #12 worked for me, but I needed to uninstall and reinstall Pathauto. Simply adding the token to the Safe Tokens field, as noted in comment #13, did not work for me. Thank you for everyone's work on this!

bohus ulrych’s picture

Wow, great work! It helped me a lot, thanks.

What I did to make this work:
1) apply patch
2) clear cache
3) updated Safe tokens on the /admin/config/search/path/settings with both join-path-exclude-no-links, menu-path-use-parent-url
4) created my pattern e.g. [node:menu-link:parents:menu-path-use-parent-url]/[node:title]
5) from the Content (/admin/content) page I updated URL aliases

segx’s picture

I updated the Pathauto module today (1.9.0 => 1.10.0) with patch #12 and received the error:

Could not apply patch! Skipping. The error was: Cannot apply patch https://www.drupal.org/files/issues/2021-10-20/remove-nolinks-3214658-12...

Was this issue resolved?

ethant’s picture

Re-rolling for version 1.10

segx’s picture

Patch #18 was successfully installed for me. Thank you!

retiredpro’s picture

StatusFileSize
new5.74 KB

Thanks for re-roll EthanT. Looks like a comma was accidentally added to the safe token name. Uploading a patch without the comma.

anoopsingh92’s picture

Assigned: Unassigned » anoopsingh92

Reviewing #20

anoopsingh92’s picture

Assigned: anoopsingh92 » Unassigned
StatusFileSize
new30.34 KB

HI @retiredpro, I reviewed your patch #20. It is applying successfully for me.
Patch #20
Thanks for the patch.

bvoynick’s picture

Status: Needs review » Needs work
StatusFileSize
new5.73 KB

The reroll also missed pathauto_token_info(), without which the tokens are not shown in the token browser and will fail validation in the UI.

Setting back to needs work because I also see a problem in the handling for menu-path-use-parent-url: it is assumed loadLinksByRoute() will find at least one result, but that is not a safe assumption. I believe the line

$parent = $menu_link->getParent();

currently will fatal if there are no menu links found.

Edit: my bad, I missed the changes to other files besides pathauto.tokens.inc. This is not an acceptable reroll either.

bvoynick’s picture

arantxio’s picture

Version: 8.x-1.8 » 8.x-1.11
StatusFileSize
new5.68 KB
new1.16 KB

I've adjusted the patch that @bvoynick made in comment #23 for our customer.

It adjusts the query so that it doesn't query on the values on the menu_name row. This way it returns all values with a 'nolink' parameter.

Also i've moved the clean_no_links_raw variable to the top of the case, so that when $no_links is empty it will not throw an error for an empty array.

This patch works for us on the latest 1.11 build.

jimmynash’s picture

Applying patch in #25 works for me on version 1.11.

Very useful patch! Thanks!

arantxio’s picture

StatusFileSize
new5.73 KB
new521 bytes

On one of our sites the alias is missing some slashes which made the logic not work for it. I've adjusted the patch to match this logic. Might also be useful for someone else.

arnaud-brugnon’s picture

#25 is not a good idea.
For some reasons (for my client for example), there is the same label in multiple link contents but some have links and other don't.

With #25, my alias is empty.
But it should not be.

kevinquillen’s picture

Patch in #27 appears to work for join-path exclude no links.

kevinquillen’s picture

I don't know what changed though - we don't have this issue in a Drupal 9 project. is ignored when generating aliases with Pathauto.

mably’s picture

These tokens are not directly related to pathauto and should probably be hosted elsewhere.

samijuv’s picture

We've been running patch #27 and hit a bug with the join-path-exclude-no-links token: str_replace performs a plain substring match, so a no-link title like "service" would be stripped not only from its own segment /service but also from any segment that contains it as a substring, e.g. /service/customer-services would become /customer-s.

Suggested fix is to replace str_replace with preg_replace using a lookahead (?=/|$) so the no-link title is only matched at a path segment boundary (followed by / or end of string).

I've attached an updated patch (remove-no-links-fix-partial-segment-match.patch) based on #27 with this fix applied.

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

esthertempel’s picture

StatusFileSize
new5.42 KB

Re-roll of #32 against the latest changes in 8.x-1.x. Tested locally on Drupal 11.3.9 with Pathauto 1.15.0.