WPML (WordPress Multilingual Plugin) is one of the most powerful tools for translating WordPress websites. But under the hood, it’s more than just a translation switcher—it fundamentally alters how post content, meta, taxonomy, and queries behave.
This guide is for developers, implementers, and technical site owners who want to go beyond the surface and understand what’s really happening when WPML is active on your WordPress site.
Once we cover that, we’ll show you how we make it work on a Static WordPress infrastructure.
WPML does not store all translations in the same post object. Instead, it creates a separate post entry for each language. These translated posts are tied together via a shared trid
(translation group ID), maintained in the wp_icl_translations
table.
Each translated post:
post ID
wp_posts
just like a normal posttrid
to link it back to the main post groupThis design allows you to fully customize translated content per language—titles, permalinks, images, even layout if needed.
wp_icl_translations
holds language code, element_id
, element_type
, and trid
element_type
could be post_post
, post_page
, tax_category
, etc.When you duplicate a post in WPML—either manually or automatically—it creates a new post and duplicates all associated custom fields (post meta).
This can be:
These options are configured via WPML → Settings → Custom Fields Translation where you’ll see options like:
Copy
: Field is copied once, then independentCopy Once
: Copied during duplication, but changes don’t syncTranslate
: Unique per language versionDon’t Translate
: Skipped entirelyWhen querying get_post_meta()
, you’re always referencing the current language’s post ID, so it retrieves that language’s specific meta—even if it’s identical to the original.
WPML uses filters to ensure you’re only working with content in the current language. These include:
pre_get_posts
– Adjusts queries to only return posts in the current languageget_terms
– Ensures taxonomies are filtered by languageget_the_title
, the_content
, get_permalink
– Localizes outputget_post_metadata
– Filters meta fields for current-language postIf you bypass these filters (e.g. using direct SQL queries or WP_Query without WPML compatibility), you may return untranslated or cross-language content unintentionally.
Use WPML’s API for safe multilingual queries: wpml_object_id()
, icl_object_id()
, icl_get_languages()
Like posts and pages, WPML also duplicates taxonomies for translation.
Each translated taxonomy term has:
wp_terms
trid
in wp_icl_translations
This enables per-language category names, slugs, and descriptions—plus full translation of tag archives, custom taxonomies, and breadcrumb trails.
WPML also duplicates images and attachments, especially when using the Media Translation module. Each image is copied to the translated post and can be replaced per language if needed.
You can translate:
This is stored per attachment ID in the language-specific post and referenced in the editor for clarity.
If you’re writing code that must be language-aware, WPML provides several helper functions:
$translated_id = apply_filters( 'wpml_object_id', $original_id, 'post', true, $language_code );
$current_lang = apply_filters( 'wpml_current_language', NULL );
$translations = apply_filters( 'wpml_get_element_translations', NULL, icl_get_element_id($post_id, 'post_post') );
remove_filter( 'get_post_metadata', 'wpml_get_post_metadata_filter' );
// do something...
add_filter( 'get_post_metadata', 'wpml_get_post_metadata_filter' );
wp_icl_translations
to trace trid
relationships.The Headless Hostman is an integrated platform that converts your existing WordPress site into a fully Static production site.
We support 99.9% of Plugins out of the box, especially WPML.
When you’re managing your WordPress site, there’s nothing more you need to do.
When you initiate a Full, or Push by Post Type, we automatically circulate through ALL languages within those post types.
They push without any further intervention.
When you edit or create a new post, WPML gets to work in the background generating the language variant of that page.
When it’s completed, we have an automatic process that will push it to Static when it’s done.
On your live Static Site, toggling is the exact same and all of the relevant translation pages are there to back it up.
It’s that easy.