4

Suppose you're building a web application in ASP.NET MVC, and you have to display some formatted text. A very simple example might be:

Click any of the links below, or click here to cancel. Contact Customer Service with any questions.

What do you store in the resource file, and what do you code inline in your view?

For example, do you hardcode the target of the link in the resource? Or do you put {0} and populate it with string.Format in the View? Or store the link text as a separate resource and put the markup in the View, including the target?

What if the instructions are long, and need to be displayed in a tabular format? Do you put the <TABLE> <TR> and <TD> tags into the resource? Or do you have to put those tags in your View and create resources for each cell?

If you put HTML markup in some of your resources, you have to dodge the automatic HTML-escape mechanism employed by Razor (e.g. use Html.Raw). How do you remember which resources can be inserted directly and which need to be unescaped? Do you keep formatted resources in a separate resource file? Use a naming convention? Cross your fingers?

Bottom line: How do you deal with the common requirement of formatting part of a resource?

1
  • 3
    Back in the day I learned that links called "here" are bad for screen readers, since they have a mode that just lists links with their text.Are you sure you can't reformat your text so that the link is a clearly delineated part with proper text? – Sebastian Redl May 28 '17 at 20:26
1

In ASP.NET MVC, HTML content belongs to the view, and localized strings belong to resource files.

The difficulty is what happens when you need to mix both, i.e. when you need to have localized HTML content. There are several alternatives:

  • Put HTML in resource files. This is the worst solution, which should be avoided unless you have very good reasons not to. The issue is not only that it makes it overly complex to handle HTML which should be output as is with Html.Raw and user content which should be properly escaped, but also the complete lack of support from the IDE: with resources, you won't even have syntax highlighting.

    It also means that you're making it impossible to insert any dynamic content in HTML stored in resources. In worst cases if you're in a team of programmers who don't know well what they are doing, someone will end up reinventing the wheel by creating a system of placeholders to insert dynamic content in HTML from resources.

  • Put localized HTML content in views, one view per culture.

    The benefit of this approach is that each individual view would be easy to read and maintain, with the source being quite close to the result you'll see in the browser.

    The drawback, however, is that the same markup change has to be made in every localized view. If you need to support, say, six languages, every change has to be replicated six times.

  • Put HTML without translated content in a view, and call the corresponding localized resource strings from the view.

    The benefit of this approach is that you specify the markup only once.

    However, any content change would be cumbersome; for instance, in order to add a paragraph with one word in italic, you'll have to create three additional resource strings, create their translations and use them in the new markup.

    A more subtle issue is the same as for any resources-based approach: localization is not just about filling the placeholders. Sometimes you have to change the entire sentence; sometimes, you have to change the order of content (say [Cancel] the previous action would require a placeholder before the cancel button in some languages, such as, if I'm not mistaken, German); sometimes, you have to use a different color, or a different set of icons. Something as basic as putting ¿...? in Spanish versus ...? in English can be overly complex when you mix markup, dynamic content and placeholders, and I'm not even mentioning all the grammar subtleties.¹

    Therefore, localized views seem to me to be a more flexible solution, which, in long term, would require less maintenance. The exception would be a situation where you need to support a huge number of languages (twenty or more) in a context where nobody really cares about subtle adaptations of content to different cultures.


¹ One example I enjoy a lot is the request I received once for a web app which had to support a dozen of languages. On a page, there was a counter of products which was written as “6 products.” Things went well with some numbers, but not with others: “1 products” was not particularly correct in terms of English grammar. Therefore, the product owner asked if it would be possible to display a proper variant when needed. As I gave an estimate of how long would it take, the PO looked at me as if I was crazy: “Why, you need that much time for just adding a ‘product’ version and displaying it if the number is equal to one?! It should be one line of code!” So I started to explain that the if n == 1 rule may be true in English, but certainly not in languages such as Russian, where there will be one form for any number which ends by one, unless it ends by eleven, another form for numbers ending by 2, 3 or 4 but not by 12, 13 and 14, and a third form for anything else. More cultures to support means more rules to introduce, which are far more complex than adding a resource string.


Original answer:

It is unfortunate that you can't use ASP.NET MVC instead (especially in a context of an MVC web app!) In ASP.NET MVC, there is a mechanism specifically for that, called partial views. Instead of having to handle resource files (which has numerous drawbacks, including but not limited to the lack of proper editor with syntax highlighting and the contrived diffs in version control), you are simply putting the HTML content where it belongs—in the view—and then include it in other pages.

In ASP.NET, a similar mechanism could be a user control that you later include using RenderPartial. User controls give you the ability to pass parameters to them, making it possible, in your case, to pass the URI. Then you simply inject the value in HTML.

Both partial views and user controls give you an additional advantage of being able to add both markup and logic later with a relative ease—something you won't get with resource strings.

So:

  • Keep HTML where it belongs, that is in the view.
  • Use resources for their primary purpose: storing localized strings.
2
  • Actually we are using ASP.NET MVC (with Razor) and I do understand how partial views work. But I am not clear on how partial views solves this problem. Could you perhaps provide an example solution for the sentence I'm using as an example in my question? – John Wu Aug 18 '17 at 18:32
  • @JohnWu: sorry for my late edit. I've modified the answer. I also edited your question to avoid the ambiguity (ASP.NET and ASP.NET MVC are really two different technologies; if you are using one term instead of another, you'll get wrong answers, as if you were asking for a programming question related to Java, but calling the language JavaScript). – Arseni Mourzenko Sep 20 '17 at 21:06
0

From a resource string prospective I would store this:

Click any of the links below, or click {0} to cancel. Contact {1} with any questions.

However, this only solves the problem of a dynamic string. I don't think you want to mix markup with strings, so I would advise against adding HTML tags as part of the resource. Resources should be literal text that needs a translation to another language.

The problem is, you want the string AND the mark up.

So, I would not use resource strings at all for this case! What you really want is content. So, don't store any of this stuff in a resource string, instead request content which will return everything, the text, the markup etc.

This could be a home grown web service/dll or an enterprise content management system, but not a resource string.

0

I've been part of a team maintaining and developing a booking engine for a transportation company moving 7M passengers per year. The booking engine is available in 10 different locales. The locales are all maintained by different content editors.

We use html in resources for simple stuff like h1 and links. This has not caused us any problems.

For example, do you hardcode the target of the link in the resource? Or do you put {0} and populate it with string.Format in the View

Yes that would be a good approach. Just put the html link with a placeholder that you can replace.

What if the instructions are long, and need to be displayed in a tabular format?

Putting an entire html table in a resource would be a little extreme. I would try and find an alternative solution.

How do you remember which resources can be inserted directly and which need to be unescaped?

Assuming the content editors are not trying to do a hostile takeover we should be able to trust them. In that case we can just use Html.Raw for all resources.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.