March 2012
M T W T F S S
« Jan   Apr »
 1234
567891011
12131415161718
19202122232425
262728293031  

Categories

ASP.NET Internationalization Programming – Resource Administration

The following are extracts from ASP.NET Internationalization of Software Internationalization Tool World Wide Navi‘s Internationalization Programming Advisory Info.

ASP.NET uses resx resources (About resx, see Resource Administration, .NET chapter) for internationalization in some different ways from C# and other .NET programming languages.

This page describes its unique points with World Wide Navi string externalization samples.

1. Adding headers in ASPX

Add culture (language and region) settings to ASPX header area.

Default.aspx

  <%@ Page  Language="C#" ...%>
=><%@ Page  Culture="auto"
UICulture="auto" Language="C#" ...%>

2. String Externalization (literal replacement)

ASP.NET has 4 syntaxes for string resource handling.

  • Syntax 1 needs ‘<%=..%>’.
  • ‘”‘ are truncated in Syntax 2.
  • Syntax 3 is very similar to syntax 1, but some different.
  • The default text can remain adding meta in Syntax 4.
  • Syntax 3 & 4 can be used for ASP tags only.
Default.aspx

* Syntax 1. (tag text replacement)
 '<%=' + 'Resources.Default.' + RESOURCE_KEY + '%>'
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>This is a sample site!</title>
 => <title><%=Resources.Default.
DefaultWwnaviMsg1%></title>
</head>
<body>

* Syntax 2. (program literal replacement)
'Resources.Default.' + RESOURCE_KEY
<div>
    <% Response.Write("Hello, World!"); %>
 => <% Response.Write(Resources.
Default.DefaultWwnaviMsg2); %>
</div> 

* Syntax 3. (text replacement in ASP tag)
 '<%$' + 'Resources.Default,' + RESOURCE_KEY + '%>'
<asp:Label ID="Label1" runat="server"
Text="This is label 1.">
=><asp:Label ID="Label1" runat="server"
Text="<%$Resources:Default,
DefaultWwnaviMsg3%>">
</asp:Label>

* Syntax 4. (meta insertion in ASP tag)
 'meta:resourcekey="' + RESOURCE_KEY + '"'
<asp:Label ID="Label1" runat="server"
Text="This is label 1.">
=><asp:Label ID="Label2" runat="server"
 Text="This is label 1."
meta:resourcekey="DefaultWwnaviMsg4" >
</asp:Label>

You need to use proper process for each string based on its location.

(You can choose either 3 or 4 in ASP tags.)

3. Creating Resx Files

Put externalized strings into resx (resource) files.You need to create ‘App_GlobalResources’ folder under your project directory and put resx files there named ‘ASPX_FILE_NAME(without extension).resx’(*1).

PROJECT_DIRECTORY
    -  App_GlobalResources
         -  Default.resx
         -  WebForm1.resx
         *1)If you use syntax 4 (meta attribute),
           you heed to add extension
           (Default.aspx.resx).
Default.resx 

<?xml version="1.0" encoding="utf-8"?>
<root>
  <xsd:schema id="root" xmlns=""
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    ...
  </xsd:schema>
  ...
  <resheader name="writer">
    <value>System.Resources.ResXResourceWriter,
     System.Windows.Forms, Version=2.0.0.0,
     Culture=neutral,
     PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <data name="DefaultWwnaviMsg1" xml:space="preserve">
     (RESOURCE_KEY)
    <value>This is a sample site!</value>
     (RESOURCE_STRING)
  </data>
</root>

4. Compiling and localization

Build and run, you will see the resource strings shown in browser.If you want to add other language resources, put ASPX_FILE_NAME.LOCALE_CODE(e.g. ‘ja’).resx in App_GlobalResources.

App_GlobalResources
  -  Default.resx
    ... master resource (e.g. English)
  -  Default.ja.resx
    ... localized resource (e.g. Japanese)


PHP Internationalization Programming – Internationalization By gettext

The following are extracts from PHP Internationalization of Software Internationalization Tool World Wide Navi‘s Internationalization Programming Advisory Info.

1. Put Strings To Localize In gettext Function
Put strings that you want to localize in gettext function (in most cases, ‘_()’).

These strings get localized (translated) by each external resource file.

echo "Hello from PHP!"; ->
echo _("Hello from PHP!");

2. Write Initalizing Code
Apply user locale (language & region) and tell the resource name and path to gettext mechanism.

index.php (or other php)

<?php require_once($_SERVER[
"DOCUMENT_ROOT"].'/gettext/wwnaviRs/' .
'wwnavi.gettext.php');?>
// Running initializing
code for locale setting
and gettext reading.
...
echo _("Hello from PHP!");
...
wwnavi.gettext.php
// Initializing code.

require_once('wwnaviLang.php');
// Language and
region arrays used later.

$header = $_SERVER[
'HTTP_ACCEPT_LANGUAGE'];
// Getting user
HTTP header with language info.

$lang='';
// Parse user locale
from HTTP headers.
// Locale expression are different
from each web browser('en', 'en-us', 'en_US'...),
// but setlocale parameters
need to be 'language_REGION'.
if(strpos($header, ',')>0) {
    $hds = explode(',', $header);
    $lang = $hds[0];
    $lang = str_replace('-', '_',
$lang);
    if(strpos($lang, '_')>0) {
        $ls = explode('_', $lang);
        if(count($ls)>1) $lang = $ls[0] .
       '_' . strtoupper($ls[1]);
    }else if(!empty($wwnaviLang[
        $lang])) {
        $lang .= '_' . $wwnaviLang[
        $lang];
        // If language code
        (e.g. 'en') only, add region
        code (e.g. 'US')
        // from pre-defined arrays
       because setlocale needs full
      locale name.
    }
}
//echo $lang . '
';
//putenv("LC_ALL=$lang");

setlocale(LC_ALL, $lang);
// $lang need to be
language and region name (e.g. "en_US") at least.

$domain = 'wwnaviBundle';
// Telling gettext resource
name and path.
bindtextdomain($domain,
dirname(__FILE__));
textdomain($domain);
bind_textdomain_codeset($domain,
'UTF-8');
wwnaviLang.php 
// Pre-defined arrays of
language and default region code.

$wwnaviLang = array(
...
'de'=>'DE',
'en'=>'US',
'es'=>'ES',
'et'=>'EE',
'eu'=>'ES',
'fa'=>'IR',
'fi'=>'FI',
'fo'=>'FO',
'fr'=>'FR',
...
'ja'=>'JP',
...

3. Create gettext Master Template Resource (.POT)
You need to create a master resource (.pot) with pairs of msgid and msgstr under the resource path.

xgettext command is useful which scans ‘_()’ strings and create pot files.

YOUR_DOCUMENT_ROOT/gettext/
wwnaviRs/(*1)
 ... wwnaviBundle.pot(*1)

*1)The same directory
as specified in the code above.
wwnaviBundle.pot
...

#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2012-03-05 17:32+0900\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

#: /...../examples/php/gettext/index.php:10
msgid "Hello from PHP!"
msgstr ""

#: /...../examples/php/gettext/index.php:13
msgid "This is a DIV text."
msgstr ""
...

#: /root/wwnavi/workspace/examples/php/gettext/
sub/sub2/sub2.php:31
#, php-format
msgid "My local time is %c!"
msgstr ""
xgettext -j -L php  -k"_" --from-code=UTF-8
-o /..../examples/php/gettext/wwnaviRs/
wwnaviBundle.pot  \
   /..../examples/php/gettext/index.php

4. Localize .POT Into Each Language Resource (.PO)
Copy the master template to the target locale directory
(LOCALE(e.g. ‘ja_JP’)/LC_MESSAGES) as a .po file
and translate msgstr.

Case of Japanese Translation

YOUR_DOCUMENT_ROOT/gettext/
wwnaviRs/ja_JP/LC_MESSAGES
… wwnaviBundle.po

ja_JP/LC_MESSAGES/wwnaviBundle.po

#, fuzzy
msgid “”
msgstr “”
“Project-Id-Version: PACKAGE VERSION\n”
“Report-Msgid-Bugs-To: \n”
“POT-Creation-Date: 2012-03-05 17:32+0900\n”
“PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n”
“Last-Translator: FULL NAME \n”
“Language-Team: LANGUAGE \n”
“MIME-Version: 1.0\n”
“Content-Type: text/plain; charset=UTF-8\n”
“Content-Transfer-Encoding: 8bit\n”

#: /…../examples/php/gettext/index.php:10
msgid “Hello from PHP!”
msgstr “PHPからこんにちは!”

#: /…../examples/php/gettext/index.php:13
msgid “This is a DIV text.”
msgstr “これはDIVのテキストです。”

#: /root/wwnavi/workspace/examples/php/gettext/
sub/sub2/sub2.php:31
#, php-format
msgid “My local time is %c!”
msgstr “わたしの現地時間は%cです!”

***CAUTION: Do not modify(translate) format string like ‘%c’.

5. Compile .PO Into .MO (Resource Binary)
Run msgfmt command to create a resource binary (.mo)
in the target locale directory.

msgfmt -o
 wwnaviBundle.mo wwnaviBundle.po

Now you can switch your messages between English and Japanese changing your browser language settings.

These process can be checked with PHP string externalization samples in World Wide Navi.

POT/PO localization process gets more easy and effective with our localization tool, Sisulizer.



Software Localization Tool Sisulizer Product Page Updated

We added English/Japanese detail pages to the product page of our software localization tool, Sisulizer.

http://www.kokusaika.jp/product/sisulizer/details.html

Check and use it for your deciding to buy!

We described about the various supports of Web Application, Android, .NET, and Delphi with our Software Internationalization Tool,  World Wide Navi‘s Internationalization Programming Advisory Info.

We intend to launch a new special site for Sisulizer and broadcasting more useful information!

We also started up Sisulizer Twitter for Japanese users!

@sisulizerJp

We’ll post many information about not only Sisulizer but localization, please follow us!