Textpattern Plugin "dem_clone" and Multi-Language Setup

1. Download dem_clone

dem_clone_v0.1.txt

2. Follow this tutorial for a multi-lingual setup

A few notes up front

Credits go to jakob and Bloke for help and inspiration! Thank you guys!

Many times I hit the point where I wanted a more streamlined solution when it comes to multiple languages and textpattern. There had to be some solid and easy setup for multi-language Websites that are based on textpattern.
I do not want to get into details about the pros of textpattern, but I think its extremely versatile character – for which I love it – makes it so hard to find THE solution for any type of multi-lingual website. So this setup here can only be a solution for some kind of websites. I tried to make it as easy as possible and it would be working for most of the websites that I usually would set up but it might not be the case for yours.

It was all tested with textpattern version 4.8.5

It should work pretty flawlessly when you:

Overview/Basic Setup

Plugins needed:

How it works:

Let´s get started

Install the plugins and create the sections needed

When creating the section it might make your life easier when you name them like this:

name title
contact Contact
kontakt Contact_de

assuming that “en” would be your default language.
Like that it will be easier to identify sections later that are grouped together on the Content -> Articles page.
By beeing ordered alphabetically all coupled sections are grouped.


Setting up adi_menu

All the heavy lifting is done by adi_menu (and smd_query in the background). So the setup here is important to get it all working.
In the adi_menu panel (Presentation -> Menu) do the following:

Give your subsections an Alternative title
e.g. kontakt will get Kontakt as alternative title

Give your subsections a parent section.
Obviously “kontakt” will get “de” and “contact” will get “en”

Use the “clone title” field to group sections of same type in different languages.
For contact and kontakt section you just put “contact” in both Clone title fields.
Like that they are coupled by carrying the “clone title”.

At the end your menu setup should look like this:

section_name Title Alternative title Parent Clone title
contact Contact Contact en contact
de start
en start
kontakt Contact_de Kontakt de contact


Create your main forms.

Know the current language and be able to switch it. No matter if you are in an article or in a section.
Create language snippets to deliver reoccuring words and snippets in the correct language.

Create a form called language

That will give you the variable “lang” which will show you the current language – no matter what.

<txp:smd_query query='SELECT css FROM txp_section WHERE name = "?s"' wraptag="" break="">
<txp:variable name="lang">{css}</txp:variable>
</txp:smd_query>
Create a form called langswitcher

What it does is basically checking if you are in section. or in an article.
If you are in a section, it will give you the name of the coupled section in the other langue.
If you are in an article if will give you the coupled article in the other language.

<txp:if_article_list>
<txp:smd_query query='SELECT name,css FROM txp_section WHERE adi_menu_title IN (SELECT adi_menu_title FROM txp_section WHERE name = "?s") ORDER BY css' wraptag="" break="">
<txp:variable name="allrows" value="{smd_allrows}"/>
<txp:if_variable name="allrows" value="2">
<txp:variable name="parent">{css}</txp:variable>
<a href="/{name}/" class="l_{css} text-uppercase text-sans"><txp:if_variable name="parent" value="">{name}<txp:else/>{css}</txp:if_variable></a>
</txp:if_variable>
</txp:smd_query>
<txp:else/>
<txp:smd_query query='SELECT url_title, Section, css FROM textpattern
LEFT JOIN txp_section ON Section = name WHERE id = "<txp:article><txp:custom_field name="klon"/></txp:article>" OR custom_1 = "<txp:article><txp:article_id/></txp:article>" OR id = "<txp:article><txp:article_id/></txp:article>" ORDER BY css' wraptag="" break="">
<txp:variable name="allrows" value="{smd_allrows}"/>
<txp:if_variable name="allrows" value="2">
<a href="/{Section}/{url_title}" class="l_{css} text-uppercase text-sans">{css}</a>
</txp:if_variable>
</txp:smd_query>
</txp:if_article_list>
Create two (or more) forms that hold language snippets for each language

Name those forms language_de and language_en etc.
In there you can place all your snippets as variables.
For example in language_de you would put:

<txp:variable name="more" value="mehr"/>

And in langauge_en you would put:

<txp:variable name="more" value="more"/>

Add all the variables that you need on your page here in both languages.


Placing your forms

On top of every page of your website put :

<txp::language/>
<txp:output_form form='language_<txp:variable name="lang"/>'/>

That will grap always the current language and put the appropriate language-snippets file.

Put

<txp::langswitcher/>

where you need it.


adi_menu tag attributes

Put your adi_menu tag where you need it.
Make sure you are using those attributes for the adi_menu tag.

ignore_alt_title="0" sections='<txp:variable name="lang"/>' include_parent="0"

Note that the lang-Variable controls the output of the menus section by defining the parent (or “root”) section. Like that you always have the correct menu for your language.


Custom_field for related articles

Name your custom_1 field “Clone”. We still assume English is your default language.
When you create a clone of an english article in a non-english language put the id of the english article in it.
E.g. if article “Contact us” is your default article and has the ID 23, then the article for “Kontaktieren Sie uns” needs to get “23” in its “Clone” field. Do not forget to change the section of the new article from “Contact” to “Contact_de”.

Or you can just let dem_clone let do this job for you.


Using if_section

For being able to use if_section in both languages you will tweak the if_section-tag a bit.
That can be done with the help of another form that we will just call “sec”. It should look like this:

<txp:smd_query query='SELECT name FROM lenne_txp_section WHERE adi_menu_title = "<txp:yield name="n"/>" AND css = "<txp:variable name="lang"/>"'>{name}</txp:smd_query>

This will give you always the correct section for your current language.
So instead of

<txp:if_section name="contact">

you would need to go with

<txp:if_section name="<txp::sec n="contact"/>"/>

Which will give you “contact” when you are on English pages and “kontakt” if you are on German ones.


I constantly try to improve this setup. If you have better ideas or questions, do not hesitate to contact me.

Top