Importar CSV a nodos / entidades en Drupal 8, incluida una IU

7

¿Cuál es la mejor solución para importar archivos CSV en nodos o entidades en Drupal 8 que ofrece una interfaz de usuario para que los editores de contenido puedan importar regularmente?

Escuché que D8 Migrate funciona bien, pero entiendo que actualmente no hay una interfaz de usuario para el proceso de importación.

La importación de CSV a través de Feeds todavía no parece estar lista.

Scott Anderson
fuente
3
Intenté una prueba básica usando la última versión de Feeds D8 y aplicando el parche en el n. ° 4 de este hilo drupal.org/node/2443471#comment-9723715 y parece funcionar correctamente. Vea cómo funciona para campos más complejos.
Scott Anderson el
Debería pensar que Drupal está guardando wordpress todo el tiempo o que Drupal todavía se está desarrollando.
Vishal Kumar Sahu

Respuestas:

10

Hago esto todo el tiempo, haciendo uso de entidades de configuración de migración (proporcionadas por el módulo migrate_plus ). Defina un complemento de migración en el directorio config / install de su módulo de migración, utilizando el complemento de origen CSV del módulo migrate_source_csv , omitiendo la configuración de origen 'ruta', que se completará desde el formulario. Digamos que la ID de esta migración es example_csv. Cree un formulario con un elemento de carga de archivos (llamado 'csv_file' en este caso) y en el método 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.'));
      }
    }
  }

Esto actualiza la configuración de migración con el nuevo archivo. Todavía tiene que ejecutar la migración usando drush mi example_csvpara importar realmente el contenido.

O agregue algún código a la función para ejecutar realmente la importación:

      $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
fuente
1

Probablemente sea mejor y más rápido usar Feeds , pero dado que la versión D8 todavía está en desarrollo; alternativamente, puede usar Excel + VBA ( Visual Basic para aplicaciones , viene con Excel) + Internet Explorer 11.

Aquí un ejemplo de cómo puede importar su contenido CSV usando VBA.

Por ejemplo, supongamos que desea importar esto y crear nuevos nodos con la información de su CSV:

ingrese la descripción de la imagen aquí

Aquí hay un código VBA de muestra:

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

Asegúrese de cambiar el nombre de dominio en myURL = "https://rgr79.ply.st/node/add/article"línea a su dominio. Estoy usando un dominio simplytest.me , si aún no lo sabes.

¿Cómo agregar el código VBA?

Haga clic en la pestaña Desarrollador y luego en el icono de Visual Basic (o ALT + F11)

ingrese la descripción de la imagen aquí

y pegue el código dentro de Sheet1 (Sheet1)

ingrese la descripción de la imagen aquí

Ahora en la barra de herramientas, haga clic en tooly luegoReferences

ingrese la descripción de la imagen aquí

Deberá desplazarse, buscar y marcar

  • Biblioteca de objetos HTML de Microsoft
  • Controles de internet de Microsoft

ingrese la descripción de la imagen aquí

Nota: Sé que funciona con Internet Explorer 11, no estoy seguro si funciona con el nuevo navegador Microsoft Edge.

Ahora estás listo para ejecutar el script. Puede hacerlo haciendo clic en el botón Reproducir

ingrese la descripción de la imagen aquí

También puede ejecutarlo haciendo clic en el icono de macros (ver imagen2), pero prefiero hacerlo desde la ventana de VBA.

Entonces presionas el botón de reproducción y una ventana de IE se abre automáticamente y ves esto:

ingrese la descripción de la imagen aquí

Oh sí, olvidaste iniciar sesión, jajaja.

Entonces procedes a iniciar sesión en Drupal y luego cierras el explorador (ya que el historial de cookies guarda tu inicio de sesión) y planeas presionar el botón de reproducción nuevamente. Pero no puede ... ve el botón de reproducción atenuado y no puede realizar ningún cambio en el código VBA ... ¿Qué está pasando?

Bueno, su código aún se está ejecutando, por lo que debe presionar el botón Detener (restablecer).

ingrese la descripción de la imagen aquí

Ahora puede hacer clic en el botón de reproducción nuevamente y disfrutar del mundo de la automatización.

Importante

Si planea insertar cosas en el campo Cuerpo (como lo estamos haciendo en este ejemplo), dado que Drupal 8 usa CKEditor para este campo y CKEditor es JS, no podemos apuntar a una clase div o ID; por lo tanto, no podemos agregar contenido dentro de CKEditor.

Afortunadamente, hay una solución alternativa. Asegúrese de que la configuración de seguridad de IE 11 esté establecida en Alta, esto bloqueará automáticamente todos los JS. Por lo tanto, CKeditor no se cargará, y el campo del cuerpo será igual que los otros campos.

ingrese la descripción de la imagen aquí


Si necesita editar nodos, por ejemplo:

ingrese la descripción de la imagen aquí

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
No Sssweat
fuente
Gracias ... esa es una opción interesante. Sin embargo, creo que necesitaré una solución más simple desde la perspectiva de la interfaz de usuario.
Scott Anderson
2
No funcionará si los usuarios no tienen IE y parece innecesariamente complejo. Creo que el camino a seguir sería un formulario de confirmación de administrador personalizado, un lote de operaciones y un proceso de migración ... @mikeryan sería la persona a quien preguntar.
Kevin
Eres un asesino
Vishal Kumar Sahu
0

La multa anterior está trabajando para mí, pero Migratin::Load()y el save()método no está disponible en Drupal 8 3.x. He realizado algunos cambios en el código sugerido arriba de @Mike Ryan. Aquí está el código de trabajo en el controlador de formulario sumbit.

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
fuente