Install&Update wordpress languages with composer

Thanks for pointing that out. It’s pretty easy to override that default hook file but it might be worth looking into to remove that specific option.

I think that --no-scripts is good for security especially for noobs. @swalkinshaw do you know if composer has option to allow specific script to run or specific package but deny all others? Like a whitelisting feature.

This might be pointless but anyone Is able to put harmless code in their composer packages and I guess that most users never look the code which is run in the implicit scripts like these language packages.

Don’t think that’s possible but you can always use composer run-script to manually trigger them.

This is my current workaround for a trellis-bedrock project to get the great composer language dropin up and running. If anyone has a better approach, please share :slightly_smiling:

  1. Remove --no-scripts flag from trellis/roles/deploy/hooks/build-after.yml. This enables composer to move the language files to the configured language directory. Note: imho we currently cannot use run-script, because the dropin installer doesn’t support triggering scripts (yet).
  2. Add web/app/languages/* to site/.gitignore (or wherever your bedrock project is located)
  3. The language folder has to be a shared folder on the server. Open trellis/roles/deploy/defaults/main.yml and add the following path to project_shared_children
project_shared_children:
[...]
  - path: web/app/languages
    src: languages
2 Likes

@o1y thanks for sharing this!

Two improvements/tips which both have to do with trying to avoid modifying “core” Trellis files:

  1. You could make a copy of roles/deploy/hooks/build-after.yml and make your customizations there. Then define the new hook file as see here.
  2. Override project_shared_children in your own group_vars folder. Maybe group_vars/all/main.yml

This will make it easier to keep Trellis up to date (if that’s a concern of yours).

3 Likes

BREAKING CHANGES
This repository is now located in: https://wp-languages.github.io

I needed to change the address because composer changed and needs all repositories as https. I redirected https://languages.koodimonni.fi to the new repository as well, but please use https://wp-languages.github.io instead than my server.

5 Likes

This repository only contains translations for core and few selected plugins (mainly core plugins + woocommerce, bbpress). I added details in wp-languages.github.io repo if you want to manually add any translation zip into your project.

If you can run wp-cli in your deploy please consider using it’s language features:

$ wp core language install fi
Success: Language installed.

# Updates (or installs) all languages for core, plugins and themes.
# When I runned this I had jetpack installed but without any translations.

$ wp core language update
Updating 'Finnish' translation for Jetpack by WordPress.com 3.9.2...
Downloading translation from https://downloads.wordpress.org/translation/plugin/jetpack/3.9.2/fi.zip...
Translation updated successfully.
Success: Updated 1/1 translations.

It will contain every plugin translation package always. https://wp-languages.github.io can’t contain all translation data in it’s current form, but if you only need core translations it is a really handy tool.

5 Likes

@Koodimonni, thank you for your work! :slight_smile:

If anyone wants to integrate the WP-CLI way into their deployments, I posted my workflow here:

Thanks @Koodimonni for your great work. I noticed some strange behaviour though:

When switching to any other language but english (tried de and fr), the visual post editor will not show since the language files for tinymce are missing.

Am I missing something or should they be added to the packages?

Wordpress expects them to be in web/wp/wp-includes/js/tinymce/langs. However, with "koodimonni-language/core-de_de" for example, I am not getting any other languages installed there except the default wp-langs-en.js.

Here’s a screenshot on how to reproduce this:

I haven’t installed anything extra besides the language packages from my composer packages.

Here’s a screenshot from finnish koodimonni-language/core-fi package in chrome:

So because it works for me I can’t really easily debug this for you.

If you really want my help please start an issue in Github instead rather than posting over here.

The example behind your link doesn’t work .
The dropin-paths don’t match the ones in your post.

I can’t get it to work at all. What would a working composer.json look like and where would the languages be installed?

@marcelgro It works just fine for me.

Here’s the example steps you can follow:

# Create temporary folder for testing
$ mkdir /tmp/composer-test
$ cd /tmp/composer-test

# Download the example composer.json
$ curl -O https://gist.githubusercontent.com/onnimonni/154cd5988cb93f2490c5/raw/d80fecd50bcb191e19ea1f4b1607a16dc41a7321/composer.json

# Install packages with composer
$ composer install

# List all files
$ tree
.
├── composer.json
├── composer.lock
├── htdocs
│   ├── wordpress
│   │   ├── composer.json
│   │   ├── index.php
│   │   ├── license.txt
│   │   ├── readme.html
│   │   ├── wp-activate.php
│   │   ├── wp-admin
│   │   └── ...
│   └── wp-content
│       ├── languages
│       │   ├── admin-az.mo
│       │   ├── admin-az.po
│       │   ├── admin-ca.mo
│       │   ├── admin-ca.po
│       │   ├── admin-en_AU.mo
│       │   ├── admin-en_AU.po
│       │   ├── admin-en_GB.mo
│       │   ├── admin-en_GB.po
│       │   ├── admin-fi.mo
│       │   ├── admin-fi.po
│       │   ├── admin-fr_FR.mo
│       │   ├── admin-fr_FR.po
│       │   ├── admin-network-az.mo
│       │   ├── admin-network-az.po
│       │   ├── admin-network-ca.mo
│       │   ├── admin-network-ca.po
│       │   ├── admin-network-en_AU.mo
│       │   ├── admin-network-en_AU.po
│       │   ├── admin-network-en_GB.mo
│       │   ├── admin-network-en_GB.po
│       │   ├── admin-network-fi.mo
│       │   ├── admin-network-fi.po
│       │   ├── admin-network-fr_FR.mo
│       │   ├── admin-network-fr_FR.po
│       │   ├── admin-network-nl_NL.mo
│       │   ├── admin-network-nl_NL.po
│       │   ├── admin-network-ru_RU.mo
│       │   ├── admin-network-ru_RU.po
│       │   ├── admin-nl_NL.mo
│       │   ├── admin-nl_NL.po
│       │   ├── admin-ru_RU.mo
│       │   ├── admin-ru_RU.po
│       │   ├── az.mo
│       │   ├── az.po
│       │   ├── ca.mo
│       │   ├── ca.po
│       │   ├── continents-cities-az.mo
│       │   ├── continents-cities-az.po
│       │   ├── continents-cities-ca.mo
│       │   ├── continents-cities-ca.po
│       │   ├── continents-cities-fi.mo
│       │   ├── continents-cities-fi.po
│       │   ├── continents-cities-fr_FR.mo
│       │   ├── continents-cities-fr_FR.po
│       │   ├── continents-cities-nl_NL.mo
│       │   ├── continents-cities-nl_NL.po
│       │   ├── continents-cities-ru_RU.mo
│       │   ├── continents-cities-ru_RU.po
│       │   ├── en_AU.mo
│       │   ├── en_AU.po
│       │   ├── en_GB.mo
│       │   ├── en_GB.po
│       │   ├── fi.mo
│       │   ├── fi.po
│       │   ├── fr_FR.mo
│       │   ├── fr_FR.po
│       │   ├── nl_NL.mo
│       │   ├── nl_NL.po
│       │   ├── plugins
│       │   │   ├── akismet-az.mo
│       │   │   ├── akismet-az.po
│       │   │   ├── akismet-ca.mo
│       │   │   ├── akismet-ca.po
│       │   │   ├── akismet-en_AU.mo
│       │   │   ├── akismet-en_AU.po
│       │   │   ├── akismet-en_GB.mo
│       │   │   ├── akismet-en_GB.po
│       │   │   ├── akismet-fi.mo
│       │   │   ├── akismet-fi.po
│       │   │   ├── akismet-fr_FR.mo
│       │   │   ├── akismet-fr_FR.po
│       │   │   ├── akismet-nl_NL.mo
│       │   │   ├── akismet-nl_NL.po
│       │   │   ├── akismet-ru_RU.mo
│       │   │   ├── akismet-ru_RU.po
│       │   │   ├── bbpress-ca.mo
│       │   │   ├── bbpress-ca.po
│       │   │   ├── bbpress-en_AU.mo
│       │   │   ├── bbpress-en_AU.po
│       │   │   ├── bbpress-en_GB.mo
│       │   │   ├── bbpress-en_GB.po
│       │   │   ├── bbpress-fi.mo
│       │   │   ├── bbpress-fi.po
│       │   │   ├── bbpress-fr_FR.mo
│       │   │   ├── bbpress-fr_FR.po
│       │   │   ├── bbpress-nl_NL.mo
│       │   │   ├── bbpress-nl_NL.po
│       │   │   ├── bbpress-ru_RU.mo
│       │   │   ├── bbpress-ru_RU.po
│       │   │   ├── woocommerce-ca.mo
│       │   │   ├── woocommerce-ca.po
│       │   │   ├── woocommerce-en_AU.mo
│       │   │   ├── woocommerce-en_AU.po
│       │   │   ├── woocommerce-en_GB.mo
│       │   │   ├── woocommerce-en_GB.po
│       │   │   ├── woocommerce-fi.mo
│       │   │   ├── woocommerce-fi.po
│       │   │   ├── woocommerce-fr_FR.mo
│       │   │   ├── woocommerce-fr_FR.po
│       │   │   ├── woocommerce-nl_NL.mo
│       │   │   ├── woocommerce-nl_NL.po
│       │   │   ├── woocommerce-ru_RU.mo
│       │   │   ├── woocommerce-ru_RU.po
│       │   │   ├── wordpress-importer-az.mo
│       │   │   ├── wordpress-importer-az.po
│       │   │   ├── wordpress-importer-ca.mo
│       │   │   ├── wordpress-importer-ca.po
│       │   │   ├── wordpress-importer-en_AU.mo
│       │   │   ├── wordpress-importer-en_AU.po
│       │   │   ├── wordpress-importer-en_GB.mo
│       │   │   ├── wordpress-importer-en_GB.po
│       │   │   ├── wordpress-importer-fi.mo
│       │   │   ├── wordpress-importer-fi.po
│       │   │   ├── wordpress-importer-fr_FR.mo
│       │   │   ├── wordpress-importer-fr_FR.po
│       │   │   ├── wordpress-importer-nl_NL.mo
│       │   │   ├── wordpress-importer-nl_NL.po
│       │   │   ├── wordpress-importer-ru_RU.mo
│       │   │   └── wordpress-importer-ru_RU.po
│       │   ├── ru_RU.mo
│       │   ├── ru_RU.po
│       │   └── themes
│       │       ├── twentyeleven-az.mo
│       │       ├── twentyeleven-az.po
│       │       ├── twentyeleven-ca.mo
│       │       ├── twentyeleven-ca.po
│       │       ├── twentyeleven-en_AU.mo
│       │       ├── twentyeleven-en_AU.po
│       │       ├── twentyeleven-en_GB.mo
│       │       ├── twentyeleven-en_GB.po
│       │       ├── twentyeleven-fi.mo
│       │       ├── twentyeleven-fi.po
│       │       ├── twentyeleven-fr_FR.mo
│       │       ├── twentyeleven-fr_FR.po
│       │       ├── twentyeleven-nl_NL.mo
│       │       ├── twentyeleven-nl_NL.po
│       │       ├── twentyeleven-ru_RU.mo
│       │       ├── twentyeleven-ru_RU.po
│       │       ├── twentyfifteen-az.mo
│       │       ├── twentyfifteen-az.po
│       │       ├── twentyfifteen-ca.mo
│       │       ├── twentyfifteen-ca.po
│       │       ├── twentyfifteen-en_AU.mo
│       │       ├── twentyfifteen-en_AU.po
│       │       ├── twentyfifteen-en_GB.mo
│       │       ├── twentyfifteen-en_GB.po
│       │       ├── twentyfifteen-fi.mo
│       │       ├── twentyfifteen-fi.po
│       │       ├── twentyfifteen-fr_FR.mo
│       │       ├── twentyfifteen-fr_FR.po
│       │       ├── twentyfifteen-nl_NL.mo
│       │       ├── twentyfifteen-nl_NL.po
│       │       ├── twentyfifteen-ru_RU.mo
│       │       ├── twentyfifteen-ru_RU.po
│       │       ├── twentyfourteen-az.mo
│       │       ├── twentyfourteen-az.po
│       │       ├── twentyfourteen-ca.mo
│       │       ├── twentyfourteen-ca.po
│       │       ├── twentyfourteen-en_AU.mo
│       │       ├── twentyfourteen-en_AU.po
│       │       ├── twentyfourteen-en_GB.mo
│       │       ├── twentyfourteen-en_GB.po
│       │       ├── twentyfourteen-fi.mo
│       │       ├── twentyfourteen-fi.po
│       │       ├── twentyfourteen-fr_FR.mo
│       │       ├── twentyfourteen-fr_FR.po
│       │       ├── twentyfourteen-nl_NL.mo
│       │       ├── twentyfourteen-nl_NL.po
│       │       ├── twentyfourteen-ru_RU.mo
│       │       ├── twentyfourteen-ru_RU.po
│       │       ├── twentysixteen-az.mo
│       │       ├── twentysixteen-az.po
│       │       ├── twentysixteen-ca.mo
│       │       ├── twentysixteen-ca.po
│       │       ├── twentysixteen-en_AU.mo
│       │       ├── twentysixteen-en_AU.po
│       │       ├── twentysixteen-en_GB.mo
│       │       ├── twentysixteen-en_GB.po
│       │       ├── twentysixteen-fi.mo
│       │       ├── twentysixteen-fi.po
│       │       ├── twentysixteen-fr_FR.mo
│       │       ├── twentysixteen-fr_FR.po
│       │       ├── twentysixteen-nl_NL.mo
│       │       ├── twentysixteen-nl_NL.po
│       │       ├── twentysixteen-ru_RU.mo
│       │       ├── twentysixteen-ru_RU.po
│       │       ├── twentyten-az.mo
│       │       ├── twentyten-az.po
│       │       ├── twentyten-ca.mo
│       │       ├── twentyten-ca.po
│       │       ├── twentyten-en_AU.mo
│       │       ├── twentyten-en_AU.po
│       │       ├── twentyten-en_GB.mo
│       │       ├── twentyten-en_GB.po
│       │       ├── twentyten-fi.mo
│       │       ├── twentyten-fi.po
│       │       ├── twentyten-fr_FR.mo
│       │       ├── twentyten-fr_FR.po
│       │       ├── twentyten-nl_NL.mo
│       │       ├── twentyten-nl_NL.po
│       │       ├── twentyten-ru_RU.mo
│       │       ├── twentyten-ru_RU.po
│       │       ├── twentythirteen-az.mo
│       │       ├── twentythirteen-az.po
│       │       ├── twentythirteen-ca.mo
│       │       ├── twentythirteen-ca.po
│       │       ├── twentythirteen-en_AU.mo
│       │       ├── twentythirteen-en_AU.po
│       │       ├── twentythirteen-en_GB.mo
│       │       ├── twentythirteen-en_GB.po
│       │       ├── twentythirteen-fi.mo
│       │       ├── twentythirteen-fi.po
│       │       ├── twentythirteen-fr_FR.mo
│       │       ├── twentythirteen-fr_FR.po
│       │       ├── twentythirteen-nl_NL.mo
│       │       ├── twentythirteen-nl_NL.po
│       │       ├── twentythirteen-ru_RU.mo
│       │       ├── twentythirteen-ru_RU.po
│       │       ├── twentytwelve-az.mo
│       │       ├── twentytwelve-az.po
│       │       ├── twentytwelve-ca.mo
│       │       ├── twentytwelve-ca.po
│       │       ├── twentytwelve-en_AU.mo
│       │       ├── twentytwelve-en_AU.po
│       │       ├── twentytwelve-en_GB.mo
│       │       ├── twentytwelve-en_GB.po
│       │       ├── twentytwelve-fi.mo
│       │       ├── twentytwelve-fi.po
│       │       ├── twentytwelve-fr_FR.mo
│       │       ├── twentytwelve-fr_FR.po
│       │       ├── twentytwelve-nl_NL.mo
│       │       ├── twentytwelve-nl_NL.po
│       │       ├── twentytwelve-ru_RU.mo
│       │       └── twentytwelve-ru_RU.po
│       ├── object-cache.php
│       ├── plugins
│       │   └── wp-redis
│       │       ├── ...
│       └── themes
│           └── twentyfifteen
│               ├── ...
└── vendor
    ├── autoload.php
    ├─...

@koodimonni Great work! But I have a question. How to handle custom translations? I have overwritten a single translation in wp-content/languages/plugins/woocommmerce_nl-NL.po file. Will this translation be lost when woocommerce ships a new translation file? If yes, how can I avoid this?

Thanks in advance for your help!

1 Like

First, I’d like to thank you for the awesome work.

I’ve noticed that even if you use the catch-all meta-package approach, wordpress will still complain about out of date locales, and of course it won’t show you which ones unless you insert ftp credentials, so I’m left unable to know the status of locales.

I mean, this more of a wordpress deficiency than koodimonni related but posting here because there’s a chance people coming to this page have had this issue. It’s minor but still bothers me (:

I am using the wp CLI for installing + updating the core, theme and plugin languages.
This won’t lock the language version in, but it will work per deploy and still fast.
See these docs: https://github.com/roots/docs/pull/191; formatted version

It’s fantastic!
I just knew Bedrock and I’m loving it

@carloseduardo: There is now also a documentation page for this:

3 Likes