Problem/Motivation

Our site requires paths to match the menu hierarchy by node title. For example I have the following menu:

Node A
- Node B
-- Node C

The url alias for node c should be "node-a/node-b/node-c"

We have a custom queue worker which, on node update, adds an nid to the queue. The queue gets processed on cron, which recursively gathers menu children for the updated node and updates the path alias for each child. What this is supposed to achieve is: when a parent changes it's title, the children will be updated on next cron run.

So if I updated "Node A" to "Node A Changed" then the url for node c would be updated to "node-a-changed/node-b/node-c"

We are using the pattern [node:menu-link:parents:join-path]/[node:title] in pathauto, which works perfectly on first node creation (both parent and child, grandchild etc). The problem is when the parent gets updated, the alias when regenerated doesn't change. I've tested this with our queue runner, deleting all aliases and bulk updating, manually deleting specific aliases and updating the node etc etc. Nothing seems to work, even adding a new child post update.

I've tried all variations of clearing the cache as well.

One token that seems to almost get it right is [node:menu-link:parent:url] which correctly uses the new url alias of the parent when regenerated. However it seems to use the absolute url of the parent which is obviously not great.

If I've missed something I'd be happy to hear the solution, I've tried stepping through the token code but it's a bit above me for the moment.

Proposed resolution

Fix or advise solution.

Remaining tasks

Code.
Tests.

User interface changes

None.

API changes

None.

Data model changes

None.

Comments

acbramley created an issue. See original summary.

Berdir’s picture

Status: Active » Closed (duplicate)

This is a duplicate of #2769299: node:menu-link:parents:join-path doesn't work as expected which has a working patch to fix this. See also my explanation there about there being a better token for your use case IMHO.

acbramley’s picture

Thanks @berdir

acbramley’s picture

Status: Closed (duplicate) » Active

As mentioned in https://www.drupal.org/node/2769299#comment-11518459 that patch didn't fix the issue for me.

Berdir’s picture

Issue tags: +Needs tests

I have no idea why the existing fixes don't fix this, we'll need a failing test to be able to debug this.

About node:menu-link:parent:url, as discussed in the other issue, it should work with node:menu-link:parent:url:relative, but the problem is that / are then encoded. Not encoding certain tokens is a feature in pathauto, see #2773573: AliasCleaner preg_match for tokens is too broad for a related issue. We need to find a way to match url:relative as well.

acbramley’s picture

Thanks @berdir, I'll see if I can get some time soon to work on a test.

LpSolit’s picture

Did you try [node:menu-link:parent:url:path] ? This may do what you want.

Berdir’s picture

I suggested something like that as well in the related issues, I used :relative which didn't work because of the mentioned issue above. path might have a problem with not getting you the alias, not sure. but :relative might also include the url prefix.

imadalin’s picture

I don't think that token should be responsible for hooking in the node save and iterate through all children in the menu.
I admit that the expected functionality is not working, as I'm working on a project that we need to achieve the same.
It needs some thoughts on how to be approached.

This token might not be used in pathauto always, as it might be used in other places, as it is a token and not complete functionality to something that somebody thinks of.

PS: on Drupal 8.2.7 with Token 8.x-1.0-rc1, if manually saving the child of a parent, the Path is updated.

acbramley’s picture

@imadalin I agree, that's not what I was proposing. As explained in the issue summary, we had a custom queue worker that would do this. Manual saving works fine but automated updates didn't.

imadalin’s picture

@acbramley do you have a hint for how you're doing the "worker" or is something you'd not share?
I'd like to work on something similar when I get some free time for this.