1

I have made 2 custom tokens that I use to determine the URL alias in the Pathauto pattern. They work fine too, but since my custom tokens rely on certain (taxonomy) fields in the node, they always get the "old" field value when the user changes them. The url alias isn't correct until the second time I save the node. Thus I need to "presave" the node immediately when the user changes the field value, so that the new token value is taken into consideration when saving the node... How can I do that?

Since the change is done on the client side I would need to use Ajax to call node_save or hook_node_presave directly when the field value is changed?

Any help is appreciated :-)

EDITED: I have realized that I probably need to write a JS script that uses ajax to call a php function that saves the node when the field is changed. So the question now is if that is wise to do when the user is in the editing mode… ?

Edited again:

I finally worked it out. I skipped the JS solution and opted for using field_attach_presave('node', $node) and field_attach_update('node', $node) in the function hook_node_presave. Doing so permits to save 2 specific fields programmatically just before the node is saved definitely by the user. And Pathauto can use those 2 fields as tokens for my URLs. It works too :-). There are many reasons for this non straight-forward solution, a bit to lengthy to explain here (migration is involved among other tings). But I am happy with this solution. Thanks for the input though!

  • Why bother with JavaScript? It should also work to save the node again (2nd time) once the user submits it right? – Neograph734 Mar 10 '16 at 15:22
  • It would be usefull to post your code, the need to save twice points more towards some error in the logic/implementation. A plain Drupal installation with Pathauto takes does not have this problem, i.e. a taxonomy term on a node is immediately available as a token in the URL pattern. About your EDIT, I would advise against such a workaround, you should work with Pathauto, not around it ;) – Stefanos Petrakis Mar 10 '16 at 16:44
  • What I am trying to do is to give the Pathauto module something to work with. Unfortunately there are no tokens available to implement what I am trying to acheive and yes I have installed the "taxonomy entity index module" which in fact can give me the taxonomy term, but not the vocabulary. I have also tried the tokens entity modulem without any luck. My custom token gives me the vocabulary name because there is no field in the node for that. But if you think that I should avoid the js solution I am listening. I don't want to do anything stupid :-) – TBJ Mar 10 '16 at 19:01
3

Happy you solved it without walking around it via AJAX, I think it was a good call. I am still gonna pick up on this thread though, simply out of stubbornness, please bear with me. :-)

So, your hook_node_presave entry point is fine and in all practical aspects you probably will not need to read further down. However, your tokens should have been available from the very beginning to Pathauto. The problem was - following your code from this revision - the use of the menu_get_object() function. I assume the following caused the problem:

  1. You created and saved a new node with your migration code
  2. Your hook_tokens implementation was called from the Pathauto module during node_save
  3. menu_get_object was called and returned nothing
  4. New node was created with the wrong URL path

The reason menu_get_object returned nothing is because the new node was not yet available via Drupal's routing. This is expected since all new nodes need to be properly saved once to get a route like node/NID ). This also explains why your code worked properly for a - now - existing node, with a registered route.

Your code would actually have worked fine if you had used the $data parameter, you could have picked your node object from there like this:

// $node = menu_get_object();
$node = $data['node']; 

I tried this quickly in my sandbox and I could both reproduce the original problem and also solve it.

Conclusion: Your code, if you still want to use it, and get rid of the additional hook_node_presave implementation, should work fine if you apply the above change.

Cheers!

  • Wow, thanks a lot. Actually i have one new problem with my solution (I need to comment out the field_attach_presave rows during migration, and then uncomment them afterwards to avoid error messages). With your input I will certainly try to use my first code, but using $node = $data['node'] instead. I didn't have a clue about that. I learn as I go thanks to stubborn people like you :-). Thanks a lot!! – TBJ Mar 12 '16 at 11:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.