I have a content type "News". With URL aliases pattern and token the URL is like this: news/node_title.

Is it possible to create two nodes on one submission with different URL aliases? Let's say on submitting on the news node, it will create two nodes with two URLs like this: The first one is news/node_title and the second will be news2/node_title.

The thing is the website will have a mini site pages inside and will have two different views for the news. The second view will show filtered news from a different country. The main menu block of the website will be hidden on the local pages and will have another menu block with visibility "news2/*", so right the URLs in full node news pages will have the issues. It will stay like this news/node_title. I want the cloned pages to have a different URL like this node2/node_title.

The guys that will create news doesn't want a new content type for that, instead I'll set a new field check box, that will act as a filter which news to go in the second view.

So far I've tried this code:

/*
 * Implements hook_node_presave().
 */
function mymodule_node_presave($node) {
	if($node->is_new == TRUE) {	
		$clone_node = clone $node; // Create a clone of the node		
		$clone_node->path['alias'] = 'news2/' . $node->nid; // Create a new alias programmatically
		node_save($clone_node); // Saving a new cloned node
		//dpm($clone_node);	
	}
}

The issue here is the node_save($clone_node); doesn't work.
The page is loading and for a while it simply refreshing the create node form, without saving anything.

P.S. What happened to the drupal.org highlighted version of the code?

Comments

pobster’s picture

Try this;

/*
 * Implements hook_node_presave().
 */
function mymodule_node_presave($node) {
    if (!isset($node->prevent_loop) && !$node->nid) {    
        $clone_node = clone $node; // Create a clone of the node
        $clone_node->is_new = TRUE; // This is also a new node
        unset($clone_node->nid, $clone_node->vid); // So remove references to the old node
//      $clone_node->path['alias'] = 'news2/' . $node->nid; // Create a new alias programmatically
        $clone_node->prevent_loop = TRUE; // Set a flag so this 'presave' hook isn't called in an infinite loop
        $clone_node = node_submit($clone_node); // This probably isn't necessary...
        node_save($clone_node); // Saving a new cloned node
        //dpm($clone_node);    
    }
}

Note the alias part will no longer work as you don't have a nid - you're forgetting that the nid will increase (it's a new node, not the same one as before).

Thanks,

Pobster

satvision83’s picture

Thank you for your answer.
This line "if (!isset(prevent_loop) && !$node->nid) {" has an error.

By the way, I don't see this function "prevent_loop" in PHP manual.

As far as I know isset expects some variable, not function.

pobster’s picture

It's not a function call, it's a node property which I'm setting further down (it can be anything, I was just being explicit - I thought it would make sense for a tutorial). Don't forget that when you save a new node, this exact same function will run for it - it's a NEW node, you need to prevent it from running the presave hook the second time. I've updated my snippet - don't know how I missed it before, obviously I'm not writing it in an IDE - just in the text editor here.

satvision83’s picture

Thanks for explaining that. I've tried the updated code and I can see it's creating a two nodes, that's great!
But, unfortunately if it's not possible to create a new alias it won't do for the task.

pobster’s picture

It's not that it won't create the alias - you've just not specified exactly what should be created? For your example you've used node ID (nid) which you can still use if you like? I just removed it because it makes no sense at all for an alias ... but then I don't know your use-case? Maybe if you give an example of what you're expecting then we can make it work?

edit: Just to spell this out a little, this is what you're suggesting in your original comment;

First node: news/5
Second node: news2/5 (although the actual node ID will be 6)

Now this is entirely possible, I just commented it out because it makes no sense to me?

satvision83’s picture

Yes, the first node will be: news/5 and the second will be: news2/6.
I've uncommented the line, but it still creates the two nodes with the same alias.

pobster’s picture

As it will, you're not thinking about this clearly - remember the "prevent_loop" thing we did? You can't set an alias when you don't have the node ID. Don't forget that we're only acting on the presave for the original node - this is why we're setting the "prevent_loop" in the first place - as the node_save triggers another presave hook for the second node.

Come to think of it ... hook_node_presave is called before the node is saved to the database, so a new node won't even have a node ID set yet. You probably should move setting the aliases to https://api.drupal.org/api/drupal/modules%21node%21node.api.php/function....

Thanks,

Pobster

satvision83’s picture

Pobster, thank you very much for explaining this in details and thanks for your advice.