AJ's blog

December 14, 2013

ASP.NET MVC I18n – Part 5: Imperative View Localization

Filed under: .NET, .NET Framework, ASP.NET MVC, HTML5, Internationalization — ajdotnet @ 10:58 am

This is going to be a simple one…

Note: This post is part of a series

The most simple way to accommodate different languages is by direct, imperative coding. E.g. images can be localized by maintaining the region as part of the filename and appending it via code. So, let’s make our language switcher from earlier a little nicer:

<a href="@url"><img src="~/Content/flag_@(currentCulture.Name).gif" height="12" width="20" />
     <img src="~/Content/arrow.png" height="12" width="9" />
     <img src="~/Content/flag_@(nextCulture.Name).gif" height="12" width="20" /></a>

Resulting in respective flag images in the upper right corner:

 

As another example, that feedback message regarding the UI‘s region could be localized the following way:

@switch (UICulture)
{
    case "de-DE":
        <p>Derzeitige Sprache ist: @UICulture</p>
        break;
    default:
        <p>Current culture is: @UICulture</p>
        break;
}

 

For smallish content that certainly works, but once the affected fragment spans considerable amount or even most of the view, it‘s probably better to provide separate partial views. For example for the feature text (the blue area) on the index view:

@{ Html.RenderPartial("_Index_featured_" + UICulture); }

… which uses the _Index_featured_en-US.cshtml and _Index_featured_de-DE.cshtml partial views respectively. Careful, though. There is no fallback in this code, meaning you have to provide all localized versions, which may not always be necessary or feasible. However, it‘s quite easy to come up with a helper method, that looks for the respective files and implements proper fallback strategies.

 

This imperative approach works well for the occasional demand. However, if this becomes a regular demand, you will start looking for better solutions. E.g. you might want to place the localized views beside the regular ones with the region as part of the filename (or in region specific folders with the same filename). Just be careful that you preferred strategy does not collide with other features, such as mobile views or areas. (There are already too many competing demands.)

I do not need to walk you through respective solutions however, as Vlad has already written about the topic. He adds region specific view folders and evaluates them using his own view engine (for WebForms, but the principle holds for Razor as well). You could of course apply a different naming scheme, e.g. attach the region to the view name itself.

That’s all for now folks,
AJ.NET

December 8, 2013

ASP.NET MVC I18n – Part 4: CSS Styles

Filed under: .NET, .NET Framework, ASP.NET MVC, HTML5, Internationalization — ajdotnet @ 11:18 am

We have our user‘s language choice acknowledged and can start making use of it.

Note: This post is part of a series

Let‘s start with a topic that is not exactly MVC (which is probably why so many tutorials don‘t mention it), but I would like to get it out of our way: region specific information in CSS style sheets.

Of course it is a characteristic of ASP.NET MVC, compared with classical WebForms, that one needs a far better understanding of the underlying technologies, such as HTTP, HTML, CSS. So, in a way, talking about CSS is very much in line with ASP.NET MVC ideas…

For my little sample application I provided the logo image as background image of the header:

<body>
    <header>
       
<div class="content-wrapper head">
           
<div class="float-right">
               
<section id="login">
                    @{ Html.RenderPartial("_SetPreferredCulture"); }
                </section>
            </div>
        </div>
    </header>

The background comes with the head style:

.head {
    background-image: url(‘logo_en-US.png’);
    background-repeat: no-repeat;
    height: 100px;
}

That much s independent of the region.

For the region to come into play, we need it present in our html content, which is usually done on the root element in _layout.cshtml:

<!DOCTYPE html>
     <html lang="@UICulture" xml:lang="@UICulture">

UICulture is readily available from the view class. Putting the language in the lang and the xml:lang attribute (provided you maintain XML conformity) – and omitting it anywhere else, like in the http-equiv header Content-Language – is the recommended way of providing this information.

Also here: “The Content-Language value for an http-equiv attribute on a meta element should no longer be used. You should use a language attribute on the html tag to declare the default language of the actual text in the page.”

http://www.w3.org/International/questions/qa-http-and-lang

Now we can use the lang pseudo-class in CSS to provide two different backgrounds:

.head {
    background-image: url(‘logo_en-US.png’);
    background-repeat: no-repeat;
    height: 100px;
}
:lang(de-DE) .head {
    background-image: url(‘logo_de-DE.png’);
}

And it works, too Zwinkerndes Smiley

That‘s it. Simple and easy.

 

One (rare) pitfall…

Suppose the current culture is „de-DE“ (and and advertised on the lang attribute on the HTML element), and the application has some „information area“ for arbitrary content. If that particular content is only available in English, you might want to set the lang attribute of the respective DIV to „en-US“, perhaps to show some flag as background.

Now, common expectation and standards would agree that the DIV and it’s content would now be English instead of German:

“An element inherits language code information according to the following order of precedence (highest to lowest):

  • The lang attribute set for the element itself.
  • The closest parent element that has the lang attribute set (i.e., the lang attribute is inherited).

[…]”

http://www.w3.org/TR/REC-html40/struct/dirlang.html#h-8.1.2

And in HTML5:

“To determine the language of a node, user agents must look at the nearest ancestor element (including the element itself if the node is an element) that has a lang attribute in the XML namespace set or is an HTML element and has a lang in no namespace attribute set. That attribute specifies the language of the node (regardless of its value).”

http://www.w3.org/TR/html5/dom.html#the-lang-and-xml:lang-attributes

In other words; The language is determined by looking for the lang attribute in the parent elements until found. This would imply that the language of a node and its subnodes changes with a lang attribute.

What actually happens, however – in IE and Firefox anyway – is that the language does not change, but is added. Both language tags, the one on the DIV and the one on the HTML element are “active”. And also CSS styles for both languages that use the pseudo-class. So the little image you wanted to indicate the language is determined by the precedence of the language dependent styles – not the language itself.

Granted, it’s rarely an issue. But if it is it can be very annoying!

 

That’s all for now folks,
AJ.NET

Blog at WordPress.com.