MLP Multilingual
Multilingual content, language-aware URLs, and full bidirectional RTL support for WordPress.
by Sahbi Ben Gdaiem · github.com/gsahbi/mlp-multilingual · website
Install
No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:
wp plugin install https://github.com/gsahbi/mlp-multilingual/archive/refs/heads/main.zipMLP Multilingual is a WordPress plugin for running one site in several languages. It's for site owners and developers who want to translate posts, pages and terms, route each language under its own URL, and offer visitors a language switcher — without a translation-job workflow, machine translation, or a WooCommerce dependency they don't need.
Content stays entirely under the site owner's control: every translation is written by a person with the right WordPress capability, the same way any other post is edited.
Features
- Content translation for posts, pages and any taxonomy, linked into translation groups.
- Four URL strategies: a language directory (
/fr/), a subdomain (fr.example.com), a separate domain per language, or a?lang=query parameter. - A language switcher available as a block, a
[mlp_language_switcher]shortcode, and a widget. - Reciprocal
hreflangannotations (includingx-default) on translated posts and pages. - Full bidirectional RTL support, including a block editor canvas that flips to match the post's own language while the admin chrome stays in the site's admin language.
- Admin screens for Languages, Settings, Tools and Strings.
- REST API support: language fields on post responses, and a
langcollection parameter for filtering requests by language. - Compatibility functions for themes and plugins written against Polylang or WPML (activation is refused while either is actually active — see the user guide).
- String translation for gettext strings and for literal text labels baked into block markup, from a dedicated admin screen.
It deliberately does not do translation-job management, machine translation, WooCommerce integration, or WordPress multisite/network installs. See the user guide's first section for the full list of what it does and doesn't cover.
Requirements
- WordPress 6.4 or newer.
- PHP 8.1 or newer.
- Polylang and WPML must not be active at the same time as this plugin.
Installation
From a zip
- Upload the plugin's zip through the WordPress admin's Plugins → Add
New → Upload Plugin, or extract it into
wp-content/plugins/on the server. - Activate it from the Plugins screen. Activation is refused (with an explanation) if Polylang or WPML is currently active — deactivate whichever one you are replacing first.
- Continue with the user guide's quick start to add your first languages.
This plugin is not (yet) listed on WordPress.org (see Project status
below); build the zip yourself with bin/build-zip from a checkout of this
repository — see Development below.
For development
- Clone this repository.
- Install the containerised toolchain's prerequisites: Docker and Node. No local PHP, Composer, or WP-CLI install is required — see Development below for how those run instead.
bin/composer installto install PHP dependencies.npx wp-env startto bring up a local WordPress instance athttp://localhost:8888, with this checkout mounted as themlp-multilingualplugin (see.wp-env.json).bin/seed-e2eif you want the same demo content (languages, a/language-demo/page, and a translated post pair) the e2e suite reads.
Documentation
The user guide is written for the person running the site — everything from installation to the exact wording you'll see when something goes wrong, with no assumed knowledge of how the plugin is built.
Contributing code or documentation instead? See CONTRIBUTING.md.
Licence
GPL-2.0-or-later. See LICENSE for the full text.
Project status
Version 0.1.0 — pre-release. The plugin is feature-complete against its own
design spec and its test suite is green (unit, integration and end-to-end
tiers; see Development below), but it is not yet listed on
WordPress.org, and its plugin header, LICENSE and readme.txt still carry
a handful of TODO: placeholders (author name and URLs, WordPress.org
contributor usernames) that only the maintainer publishing it can fill in.
Single-site only; no WordPress Multisite/network support is planned.
Development
There is no PHP, Composer, or WP-CLI on the development host -- only Docker
and Node. PHP tooling therefore runs inside containers, and Node tooling runs
through the locally installed Node (npx), both hidden behind bin/
wrappers so none of the commands below need a local PHP install:
| Command | Runs |
|---|---|
bin/test [unit\|integration\|e2e\|all] |
PHPUnit -- unit tier standalone, integration tier against a wp-env WordPress instance. e2e is Playwright (spec 13's third tier: the RTL canvas and the language switcher, only observable in a real browser) and runs against the wp-env dev instance at http://localhost:8888 -- it is deliberately not included in all, since (unlike unit/integration) it depends on content bin/seed-e2e must seed first, rather than each test building its own fixtures |
bin/seed-e2e |
Activates the plugin (wp-env mounts it via mappings but never activates it), then idempotently seeds the four languages, the /language-demo/ page group and the Hello/مرحبا post pair that bin/test e2e's specs read, and consumes the rewrite flush creating those languages scheduled. Safe on a fresh wp-env or an already-seeded one |
bin/lint |
PHPStan, level 6 |
bin/phpcs [--fix] |
PHPCS (WordPress-Extra + WordPress-Docs), or PHPCBF with --fix |
bin/stylelint |
Stylelint -- enforces spec 8.3's logical-CSS-properties-only rule, and guards against a -rtl.css file existing anywhere |
bin/php <args> |
Arbitrary PHP inside the project's PHP container |
bin/composer <args> |
Composer inside a container |
bin/wp <args> |
WP-CLI against the wp-env instance |
bin/build-zip |
Builds an installable, runtime-only plugin zip under build/ (see .distignore for what it excludes) |
All of the above must pass before a change is considered done. See CONTRIBUTING.md for the full contributor workflow and the standards enforced on top of these tools.