I know this matter has already been brought on these pages many times, but still I haven't found the "good solution" I am required to find. Let's start the explanation.
我知道这件事已经被写在这些页面上很多次了,但是我仍然没有找到我需要的“好办法”。让我们开始解释。
Localization in .net, and in mvc, is made in 2 ways that can even be mixed together:
.net和mvc中的本地化有两种方式,甚至可以混合在一起:
- Resource files (both local or global)
- 资源文件(本地或全局)
- Localized views with a viewengine to call the appropriate view based on culture
- 使用viewengine本地化视图,以基于区域性调用适当的视图
I'll explain the solutions I tried and all the problems I got with every one of them.
我会解释我尝试过的解决方案,以及所有的问题。
Text in resource files, all tags in the view
资源文件中的文本,视图中的所有标记。
This solution would have me put every text in resources, and every tag in the view, even the inline tags such as [strong] or [span].
这个解决方案会让我把资源中的每个文本,以及视图中的每个标记,甚至包括[strong]或[span]这样的内联标记。
Pros:
优点:
- Clean separation, no structure whatsoever in localization.
- 干净的分离,没有任何结构在本地化。
- Easy encoding: everything that is returned from the resource gets html encoded.
- 简单编码:从资源返回的所有内容都被html编码。
Cons:
缺点:
- If I have a paragraph with some strongs, a couple of link etc I have to split it in many resource keys. This is considered to make the view too unreadable and also takes too much time to create it.
- 如果我有一个段落有一些强的,一些链接等等,我必须把它分成很多资源键。这被认为使视图不可读,并且创建它也花费了太多的时间。
- For the same reason as above, if in two different languages the [strong] text is in different places (like "Il cane di Marco" and "Marcos's dog"), I can't achieve it, since all my tags are in the view.
- 出于同样的原因,如果在两种不同的语言中,[强]文本位于不同的地方(比如“Il cane di Marco”和“Marcos's dog”),我无法实现它,因为我的所有标记都在视图中。
Text and inline tags in resource files, through parameters
资源文件中的文本和内联标签,通过参数
This method will have the resources contain some placeholders for string.Format, and those placeholders will be filled with inline tags post-encoding.
这个方法将使资源包含一些字符串占位符。格式,这些占位符将被后编码的内联标记填充。
Pros:
优点:
- Clean separation, with just placeholders in the text, so if I am ever to replace [strong] with [em] I do it in the view where I pass it as parameter and it gets changed in every language
- 干净的分离,文本中只有占位符,所以如果我要用[em]替换[strong],我会在视图中这样做,我将它作为参数传递,在每种语言中它都会被修改
Cons:
缺点:
- Encoding is a bit harder, I have to pre-encode the value from the resource, then use string.Format, and finally return it as MvcHtmlString to tell the view engine to not re-encode it when displaying.
- 编码有点难,我必须先对资源中的值进行预编码,然后再使用字符串。格式化,最后返回MvcHtmlString,告诉视图引擎在显示时不要重新编码。
- For the same reason as above, including, for instance, an ActionLink as parameter would be troublesome. Let's say I get the text for my actionlink from a resource. My method already encodes it. But then, the ActionLink method would re-encode it again. I would need a distinct method to get resources without encoding them, or new helper methods that get an MvcHtmlString instead of a string as text parameter, but both are rather unpractical.
- 出于与上面相同的原因,包括,例如,将ActionLink作为参数是很麻烦的。假设我从资源中获取actionlink的文本。我的方法已经对它进行了编码。但是,ActionLink方法会重新对它进行编码。我需要一个不同的方法来获取资源而不进行编码,或者需要一个新的助手方法来获取MvcHtmlString而不是字符串作为文本参数,但这两个方法都不实用。
- Still takes a whole lot of time to build views, having to create all the resource keys and then fill them.
- 仍然需要花费大量的时间来构建视图,必须创建所有的资源键,然后填充它们。
Localized views
局部视图
Pros:
优点:
- All views are plain html. No resources to read.
- 所有视图都是纯html。没有资源来阅读。
Cons:
缺点:
- Duplicated html everywhere. I don't even need to explain how this is totally evil.
- 复制html无处不在。我甚至不需要解释为什么这是完全邪恶的。
- Have to manually encode all troublesome characters like grave vowels, quotes and such.
- 必须手工编码所有麻烦的字符,如严肃的元音、引号等。
Conclusions
结论
A mix of the above techinques inherits pros and cons, but it's still no good. I am challenged to find a proper productive solution, while all of the above are considered "unpractical" and "time consuming".
以上的techinques虽然兼有正反两方面的优点,但仍然不是很好。我面临的挑战是找到一个合适的有效的解决方案,而所有这些都被认为是“不实用的”和“耗时的”。
To make things worse, I found out that there isn't a single tool that refactors "text" from aspx or cshtml (or even html) views/pages into resources. All the tools out there can refactor System.String instances in code files (.cs or .vb) into resources only (resharper for instance, and a couple of others I can't remember now).
更糟糕的是,我发现没有一个工具可以将“文本”从aspx或cshtml(甚至html)视图/页面重构到资源中。所有的工具都可以重构系统。代码文件中的字符串实例(。cs或.vb)只用于资源(resharper,和其他一些我现在不记得了的)。
So I'm stuck, can't find anything appropriate on my own, and can't find anything on the web either. Is it possible noone else got challenged with this problem before and found a solution?
所以我被困住了,无法自己找到合适的东西,也无法在网上找到任何东西。有没有可能之前没有人遇到过这个问题并找到了解决方案?
3 个解决方案
#1
7
I personally like the idea of storing inline tags in the resource file. However I do it a little differently. I store very plain tags like <span class='emphasis'>dog</span>
and then I use CSS to style the tags appropriately. Now, instead of "passing in" a tag as a parameter, I simply style the span.emphasis
rule in my CSS appropriately. Change carries over to all languages.
我个人喜欢在资源文件中存储内联标记的想法。但是我做的有点不同。我存储非常普通的标签,比如dog,然后我使用CSS适当地样式化标签。现在,我不再“传入”一个标记作为参数,而是对span进行样式化。强调规则在我的CSS适当。变化传播到所有的语言。
The Sexier Option:
性感的选择:
Another option I thought of and quite enjoy is to use a "readable markup" language like *'s very own MarkdownSharp. This way you aren't storing any HTML in the resource file, only markdown text. So in your resource you would have **dog**
and then it gets shunted through markdown in the view (I created a helper for this, (Usage: Html.Markdown(string text)
). Now you're not storing tags, you're storing a common human readable markup language. The markdownsharp source is one .CS file and it's easy to modify. So you could always change the way it renders the ending HTML. This gives you total control over all your resources without storing HTML, and without duplicating views or chunks of HTML.
我还想到了另一个非常喜欢的选择,那就是使用“可读标记”语言,比如*自己的MarkdownSharp。这样,您就不会在资源文件中存储任何HTML,而只存储markdown文本。所以在你的资源中你会有** *dog*然后它会在视图中通过markdown被分流(我为此创建了一个助手,用法:Html。减记(字符串文本))。现在不存储标记,而是存储一种通用的人类可读标记语言。markdownsharp源文件是一个. cs文件,很容易修改。所以你总是可以改变它呈现HTML结尾的方式。这使您可以完全控制所有资源,而无需存储HTML,也无需复制视图或HTML块。
EDIT
编辑
This also gives you control over the encoding. You could easily make sure the content of your resource files contain no valid HTML. Markdown syntax (as you know from using stack overflow) does not contain HTML tags and thus can be encoded without harm. Then you just use your helper to convert the Markdown syntax to valid HTML.
这也使您能够控制编码。您可以轻松地确保资源文件的内容不包含有效的HTML。Markdown语法(您从使用stack overflow了解到)不包含HTML标记,因此可以安全地编码。然后使用助手将Markdown语法转换为有效的HTML。
EDIT #2
编辑# 2
There is one bug in markdown that I had to fix myself. Anything markdown detects is to be rendered as a "code" block will be HTML encoded. This is a problem if you have already HTML encoded all content being passed to markdown as anything in the code blocks will be essentially re-encoded which turns >
into &gt;
and completely screws up the text within code blocks. To fix this I modified the markdown.cs file to include a boolean option that stops markdown from encoding text within code blocks. See this issue for the fixed .cs file that I added to the MarkdownSharp project issues.
在markdown中有一个bug需要我自己修复。任何markdown检测到的东西都将被呈现为一个“代码”块,将被HTML编码。这是一个问题,如果你已经对所有被传递给markdown的内容进行了HTML编码,那么代码块中的任何内容本质上都将被重新编码,这就是turn >成,gt;并且在代码块中完全打乱文本。为了解决这个问题,我修改了markdown。cs文件包含一个布尔选项,阻止markdown在代码块中编码文本。有关我添加到MarkdownSharp项目问题的固定.cs文件,请参见此问题。
EDIT #3 - Html Helper Sample
编辑#3 - Html帮助示例
public static class HtmlHelpers
{
public static MvcHtmlString Markdown(this HtmlHelper helper, string text)
{
var markdown = new MarkdownSharp.Markdown
{
AutoHyperlink = true,
EncodeCodeBlocks = false, // This option is my custom option to stop the code block encoding problem.
LinkEmails = true,
EncodeProblemUrlCharacters = true
};
string html = markdown.Transform(markdownText);
return MvcHtmlString.Create(html);
}
}
#2
2
Nothing stops you from storing HTML in resource files, then calling @Html.Raw(MyResources.Resource)
.
没有什么能阻止您在资源文件中存储HTML,然后调用@Html.Raw(MyResources.Resource)。
#3
0
Have you thought about using localized models, have your view be strongly types to IMyModel and then pass in the appropriately decorated model then you can use/change how your doing your localization fairly easy by modifying the appropriated model.
您是否考虑过使用本地化模型,将您的视图作为IMyModel的强类型,然后传入适当修饰的模型,然后您就可以通过修改专用模型来使用/改变您的本地化工作的方式。
it's clean, very flexible, and very easy to maintain.
它很干净,很灵活,很容易维护。
you could start out with Recourse file based localization and then for paces you need to update more often switch that model to a cached DB based localization model.
您可以从基于资源文件的本地化开始,然后针对需要经常更新的性能测试,将该模型切换到基于缓存DB的本地化模型。
#1
7
I personally like the idea of storing inline tags in the resource file. However I do it a little differently. I store very plain tags like <span class='emphasis'>dog</span>
and then I use CSS to style the tags appropriately. Now, instead of "passing in" a tag as a parameter, I simply style the span.emphasis
rule in my CSS appropriately. Change carries over to all languages.
我个人喜欢在资源文件中存储内联标记的想法。但是我做的有点不同。我存储非常普通的标签,比如dog,然后我使用CSS适当地样式化标签。现在,我不再“传入”一个标记作为参数,而是对span进行样式化。强调规则在我的CSS适当。变化传播到所有的语言。
The Sexier Option:
性感的选择:
Another option I thought of and quite enjoy is to use a "readable markup" language like *'s very own MarkdownSharp. This way you aren't storing any HTML in the resource file, only markdown text. So in your resource you would have **dog**
and then it gets shunted through markdown in the view (I created a helper for this, (Usage: Html.Markdown(string text)
). Now you're not storing tags, you're storing a common human readable markup language. The markdownsharp source is one .CS file and it's easy to modify. So you could always change the way it renders the ending HTML. This gives you total control over all your resources without storing HTML, and without duplicating views or chunks of HTML.
我还想到了另一个非常喜欢的选择,那就是使用“可读标记”语言,比如*自己的MarkdownSharp。这样,您就不会在资源文件中存储任何HTML,而只存储markdown文本。所以在你的资源中你会有** *dog*然后它会在视图中通过markdown被分流(我为此创建了一个助手,用法:Html。减记(字符串文本))。现在不存储标记,而是存储一种通用的人类可读标记语言。markdownsharp源文件是一个. cs文件,很容易修改。所以你总是可以改变它呈现HTML结尾的方式。这使您可以完全控制所有资源,而无需存储HTML,也无需复制视图或HTML块。
EDIT
编辑
This also gives you control over the encoding. You could easily make sure the content of your resource files contain no valid HTML. Markdown syntax (as you know from using stack overflow) does not contain HTML tags and thus can be encoded without harm. Then you just use your helper to convert the Markdown syntax to valid HTML.
这也使您能够控制编码。您可以轻松地确保资源文件的内容不包含有效的HTML。Markdown语法(您从使用stack overflow了解到)不包含HTML标记,因此可以安全地编码。然后使用助手将Markdown语法转换为有效的HTML。
EDIT #2
编辑# 2
There is one bug in markdown that I had to fix myself. Anything markdown detects is to be rendered as a "code" block will be HTML encoded. This is a problem if you have already HTML encoded all content being passed to markdown as anything in the code blocks will be essentially re-encoded which turns >
into &gt;
and completely screws up the text within code blocks. To fix this I modified the markdown.cs file to include a boolean option that stops markdown from encoding text within code blocks. See this issue for the fixed .cs file that I added to the MarkdownSharp project issues.
在markdown中有一个bug需要我自己修复。任何markdown检测到的东西都将被呈现为一个“代码”块,将被HTML编码。这是一个问题,如果你已经对所有被传递给markdown的内容进行了HTML编码,那么代码块中的任何内容本质上都将被重新编码,这就是turn >成,gt;并且在代码块中完全打乱文本。为了解决这个问题,我修改了markdown。cs文件包含一个布尔选项,阻止markdown在代码块中编码文本。有关我添加到MarkdownSharp项目问题的固定.cs文件,请参见此问题。
EDIT #3 - Html Helper Sample
编辑#3 - Html帮助示例
public static class HtmlHelpers
{
public static MvcHtmlString Markdown(this HtmlHelper helper, string text)
{
var markdown = new MarkdownSharp.Markdown
{
AutoHyperlink = true,
EncodeCodeBlocks = false, // This option is my custom option to stop the code block encoding problem.
LinkEmails = true,
EncodeProblemUrlCharacters = true
};
string html = markdown.Transform(markdownText);
return MvcHtmlString.Create(html);
}
}
#2
2
Nothing stops you from storing HTML in resource files, then calling @Html.Raw(MyResources.Resource)
.
没有什么能阻止您在资源文件中存储HTML,然后调用@Html.Raw(MyResources.Resource)。
#3
0
Have you thought about using localized models, have your view be strongly types to IMyModel and then pass in the appropriately decorated model then you can use/change how your doing your localization fairly easy by modifying the appropriated model.
您是否考虑过使用本地化模型,将您的视图作为IMyModel的强类型,然后传入适当修饰的模型,然后您就可以通过修改专用模型来使用/改变您的本地化工作的方式。
it's clean, very flexible, and very easy to maintain.
它很干净,很灵活,很容易维护。
you could start out with Recourse file based localization and then for paces you need to update more often switch that model to a cached DB based localization model.
您可以从基于资源文件的本地化开始,然后针对需要经常更新的性能测试,将该模型切换到基于缓存DB的本地化模型。