Problem/Motivation

For Umami to work with multilingual content (initially with Spanish content), we need to be able to import multilingual content.

Few steps need to be completed in order to achieve that:

  1. The existing CSV content files in English should move to a structure that can support future languages (3028627
  2. Enable multilingual functionality as part of Umami install profile3029839
  3. Translated content in Spanish need to finalized in order to be part of OOTB 3028769

While this process might take time, there are other multilingual configurations and settings that need to be addressed.

Proposed resolution

  1. Creating a patch [WIP] of "good enough" patches (instead of waiting for them until they are finalized)
  2. Creating dummy Spanish content
  3. Updating InstallHelper.php to support multilingual import

That last step of updating InstallHelper.php would be the only real patch that would eventually be committed to core.
The [WIP] patches are there to allow other people to easily test multilingual capabilities with Umami.

CommentFileSizeAuthor
#64 interdiff_62-64.txt544 bytesshaal
#64 umami-import-multilingual-content-64.patch73.3 KBshaal
#63 Screen Shot 2019-03-22 at 20.31.26.png117.75 KBkjay
#62 interdiff_61-62.txt569 bytesshaal
#62 umami-import-multilingual-content-62.patch73.36 KBshaal
#61 interdiff_56-61.txt8.26 KBshaal
#61 umami-import-multilingual-content-61.patch73.36 KBshaal
#56 interdiff_55-56.txt805 bytesshaal
#56 umami-import-multilingual-content-56.patch72.96 KBshaal
#55 interdiff_49-55.txt14.06 KBshaal
#55 umami-import-multilingual-content-55.patch72.96 KBshaal
#54 Screen Shot 2019-03-21 at 17.51.43.png245.92 KBkjay
#54 Screen Shot 2019-03-21 at 17.50.55.png228.92 KBkjay
#50 Screenshot_2019-03-21 Welcome to Umami Food Magazine Umami Food Magazine.jpg542.13 KBrteijeiro
#49 interdiff_47-49.txt28.13 KBshaal
#49 umami-import-multilingual-content-49.patch72.27 KBshaal
#47 interdiff_46-47.txt1.31 KBshaal
#47 umami-import-multilingual-content-47.patch105.62 KBshaal
#46 interdiff_44-46.txt9.41 KBshaal
#46 umami-import-multilingual-content-46.patch105.62 KBshaal
#44 interdiff_43-44.txt3.9 KBshaal
#44 umami-import-multilingual-content-44.patch103.39 KBshaal
#43 interdiff_40-43.txt9.24 KBshaal
#43 umami-import-multilingual-content-43.patch103.39 KBshaal
#40 interdiff--3037111-36-40.txt1.77 KBkjay
#40 umami-import-multilingual-content-40.patch101.97 KBkjay
#39 interdiff--3037111-36-38.txt1.91 KBsmaz
#36 interdiff--3037111-34-36.txt5.49 KBsmaz
#36 umami-import-multilingual-content-36.patch102.23 KBsmaz
#34 interdiff_31-34.txt13.05 KBshaal
#34 umami-import-multilingual-content-34.patch98.37 KBshaal
#33 Screenshot 2019-03-20 at 0.18.28.png59.6 KBGábor Hojtsy
#31 interdiff_28-31.txt18.93 KBshaal
#31 umami-import-multilingual-content-31.patch89.93 KBshaal
#28 interdiff_27-28.txt772 bytesshaal
#28 umami-import-multilingual-content-28.patch88.43 KBshaal
#27 interdiff_24-27.txt3.57 KBshaal
#27 umami-import-multilingual-content-27.patch88.43 KBshaal
#24 interdiff_22-24.txt44.5 KBshaal
#24 umami-import-multilingual-content-24.patch84.04 KBshaal
#22 interdiff_20-22.txt1.27 KBshaal
#22 umami-import-multilingual-content-22.patch100.46 KBshaal
#20 interdiff_19-20.txt27.88 KBshaal
#20 umami-import-multilingual-content-20.patch100.46 KBshaal
#19 interdiff_17-19.txt5.92 KBshaal
#19 umami-import-multilingual-content-19.patch104.08 KBshaal
#17 interdiff_14-17.txt77.12 KBshaal
#17 umami-import-multilingual-content-17.patch103.19 KBshaal
#14 interdiff_11-14.txt4.69 KBshaal
#14 umami-import-multilingual-content-14.patch116.23 KBshaal
#12 umami-import-multilingual-content-11.patch116.42 KBshaal
#10 interdiff_9-10.txt111.74 KBshaal
#10 umami-import-multilingual-content-10.patch216.1 KBshaal
#9 interdiff_5-9.txt1.29 KBshaal
#9 umami-import-multilingual-content-9.patch99.67 KBshaal
#7 English_Spanish Umami URLs.jpg37.83 KBGábor Hojtsy
#5 umami-import-multilingual-content-5.patch99.68 KBshaal
#2 umami-import-multilingual-content-2.patch126.82 KBshaal
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

shaal created an issue. See original summary.

shaal’s picture

Initial patch for testing, by applying it Umami install profile will import English content + dummy Spanish content.

shaal’s picture

Status: Active » Needs review

(checking if it will pass tests)

Gábor Hojtsy’s picture

Status: Needs review » Needs work
shaal’s picture

Status: Needs work » Needs review
FileSize
99.68 KB

Interdiff was not possible with the previous patch #2.

Changes in this patch:

Todo:
Move blocks' content from InstallHelper.php into external English CSV files, and then get block content get translated as well (ie. text on hero image, footer, etc.)

There's a decision that needs to be made / issue that needs to be resolved.
When the user chooses a 3rd language (not English and not Spanish), how should we handle imported multilingual content?

When installing Umami in English/Spanish, content will always be available in English and Spanish, ie:
drupalsite.local/en/awesome-recipe
and
drupalsite.local/es/awesome-recipe

But when installing Umami in 3rd language how should we import the English content?

  1. as the default (3rd language)
  2. as English content
  3. as both default and English

Here's what will happen with each option (only relevant when Umami is installed in a 3rd language, I'll use he as an example):
1) as default (3rd language) content:

  • drupalsite.local/awesome-recipe - works
  • drupalsite.local/he/awesome-recipe - works
  • drupalsite.local/es/awesome-recipe - works
  • drupalsite.local/en/awesome-recipe - doesn't work

2) as English content

  • drupalsite.local/en/awesome-recipe - works
  • drupalsite.local/es/awesome-recipe - works
  • drupalsite.local/awesome-recipe - doesn't work
  • drupalsite.local/he/awesome-recipe - doesn't work

3) as both default and English

  • drupalsite.local/en/awesome-recipe - works
  • drupalsite.local/es/awesome-recipe - works
  • drupalsite.local/awesome-recipe - works
  • drupalsite.local/he/awesome-recipe - works

=====

But the best solution would actually be importing English as English and Spanish as Spanish, yet somehow still allow no-language-prefix to work as well -
drupalsite.local/awesome-recipe - would display content in English

(I don't know what settings are needed to make that best solution to work)

Gábor Hojtsy’s picture

But the best solution would actually be importing English as English and Spanish as Spanish, yet somehow still allow no-language-prefix to work as well - drupalsite.local/awesome-recipe - would display content in English (I don't know what settings are needed to make that best solution to work)

Yes this would be the best. You can set the English prefix to be empty if the site was not installed in Spanish by default. So the /whatever URLs would always be English even if you install in Italian or Uyghur. This is a bit different from default Drupal behaviour but it can be configured this way and it makes sense for Umami since we don't have translation to all the languages.

Gábor Hojtsy’s picture

Here is a drawing form :)

In other words if you install in a language that has default content in that language, then make that language path prefix empty (as is Drupal's default), otherwise make English path prefix empty and the language you installed in not empty.

shaal’s picture

Here are a few scenarios that users expect.

Installing Umami in English, expecting:
/ English interface, English content
/en English interface, English content
/es Spanish interface, Spanish content

Installing Umami in Spanish, expecting:
/ Spanish interface, Spanish content
/en English interface, English content
/es Spanish interface, Spanish content

Installing Umami in Hebrew, expecting:
/ Hebrew interface, English content
/en English interface, English content
/es Spanish interface, Spanish content
/he Hebrew interface, Hebrew content

(the last /he should display Page not found messages since there is no content in that language, until the user will add some)

shaal’s picture

I think the simplest (and best?) solution,
is importing English content as English. Leaving all rest of Drupal settings as default.
Then installing Umami in a 3rd language - would work as expected.
It works like the scenarios detailed in #8

One thing that is left to figure out is a View's setting that is missing
(we need that setting for a multilingual website regardless of this specific patch)
Can we create in the View a condition "If no content in the current language - display English content"?

shaal’s picture

Status: Needs review » Needs work

The last submitted patch, 10: umami-import-multilingual-content-10.patch, failed testing. View results

shaal’s picture

Status: Needs work » Needs review
FileSize
116.42 KB

Something went wrong in the last patch I submitted... I think merging latest 8.7.x made a little mess.
Because 8.7.x includes Umami Tour - generating interdiff was not possible.

Patch now supports importing multilingual blocks!!

I added the CSV files needed for English block, as well as dummy CSV content in Spanish.

Looking forward to the completion of #3029839: Multilingual functionality - enable English and Spanish as part of Umami installation
Once that other issue is fixed - this patch can become much smaller (currently it's providing the missing functionality that will be included in that other issue)

Status: Needs review » Needs work

The last submitted patch, 12: umami-import-multilingual-content-11.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

shaal’s picture

Status: Needs work » Needs review
FileSize
116.23 KB
4.69 KB

Fixed coding standard issues
Fixed typo in block import that prevented footer block to get the image.

shaal’s picture

Status: Needs review » Needs work

I just realized... that if we won't have ALL content translated from English to Spanish, we should change the structure of CSV files to include an internal ID (like what @smaz did for taxonomy files), and update installHelper.php to support importing content and translation by ID instead of (currently) by row of CSV file.

Remaining tasks

  1. Change the structure of default content CSV files to include id.
  2. Update installHelper.php to import content and translation by ID instead of by row

Also, need to change the structure of dummy content CSV files in Spanish to be the same as the new structure of CSV files in English.

Gábor Hojtsy’s picture

Version: 8.7.x-dev » 8.8.x-dev

@shaal good thinking about #15.

Also #3029839: Multilingual functionality - enable English and Spanish as part of Umami installation landed, so that patch of the patch will not apply anymore.

shaal’s picture

This patch is kind of a complete rework...

Including:

  • Re-roll to work with latest 8.7 Umami updates
  • CSV files now have ID instead of depending on Rows (which allow us to skip any entity translation that is not available)
  • Optimized a lot of repetitive code into simpler generalized functions
  • Restructure CSV file locations - to simplify future content and entities

installHelper.php can now import content in any language, the minimum requirements for that to happen:

  1. Language should be added to the website
  2. At least one CSV file, that is stored in the same location & structure as English CSV file, but under a specific directory, ie: /he

Status: Needs review » Needs work

The last submitted patch, 17: umami-import-multilingual-content-17.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

shaal’s picture

Fixed coding standard issues, and fixed the test to work with the new CSV files locations.

shaal’s picture

This patch is based on #19 and includes the following changes:

  • Updated recipes content in Spanish, from dummy content to the final translation.
  • Fixed multilingual import of "Recipe Instruction" files for Recipes, and "Body" files for Articles.
  • Added config files with Spanish translation to Recipe's fields

I don't know why that last item, with the config files translations, is still not taking effect during installation.

shaal’s picture

I applied patch #135 in https://www.drupal.org/project/drupal/issues/2599228#comment-13015153

The good - Not getting an error when allowing content types to be translatable
The bad - the config entities that have field label translations - are not shown in Spanish when the site is installed

shaal’s picture

Gábor Hojtsy’s picture

Status: Needs review » Needs work
  1. +++ b/core/profiles/demo_umami/config/install/field.field.node.recipe.field_summary.yml
    @@ -13,7 +13,7 @@ bundle: recipe
    diff --git a/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_cooking_time.yml b/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_cooking_time.yml
    
    diff --git a/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_cooking_time.yml b/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_cooking_time.yml
    new file mode 100644
    
    new file mode 100644
    index 0000000000..e78b29cdf6
    
    index 0000000000..e78b29cdf6
    --- /dev/null
    
    --- /dev/null
    +++ b/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_cooking_time.yml
    
    +++ b/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_cooking_time.yml
    +++ b/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_cooking_time.yml
    @@ -0,0 +1,3 @@
    
    @@ -0,0 +1,3 @@
    +settings:
    +  suffix: ' minutos'
    +label: 'Hora de cocinar'
    diff --git a/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_difficulty.yml b/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_difficulty.yml
    
    diff --git a/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_difficulty.yml b/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_difficulty.yml
    new file mode 100644
    
    new file mode 100644
    index 0000000000..8824fce5d9
    
    index 0000000000..8824fce5d9
    --- /dev/null
    
    --- /dev/null
    +++ b/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_difficulty.yml
    
    +++ b/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_difficulty.yml
    +++ b/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_difficulty.yml
    @@ -0,0 +1 @@
    
    @@ -0,0 +1 @@
    +label: Dificultad
    diff --git a/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_ingredients.yml b/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_ingredients.yml
    
    diff --git a/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_ingredients.yml b/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_ingredients.yml
    new file mode 100644
    
    new file mode 100644
    index 0000000000..520fc9562d
    
    index 0000000000..520fc9562d
    --- /dev/null
    
    --- /dev/null
    +++ b/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_ingredients.yml
    
    +++ b/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_ingredients.yml
    +++ b/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_ingredients.yml
    @@ -0,0 +1,2 @@
    
    @@ -0,0 +1,2 @@
    +label: Ingredientes
    +description: 'Listar los ingredientes necesarios para esta receta, uno por artículo.'
    diff --git a/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_number_of_servings.yml b/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_number_of_servings.yml
    
    diff --git a/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_number_of_servings.yml b/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_number_of_servings.yml
    new file mode 100644
    
    new file mode 100644
    index 0000000000..cf2ec13f55
    
    index 0000000000..cf2ec13f55
    --- /dev/null
    
    --- /dev/null
    +++ b/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_number_of_servings.yml
    
    +++ b/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_number_of_servings.yml
    +++ b/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_number_of_servings.yml
    @@ -0,0 +1 @@
    
    @@ -0,0 +1 @@
    +label: 'Cantidad de raciones'
    diff --git a/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_preparation_time.yml b/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_preparation_time.yml
    
    diff --git a/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_preparation_time.yml b/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_preparation_time.yml
    new file mode 100644
    
    new file mode 100644
    index 0000000000..26fa69d9d9
    
    index 0000000000..26fa69d9d9
    --- /dev/null
    
    --- /dev/null
    +++ b/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_preparation_time.yml
    
    +++ b/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_preparation_time.yml
    +++ b/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_preparation_time.yml
    @@ -0,0 +1,3 @@
    
    @@ -0,0 +1,3 @@
    +settings:
    +  suffix: ' minutos'
    +label: 'Tiempo de preparación'
    diff --git a/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_recipe_category.yml b/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_recipe_category.yml
    
    diff --git a/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_recipe_category.yml b/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_recipe_category.yml
    new file mode 100644
    
    new file mode 100644
    index 0000000000..ad4fd9b0c6
    
    index 0000000000..ad4fd9b0c6
    --- /dev/null
    
    --- /dev/null
    +++ b/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_recipe_category.yml
    
    +++ b/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_recipe_category.yml
    +++ b/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_recipe_category.yml
    @@ -0,0 +1 @@
    
    @@ -0,0 +1 @@
    +label: 'Categoría de receta'
    diff --git a/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_recipe_instruction.yml b/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_recipe_instruction.yml
    
    diff --git a/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_recipe_instruction.yml b/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_recipe_instruction.yml
    new file mode 100644
    
    new file mode 100644
    index 0000000000..ed62672f75
    
    index 0000000000..ed62672f75
    --- /dev/null
    
    --- /dev/null
    +++ b/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_recipe_instruction.yml
    
    +++ b/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_recipe_instruction.yml
    +++ b/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_recipe_instruction.yml
    @@ -0,0 +1 @@
    
    @@ -0,0 +1 @@
    +label: 'Instrucción de receta'
    diff --git a/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_summary.yml b/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_summary.yml
    
    diff --git a/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_summary.yml b/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_summary.yml
    new file mode 100644
    
    new file mode 100644
    index 0000000000..01b62ae21d
    
    index 0000000000..01b62ae21d
    --- /dev/null
    
    --- /dev/null
    +++ b/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_summary.yml
    
    +++ b/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_summary.yml
    +++ b/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_summary.yml
    @@ -0,0 +1,2 @@
    
    @@ -0,0 +1,2 @@
    +label: Resumen
    +description: 'Proporcione una breve descripción de esta receta.'
    diff --git a/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_tags.yml b/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_tags.yml
    
    diff --git a/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_tags.yml b/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_tags.yml
    new file mode 100644
    
    new file mode 100644
    index 0000000000..fe94ab5b49
    
    index 0000000000..fe94ab5b49
    --- /dev/null
    
    --- /dev/null
    +++ b/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_tags.yml
    
    +++ b/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_tags.yml
    +++ b/core/profiles/demo_umami/config/install/language/es/field.field.node.recipe.field_tags.yml
    @@ -0,0 +1,2 @@
    
    @@ -0,0 +1,2 @@
    +label: Etiquetas
    +description: 'Introduzca una lista separada por comas. Por ejemplo: vegetarianos, brownies de chocolate, aperitivos.'
    diff --git a/core/profiles/demo_umami/config/install/language/es/field.storage.node.field_difficulty.yml b/core/profiles/demo_umami/config/install/language/es/field.storage.node.field_difficulty.yml
    
    diff --git a/core/profiles/demo_umami/config/install/language/es/field.storage.node.field_difficulty.yml b/core/profiles/demo_umami/config/install/language/es/field.storage.node.field_difficulty.yml
    new file mode 100644
    
    new file mode 100644
    index 0000000000..1d2c03e1ed
    
    index 0000000000..1d2c03e1ed
    --- /dev/null
    
    --- /dev/null
    +++ b/core/profiles/demo_umami/config/install/language/es/field.storage.node.field_difficulty.yml
    
    +++ b/core/profiles/demo_umami/config/install/language/es/field.storage.node.field_difficulty.yml
    +++ b/core/profiles/demo_umami/config/install/language/es/field.storage.node.field_difficulty.yml
    @@ -0,0 +1,8 @@
    
    @@ -0,0 +1,8 @@
    +settings:
    +  allowed_values:
    +    1:
    +      label: Medio
    +    0:
    +      label: Fácil
    +    2:
    +      label: Difícil
    

    None of these should be shipped in umami, they would be downloaded from drupal.org for all the config that is shipped as yml files within umami once drupal.org translates the fields. They should not be shipped in umami.

  2. +++ b/core/profiles/demo_umami/modules/demo_umami_content/default_content/languages/en/node/page.csv
    @@ -0,0 +1,2 @@
    +1,About Umami,"<p>Umami is a fictional food magazine that has been created to demonstrate how you might build a Drupal site using functionality provided 'out of the box'.</p><p>For more information visit <a href='https://www.drupal.org/docs/8/umami-drupal-8-demonstration-installation-profile'>https://www.drupal.org/docs/8/umami-drupal-8-demonstration-installation-profile</a>.</p>",Samuel Adamson,about-umami
    \ No newline at end of file
    
    +++ b/core/profiles/demo_umami/modules/demo_umami_content/default_content/languages/es/node/page.csv
    @@ -0,0 +1,2 @@
    +1,Acerca de Umami,"<p> Umami es una revista ficticia de alimentos que se ha creado para demostrar cómo se puede construir un sitio de Drupal con la funcionalidad que se proporciona 'fuera de la caja'. </p> <p> Para obtener más información, visite <a href = 'https: //www.drupal.org/docs/8/umami-drupal-8-demonstration-installation-profile'> https://www.drupal.org/docs/8/umami-drupal-8-demonstration -installation-profile </a>. </p> ",Samuel Adamson,about-umami
    \ No newline at end of file
    

    Let's make sure there are newlines at end of files :)

shaal’s picture

This patch includes all suggestions from #23 + updated contnet for articles CSV files in Spanish.

smaz’s picture

Status: Needs review » Needs work

I haven't fully reviewed the code but:

1) There's a PHP 7.0 incompatibility:
[$all_content, $translated_languages] = $this->readMultilingualContent($filename);
That shorthand for list was introduced in PHP 7.1: https://wiki.php.net/rfc/short_list_syntax
If core is still supporting 7.0, we'd need to change that to:
list($all_content, $translated_languages) = $this->readMultilingualContent($filename);

2) I get the following during install (installing via drush)
[warning] array_combine() expects parameter 1 to be array, null given InstallHelper.php:181
[warning] array_combine() expects parameter 1 to be array, null given InstallHelper.php:181
[warning] array_combine() expects parameter 1 to be array, null given InstallHelper.php:181
[warning] array_combine() expects parameter 1 to be array, null given InstallHelper.php:181
[warning] array_combine() expects parameter 1 to be array, null given InstallHelper.php:181
[warning] array_combine() expects parameter 1 to be array, null given InstallHelper.php:181
[warning] array_combine() expects parameter 1 to be array, null given InstallHelper.php:181
[warning] array_combine() expects parameter 1 to be array, null given InstallHelper.php:181
[warning] array_combine() expects parameter 1 to be array, null given InstallHelper.php:181
[warning] array_combine() expects parameter 1 to be array, null given InstallHelper.php:181
[warning] array_combine() expects parameter 1 to be array, null given InstallHelper.php:181
[warning] array_combine() expects parameter 1 to be array, null given InstallHelper.php:181
[warning] array_combine() expects parameter 1 to be array, null given InstallHelper.php:181
[warning] array_combine() expects parameter 1 to be array, null given InstallHelper.php:181
[warning] array_combine() expects parameter 1 to be array, null given InstallHelper.php:181
[warning] array_combine() expects parameter 1 to be array, null given InstallHelper.php:181
[warning] array_combine() expects parameter 1 to be array, null given InstallHelper.php:181
[warning] array_combine() expects parameter 1 to be array, null given InstallHelper.php:181
[warning] array_combine() expects parameter 1 to be array, null given InstallHelper.php:181
[warning] array_combine() expects parameter 1 to be array, null given InstallHelper.php:181
[warning] array_combine() expects parameter 1 to be array, null given InstallHelper.php:181
[warning] array_combine() expects parameter 1 to be array, null given InstallHelper.php:181
[warning] array_combine() expects parameter 1 to be array, null given InstallHelper.php:181
[warning] array_combine() expects parameter 1 to be array, null given InstallHelper.php:181
[warning] array_combine() expects parameter 1 to be array, null given InstallHelper.php:181
[warning] array_combine() expects parameter 1 to be array, null given InstallHelper.php:181
[warning] array_combine() expects parameter 1 to be array, null given InstallHelper.php:181
[warning] array_combine() expects parameter 1 to be array, null given InstallHelper.php:181
[warning] Invalid argument supplied for foreach() InstallHelper.php:678
[warning] array_combine() expects parameter 1 to be array, null given InstallHelper.php:181
[warning] array_combine() expects parameter 1 to be array, null given InstallHelper.php:181
[warning] array_combine() expects parameter 1 to be array, null given InstallHelper.php:181
[warning] array_combine() expects parameter 1 to be array, null given InstallHelper.php:181
[warning] array_combine() expects parameter 1 to be array, null given InstallHelper.php:181
[warning] Invalid argument supplied for foreach() InstallHelper.php:678

I'm guessing this is the blank lines at the end of CSVs? If so either a) we need to be allowed to have no newlines at the end of CSV files or b) our import code needs to check it's not a blank line.

3) 3 field configs now have:

-translatable: false
+translatable: true

Is the configuration for all fields in another patch? If so, those shouldn't be in this patch or we'll need to re-roll it when the other one is added.

Gábor Hojtsy’s picture

#2599228: Programmatically created translatable content type returns SQL error on content creation landed, so this can continue working without outside dependencies now.

shaal’s picture

Status: Needs work » Needs review
FileSize
88.43 KB
3.57 KB

Based on patch #24 with these modifications:
Enable Recipe, Article, and Page content types + taxonomies to be translatable (You will see a "Translate" tab when viewing content)

The config files that have Translatable: true setting the fields that can be translatable, for an example in Recipe:
Ingredients, Recipe Instruction, Summary.
While the config files with Translatable: false setting the fields that should not be translatable, such as Tags (The tag translation happens in the tag content itself, the Tag ID stays the same in both languages).

shaal’s picture

The last submitted patch, 27: umami-import-multilingual-content-27.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

Status: Needs review » Needs work

The last submitted patch, 28: umami-import-multilingual-content-28.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

shaal’s picture

Import Spanish block content, connect block content with nodes through internal id (from CSV).

The 2 hero blocks (homepage and /recipes page) - are always in English, and wouldn't switch to Spanish.

Status: Needs review » Needs work

The last submitted patch, 31: umami-import-multilingual-content-31.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

Gábor Hojtsy’s picture

The hero block type is not configured to be translatable for most of its fields:

The other block types seem to be fine, but its worth double-checking them :)

shaal’s picture

Status: Needs work » Needs review
FileSize
98.37 KB
13.05 KB

@Gabor, thank you for these finding #33!
I looked into it and found 5 block fields that were not set as translatable.

Updated Spanish recipes of Vegan chocolate and nut brownies and

Super easy vegetarian pasta bake

Fixed code standards.
oops, I see now that I left a commented line by mistake, it's marked with ////

1 remaining task:
Update the Test to be aligned with Umami's multilingual changes.

Status: Needs review » Needs work

The last submitted patch, 34: umami-import-multilingual-content-34.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

smaz’s picture

This should fix the failing tests due to config mis-matching & the coding standards issue (just removed the commented out line).

smaz’s picture

Status: Needs work » Needs review

Setting to needs review to trigger testbot.

Status: Needs review » Needs work

The last submitted patch, 36: umami-import-multilingual-content-36.patch, failed testing. View results

smaz’s picture

Status: Needs work » Needs review
FileSize
1.91 KB

Fixing the new failures hopefully!

CSV headers now don't just try to get it from the english file.
Removed unused variable.

kjay’s picture

I'm having a stab at recreating the patch on behalf of @smaz based on the interdiff he posted in #39.

Status: Needs review » Needs work

The last submitted patch, 40: umami-import-multilingual-content-40.patch, failed testing. View results

shaal’s picture

+++ b/core/profiles/demo_umami/modules/demo_umami_content/src/InstallHelper.php
@@ -179,16 +175,12 @@ protected function readMultilingualContent($filename) {
-    }

@smaz re: #39, Why was this bracket removed?

shaal’s picture

Status: Needs work » Needs review
FileSize
103.39 KB
9.24 KB

This patch includes #40 and the following updates:

  • Added the latest missing recipes in Spanish
  • Blocks are linking to the node alias including its language
shaal’s picture

Fixed partial translation of Spanish recipe content.

kjay’s picture

Status: Needs review » Needs work

This is absolutely amazing work and it's so good to see this coming together.

This patch installed no problem for me and I was able to navigate around the translated content. The views provided the expected behaviour of offering less content when in Spanish (only offering the content actually translated).

A few minor issues that I noticed:

  1. The slug for the Spanish About Umami page could be translated based on the title but is still in English (could be 'acerca-de-umami' but is still 'about-umami').
  2. The link on the Spanish About Umami page to the drupal.org documentation has a space in the link text and has a space between the https: // which prevents the link from functioning. There are also spaces between the opening and closing a tag which may be undesired.
  3. It could just be my installation but I seem to end up with an empty 'article_body' directory at core/profiles/demo_umami/modules/demo_umami_content/default_content/article_body
  4. Line 4 of core/profiles/demo_umami/modules/demo_umami_content/default_content/languages/es/article_body/dairy-free-delicious-milk-chocolate.html has malformed closing h2 tag
  5. Line 1 of core/profiles/demo_umami/modules/demo_umami_content/default_content/languages/es/article_body/the-real-deal-for-supermarket-savvy-shopping.html has malformed closing p tag
shaal’s picture

Status: Needs work » Needs review
FileSize
105.62 KB
9.41 KB

Thank you @kjay !

I fixed the content and HTML typos as described in #45 + couple more I have found.

Re: 2)
Must be an old installation.
That directory is no longer in core and the files that used to be there were moved into ..../default_content/languages/en/article_body

shaal’s picture

Removed a space in the Spanish about page URL which made the link invalid.

Gábor Hojtsy’s picture

Status: Needs review » Needs work

Needs a reroll now that the content patches got committed.

shaal’s picture

Reroll for patch #47.

Removed all Spanish CSV files from the patch.

rteijeiro’s picture

Status: Needs review » Needs work
FileSize
542.13 KB

Things I noticed:

  1. When the installation is about to finish, the Site Name is automatically populated with "Umami Food Magazine". Not sure if that must be translated as well.
  2. After the installation is completed, I end up in a page with mixed content in Spanish and English (see screenshot) and without front page. The message "No front page content has been created yet." appears.
  3. Menu is not translated
  4. Articles are correctly translated.
  5. Recipes are not translated.
  6. Blocks are not translated. I can see "Recipe collections" block title untranslated but links are translated. Other blocks are still in English.

Anything else I should test?

shaal’s picture

Status: Needs work » Needs review

Thank you @rteijeiro !

You were testing the lean version of the import patch, which no longer contains CSV Spanish translations in it and depends on CSV's available in core.

When you tested this Blocks and Recipes were not in core yet - so you would only see the English version of the missing Spanish content.
In meantime - Block CSV patch got into core and very soon Recipes CSV patch should get into core as well.

Let's review this again as soon as #3038309: Spanish translations of Umami demo recipes got into core.

Gábor Hojtsy’s picture

Both of those are in now, @rteijeiro please retest. I think there will be somewhat different results, but some of the issues you found should still apply.

smaz’s picture

Status: Needs review » Needs work

I'm looking at the code, I haven't checked the resulting content:

importContentFromFile is called 8 times, and each time it will read/process the directories for what languages are there. Can this be refactored to only read the filesystem once?
Perhaps we should use https://api.drupal.org/api/drupal/core!lib!Drupal!Core!Language!Language... to get languages instead.

In readMultilingualContent, we have two foreach loops. We might be able to just use one:

// Add keys to each content in all languages.
    foreach ($translated_languages as $translated_language) {
      foreach ($data[$translated_language] as $index => $content) {
        $keyed_content[$translated_language][$index] = array_combine($header, $content);
      }
    }

Can we do the $keyed_content part here?

        while (($content = fgetcsv($handle)) !== FALSE) {
          $data[$language][$line_counter] = $content;
          $line_counter++;
        }
        fclose($handle);

A few other minor things:

getNodePath: $langcode, $content_type missing from docblock above
saveNodePath: $langcode, $content_type missing from docblock
processPage: unused $module_path argument
processRecipe: $langcode missing from docblock
processArticle: $langcode missing from docblock
processBannerBlock: $langcode missing from docblock
processDisclaimerBlock: No docblock, unused $module_path argument, function shouldn't have a blank line before $values =... I think
processFooterPromoBlock: No docblock
processContent: Docblock says 'Imports content', but this doesn't - it processes the content to be a structured array?
importContentFromFile: $ct_machine_name is not explained in the docblock

kjay’s picture

This patch installs well and I focused on reviewing the content installed and the behaviour of the site, which worked really well :) This is great work!

Unfortunately I did experience an issue with installation when using the interface. Installing with Drush seemed to work fine but with the interface there is a warning generated at the Configure site stage and it persists through the installation phase - see screenshot attached. Is this just happening for me?

Installation screen warnings

Once installed, the front page fails to load, I got a 404 unfortunately. This was cleared with by clicking on home. See the issue in the attached screenshot:

Post installation

The only code issue I spotted were the spaces between the opening and closing p tags in core/profiles/demo_umami/modules/demo_umami_content/default_content/languages/es/node/page.csv line 2.

shaal’s picture

Thank you @smaz and @kjay !

#53
Now using the API instead of figuring out languages to import according to existing directories.
readMultilingualContent function - is now adding the header in 1 loop instead of running a loop again.
Added missing entire docblocks and missing docblock pieces.

#54
That warning message during installation is a core issue, @gabor created a separate issue to solve that.
I couldn't reproduce getting a 404 page error after installation. Can you please provide steps to reproduce?

+ I added some extra performance improvements.

shaal’s picture

Thanks @kjay
Fixed 2 trailing whitespaces.

kjay’s picture

Status: Needs review » Reviewed & tested by the community

The patch on #56 installs without warnings or errors for me. I installed using the standard profile selection form and with Drush - both worked great with only the issue of the warning about 2 translation strings that @shaal has confirmed as being a core issue being addressed elsewhere.

I installed 3 times and didn't have a repeat of the 404 for the front page and this was probably just an error of how I was doing a previous test.

I visited all the pages in both English and Spanish and all worked as expected.

This is a fantastic feature for Umami - marking RTBC.

Gábor Hojtsy’s picture

Status: Reviewed & tested by the community » Needs work

Overall great stuff! Sorry, but found a bunch of code style / phpdoc issues :)

  1. +++ b/core/profiles/demo_umami/modules/demo_umami_content/src/InstallHelper.php
    @@ -66,6 +66,16 @@ class InstallHelper implements ContainerInjectionInterface {
    +   * Used to store node IDs created in the import process. This allows the created nodes
    +   * to be cross referenced when creating blocks.
    

    First line should wrap to 80 chars (before "created").

  2. +++ b/core/profiles/demo_umami/modules/demo_umami_content/src/InstallHelper.php
    @@ -110,49 +121,64 @@ public static function create(ContainerInterface $container) {
    +   * Read Multilingual Content.
    

    Should not be title cased.

  3. +++ b/core/profiles/demo_umami/modules/demo_umami_content/src/InstallHelper.php
    @@ -110,49 +121,64 @@ public static function create(ContainerInterface $container) {
    +   * @return array
    +   *   All multilingual content that was read from the files.
    +   *   List of language codes that need to be imported.
    

    An array with two items. The first item is an array of ..., the second item is an array of ....

  4. +++ b/core/profiles/demo_umami/modules/demo_umami_content/src/InstallHelper.php
    @@ -187,6 +213,50 @@ protected function saveTermId($vocabulary, $term_csv_id, $tid) {
    +   * Retrieves the Node path of Node ID saved during the import process.
    

    Don't capitalize Node.

  5. +++ b/core/profiles/demo_umami/modules/demo_umami_content/src/InstallHelper.php
    @@ -187,6 +213,50 @@ protected function saveTermId($vocabulary, $term_csv_id, $tid) {
    +   * @param string $langcode
    +   *   Current language code.
    +   *
    +   * @param string $content_type
    +   *   Current content type.
    +   *
    +   * @param string $node_id
    +   *   The node's ID from the CSV file.
    ...
    +   * @param string $langcode
    +   *   Current language code.
    +   *
    +   * @param string $content_type
    +   *   Current content type.
    +   *
    +   * @param string $node_id
    +   *   The node's ID from the CSV file.
    +   *
    +   * @param string $node_url
    +   *   Node's alias url when saved in the Drupal database.
    

    Should not have empty lines between these.

    If this node ID is an ID from the CSV file indeed, can we call it "node CSV ID" or somesuch to distinguish it clearly from node id as understood by Drupal? This would likely need to change elsewhere.

    alias url => URL alias

  6. +++ b/core/profiles/demo_umami/modules/demo_umami_content/src/InstallHelper.php
    @@ -187,6 +213,50 @@ protected function saveTermId($vocabulary, $term_csv_id, $tid) {
    +   * Saves a node ID generated when saving content.
    +   *
    +
    

    Extra empty line that does not even have a *

  7. +++ b/core/profiles/demo_umami/modules/demo_umami_content/src/InstallHelper.php
    @@ -216,314 +286,426 @@ protected function importEditors() {
    +    // Set field_preparation_time Field.
    

    Here and elsewhere in sentences, don't capitalize Field.

  8. +++ b/core/profiles/demo_umami/modules/demo_umami_content/src/InstallHelper.php
    @@ -216,314 +286,426 @@ protected function importEditors() {
    +   * @param array $data
    +   *   Data of line that was read from the file.
    +   *
    +   * @param string $langcode
    +   *   Current language code.
    

    Remove empty line between @params

  9. +++ b/core/profiles/demo_umami/modules/demo_umami_content/src/InstallHelper.php
    @@ -216,314 +286,426 @@ protected function importEditors() {
    +   * @param array $data
    +   *   Data of line that was read from the file.
    +   *
    +   * @param string $langcode
    +   *   Current language code.
    ...
    +   * @param array $data
    +   *   Data of line that was read from the file.
    +   *
    +   * @param string $langcode
    +   *   Current language code.
    ...
    +   * @param array $data
    +   *   Data of line that was read from the file.
    +   *
    +   * @param string $langcode
    +   *   Current language code.
    ...
    +   * @param string $bundle_machine_name
    +   *   Current bundle's machine name.
    +   *
    +   * @param string $content
    +   *   Current content that needs to be structured.
    +   *
    +   * @param string $langcode
    +   *   Current language code.
    

    Should not have empty line.

  10. +++ b/core/profiles/demo_umami/modules/demo_umami_content/src/InstallHelper.php
    @@ -216,314 +286,426 @@ protected function importEditors() {
    +   * @param string $entity_type
    +   *   Entity Type to be imported
    +   *
    +   * @param string $bundle_machine_name
    +   *
    

    Entity type...

    Should not have extra newline.

    Missing explanation for bundle machine name

smaz’s picture

A couple more to add:

1) Now that we have gone from the two for...each loops in readMultilingualContent, we don't need this else statement anymore:

protected function readMultilingualContent($filename) {
...
    else {
      // Language directory exists, but the file in this language was not found,
      // remove that language from list list of languages to be translated.
      $key = array_search($language, $translated_languages);
      unset($translated_languages[$key]);
       }
...


2) We should be using Dependency Injection for the language manager service. We can also improve this to only get the languages once, rather than every time we call readMultilingualContent().

+    $translated_languages = array_keys(\Drupal::languageManager()->getLanguages());

This would need:

protected $languageManager;
protected $enabledLanguages;

In create:

public static function create(...) {
...
$container->get('language_manager')
...
}

In __construct, add the language manager argument that's now being passed in:

  public function __construct(...) {
    ...
    $this->languageManager = $languageManager;
    $this->enabledLanguages = array_keys($this->languageManager->getLanguages());
  }

Then when we need to use the languages, we change from:

+    // Find all enabled languages.
+    $translated_languages = array_keys(\Drupal::languageManager()->getLanguages());
+
+    // Load all the content from any CSV files that exist for enabled languages.
+    foreach ($translated_languages as $language) {

to:

+    // Load all the content from any CSV files that exist for enabled languages.
+    foreach ($this->enabledLanguages as $language) {
smaz’s picture

Actually, my first point above may not be correct as `importContentFromFile` uses the returned $translated_languages.

shaal’s picture

Status: Needs work » Needs review
FileSize
73.36 KB
8.26 KB

Thank you @gabor and @smaz !

#58
I cleaned and organized all the comments.
I changed $node_id to $node_csv_id

#59
getLanguages() is now called only once at the beginning and then saved into a variable.

shaal’s picture

Minor capitalization fix.

kjay’s picture

I've reviewed the patch in #62 and the patch installs Umami no problem, whether by drush or profile selection screen.

I've checked every page in both English and Spanish and all look to be working as expected.

A review of the code (for formatting) all looks good with the exception of one possible issue, see the following screenshot of warning that PHPStorm flags for me - that a parameter description is offered for a missing parameter.

PHPStorm parameter warning.

shaal’s picture

Thank you @kjay

#63
Yes, that $langcode was no longer needed in that function. I removed the extra comment.

kjay’s picture

Status: Needs review » Reviewed & tested by the community

The patch in #64 takes care of the redundant comment and installs great. Great work! Going for another RTBC :)

  • Gábor Hojtsy committed f0d346e on 8.8.x
    Issue #3037111 by shaal, kjay, smaz, Gábor Hojtsy, rteijeiro: Import...
Gábor Hojtsy’s picture

Version: 8.8.x-dev » 8.7.x-dev
Status: Reviewed & tested by the community » Fixed
Issue tags: +8.7.0 highlights

Superb, thanks all! Committed to 8.8 and 8.7!

  • Gábor Hojtsy committed 2f069e8 on 8.7.x
    Issue #3037111 by shaal, kjay, smaz, Gábor Hojtsy, rteijeiro: Import...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.