Multi-language Website

speed up your website's navigation

Should I replace Polylang, WPML, or TranslatePress?

They don’t translate automatically, at least not at a satisfactory level, and you would still need to maintain all languages separately. They don’t save you any web space because they still copy all of your pages and posts. They slow down your website because all complex plugins do. They are error-prone. At least I always get confused by their structure and functionality and end up re-doing things. And if you don’t do it 100% correctly you end up finding word strings in the wrong language scattered all over your page every time you’ve made a small edit.

I admit, there is a right way to make it work. But when I was tasked to build a website with 5 languages, the question that came to my mind was, ‘can I create a multi-language website without a language plugin and save myself from frustrations?’

Is it even possible to make a multi-language website without language plugin?

Not only is the answer to this question Yes, but with Oxygenbuilder it’s also amazingly easy. All I needed were 2 custom fields, 2 conditions, 1 dynamic data, and 1 main template.

Let’s assume you want to develop a website with pages and a custom post type called ‘sights’. This post type needs a header. Next, add categories called ‘sights en’, ‘sights de’, and ‘sights it for English, German and Italian etc’. One for every language on the website.

Set up language picker and language switch with ACF

Now go ahead and create 2 custom fields with the free version of ACF.

The first field is called language picker. Make it a radio button. Add a choice for each language, for example, main en, main de, and main it. As rule set ‘Post type is equal to Page’.

The second custom field is the language switch. Make it a URL field. Then duplicate the field until you have 1 per language. You can call them language switch en, language switch de, and so on. The first rule is the same as above ‘Post type is equal to Page’.

On top, you have to add a rule for every post type that requires a header. In our example, set a rule ‘Post type is equal to Sights’. It’s easy because WordPress shows you all the post types you have created and you just have to pick the right one.

Now open your main template in the Oxygenbuilder. You usually have at least a header, a footer, and maybe a modal in there. When you click ‘collapse all’ in the structure panel you will only see the sections.

Choose a section in the structure panel. Then click on the conditions icon in the top left corner of your screen.
Click on ‘set conditions’ (that’s the one that looks lit up in the image above) and make sure that it says ‘Show element if ANY of these conditions are true.’

To set the first condition click on the left field and choose ‘dynamic data’. Then click on ‘Advanced Custom Field’.
Then click on ‘language picker’. That is the first of the two custom fields we defined earlier.
Leave the == as is.
In the field on the right, you type one of the 5 defined values, in our example ‘main en’.

For the second condition choose post_category in the left field.
Leave the == as is
Click on the right field and choose ‘sights en’. Set these conditions on every section which includes text or links.

When you add a new page you will now see the 2 custom fields. Since we are developing our website in English you should pick ‘main en’. Thus, the English header and footer will be displayed on the frontend of this page. If you don’t pick any of the choices this page won’t have a header and footer.

There are also 5 empty fields where you should enter URLs. In order not to get confused I use this naming convention for my slugs. If the URL of this page is www.my-website.com/services/ I would paste it into all 5 fields. Then I would add appendixes to it. So, the German services page would be www.my-website.com/services-de/ and so on. I would use the same naming conventions for posts, too. You can do that even though these URLs don’t exist, yet.
You do that on all pages and posts that require a header such as ‘Sights’. If for SEO purposes you need to rename the slug you can do so later with a plugin called Better Search Replace. (You can also use the correct slug right away, it’s just a bit more confusing.)

Now go back to the main template in Oxygen. Let’s assume that you display flags to navigate between the languages. Find the link wrapper for the English flag. Now go to the URL field on the lefthand Oxygen panel and click on data. Choose ‘language switch en’. Then repeat this on the link wrapper with the German flag but choose language switch de. And so on.
Now develop and design your website until you are happy with the structure and content.

Are you already happy with the layout, the design, the images, etc? Is your client happy with it, too? After the next step any changes you’ll make you’ll have to make in as many places as you have languages.

First, you should work on the main template with the header and footer. As mentioned above, we keep them all in one template only. So go ahead and duplicate each section so that you have one per language. Besides translating the text you also have to change the links in the menus. Here my slug-naming-convention comes in handy again. Depending on whether you use the native WP-menus or whether you have created a custom menu you add an additional WP-menu or edit the custom links.
Most importantly, you have to change the conditions. But that is really easy. Just replace ‘main en’ with ‘main de’, ‘main it’ etc, and ‘sights en’ with ‘sights de’ and ‘sights it’ etc. Don’t forget to apply the conditions to every section on the main template.

Now you have to duplicate the pages and all posts that require a header like e.g. ‘sights’. Make sure to change the slug according to the naming convention. Then change the language picker to the correct language. Now publish it so that you can get into the Oxygenbuilder to translate the content. (Or do that with ACF or in Gutenberg editor, but that’s another topic)
Kampot Web Solutions
linkedin facebook pinterest youtube rss twitter instagram facebook-blank rss-blank linkedin-blank pinterest youtube twitter instagram