@boblet

Month

December 2007

5 posts

Setting a language preference cookie

Once you’ve got language extensions and MultiViews working, you’ll probably want to set a cookie to record the user’s language preference. You can do this in a MT4 template like so:

<div class="lang-links"><mt:if name="page-lang" like=".en$"><a href="index.ja.html" onclick="createCookie('language','ja',365);">日本語</a> | English<mt:else>日本語 | <a href="index.en.html" onclick="createCookie('language','en',365);">English </a></mt:else></mt:if></div>

(Note this uses the previously mentioned page-lang snippet. Also there’s an extra space after “English” for line breaking purposes if you c&p.)

I used PPK’s createCookie Javascript:

function createCookie(name,value,days) {
    if (days) {
        var date = new Date();
        date.setTime(date.getTime()+(days*24*60*60*1000));
        var expires = "; expires="+date.toGMTString();
    }
    else var expires = "";
    document.cookie = name+"="+value+expires+"; path=/";
}

Now all you have to do is set these preferences in a .htaccess file:

# i18n with content negotiation
# enable MultiViews for extensionless URIs
Options +MultiViews +FollowSymLinks
# add acceptible languages
AddLanguage ja .ja
AddLanguage en .en
# set language priority
LanguagePriority ja en
# serve priority language if priority conflict or
#  no acceptable language (>= Apache 2.0.30)
ForceLanguagePriority Prefer Fallback
# override using cookies (theoretically)
SetEnvIf HTTP_COOKIE "language=en" prefer-language=en
SetEnvIf HTTP_COOKIE "language=ja" prefer-language=ja

I tried linking the script and calling it via ids:

document.getElementById('cookie-en').onclick = function () {
    createCookie('language','en',365);
}
document.getElementById('cookie-ja').onclick = function () {
    createCookie('language','ja',365);
}

but I’m currently doing things old-skool because … Apache’s caching seems to override this setting. Crap. To check for this reload pages that should be in a different language based on your cookie to preserve sanity. The FireFox Web Developer’s Toolbar has an excellent “View Cookie Information” option for testing cookies are being set correctly.

Dec 28, 200714 notes
Using content negotiation in MovableType 4

Once you’ve hacked MT4 to allow periods in slugs (filenames), you can add language suffixes in the Filename field when you make pages, eg the slug about.en will give you the page about.en.html (assuming .html is your default suffix). Now you can set $MTPageBasename (which contains the language suffix) as a variable in your MT template:

<MTSetVarBlock name="page-lang"><$MTPageBasename$></MTSetVarBlock>

Then you can regex the variable for the suffix to do stuff:

<MT:If name="page-lang" like="\.en$"><h1>English</h1></MT:If>

<MT:If name="page-lang" like="\.ja$"><h1>Japanese</h1></MT:If>

Or:

<html <MT:If name="page-lang" like="\.en$">lang="en" xml:lang="en"</MT:If><MT:If name="page-lang" like="\.ja$">lang="ja" xml:lang="ja"</MT:If> xmlns="http://www.w3.org/1999/xhtml">

Wow, MT4 is actually half usable out of the box now. Wahey!

Dec 21, 2007
“Excellent. The hate I’ve felt all these years is dimming from a bright burning sun to the dull tickle of an annoyance.” —Phil, on the news that the Microsoft IE team has finally passed Acid2 in internal testing. For IE8 :-S
Dec 19, 20079 notes
Allowing Content Negotiation in TextPattern 4.05 and MovableType 4.0

Both CMSs strip periods from URL slugs, which makes adding a “.ja” or “.en” to the end of your filename for Apache content negotiation a bit hard. Internationalization is fun huh.

Of course this means you’re responsible for not allowing periods you don’t want in your filenames. As long as you’re using some .htaccess magic to strip filename suffixes (so the actual filename still ends in .html) you should be fine.

TextPattern

lib/txplib_misc.php (line 643): add “.” (literal period) to whitelist of function sanitizeForUrl($text)

Bonus: allow HTML in article titles (eg <em>)

publish/taghandlers.php (line 1825): remove escape_title wrapper from $thisarticle in function title($atts)

You’re responsible for escaping any literal “<” and “>”, which if not done will definitely fuck things up.

MovableType
  • lib/MT/Util.pm (line 597): add “.” (literal period) to whitelist of sub utf8_dirify (and to sub iso_dirify above that if you need)
  • mt-static/mt.js (line 940): add “.” (literal period) to whitelist of function dirify (s)
Apache .htaccess

Now you’ll need to tell Apache to negotiate between the language versions you make. MultiViews is easiest:

# i18n with content negotiation
# enable MultiViews for URIs that don’t exist
Options MultiViews
# add acceptible languages
AddLanguage ja .ja
AddLanguage en .en
# set language priority
LanguagePriority ja en
# serve priority language if priority conflict
  or no acceptable language (>= Apache 2.0.30)
#ForceLanguagePriority Prefer Fallback

You’ll have to link to the basename without any suffixes for this to work. (Apache docs: content negotiation naming guide)

Update

Okaaaay… changing Util.pm may result in an ugly error where the .cgi file you’re trying to access gets returned as text. However, just the change to mt.js seems to be sufficient. It’s still converted on auto-save (huh? wouldn’t the JS be doing that?), but re-changing the name to a period and re-saving worked successfully.

Strange, I would have thought the Util.pm was the important thing to change. Maybe there’s a bug in the dirify code?

Dec 19, 20071 note
“So anyway, congratulations to Six Apart for finally joining the open community of freedom-loving pussy eaters.” —Mark Pilgrim
Dec 17, 2007
Next page →
2011 2012
  • January
  • February
  • March 1
  • April
  • May
  • June
  • July
  • August
  • September
  • October
  • November
  • December
2010 2011 2012
  • January 1
  • February 2
  • March 1
  • April
  • May 2
  • June 2
  • July
  • August
  • September
  • October 2
  • November 2
  • December
2009 2010 2011
  • January 3
  • February 4
  • March 3
  • April 5
  • May 4
  • June 1
  • July 1
  • August 1
  • September 2
  • October 2
  • November
  • December 3
2008 2009 2010
  • January 3
  • February
  • March 4
  • April 4
  • May 8
  • June 7
  • July 9
  • August 3
  • September 1
  • October 5
  • November 2
  • December 2
2007 2008 2009
  • January 4
  • February
  • March 5
  • April 3
  • May 4
  • June 7
  • July 9
  • August 6
  • September 6
  • October 3
  • November 4
  • December 6
2007 2008
  • January
  • February
  • March
  • April
  • May
  • June
  • July
  • August
  • September
  • October
  • November 3
  • December 5