【问题标题】:How to programmatically create a node in Drupal 8?如何以编程方式在 Drupal 8 中创建节点?
【发布时间】:2014-08-02 02:14:02
【问题描述】:

我正在 Drupal 8 中设计一个新模块。这是一个长期项目,至少要几个月后才会公开,所以我将其用作了解新功能的一种方式。

在这个模块中,我希望能够以编程方式创建节点。在 Drupal 7 中,我会通过创建对象,然后调用“node_submit”和“node_save”来做到这一点。

这些函数在 Drupal 8 中不再存在。相反,根据文档,“模块和脚本可以使用通常的表单 API 模式以编程方式提交节点。”我不知所措。这是什么意思?我使用 Form API 在 Drupal 7 中创建表单,但我不明白这里的文档在说什么。

我要做的是根据不是直接从用户提供的表单中获取的信息,以编程方式创建至少一个甚至可能多个新节点。我需要能够:

1) 指定内容类型

2) 指定网址路径

3) 设置以前由现已过时的 node_object_prepare() 处理的任何其他必要变量

4) 提交新的节点对象

我希望能够在一个独立的、高度抽象的函数中执行此操作,而不是绑定到特定的块或表单。

那么我错过了什么?

【问题讨论】:

  • @Clive entity_create() 将根据您的链接在 Drupal 9 中被删除。更好地使用对象方式:Entity::create() 或 Node::create() 作为节点。
  • @v.nivuahc 是的,这是真的。不过,当我写评论时,它们并没有被弃用,它们是闪亮的和新的;)

标签: php drupal drupal-8


【解决方案1】:

想通了。对于遇到此问题的其他人,节点现在被视为实体,实体模块现在是核心的一部分。所以我的代码最终看起来像这样:

$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();

【讨论】:

  • 我正要建议你使用存储服务创建实体,但我注意到这就是 Drupal 在 entity_create 内部所做的。
  • entity_create 根据文档已弃用:@deprecated 在 Drupal 8.0.x 中,将在 Drupal 9.0.0 之前删除。使用 Entity::create() 方法覆盖实体类型,例如\Drupal\node\Entity\Node::create() 如果实体类型已知。如果实体类型是可变的,使用实体存储的create()方法构造一个新的实体:见drupal.stackexchange.com/a/108874/1895
【解决方案2】:

devel/devel_generate 模块的 D8 版本就是一个很好的例子。

来自devel_generate:

  $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);

使用格式化文本

在代码行之前/之后使用 grep 帮助我弄清楚如何使用“full_html”添加节点。

用这个搜索 Drupal 核心代码:

$ cd drupal/core
$ grep -B 5 -A 5 -r entity_create.*node * > /tmp/temp-grep.txt

然后,在文本编辑器中打开 /tmp/temp-grep.txt。在那里戳一下,你会看到这个:

--
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',
--

请注意“body”现在如何变成具有“值”和“格式”的数组。

【讨论】:

    【解决方案3】:

    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();

    【讨论】:

      【解决方案4】:

      RE:已弃用的实体创建

      这是一个没有弃用函数的简短示例。这对于动态创建特别有用:

      //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();
      

      【讨论】:

      • 自编写以来,已弃用或更改了更多内容: \Drupal::entityManager() 应变为 \Drupal::service('entity.manager') drupal.org/node/2721791; $entity_def->get() 应该变成 $entity_def->getKey()。理想情况下,如果您在表单中执行此操作,则应避免直接访问 \Drupal,并使用依赖注入:code.tutsplus.com/tutorials/…
      【解决方案5】:

      使用核心服务在 Drupal 8 中创建节点的最佳方式

      $node = \Drupal::entityTypeManager()->getStorage('node')->create([
        'type'       => 'content_type_machine_name',
        'field_text' => 'Foo',
        'title'      => 'Text Title',
      ]);
      $node->save();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-19
        • 1970-01-01
        • 2021-10-27
        • 1970-01-01
        • 2016-03-19
        • 2015-12-27
        相关资源
        最近更新 更多