WP Manifestindependent plugin directory
manifest / i18n / mlp-multilingual

MLP Multilingual

Multilingual content, language-aware URLs, and full bidirectional RTL support for WordPress.

by Sahbi Ben Gdaiem · github.com/gsahbi/mlp-multilingual · website

0stars
0forks

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.zip

MLP 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 hreflang annotations (including x-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 lang collection 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

  1. 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.
  2. 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.
  3. 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

  1. Clone this repository.
  2. 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.
  3. bin/composer install to install PHP dependencies.
  4. npx wp-env start to bring up a local WordPress instance at http://localhost:8888, with this checkout mounted as the mlp-multilingual plugin (see .wp-env.json).
  5. bin/seed-e2e if 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.