Impor CSV ke node / entitas di Drupal 8 termasuk UI

7

Apa solusi terbaik untuk mengimpor file CSV ke node atau entitas di Drupal 8 yang menawarkan UI sehingga editor konten dapat mengimpor secara teratur?

Saya pernah mendengar D8 Migrate berfungsi dengan baik tetapi saya mengerti saat ini tidak ada UI untuk proses impor.

Impor CSV melalui Umpan tampaknya belum siap.

Scott Anderson
sumber
3
Saya mencoba tes dasar menggunakan rilis Feeds D8 terbaru dan menerapkan tambalan di # 4 dari utas ini drupal.org/node/2443471#comment-9723715 dan tampaknya berfungsi dengan benar. Lihat bagaimana hasilnya untuk bidang yang lebih kompleks.
Scott Anderson
Saya harus berpikir bahwa Drupal menyimpan wordpress sepanjang waktu atau Drupal masih berkembang.
Vishal Kumar Sahu

Jawaban:

10

Saya melakukan ini sepanjang waktu, memanfaatkan entitas konfigurasi migrasi (disediakan oleh modul migrate_plus ). Tetapkan plugin migrasi di direktori config / install modul migrasi Anda, menggunakan plugin CSV source dari modul migrate_source_csv - menghilangkan konfigurasi sumber 'path', yang akan diisi dari form. Katakanlah ID migrasi ini adalah example_csv. Buat formulir dengan elemen unggah file (bernama 'csv_file' dalam kasus ini), dan dalam metode 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.'));
      }
    }
  }

Ini memperbarui pengaturan migrasi dengan file baru. Anda masih harus menjalankan migrasi menggunakan drush mi example_csvuntuk benar-benar mengimpor konten.

Atau tambahkan beberapa kode ke fungsi untuk benar-benar menjalankan impor:

      $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');
      }
Mike Ryan
sumber
1

Mungkin lebih baik dan lebih cepat untuk menggunakan Feed , tetapi karena versi D8 masih dalam pengembangan; sebagai alternatif, Anda bisa menggunakan Excel + VBA ( Visual Basic for Applications , hadir dengan Excel) + Internet Explorer 11.

Berikut ini contoh bagaimana Anda dapat mengimpor konten CSV Anda menggunakan VBA.

Misalnya, mari kita asumsikan Anda ingin mengimpor ini dan membuat node baru dengan info dari CSV Anda:

masukkan deskripsi gambar di sini

Berikut ini contoh kode 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

Pastikan Anda mengubah nama domain myURL = "https://rgr79.ply.st/node/add/article"sesuai dengan domain Anda. Saya menggunakan domain simplytest.me , jika Anda belum tahu.

Bagaimana cara menambahkan kode VBA?

Klik pada tab Pengembang dan kemudian pada ikon Visual Basic (atau ALT + F11)

masukkan deskripsi gambar di sini

dan rekatkan kode di dalam Sheet1 (Sheet1)

masukkan deskripsi gambar di sini

Sekarang di bilah alat, klik tooldan kemudianReferences

masukkan deskripsi gambar di sini

Anda perlu menggulir, menemukan, dan menandai

  • Perpustakaan Objek Microsoft HTML
  • Kontrol Internet Microsoft

masukkan deskripsi gambar di sini

Catatan: Saya tahu ini bekerja dengan Internet Explorer 11, tidak yakin apakah itu bekerja dengan browser Microsoft Edge yang baru.

Sekarang Anda siap menjalankan skrip. Anda dapat melakukannya dengan mengeklik tombol Mainkan

masukkan deskripsi gambar di sini

Anda juga dapat menjalankannya dengan mengklik Ikon Makro (lihat image2), tetapi saya lebih suka melakukannya dari jendela VBA.

Jadi Anda menekan tombol play dan jendela IE secara otomatis terbuka dan Anda melihat ini:

masukkan deskripsi gambar di sini

Oh ya, Anda lupa masuk, lol.

Jadi Anda melanjutkan untuk masuk ke Drupal dan kemudian Anda menutup explorer (karena riwayat cookie menyimpan login Anda) dan berencana untuk menekan tombol play lagi. Tetapi Anda tidak dapat ... Anda melihat tombol putar abu-abu dan tidak dapat membuat perubahan pada kode VBA ... Apa yang terjadi?

Nah kode Anda masih berjalan, jadi Anda harus menekan tombol Stop (reset).

masukkan deskripsi gambar di sini

Sekarang Anda dapat mengklik tombol putar lagi dan bersuka ria dunia otomatisasi.

Penting

Jika Anda berencana untuk memasukkan hal-hal ke bidang Tubuh (seperti yang kami lakukan dalam contoh ini), karena Drupal 8 menggunakan CKEditor untuk bidang ini dan CKEditor adalah JS, kami tidak dapat menargetkan kelas div atau ID; dengan demikian, kami tidak dapat menambahkan konten di dalam CKEditor.

Untungnya, ada pekerjaan di sekitar. Pastikan pengaturan Keamanan IE 11 Anda diatur ke Tinggi, ini secara otomatis akan memblokir semua JS. Oleh karena itu, CKeditor tidak akan memuat, dan bidang tubuh akan sama seperti bidang lainnya.

masukkan deskripsi gambar di sini


Jika Anda perlu mengedit node misalnya:

masukkan deskripsi gambar di sini

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
Tidak ada Sssweat
sumber
Terima kasih ... itu pilihan yang menarik. Saya pikir saya akan membutuhkan solusi yang lebih sederhana dari perspektif UI.
Scott Anderson
2
Tidak akan berfungsi jika pengguna tidak memiliki IE dan tampaknya tidak perlu rumit. Saya pikir cara untuk pergi adalah formulir konfirmasi admin kustom, batch op, dan proses migrasi ... @mikeryan akan menjadi orang yang bertanya.
Kevin
Kamu adalah pembunuh.
Vishal Kumar Sahu
0

Di atas berfungsi dengan baik bagi saya tetapi Migratin::Load()dan save()metode tidak tersedia di Drupal 8 3.x. Saya telah melakukan beberapa perubahan di atas @Mike Ryan kode yang disarankan. Berikut adalah kode kerja pada formulir sumbit handler.

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