将CSV导入包括用户界面在内的Drupal 8中的节点/实体


7

将CSV文件导入到提供用户界面以便内容编辑者可以定期导入的Drupal 8中的节点或实体中的最佳解决方案是什么?

我听说D8 Migrate可以很好地工作,但我知道当前没有用于导入过程的UI。

通过Feed导入CSV的文件似乎尚未准备好。


3
我尝试使用最新的Feeds D8版本进行基本测试,并从该线程drupal.org/node/2443471#comment-9723715在#4处应用了补丁,它似乎正常工作。了解如何处理更复杂的字段。
斯科特·安德森

我应该认为Drupal一直在节省wordpress或Drupal还在发展。
维沙尔·库马尔·萨胡

Answers:


10

我一直在使用迁移配置实体(由migration_plus 模块提供)来进行此操作。使用migrate_source_csv模块中的CSV源插件在迁移模块的config / install目录中定义一个迁移插件-省略“路径”源配置,该配置将从表格中填写。假设此迁移的ID为example_csv。创建一个带有文件上载元素的表单(在本例中为“ csv_file”),并使用submitForm()方法创建一个表单:

  public function submitForm(array &$form, FormStateInterface $form_state) {
    $all_files = $this->getRequest()->files->get('files', []);
    if (!empty($all_files['csv_file'])) {
      $validators = ['file_validate_extensions' => ['csv']];
      if ($file = file_save_upload('csv_file', $validators, 'public://', 0)) {
        $csv_migration = Migration::load('example_csv');
        $source = $csv_migration->get('source');
        $source['path'] = $file->getFileUri();
        $csv_migration->set('source', $source);
        $csv_migration->save();
        drupal_set_message($this->t('File uploaded as @uri.', ['@uri' => $file->getFileUri()]));
      }
      else {
        drupal_set_message($this->t('File upload failed.'));
      }
    }
  }

这将使用新文件更新迁移设置。您仍然必须运行迁移drush mi example_csv以实际导入内容。

向函数添加一些代码以实际执行导入:

      $migration_instance = \Drupal::service('plugin.manager.migration')->createInstance('example_csv');

      $executable = new MigrateExecutable($migration_instance, new MigrateMessage());

      try {
        $migration_status = $executable->import();
      }
      catch (\Exception $e) {
        \Drupal::logger('migrate_drupal_ui')->error($e->getMessage());
        $migration_status = MigrationInterface::RESULT_FAILED;
      }
      if ($migration_status) {
        drupal_set_message($this->t('Import Successful'));
      }
      else {
        drupal_set_message($migration_status, 'error');
      }

1

使用Feeds可能更好,更快,但是由于D8版本仍在开发中;或者,您可以使用Excel + VBA(Excel附带的Visual Basic for Applications)+ Internet Explorer 11。

这是一个示例,您如何使用VBA导入CSV内容。

例如,假设您要导入它并使用来自CSV的信息创建新节点:

在此处输入图片说明

这是示例VBA代码:

Sub Drupal_Import()

Dim IE As Object
Set IE = CreateObject("InternetExplorer.Application")

Dim x As Integer

For x = 2 To 4 'this controls which rows get added, so only 2 to 4

myURL = "https://rgr79.ply.st/node/add/article"

With IE
.Visible = True 'makes your Internet Explorer window visible.
.navigate myURL
End With

Do
el = vbNullString
On Error Resume Next
Set HTML = IE.document
el = HTML.getElementsByClassName("visually-hidden")(1).innerText
DoEvents
Loop While el = vbNullString

'the above loops until the visualy-hidden class is detected, which means the edit form has been loaded

Application.Wait (Now + TimeValue("00:00:03")) 'tells the program to wait 3 secs.

Set HTML = IE.document

HTML.getElementById("edit-title-0-value").Value = Cells(x, 1).Value 'here the 1 is the Y (so 1 is Column A)

HTML.getElementById("edit-body-0-value").Value = Cells(x, 2).Value 'here the 2 is the Y (so 2 is Column B)

Cells(x, 3).Value = "Done" 'here we use the 3rd column (Column C) and mark it as Done to keep track.

HTML.getElementsByClassName("button js-form-submit form-submit")(1).Click 'clicks the submit button

Application.Wait (Now + TimeValue("00:00:00")) 'here I have a wait for 0, increase it to 2 or 3 if you see your VBA get stuck after submitting a node.

Do
el = vbNullString
On Error Resume Next
Set HTML = IE.document
el = HTML.getElementsByClassName("messages messages--status")(0).innerText
DoEvents
Loop While el = vbNullString

'all the above does is loops the code until the drupal message is detected, which means the node was loaded, after the submit.

Next x

End Sub

确保将域名直接更改myURL = "https://rgr79.ply.st/node/add/article"为您的域。如果您还不能告诉我,我正在使用Simplytest.me域。

如何添加VBA代码?

单击开发人员选项卡,然后单击Visual Basic图标(或ALT + F11)

在此处输入图片说明

并将代码粘贴到Sheet1(Sheet1)内

在此处输入图片说明

现在在工具栏中,单击tool,然后References

在此处输入图片说明

您将需要滚动,查找和选中标记

  • Microsoft HTML对象库
  • Microsoft Internet控件

在此处输入图片说明

注意:我知道它可以与Internet Explorer 11一起使用,不确定是否可以与新的Microsoft Edge浏览器一起使用。

现在,您可以运行脚本了。您可以通过单击“播放”按钮来实现

在此处输入图片说明

您也可以通过单击“宏”图标(请参见image2)来运行它,但是我更喜欢从VBA窗口中进行操作。

因此,您按下了播放按钮,IE窗口自动打开,您将看到以下内容:

在此处输入图片说明

哦,是的,您忘记登录了,大声笑。

因此,您继续登录到Drupal,然后关闭资源管理器(因为cookie历史记录会保存您的登录信息)并计划再次按下播放按钮。但是您不能...您看到播放按钮变灰并且无法对VBA代码进行任何更改...怎么回事?

那么您的代码仍在运行,因此您需要单击Stop(重置)按钮。

在此处输入图片说明

现在,您可以再次单击播放按钮,并享受自动化的世界。

重要

如果您打算在Body字段中插入内容(如本例所示),由于Drupal 8在此字段中使用CKEditor且CKEditor是JS,因此我们无法定位div类或ID;因此,我们无法在CKEditor中添加内容。

幸运的是,这里有一个解决方法。确保将IE 11安全设置设置为“高”,这将自动阻止所有JS。因此,CKeditor将不会加载,并且body字段将与其他字段一样。

在此处输入图片说明


如果需要编辑节点示例:

在此处输入图片说明

Sub Drupal_Edit()

Dim IE As Object
Set IE = CreateObject("InternetExplorer.Application")

Dim x As Integer

For x = 2 To 4 'this controls which rows get added, so only 2 to 4

myURL = "https://rgr79.ply.st/node/" & Cells(x, 3) & "/edit"

With IE
.Visible = True 'makes your Internet Explorer window visible.
.navigate myURL
End With

Do
el = vbNullString
On Error Resume Next
Set HTML = IE.document
el = HTML.getElementsByClassName("visually-hidden")(1).innerText
DoEvents
Loop While el = vbNullString

'the above loops until the visualy-hidden class is detected, which means the edit form has been loaded

Application.Wait (Now + TimeValue("00:00:04")) 'tells the program to wait 3 secs.

Set HTML = IE.document

HTML.getElementById("edit-title-0-value").Value = Cells(x, 1).Value 'here the 1 is the Y (so 1 is Column A)

HTML.getElementById("edit-body-0-value").Value = Cells(x, 2).Value 'here the 2 is the Y (so 2 is Column B)

Cells(x, 4).Value = "Done" 'here we use the 4th column (Column D) and mark it as Done to keep track.

HTML.getElementsByClassName("button js-form-submit form-submit")(1).Click 'clicks the submit button

Application.Wait (Now + TimeValue("00:00:00")) 'here I have a wait for 0, increase it to 2 or 3 if you see your VBA get stuck after submitting a node.

Do
el = vbNullString
On Error Resume Next
Set HTML = IE.document
el = HTML.getElementsByClassName("messages messages--status")(0).innerText
DoEvents
Loop While el = vbNullString

'all the above does is loops the code until the drupal message is detected, which means the node was loaded, after the submit.

Next x

End Sub

谢谢...这是一个有趣的选择。我认为从UI角度来看,我将需要一个更简单的解决方案。
Scott Anderson

2
如果用户没有IE,并且看起来不必要地复杂,则无法使用。我认为要走的路是自定义管理员确认表单,批处理操作和迁移过程... @ mikeryan是要问的人。
凯文(Kevin)

你是杀手。
维沙尔·库马尔·萨胡

0

对我来说,但上述工作正常Migratin::Load()save()方法不可用在Drupal 8 3.x中 我在@Mike Ryan建议的代码上面做了一些更改。这是表单和位处理程序上的工作代码。

public function submitForm(array &$form, FormStateInterface $form_state) {
$all_files = $form_state->getValue('csv_file');
if (!empty($all_files)) {
  $file = file_load($all_files[0]);
  if (!empty($file)) {
    $csv_migration = \Drupal::service('plugin.manager.migration')->createInstance('panalist_migration');
    $source = $csv_migration->get('source');
    $source['path'] = $file->getFileUri();
    $csv_migration->set('source', $source);
    drupal_set_message($this->t('File uploaded as @uri.', ['@uri' => $file->getFileUri()]));
    $executable = new MigrateExecutable($csv_migration, new MigrateMessage());

    try {
      $migration_status = $executable->import();
    }
    catch (\Exception $e) {
      \Drupal::logger('migrate_drupal_ui')->error($e->getMessage());
      $migration_status = MigrationInterface::RESULT_FAILED;
    }
    if ($migration_status) {
      drupal_set_message($this->t('Import Successful'));
    }
    else {
      drupal_set_message($migration_status, 'error');
    }
  }
  else {
    drupal_set_message($this->t('File upload failed.'));
  }
}

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.