mathieumaingret/drup_csv2po

Generates the PO files of a module or a theme from a CSV translation file.

Maintainers

Package info

github.com/mathieumaingret/drup_csv2po

Type:drupal-module

pkg:composer/mathieumaingret/drup_csv2po

Transparency log

Statistics

Installs: 8 305

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

1.7 2026-07-28 08:47 UTC

This package is auto-updated.

Last update: 2026-07-28 08:48:18 UTC


README

Generates the PO files of a module or a theme from a CSV translation file, typically a Google Sheet exported as CSV. One PO file is written per language column found in the CSV.

Requirements

  • Drush
  • The language and locale core modules, both declared as dependencies.

Setup

  1. Tell Drupal where the translation files of the module or theme live, in its own .info.yml:

    'interface translation project': my_module
    'interface translation server pattern': modules/custom/my_module/translations/%project.%language.po
  2. At /admin/config/regional/translate/settings, set Translation source overwrite to All.

  3. Declare the CSV URL in settings.php:

    $settings['drup_csv2po']['csv_remote_url'] = 'https://docs.google.com/spreadsheets/d/[ID]/gviz/tq?tqx=out:csv';
    $settings['drup_csv2po']['extension_name'] = 'my_module';

Usage

drush csv2po

The command downloads the CSV, writes one PO file per language next to it, and points you to /admin/reports/translations to import them.

Which extension is translated

extension_name is looked up in the modules first, then in the themes. Without a value, the site's default theme is used. A name matching neither is rejected.

# A theme.
drush csv2po --extension_name=backend

# A module.
drush csv2po --extension_name=my_module

# Overriding the CSV URL for one run.
drush csv2po --csv_remote_url='https://docs.google.com/spreadsheets/d/XXX/gviz/tq?tqx=out:csv'

Options

Every option can be set in settings.php under $settings['drup_csv2po'], or passed to the command. The command line wins over settings.php, which wins over the defaults.

Option Default Description
extension_name the default theme Machine name of the module or theme to translate.
extension_translations_directory translations Directory, inside the extension, the files are written to.
csv_remote_url none URL the CSV is downloaded from. Required.
csv_output_filename translations.csv Name the downloaded CSV is saved under.
plural_value_separator PHP_EOL Separator between the singular and the plural value of a cell.
check_enabled_languages TRUE Only generate files for languages enabled on the site.
translations_source_langcode en Langcode of the column strings are translated from.

The canonical list is ConverterOptions::DEFAULTS.

CSV format

Column names are matched case insensitively.

Column Required Description
PAGE yes Grouping label. A comment banner is written whenever it changes. May be left empty on a row.
CONTEXT yes Translation context. May be left empty on a row.
PLURAL yes When filled, the source and translation cells hold a singular and a plural value, separated by plural_value_separator.
source langcode yes The strings to translate. EN unless translations_source_langcode says otherwise.
[LANGCODE] One column per translation, named after the langcode.

A row is skipped when its source or its translation is empty, so a language column can be filled progressively.

Example

"PAGE","CONTEXT","PLURAL","EN","FR","DE"
"FAQ","","","Frequently asked questions","Questions fréquentes","Häufig gestellte Fragen"
"FAQ","","","Search by keywords","Rechercher par mots-clés","Nach Stichwörtern suchen"
"SEARCH","","1","@count result
@count results","@count résultat
@count résultats","@count Ergebnis
@count Ergebnisse"

Safeguards

  • A CSV missing a required column aborts the run, naming the columns.
  • A language whose column holds no translation at all leaves its PO file untouched, so an emptied column cannot wipe the translations of a site.
  • Two rows sharing a context and a source string are reported: the last one wins.
  • A malformed plural value is imported as a singular translation, with a warning.