WP Translate
WP Translate is a WordPress plugin skeleton for persistent multilingual content using the Baidu Translate API.
Requirements
- WordPress 6.4 or later.
- PHP 8.1 or later.
- A Baidu Translate application ID and secret key.
- WordPress cron enabled, or a real server cron that calls WordPress cron.
Installation
- Copy this directory to
wp-content/plugins/wp-translate. - Activate WP Translate in WordPress Admin.
- Open Settings > WP Translate.
- Enter the Baidu credentials, source language, target-language codes, and URL routing mode.
- Save a post or page to schedule translation jobs for every configured target language.
Translation Lifecycle
Translations are generated by the wpt_process_translation cron task after a post or page is saved. For content published before the plugin was activated, open Settings > WP Translate and use Translate existing posts and pages to schedule all published posts and pages. A translation has a deterministic identity based on the source fingerprint, source language, target language, field context, and provider version. The plugin first looks up a completed result in the {$wpdb->prefix}wpt_translations table. Only a cache miss causes a request to Baidu.
Changing source text produces a new fingerprint and therefore schedules a new translation without deleting a valid prior translation. Front-end rendering never contacts Baidu; it reads a completed value from the table and otherwise falls back to the source value. WordPress cron must run after queuing content; production sites should configure a real server cron to call WordPress cron regularly.
Supported Content
- Post and page titles, content, and excerpts.
- Attached image
alttext. - Assigned categories and tags, including their descriptions.
- Yoast SEO title and description fields.
- Rank Math title and description fields.
Only the listed SEO meta fields are sent for translation. Arbitrary metadata, serialized data, credentials, and code are excluded.
When post content contains HTML links, the plugin preserves each link's href and attributes, translates its visible text as a separate value, and inserts that translated text back into the original link. Re-run a post translation after upgrading to regenerate previously translated content that contains links.
Category and tag names are translated when they are created, edited, or included in a full retranslation. On a translated site, term objects used by archives, navigation, and post metadata use the persisted translated name and description.
Routing
The Subdirectory mode resolves configured language paths such as /en/example-post/. The Domain binding mode maps a request host to a language using one domain=language entry per line in Settings. Use one canonical strategy for each language to avoid duplicate URLs. In domain mode, the plugin does not register front-end rewrite rules, so the primary site URL is not affected.
Post, page, term, and home links are generated for the active language. For example, a theme's "back to home" link that uses home_url() resolves to the bound language domain or language subdirectory.
For a bound subdomain, enter a value such as en.example.com=en. The server and DNS must route that hostname to the same WordPress installation before WordPress can resolve the language.
After changing routing settings, rewrite rules are refreshed. The initial implementation does not yet generate translated permalinks, canonical URLs, hreflang alternates, redirects, or sitemap entries.
Security And Data Retention
Credentials are stored in the WordPress wpt_settings option and are not rendered on the front end. The plugin stores the translation identity, language pair, field context, source fingerprint, translated value, status, and timestamps. It does not store full Baidu response payloads.
Use HTTPS and restrict database access appropriately because WordPress options are database-backed. Production sites should configure a real cron runner for reliable translation processing.
Development
Install development dependencies with composer install. The project includes WordPress API stubs for Intelephense and PHPUnit tests that use fake providers and storage, so they do not need WordPress, a database, credentials, or network access.
Run tests with:
composer test
Validate PHP syntax with:
find . -path './.git' -prune -o -type f -name '*.php' -print0 | xargs -0 -n1 php -l
Before production use, add WordPress PHPUnit integration tests with mocked wp_remote_post responses. Required coverage includes language resolution, rewrite behavior, persistence reuse and invalidation, Baidu request signing and errors, content filtering, and fallback rendering.
Retranslation
The Posts and Pages lists show a status column for every target language, including the latest successful translation time and a translation action. The Settings page also provides 重新翻译所有内容. It shows a confirmation warning before scheduling a forced refresh of published posts, pages, categories, and tags; this bypasses persisted translations and consumes Baidu API quota.
The Settings page also shows a live progress panel. It refreshes every five seconds and counts completed post/page and category/tag items for every configured target language. When 重新翻译所有内容 starts a batch, progress resets and counts only translations completed after that batch began, so historical translations do not make a new batch appear complete. Progress reads only local WordPress and translation-table data; it does not send additional requests to Baidu.
Known Limitations
- The settings UI accepts language codes but does not yet validate them against a maintained Baidu language-code list.
- API calls translate raw WordPress content. HTML, blocks, shortcodes, placeholders, and URLs need a protected-token pipeline before production use.
- Taxonomy and SEO values are queued but the current rendering filters cover only a subset of SEO plugins and term views.
- Domain binding assumes the WordPress site and server virtual hosts are already configured for every bound domain.
- Translation failures are stored as failed attempts and render the source value; retry management and an admin job monitor are not implemented yet.