UIを含むDrupal 8のノード/エンティティにCSVをインポートする


7

コンテンツエディターが定期的にインポートできるようにUIを提供するDrupal 8のノードまたはエンティティにCSVファイルをインポートするための最良のソリューションは何ですか?

D8 Migrateが適切に機能すると聞いたが、現在インポートプロセス用のUIがないことを理解している。

フィード経由のCSVインポートはまだ準備ができていないようです。


3
最新のFeeds D8リリースを使用して基本テストを試行し、このスレッドdrupal.org/node/2443471#comment-9723715の#4でパッチを適用しましたが、正しく機能しているようです。より複雑なフィールドでどのように機能するかをご覧ください。
スコットアンダーソン

Drupalが常にワードプレスを節約しているのか、それともDrupalがまだ開発中であるのかを考えるべきです。
Vishal Kumar Sahu

回答:


10

私はこれを常に行い、移行構成エンティティーmigrate_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(Visual Basic for Applications、Excelに付属)+ 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 Explorer 11で動作することはわかっていますが、新しいMicrosoft Edgeブラウザーで動作するかどうかはわかりません。

これで、スクリプトを実行する準備ができました。再生ボタンをクリックすることでそれを行うことができます

ここに画像の説明を入力してください

マクロアイコン(画像2を参照)をクリックして実行することもできますが、VBAウィンドウから実行することをお勧めします。

再生ボタンを押すと、IEウィンドウが自動的に開き、次のように表示されます。

ここに画像の説明を入力してください

ああ、あなたはログインするのを忘れました、笑。

したがって、Drupalへのログインに進み、エクスプローラーを閉じ(Cookieの履歴によりログインが保存されるため)、再生ボタンをもう一度押すことを計画します。しかし、次のことはできません...再生ボタンがグレー表示され、VBAコードに変更を加えることができません...何が起こっていますか?

さて、コードはまだ実行中なので、停止(リセット)ボタンを押す必要があります。

ここに画像の説明を入力してください

これで、もう一度再生ボタンをクリックして、自動化の世界を楽しむことができます。

重要

(この例で行っているように)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の観点からは、もっと簡単な解決策が必要だと思います。
スコットアンダーソン

2
ユーザーがIEを持っていず、不必要に複雑に思われる場合は機能しません。私が行く方法は、カスタム管理者確認フォーム、バッチ操作、および移行プロセスだと思います... @mikeryanが尋ねる人になります。
Kevin

あなたはキラーです。
Vishal Kumar Sahu

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.'));
  }
}

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.