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.
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.
- Keep HTML where it belongs, that is in the view.
- Use resources for their primary purpose: storing localized strings.