ajmaleylia

Hi, I'm Ajmal
Tech Consultant

WordPress Multilingual with JSON

Recently, I helped a client develop a multilingual WordPress site. The last time I touched WordPress was a 10 years ago. A lot has changed since then, but one thing that hasn’t is my dislike for WPML. So, I went with Polylang, which I found to be much simpler and cleaner.

But there was a catch. WordPress typically uses .mo files for translations, while I’m used to JSON files in Rails’ i18n. I wanted to stick with JSON because it’s way more flexible and human-readable. Without any additional software, POEdit to edit the language files.


JSON Translation Files

I created separate JSON files for each language in a languages folder:

English (languages/en.json):

{
  "hero_h1": "Company Name"
}  

Malay (languages/ms.json):

{
  "hero_h1": "Nama Syarikat"
}  

Loading JSON Translations

Next, I wrote a helper function to load the JSON translations dynamically based on the language locale:

function load_translations($locale) {  
  $file_path = __DIR__ . "/languages/{$locale}.json";  

  if (!file_exists($file_path)) {  
      return [];  
  }  

  $json_content = file_get_contents($file_path);  
  return json_decode($json_content, true);  
}  

This function checks if the JSON file exists and loads it into an array. Easy.


Creating a Translation Helper

To make translations easier to handle in views, I wrote a helper function __t. This function does three things:

  1. Automatically detects the current language using Polylang.
  2. Loads translations for the current language only once to save resources.
  3. Replaces placeholders in translation strings (if needed).

Here’s how it looks:

function __t($key, $locale = null, $placeholders = []) {  
  static $translations = [];  

  // Use Polylang's current language if no locale is provided  
  if ($locale === null) {  
      $locale = pll_current_language();  
  }  

  // Load translations only once per locale  
  if (!isset($translations[$locale])) {  
      $translations[$locale] = load_translations($locale);  
  }  

  $translation = $translations[$locale][$key] ?? $key;  

  // Replace placeholders if provided  
  if (!empty($placeholders)) {  
      $translation = vsprintf($translation, $placeholders);  
  }  

  return $translation;  
}  

Rendering in Your Theme

How to render translation to your theme? Just use the __t function like this:

<?php echo __t('hero_h1'); ?>  

When the language is switched in Polylang, this will automatically pull the correct text from the JSON file.


Polylang and JSON turned out to be a great combo for this project. It gave me the flexibility I wanted without the complexity of .mo files. If you’re like me and prefer a lightweight, customizable solution for multilingual WordPress sites, give this method a try!

Ready to transform your business with a powerful, custom-built website? Let’s create a solution tailored to your goals. Fast, efficient, and scalable. Message me to get started!

Notes