For a Backdrop CMS site I'm currently working on, I needed to create a node programatically (i.e. via some PHP code, as opposed to the UI). Generally when I need to do something in Backdrop, I'll search for similar solutions in Drupal 7 and then migrate them over (Backdrop still has some catching up to do in the 'online help and tutorials' department; hence this blog post).
So I went looking for how to create nodes programatically in Drupal 7, and there were plently of results. The answer is basically to create an object or array of values (your 'node'), then run it through node_save()
. Unfortunately each answer had a different idea about exactly what values you should initially assign to your 'node'. Wanting a more bullet-proof solution, I kept looking and finally saw a suggestion someone made to check out the Devel Generate module. It creates nodes programatically, so it has the code to do just this. Since that module already exists in Backdrop, I had a look.
Devel Generate creates nodes by:
- Initialising a
new Node()
object (that's already different from other tutorials I found) - Specifying the node type
- Running it through
node_object_prepare()
- Doing a bunch of Devel Generate-specific stuff
- Adding field values
- Calling
node_save()
This seemed like a much better solution to me. Not only does the initial Node
object already have a bunch of necessary keys defined, but node_object_prepare()
also sets a bunch of default values for you.
So based on that, I came up with the following code for programatically creating nodes in Backdrop:
// Initialise node.
$node = new Node();
$node->type = '[CONTENT_TYPE]';
node_object_prepare($node);
// Add field values.
$node->[FIELD_NAME][$node->langcode][0]['value'] = '[FIELD_VALUE]';
// Save node.
node_save($node);
Regarding fields, Devel Generate did this much differently. But it doesn't know what content type or fields it's working with up-front (it therefore needs to account for any/all of them). In my case, I was able to look at the Devel tab on an existing node and see the field values I needed to set. So that made that part much easier.
Hope this helps others in future. I'm sure I'll be referring back to it in time.