php - How do I programmatically create a node?
Get the solution ↓↓↓I'm designing a new module in Drupal 8. It's a long-term project that won't be going public for a few months at least, so I'm using it as a way to figure out what's new.
In this module, I want to be able to programmatically create nodes. In Drupal 7, I would do this by creating the object, then calling "node_submit" and "node_save".
These functions no longer exist in Drupal 8. Instead, according to the documentation, "Modules and scripts may programmatically submit nodes using the usual form API pattern." I'm at a loss. What does this mean? I've used Form API to create forms in Drupal 7, but I don't get what the docs are saying here.
What I'm looking to do is programmatically create at least one and possibly multiple new nodes, based on information not taken directly from a user-presented form. I need to be able to:
1) Specify the content type
2) Specify the URL path
3) Set any other necessary variables that would previously have been handled by the now-obsolete node_object_prepare()
4) Commit the new node object
I would prefer to be able to do this in an independent, highly abstracted function not tied to a specific block or form.
So what am I missing?
Answer
Solution:
use Drupal\node\Entity\Node;
$node = Node::create(array(
'type' => 'your_content_type',
'title' => 'your title',
'langcode' => 'en',
'uid' => '1',
'status' => 1,
'field_fields' => array(),
));
$node->save();
Answer
Solution:
RE: deprecated entity create
Here is a short example of usage without the deprecated functions. This is particularly helpful for dynamic creation:
//define entity type and bundle
$entity_type="node";
$bundle="article";
//get definition of target entity type
$entity_def = \Drupal::entityManager()->getDefinition($entity_type);
//load up an array for creation
$new_node=array(
//set title
'title' => 'test node',
//set body
'body' => 'this is a test body, can also be set as an array with "value" and "format" as keys I believe',
//use the entity definition to set the appropriate property for the bundle
$entity_def->get('entity_keys')['bundle']=>$bundle
);
$new_post = \Drupal::entityManager()->getStorage($entity_type)->create($new_node);
$new_post->save();
Answer
Solution:
The Drupal 8 version of devel/devel_generate module has a good example of this.
$edit_node = array(
'nid' => NULL,
'type' => $node_type,
'uid' => $users[array_rand($users)],
'revision' => mt_rand(0, 1),
'status' => TRUE,
'promote' => mt_rand(0, 1),
'created' => REQUEST_TIME - mt_rand(0, $results['time_range']),
'langcode' => devel_generate_get_langcode($results),
);
if ($type->has_title) {
// We should not use the random function if the value is not random
if ($results['title_length'] < 2) {
$edit_node['title'] = devel_create_greeking(1, TRUE);
}
else {
$edit_node['title'] = devel_create_greeking(mt_rand(1, $results['title_length']), TRUE);
}
}
else {
$edit_node['title'] = '';
}
// @todo Remove once comment become field. http://drupal.org/node/731724
if (Drupal::moduleHandler()->moduleExists('comment')) {
$edit_node['comment'] = variable_get('comment_' . $node_type, COMMENT_NODE_OPEN);
}
$node = entity_create('node', $edit_node);
Using formatted text
Using grep with before/after code lines helped me figure out how to add a node with 'full_html'.
Search the Drupal core code with this :
$ cd drupal/core
$ grep -B 5 -A 5 -r entity_create.*node * > /tmp/temp-grep.txt
Then, open up /tmp/temp-grep.txt in a text editor. Poke around there a bit and you'll see this :
--
modules/editor/src/Tests/EditorFileUsageTest.php- $body_value .= '<img src="awesome-llama.jpg" data-editor-file-uuid="invalid-editor-file-uuid-value" />';
modules/editor/src/Tests/EditorFileUsageTest.php- // Test handling of a non-existing UUID.
modules/editor/src/Tests/EditorFileUsageTest.php- $body_value .= '<img src="awesome-llama.jpg" data-editor-file-uuid="30aac704-ba2c-40fc-b609-9ed121aa90f4" />';
modules/editor/src/Tests/EditorFileUsageTest.php- // Test editor_entity_insert(): increment.
modules/editor/src/Tests/EditorFileUsageTest.php- $this->createUser();
modules/editor/src/Tests/EditorFileUsageTest.php: $node = entity_create('node', array(
modules/editor/src/Tests/EditorFileUsageTest.php- 'type' => 'page',
modules/editor/src/Tests/EditorFileUsageTest.php- 'title' => 'test',
modules/editor/src/Tests/EditorFileUsageTest.php- 'body' => array(
modules/editor/src/Tests/EditorFileUsageTest.php- 'value' => $body_value,
modules/editor/src/Tests/EditorFileUsageTest.php- 'format' => 'filtered_html',
Note how 'body' now becomes an array with a 'value' and a 'format'.
Answer
Solution:
Best way to create node in Drupal 8 via using core services
$node = \Drupal::entityTypeManager()->getStorage('node')->create([
'type' => 'content_type_machine_name',
'field_text' => 'Foo',
'title' => 'Text Title',
]);
$node->save();
Answer
Solution:
Figured it out. For anyone else with this issue, nodes are now treated as entities, and the entity module is now part of core. So my code ended up looking like this:
$new_page_values = array();
$new_page_values['type'] = 'my_content_type';
$new_page_values['title'] = $form_state['values']['page_title'];
$new_page_values['path'] = $new_page_path;
$new_page = entity_create('node', $new_page_values);
$new_page->save();
Share solution ↓
Additional Information:
Link To Answer People are also looking for solutions of the problem: trying to access array offset on value of type null
Didn't find the answer?
Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.
Similar questions
Find the answer in similar questions on our website.
Write quick answer
Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.