Multilanguage website

I’m looking for a simple way to show/hide text with a given lang attribute (for a multilanguage website). So that setting eng, all elements with no-eng language (in that page) are hidden.
Maybe this is not the better solution (I accept all possible suggestions), but I didn’t manage to switch neither from a css to another nor to set a lang attribute to a container element.
But, first of all: javascript can modify permanently an html attribute?
Thank you!

For multilingual sites I’ve created, I have always had the different languages in different subdirectories. eg domain.com/en/ for English, domain.com/it/ for Italian, with a cookie to remember the visitor’s choice.

1 Like

Another method I have seen is the use of MVCL on the server side. You have probably heard of MVC (Model, View, Controller). MVCL adds "Language to the end of that.
What it does is use the server side to dish out different content to the same page templates, depending on the user’s language choice.
This method is probably better for handling site with many language options.

1 Like

I saw something about MVC, but is a solution with a database, isn’t it?

EDIT

I’d like, possibly, a simpler solution: better with javascript/css (hide/show). But please could someone answer my beginning question: can js change html? Or modify permanently an element attribute?

Usually it uses a database. But using the server to insert content in different languages could be done without a database. Blocks of body text could be stored in files. Smaller bits of text content such as menus and buttons stored in arrays, etc.
I’m guesing from your other topic that you are looking to avoid databases because of perfomance concerns. Really I would want to be sure that a database is the real bottle-neck before making life difficult by avoiding such a useful tool.

1 Like

Yes, you guess correctly: leaving wp is my aim :slight_smile:

You could do this in CSS but I doubt that it would be much use as I would guess that you may have nested groups of languages. That would mean that if a parent was hidden then so are all the children who may have different language attributes

html[lang="en"] [lang]:not([lang="en"]) {
  display: none;
}

That says that if the html is set as lang=“en” then any other lang attributes it finds will be hidden.
e.g. In a structure like this.

  <p lang="fr">Ceci est un paragraphe Francaise.</p>
  <p lang="en">This is an English paragraph</p>
  <p lang="fr">Ceci est un paragraphe Francaise.</p>
  <p lang="es">Este es un párrafo en español.</p>
  <p lang="en">This is an English paragraph</p>
  <p lang="es">Este es un párrafo en español.</p>
  <p lang="fr">Ceci est un paragraphe Francaise.</p>

Only the English paragraphs would be displayed.

So you could then switch the html attribute to say ‘es’ or ‘fr’ with js and set up css like this.

html[lang="en"] [lang]:not([lang="en"]),
html[lang="fr"] [lang]:not([lang="fr"]),
html[lang="es"] [lang]:not([lang="es"]){
  display: none;
}

However I think that is probably too simplistic to be of any use :slight_smile:

2 Likes

Yes, of course JS can change HTML.
Permanently? That depends on how you define “permanently”. I would say no, as the HTML will always be served as-is, then subsequently modified by JS (if the user chooses other than the default language).

As Paul has demonstrated, it could thoretically be done with CSS. But I don’t think that would be simpler or better than using scripts, either server or client side. I believe in using the correct tools for the job. I don’t consider this a job for CSS, but a job for scripts.
As one of your concerns is site speed, I think presenting all contant in all languages, then hiding what the user doesn’t choose to see, will bloat your pages with redundant content, as well as complicate your HTML structure and CSS.
Whether you use client or server side scripting, I may be biased toward the server simply because that is what I’m most familiar with. But to my mind, doing this client side may present a similar problem to the CSS method, as you will need to serve all content to the client before deciding what to present.
I think you would get optimum performance by serving only what the user needs to see.

Just a quick example of how this may be done in PHP:-
Menu data in an array:-

$menu = [
	'EN' => [
			"Homepage" => "home.php",
			"Products" => "products.php",
			"About Us" => "about.php",
			"Contact Us" => "contact.php",
		],
	'FR' => [
			"Page d'accueil" => "home.php",
			"Des produits" => "products.php",
			"À propos de nous" => "about.php",
			"Contactez-nous" => "contact.php",
		],
	];

A function to render the menu:-

function makeMenu(array $array, string $lang = 'EN'){
	if(!array_key_exists($lang)){ return false ;}
	$data = $array[$lang];
	$html = "<nav><ul>";
	foreach($data as $title => $link){ $html .= "<li><a href='$link'>$title</a></li>";}
	$html .= "</ul></nav>";
	return $html ;
}

Filling the page template with the correct page in the correct language:-

<main>
	<?php include "$incdir/content/$lang/$page.html";?>
</main>

That of course requires some processing beforehand to determine what those variable will be, but you get the idea.

2 Likes

Not without lots of effort, as JS is running on the client computer and your HTML is on the server. But realistically, selection of language is up to each user, yes? So I can’t think of much HTML you’d want to change on the server as a client selected a language. JS could set some information in a cookie on the client computer though, to remember the language selection for the next session.

2 Likes

I see only now your kindly answers. Meanwhile I realized something like Paul did (probably because of a his suggestion [some, one or two, I suppose year ago]):

<!DOCTYPE html>
<html>
<style>
body[lang=it] *[lang]:not([lang="it"]){display:none;}
body[lang=en] *[lang]:not([lang="en"]){display:none;}
body[lang=es] *[lang]:not([lang="es"]){display:none;}
</style>

<body lang="it">
<h1>Multilingual js page</h1>
<h2>The setAttribute() Method</h2>

<p lang="en">This is English</p>
<p lang="it">questo è italiano</p>
<p lang="es">esto es castillano</p>

<button onclick="setEs()">Set ESP</button>
<button onclick="setEn()">Set ENG</button>
<button onclick="setIt()">Set ITA</button>

<script>
function setEn() {
  document.body.setAttribute("lang", "en"); 
}
function setIt() {
  document.body.setAttribute("lang", "it"); 
}
function setEs() {
  document.body.setAttribute("lang", "es"); 
}
</script>


</body>
</html>

I will see your new suggestions. Thank you!

Yes, this could be a problem, but my pages are quite light, and multimedia should be shared (among different languages), only text (few text) would be separated. My source code is as simple and light as possible.

One way is to do the translation at the server. Here is how I did this. Maybe you can at least get some hint.

1 Like

Thank you! However the solution I need cannot accept a machine-translated text.

The solution above (from Paul and me) works, but only in a page: if you go to another webpage, language go back to the default language.
I don’t know what could be a solution (cookies, I guess)…

EDIT

Maybe here could be a clue for a js solution.

You can translate it manually by Google or by hand :slight_smile:

1 Like

[off-topic]
DeepL is a far better translator than Google.

2 Likes

The Manitoba Laws website uses JavaScript to Show/Hide the English or French text on a bilingual document. Here is one example
The lists of Acts and regulations are unilingual (English or French), but the consolidated Acts and regulations themselves are bilingual (a constitutional requirement for Manitoba).

By storing all the language sensitive text in an array and using the text stored in the array when displaying the page, you could then have a file for each language you wish to support each containing a JSON array of the texts.
Then when you need to change language, just read the file into the array, overwriting the existing language, refresh the page and job done.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.