Multilanguage fallback revisited and a page footer with multilanguage links
Keep the translated title and slug in one place and mark them valid so they can be used even if the remainder of the item is not valid.
Before you read on, you may want to read my previous post about language fallback, see link below. Here you have an example of the complexity of multilanguage. The link should be shown in the language you are using at the moment ... another time.
Life is one long big sequence of problems we are solving all the time. It starts with getting enough oxygen, solved by breathing, maybe second is bugs and incomplete architecture when being a developer and programmer. Anyway, it was time to implement a multilanguage page footer, this is the bottom part of the page with links to pages like About, Contact, Terms of use, Privacy policy. For a true multilanguage site these links must be in the selected language.
I started with two tables and created a new part of the administrator to manage them:
FooterItem
FooterItemTranslation
Using the administrator I create a footer item and add one or more language records to it, for every language a translation record is added. My first thought was to specify the name and slug for a page here, I mean, a page may not be available in the selected language and we want to fallback to the fallback language. The translated link name (page title) and slug must be stored somewhere.
However, when building the query to select the pages I found this far too complex because now I not only had to query the content_item and content_item tables but also the footer_item and footer_item_translation table. Not exactly what I had in mind, I am a programmer and prefer KISS.
My solution to reduce complexity is to abuse the content_item_translation record again, the last time I added the 'do_not_fallback' flag and now I add another flag: 'can_use_slug'. The meaning is as follows:
- When the content_item_translation record does not exist, we fallback to the fallback language.
- When the content_item_translation record exists and is published, we use it.
- When the content_item_translation record exists but is not published we have two conditions:
- do_not_fallback, if True, the item is not available.
- can_use_slug, if do_not_fallback is False, and can_use_slug is True we can use the title and slug of the content_item_translation record.
The nice thing is that we now can build a true multilanguage footer, with multilanguage links even if the page is not published, only by translating and adding the page title and slug to the content_item_translation record and setting the can_use_slug flag. The title and slug of the page are only in one place.
A bonus is that we can also use this when showing the page to display the title of the page in the selected language while the other parts remain in English. You can check this by looking at the Terms of use page of this website in several languages. This page is only available in English but we still have multilanguage links in the footer and a multilanguage title.
Implementation is like the cache object and settings object described in previous posts and of course uses caching, no need to generate the footer every request. No code in this post, must do some cleanup first ...
Links / credits
Refining multilanguage: adding language fallback as an option
/en/blog/refining-multilanguage-adding-language-fallback-as-an-option
Read more
Multilanguage
Recent
- Hiding database UUID primary keys of your web application
- Don't Repeat Yourself (DRY) with Jinja2
- SQLAlchemy, PostgreSQL, maximum number of rows per user
- Show the values in SQLAlchemy dynamic filters
- Secure data transfer with Public Key encryption and pyNaCl
- rqlite: a high-availability and distributed SQLite alternative
Most viewed
- Using Python's pyOpenSSL to verify SSL certificates downloaded from a host
- Using UUIDs instead of Integer Autoincrement Primary Keys with SQLAlchemy and MariaDb
- Connect to a service on a Docker host from a Docker container
- Using PyInstaller and Cython to create a Python executable
- SQLAlchemy: Using Cascade Deletes to delete related objects
- Flask RESTful API request parameter validation with Marshmallow schemas