Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Language Command Laravel Package

wp-cli/language-command

A WP-CLI package for installing, activating, and managing WordPress language packs from the command line, covering core, themes, and plugins so you can add or update translations across your site quickly and consistently.

View on GitHub
Deep Wiki
Context7

Getting Started

This is not a Laravel package — there is no service provider, facade, or config file to publish. It is a WP-CLI command bundle that ships inside WP-CLI itself, so in most environments wp language already works and wp package install wp-cli/language-command is only needed if you are pinning a specific version or running a stripped-down WP-CLI PHAR.

Minimal steps:

  1. Have a working WordPress install reachable from the CLI (wp core is-installed returns 0). Every subcommand needs wp-config.php and a database connection, even list.
  2. Read the surface area first, not the README examples:
wp help language            # top-level: core / plugin / theme
wp help language core       # install, list, update, uninstall, is-installed
wp help language plugin     # adds <plugin> / --all positional handling
  1. Sanity-check connectivity to WordPress.org before wiring anything into a pipeline:
wp language core list --status=installed --format=json

First real use case: a deploy step that guarantees a locale is present and active for a WordPress site your Laravel app fronts (headless content API, marketing site behind a Laravel gateway, or a multisite you operate).

wp language core install pt_BR --activate
wp language plugin install woocommerce pt_BR
wp language theme install storefront pt_BR

If you are on Laravel side, wrap it once and never touch raw shell again:

use Symfony\Component\Process\Process;

function wp(string $sitePath, array $args): array
{
    $process = new Process(['wp', ...$args, '--path='.$sitePath, '--format=json'], timeout: 300);
    $process->run();

    return [
        'ok'     => $process->isSuccessful(),
        'stdout' => $process->getOutput(),
        'stderr' => $process->getErrorOutput(),
        'code'   => $process->getExitCode(),
    ];
}

Implementation Patterns

Map Laravel locales to WP locales explicitly. WordPress uses its own codes (pt_BR, nl_NL, ja, de_DE, zh_CN). Do not derive them from config('app.locale'); keep a lookup table so an unknown Laravel locale fails loudly instead of silently installing nothing.

Use is-installed as an idempotency gate, not install as a no-op. install re-downloads every time; the exit-code contract is the cheap check:

wp language core is-installed pt_BR || wp language core install pt_BR --activate

Exit code 0 = installed, 1 = not installed. Never parse the human output for this.

Deploy ordering matters. Language packs are versioned against the exact core/plugin/theme version string. Install translations after wp core update / plugin updates, never before:

wp core update --minor
wp plugin update --all
wp theme update --all
wp language core update
wp language plugin update --all
wp language theme update --all

Use --dry-run in "report" jobs. wp language plugin update --all --dry-run gives you the "what changed upstream" signal for a nightly digest without touching a live site.

Pull machine-readable output with --format=json/--fields, never the table. Tables are for humans and change column widths between versions:

wp language plugin list --all --fields=plugin,language,status,update --format=json

Then in PHP, filter for status === 'installed' && update !== 'none' to build the update queue yourself.

Fan out by enumerating plugins first. --all is convenient but opaque when one plugin has no translation; if you need per-item error handling, loop:

wp plugin list --field=name --format=json
# then: wp language plugin install <name> pt_BR

Use --activate instead of a second call. wp language core install nl_NL --activate is one round trip. Note wp language core activate is deprecated; the replacement is wp site switch-language nl_NL (in multisite terms: the language is a site option, not a network option).

Artisan command shape. A single wp:languages:sync {--dry-run} {--site=} command that (a) checks core is-installed, (b) installs missing core packs, (c) iterates active plugins, (d) runs updates, and (e) emits a --format=summary result is the right granularity. Keep one command; don't build four.

Cache wp-content/languages/ in CI/Docker. It is a pure download directory. Baking it into an image build saves minutes per pipeline, and re-running update at deploy time is cheap and safe when the directory is already populated.

Persist the directory across deploys. On immutable/containerized hosting, wp-content/languages must be on a persisted volume or rebuilt on every release — otherwise translations silently vanish on the next deploy while wp option get WPLANG still says pt_BR.

Gotchas and Tips

  • Deprecated entry point. wp language core activate still works but emits a deprecation warning; pin your scripts to wp site switch-language. Grep old runbooks for language core activate.
  • --format on update changes the output contract, not just the formatting. Without --format, you get progress lines and success/warning/error messages on stderr; with --format=json, you get structured data. Do not add --format=json to a job whose logs you read manually and then wonder where the progress went.
  • wp language core list without --status=installed returns all available languages (hundreds), most marked uninstalled. Always filter — unfiltered output is a common cause of "the command hung" reports on slow connections.
  • Translations depend on exact version strings. If a plugin is at 1.7.2 and the translation pack is built for 1.7.1, install may report success while the update column stays available. Check update and updated fields rather than trusting the success line.
  • Network dependency is absolute. Every install/update hits downloads.wordpress.org. Air-gapped builds, restricted egress, or a CI proxy will fail these calls — make them a separate, skippable pipeline stage rather than blocking composer install-style setup.
  • Filesystem permissions bite in containers. WP-CLI writes via the Language_Pack_Upgrader, which honors FS_METHOD. If wp-content is root-owned and PHP runs as www-data, you get "Could not create directory" — fix the mount ownership, not FS_METHOD=direct.
  • Multisite: installing is network-wide, activating is per-site. wp language core install puts files in the shared wp-content/languages; wp site switch-language writes a per-site option. Looping sites with --url= on a large network is slow — batch it and log per-site results.
  • --all on plugin install/uninstall is a blunt instrument. It targets all plugins, including inactive ones, and multiplies download time linearly. Prefer the explicit plugin list unless you genuinely want everything.
  • Tests: use When I try ... for expected failures. In Behat, an error output makes When I run fail the scenario; wp language ... is-installed on a missing pack exits 1 and needs try. Same lesson applies to your Laravel feature tests — assert on exit codes, not on error strings.
  • Extension points are WP-CLI-level, not package-level. To intercept translation behavior you hook the underlying WordPress APIs (translations_api, async_update_translation, upgrader_process_complete) or register your own WP_CLI::add_command. There is no plugin-style extension hook exposed by this command package itself.
  • Don't vendor this into your Laravel app. It has a shell-level dependency on a WP-CLI binary and a WordPress filesystem. Treat it as an external tool invoked via Symfony\Process, pinned to a tested WP-CLI version in your image, and assert the version at boot (wp --version) so a host upgrade doesn't change translation behavior under you.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast