7

In D7, it was easy with the VBO module.. But how to do it with D8? (Preferably using a view to select the nodes to resave)

In many places I saw that a small part of the VBO module is now included in the D8 core but I can't figure out how to use it (assuming a simple save should be feasible)

2
  • 1
    Can I know why you want to do this? Is just to know if I can use this solution in other moment. Dec 29, 2016 at 4:03
  • 1
    This is because I have updated a node_presave function which is updating some other nodes depending on the value of the currently saved node.
    – Baud
    Dec 29, 2016 at 10:46

2 Answers 2

9
+50

What you are asking for is included in core Views, unless I am mistaken.
In a new Content view you will be able to add a "Content: Node operations bulk form" field and that offers you an option for "Save content".

enter image description here

You could even use the default "Content" view...

enter image description here

that already offers that option out of the box:

enter image description here

0
8

Latest update:

Drush core now also provide a re-save command! (since v11.0.0-rc1)

# Re-save all article entities:
drush entity:save node --bundle=article

# Re-save all shortcut entities:
drush entity:save shortcut

# Re-save nodes 22 and 24:
drush entity:save node 22,24

# Re-save all nodes except node 9, 14 and 81:
drush entity:save node --exclude=9,14,81

# Re-save all users:
drush entity:save user

# Re-save all node entities in steps of 5, defaults to 50 if omitted:
drush entity:save node --chunks=5

Update:

Aaaand some folks also created an unattributed copy of Resave All Nodes and added some more options: Save All Nodes.


Update:

I just created Resave All Nodes. For now it only contains a form and a Drush command to trigger a batch process to resave all nodes of selected node types.

Drupal Resave All Nodes form screenshot


For everybody coming here to find a code snippet (to be placed in MYMODULE.install):

use \Drupal\node\Entity\Node;

/**
 * Resave all pages.
 */
function MYMODULE_update_8001(&$sandbox) {

  // Get an array of all 'page' node IDs.
  $nids = \Drupal::entityQuery('node')
    ->condition('type', 'page')
    ->execute();

  // Load all the nodes.
  $nodes = Node::loadMultiple($nids);
  foreach ($nodes as $node) {
    $node->save();
  }
}

Problem with this, of course, is you can reach your memory limit pretty fast when re-saving many thousands of nodes that way. So you have to implement a batch process.

Thankfully hook_update_N(&$sandbox) already has this capability built-in. Follow the link for sample code.

If running your update all at once could possibly cause PHP to time out, use the $sandbox parameter to indicate that the Batch API should be used for your update. In this case, your update function acts as an implementation of callback_batch_operation(), and $sandbox acts as the batch context parameter. In your function, read the state information from the previous run from $sandbox (or initialize), run a chunk of updates, save the state in $sandbox, and set $sandbox['#finished'] to a value between 0 and 1 to indicate the percent completed, or 1 if it is finished (you need to do this explicitly in each pass).

2
  • 1
    Rather than messing with the sandbox, just iterate over the $nids and load the node inside the loop.
    – Jonathan
    Jul 31, 2019 at 17:23
  • 2
    @Jonathan – Bad idea with 1.000.000 nodes.
    – leymannx
    Jul 31, 2019 at 17:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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