Achieving world domination with Perch

Over the past couple of weeks we’ve been building a site in perch that is available in both English and Italian. There are guidelines on how to build a multi-lingual site in perch, but we thought we’d add to it with some real world experience…

Before you get started you need to decided on an approach. As mentioned in the docs there are two options, you can either build two completely separate sites or build one site with different regions for each language. I imagine the former is easier, but in reality I think most clients want one CMS for both languages and Perch is flexible enough to make this possible. The rest of this blog post explores how to do this…

Setting and storing the language

First of all you need we need a way that the user can set the language that can also be detected by our page templates. Query strings work perfectly, so just add a language switcher like this to your site:

<nav class="translation__nav">
    <ul>
        <li><a href="?lang=en">en</a></li>
        <li><a href="?lang=it">it</a></li>
    </ul>
</nav>

We don’t want users to see that query string on every page, so let’s store it in a session cookie by adding the following to our header template:

session_start();

// Set the lang variable to our default
$lang = 'en'; 

// Get the lang query string from the URL
switch(perch_get('lang')) {
    // set the lang variable according to the query string
    case 'en':
        $lang = 'en';
        break;
    case 'it':
        $lang = 'it';
        break;
    // if there is no query string, check for a session cookie
    default: 
        if (isset($_SESSION['lang'])) {
            $lang = $_SESSION['lang'];
        }
        break;
}
// set our session cookie to whatever the lang variable is
$_SESSION['lang'] = $lang;

We can of course add as many options in there as we want.

Getting our language

Within our page templates we can now do things like:

<?php if($lang == 'it'){ ?>
<h1>Ciao!</h1>
<?php } else { ?>
<h1>Hello!</h1>
<?php } ?>

More importantly though, this also allows you to create editable regions for each language by amending your templates to look like

<?php perch_content('Main heading - '.$lang); ?>

PHP variable woes

So far, so good. Well not quite. The above only works if all the above is in the same file. If you define the $lang variable in shared header, and include that header using perch_layout(); that variable will not be available in your page. There are a few workarounds, the most obvious is to just use $_SESSION['lang'] in our page templates, and that would work, but it leaves us with one further problem: what if we need to alter our templates based on language? For example, we might have a form template, that looks something like:

<perch:label for="name">Name *</perch:label>

For our Italian friends, that needs to become

<perch:label for="name">Nome *</perch:label>

We can’t execute PHP in our HTML content templates so we need a different solution. Enter stage right, the PerchSystem class and specifically PerchSystem::set_var();

Adding PerchSystem::set_var('lang', $lang) to the above, means we can now access the lang variable in our template like so:

<perch:if id="lang" value="it">
Name *
<perch:else />
Nome *
</perch:if>

This comes in especially useful when it comes to navigation on multilingual sites. If we amend our attributes template to include an Italian page title

<perch:pages id="pageNavText-it" label="Page title (Italian)" type="text" suppress="true"/>

We can then display then switch between page titles based whichever language is set by the user:

<perch:if id="lang" value="it">
    <perch:pages id="pageNavText-it" />
<perch:else />
    <perch:pages id="pageNavText" />
</perch:if>

As is often the case with Perch, achieving some fairly complex functionality like multiple languages is a bit more involved than installing a Wordpress plugin, but it’s much more flexible.

The templates for this project are available on github.


Leave a comment