Skip to content

Instantly share code, notes, and snippets.

@jbroadway
Last active December 13, 2015 18:18
Show Gist options
  • Save jbroadway/4953728 to your computer and use it in GitHub Desktop.
Save jbroadway/4953728 to your computer and use it in GitHub Desktop.
Possible navigation/* changes to include /lang/ URL prefixes when negotiation_method = url

Similar to how class="current" is added after the nav list is generated, we may be able to check $i18n->url_includes_lang and inject the language prefixes in the same way. If we setup a menu structure like the following, this seems to work correctly for both top-level and section navigation:

  • English (en)
    • About (about)
    • Products (products)
  • Français (fr)
    • A propos (a-propos)
    • Produits (produits)

The navigation/top output then becomes:

  • English (/en)
  • Français (/fr)

And the navigation/section?section=[i18n.language] output becomes:

  • About (/en/about)
  • Products (/en/products)

And in French:

  • A propos (/fr/a-propos)
  • Produits (/fr/produits)

The second part of this is to setup a redirect in /index to go to the default language page (e.g., /en or /fr) so that that page becomes the new homepage.

Note that {! navigation/section?section=[i18n.language] !} becomes the equivalent of {! navigation/top !} on multilingual sites, and {! navigation/top !} becomes a list of available languages. This means that the default themes won't work out-of-the-box with setting navigation_method = url, since that would just show the languages as the top-level nav, but the change is small and can be documented in the multilingual setup info accordingly.

Some other points to consider:

  • The language pages at the top-level essentially become a list of active languages, since only the languages with pages for them would appear on the site.
  • Links like /fr/about or /en/a-propos will pull up the specified language instead of the intended one from the site structure, but since they're never linked to nobody would ever reach them anyway.
  • This ought to work correctly with both page_url_style = flat and page_url_style = nested once that change is merged into master.

Probably missed other details, but that's about all I can think of for now.

<!DOCTYPE html>
<html>
<head>
<title>{{ conf('General', 'site_name') }} - {{ window_title|none }}</title>
<meta charset="{{ i18n.charset }}" />
{% if detect('mobile') %}
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0" />
<link rel="stylesheet" type="text/css" href="/css/mobile.css" />
{% else %}
<link rel="stylesheet" type="text/css" href="/css/reset.css" />
<link rel="stylesheet" type="text/css" href="/css/text.css" />
<link rel="stylesheet" type="text/css" href="/css/960.css" />
<link rel="stylesheet" type="text/css" href="/css/style.css" />
{% end %}
{! admin/head !}
{{ head|none }}
</head>
<body>
<div id="wrapper" class="container_12">
<div id="head" class="grid_12">
<div class="grid_6 alpha">
<h1>{{ conf('General', 'site_name') }}</h1>
</div>
<div class="grid_6 omega menu">
{! navigation/top !}
{! navigation/section?section=[i18n.language] !}
</div>
</div>
<div class="clear"></div>
{% if id === 'index' %}
<div id="body" class="grid_12 index-body">
{! filemanager/slideshow?path=homepage !}
{% if title != '' %}<h2>{{ title|none }}</h2>{% end %}
{{ body|none }}
</div>
{% else %}
<div id="body" class="grid_8">
{% if title != '' %}<h2>{{ title|none }}</h2>{% end %}
{{ body|none }}
</div>
<div id="sidebar" class="grid_4">
{! blocks/index?id=sidebar-[id]&fallback=members !}
</div>
{% end %}
<div class="clear"></div>
<div id="footer" class="grid_12">
<div class="grid_6 alpha menu">
{! navigation/top !}
</div>
<div class="grid_6 omega powered">
{"Powered by"} <a href="http://www.elefantcms.com/">Elefant CMS</a><br />
{"Photos by"} <a href="http://www.rachaelhosein.com/">Rachael Hosein</a>
</div>
</div>
<div class="clear"></div>
</div>
{{ tail|none }}
</body>
</html>
<?php
/**
* Displays a single section of the navigation as a
* bulleted list, with `class="current"` added to
* the current page's `<li>` element for custom styling.
*/
global $i18n;
$n = new Navigation;
$section = $n->node ($data['section']);
ob_start ();
if (is_array ($section->children)) {
echo '<ul>';
foreach ($section->children as $item) {
if ($item->attr->id == $page->id) {
printf ('<li class="current"><a href="/%s">%s</a></li>', $item->attr->id, $item->data);
} else {
printf ('<li><a href="/%s">%s</a></li>', $item->attr->id, $item->data);
}
}
echo '</ul>';
}
$out = ob_get_clean ();
if ($i18n->url_includes_lang) {
$out = str_replace (
'href="/',
'href="/' . $i18n->language . '/',
$out
);
$out = preg_replace (
'#"/' . $i18n->language . '/(' . join ('|', array_keys ($i18n->languages)) . ')"#',
'"/\1"',
$out
);
}
echo $out;
?>
<?php
/**
* Displays the top-level navigation as a bulleted list,
* with `class="current"` added to the current page's
* `<li>` element for custom styling.
*/
global $i18n;
$res = $cache->get ('_navigation_top');
if ($res) {
$out = str_replace (
sprintf ('<li><a href="/%s">', $page->id),
sprintf ('<li class="current"><a href="/%s">', $page->id),
$res
);
if ($i18n->url_includes_lang) {
$out = str_replace (
'href="/',
'href="/' . $i18n->language . '/',
$out
);
$out = preg_replace (
'#"/' . $i18n->language . '/(' . join ('|', array_keys ($i18n->languages)) . ')"#',
'"/\1"',
$out
);
}
echo $out;
return;
}
$n = new Navigation;
$out = '<ul>';
foreach ($n->tree as $item) {
$out .= sprintf ('<li><a href="/%s">%s</a></li>', $item->attr->id, $item->data);
}
$out .= '</ul>';
$cache->set ('_navigation_top', $out);
$out = str_replace (
sprintf ('<li><a href="/%s">', $page->id),
sprintf ('<li class="current"><a href="/%s">', $page->id),
$out
);
if ($i18n->url_includes_lang) {
$out = str_replace (
'href="/',
'href="/' . $i18n->language . '/',
$out
);
$out = preg_replace (
'#"/' . $i18n->language . '/(' . join ('|', array_keys ($i18n->languages)) . ')"#',
'"/\1"',
$out
);
}
echo $out;
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment