Setting Up Language Packs
Omnalingo depends on WordPress language packs (.mo, .po, and .l10n.php files) for gettext string detection and gap analysis. Without them, WooCommerce and plugin UI strings either show in the source language or fall through to AI translation unnecessarily. This guide covers how the download process works and how to fix it when it goes wrong.
Why Language Packs Matter
Section titled “Why Language Packs Matter”Omnalingo’s GettextGapService checks whether each gettext string on a page already has coverage in the installed .mo or .l10n.php file for the target language. Strings with coverage are counted toward translation progress but are not stored in Omnalingo’s database — WordPress handles them. Strings without coverage are stored and queued for AI translation.
If the language pack for WooCommerce has not been downloaded, GettextGapService will find no coverage for WooCommerce strings and send all of them to the AI — wasting API quota on strings that WooCommerce already translates. Getting language packs in place before scanning saves API credits and produces more consistent translations.
How the Download Process Works
Section titled “How the Download Process Works”Language pack downloading is handled by LanguagePackService (src/Service/LanguagePackService.php) via a three-phase process triggered automatically when you add a new target language:
Phase 1 — Core language packs:
Calls WordPress’s wp_download_language_pack($locale) for each locale. Downloads .mo, .po, and .l10n.php files for WordPress core into wp-content/languages/. This must complete first because WordPress needs these files to correctly query api.wordpress.org for plugin and theme packs.
Phase 2 — Update checks:
Deletes the _site_transient_update_plugins and _site_transient_update_themes options to force a fresh API query. This ensures newly added locales are included in the check.
Phase 3 — Plugin and theme packs:
Downloads translation packs for all active plugins and the active theme (plus its parent). Uses WordPress’s Language_Pack_Upgrader internally.
Download progress is stored in the omnalingo_langpack_status WordPress option and polled by the admin sidebar widget.
Checking the Current Download State
Section titled “Checking the Current Download State”SELECT option_value FROM wp_options WHERE option_name = 'omnalingo_langpack_status';status value | Meaning |
|---|---|
starting | Download initiated, about to begin Phase 1 |
downloading_core | Phase 1 in progress |
checking_updates | Phase 2 in progress |
downloading_packs | Phase 3 in progress |
complete | All phases finished |
error | Pre-flight filesystem check failed |
idle / no row | No active download |
A stale-detection mechanism in LanguagePackService::getStatus() automatically clears any active state that has been running for more than 5 minutes. If the widget is still showing a spinner after 5 minutes, the process crashed — wait for auto-clear or delete the option manually.
Checking What Is Actually Installed
Section titled “Checking What Is Actually Installed”To see which locale files are present on disk:
ls wp-content/languages/ | grep deExpected files for German (de_DE):
de_DE.mo— WordPress core binary translation filede_DE.po— WordPress core source translation filede_DE.l10n.php— WordPress 6.5+ performant format (may not be present on older WP)
ls wp-content/languages/plugins/ | grep de_DEls wp-content/languages/themes/ | grep de_DEPlugin packs follow the naming convention pluginslug-de_DE.mo. For WooCommerce: woocommerce-de_DE.mo.
When Downloads Fail
Section titled “When Downloads Fail”Filesystem Not Writable
Section titled “Filesystem Not Writable”The most common failure. LanguagePackService runs wp_can_install_language_pack() as a pre-flight check. If this returns false, status is set to error and the download aborts immediately.
Fix:
Check write permissions on wp-content/languages/:
ls -la wp-content/languages/The directory must be writable by the web server user (typically www-data or apache). If it is not:
chmod 755 wp-content/languages/chown www-data:www-data wp-content/languages/Core Pack Downloaded But Plugin/Theme Packs Missing
Section titled “Core Pack Downloaded But Plugin/Theme Packs Missing”Phase 3 depends on the update_plugins and update_themes transients returning data that includes the newly added locale. On recently migrated or cached sites, these transients may contain stale data.
Fix: Delete the transients manually:
DELETE FROM wp_optionsWHERE option_name IN ( '_site_transient_update_plugins', '_site_transient_update_themes');Then save the language settings again — SettingsController::updateSettings() will detect the locale is still missing and trigger a fresh download.
Download Appears Stuck
Section titled “Download Appears Stuck”The admin widget polls GET /wp-json/omnalingo/v1/settings/language-packs/status. If the status option has been in an active state for more than 5 minutes, LanguagePackService::getStatus() clears it automatically. If the widget is stuck before the 5-minute threshold:
- Check the plugin log for
[ERROR]entries fromLanguagePackService. - Clear the status manually:
DELETE FROM wp_options WHERE option_name = 'omnalingo_langpack_status';
- Retry via the REST API:
Terminal window curl -X POST -H "X-WP-Nonce: $NONCE" \https://yoursite.com/wp-json/omnalingo/v1/settings/language-packs
After a Server Migration
Section titled “After a Server Migration”Language files live in wp-content/languages/ and are typically not included in code-only deployments. After migrating a WordPress site to a new server, language files may be absent even though Omnalingo’s settings still show languages as configured.
Automatic recovery: Simply save the language settings in wp-admin → Omnalingo → Settings → Languages once. SettingsController::updateSettings() compares configured locales against get_available_languages() (which reads the filesystem). Any missing locales trigger a download automatically.
Manual verification before saving:
wp eval 'echo implode("\n", get_available_languages());'If the target locale (e.g., de_DE) is not listed, it needs to be downloaded.
Manually Downloading Language Packs via WP-CLI
Section titled “Manually Downloading Language Packs via WP-CLI”If you need to force a download outside of the Omnalingo UI:
# Download WordPress core packwp language core install de_DE
# Download all plugin packs for a localewp language plugin install --all de_DE
# Download active theme packwp language theme install twentytwentyfour de_DEAfter manually installing packs, save the language settings in Omnalingo once — the health check will confirm they are present and skip re-downloading.
Verifying Gap Detection is Working
Section titled “Verifying Gap Detection is Working”After language packs are installed, run a scan and then check whether gettext strings are being classified correctly:
SELECT type, COUNT(*) FROM wp_omnalingo_strings GROUP BY type;If you see a large number of gettext-type strings with no corresponding html strings, something is wrong with the string classification — check the scan setup. A healthy scan on a WooCommerce site typically shows a mix of html and gettext types.