Loading...
 
Multi-Language Add-In for Visual Studio

Multi-Language Add-In for Visual Studio


Support for ASP.NET MVC projects

Germany

It's been a long time coming, but I have finally started implementing support for ASP.NET MVC projects. Specifically, this means support for .cshtml and .vbhtml files.

Version 6.1.8 contains a beta version of MVC support, in which the files are scanned, and you can select texts for translation.

After scanning an MVC project, the .cshtml or .vbhtml files are shown in the source code tab, as shown in the following screen shot.

Image

There are two kinds of text strings:

  • HTML texts
  • String Literals in the C# or VB source code


If you select a row in the Multi-Language grid, the text is selected in the editor window (as you can see above).

(I have modified the colour for selected text in an inactive window so you can see it better.)

When you select a text for translation, a resource string is created and the text is replaced with a reference to the resource string.

For HTML text, the resource name is prefixed with an @ symbol, to switch to C#/VB code mode.

Image

For String Literals, the text is simply replaced with the resource name.

Image

Accessing the resources requires that the access modifier on the resource file is public. You might have to change this.

Image

(Multi-Language could probably do this automatically, but the current version does not.)

I think that is enough to make a working localization.

Hiding texts with the sun/moon symbol does not yet work. In fact, I don't really know how I am going to implement it.

I haven't yet looked at features like Searching, of Filtering with regular expressions, so they probably don't work.

If you select a string in the text editor and click on the Image symbol on the Multi-Language toolbar, then it should locate the string in the grid. This command is not in the code editor context menu, because I can't figure out how to make it appear there!

At present, I am not really sure how usable this is. The example above shows the text:

There are no external authentication services configured. See this article
        for details on setting up this ASP.NET application to support logging in via external services.

split into three separate texts:

  • There are no external authentication services configured. See
  • this article
  • for details on setting up this ASP.NET application to support logging in via external services.

which would be stored as three separate resource strings.

It might be better to store the complete text (with the link) in one resource string. You could do this by selecting the first string for translation, and then cutting and pasting the rest of the text into the multi-language grid, but that is a bit messy.

It would be good to get some feedback on things like that, because I am not really ASP programmer myself.

Phil

This is good news! Thanks for this :-)

Regarding text with placeholders.

With normal ASP.NET (aspx/aspx.cs), we actually have the same issue.. We are currently doing something like:

aspx:
< asp:Literal id="Literal1" runat="server" />

aspx:cs
Literal1.Text = string.Format("There are no external authentication services configured. See {0} for details on setting up this ASP.NET application to support logging in via external services.", string.Format("< a href=\"http\">{0}< /a>", "this article"));

Translation

  • There are no external authentication services configured. See {0} for details on setting up this ASP.NET application to support logging in via external services.
  • this article


Above is optimal for the translator, but not for developer. Developer would like something like:

aspx
There are no external authentication services configured. See < asp:HyperLink id="HyoerLink1" runat="server" NavigateUrl="http">this article< /asp:HyperLink> for details on setting up this ASP.NET application to support logging in via external services.

Translation

  • There are no external authentication services configured. See
  • this article
  • for details on setting up this ASP.NET application to support logging in via external services.


Please note above yields the same results as you see with ASP.NET MVC. The difference is, we have an easy work-around with ASP.NET (putting it in code behind) - not so much with MVC, where it's less accepted to put stuff like this in e.g. Model and Controller. In MVC we would properly hack us through this by including C# code inside the view like:

cshtml
@string.Format("There are no external authentication services configured. See {0} for details on setting up this ASP.NET application to support logging in via external services.", string.Format("< a href=\"http\">{0}< /a>", "this article"));

Let me be very clear. Even though this sounds like a good solution, I tend to avoid writing C# in the view as much as possible. I want to keep it simple, so a web designer with very limited knowledge of C# can maintain the file. Even though above is very simple and basic C#, it still adds to knowledge requirement of the web designer (who should focus more on html/css/js/graphics, and not so much about how the MVC framework clues things together). Including C# in the View might be the "only" solution that would prove to work well in reality. But preferred for developer/web designer: no.

Lets get back to the ASP.NET example from the beginning.. If you are able to detect a Html.Text is actually "containing" a single html element, it might at first seems like we would be better off. But it's way more complex than one might think. Lets examine the first example once more and assume we can add a placeholder for the < asp:HyperLink> (or any other HTML element, like < a>):

aspx
There are no external authentication services configured. See < asp:HyperLink id="HyoerLink1" runat="server" NavigateUrl="http">this article< /asp:HyperLink> for details on setting up this ASP.NET application to support logging in via external services.

Translation

  • There are no external authentication services configured. See {0} for details on setting up this ASP.NET application to support logging in via external services.
  • this article


Now we get the best of both world. Developer is happy and Translator is happy. But... It's not that simple. We could see another example where we simply don't want it to be 1 string with a placeholder, but rather be 2 separated strings. But if above logic should be consistent, it's going to look very odd for the translator in some scenarios:

aspx
-+This is a test.
< asp:HyperLink id="HyoerLink1" runat="server" NavigateUrl="http">Click to read more< /asp:HyperLink>.
Thanks for watching this test.+-

Translation

  • This is a test. {0}. Thanks for watching this test.
  • Click to read more


I'm sure the translator in above scenario would prefer something else. Something like:

Translation

  • This is a test
  • Click to read more
  • Thanks for watching this test


So even though it might seem like a simple problem to solve, it's really difficult to satisfy both developer and translator without forcing them to use either aspx.cs (ASP.NET) or inline code (ASP.NET MVC).

The best alternative solution I can come up with right now is some special "html tagging" to detect when developer want one or another scenario. Could be a convention about requiring HTML to encapsulate the text if we don't want to use a placeholder. Like:

aspx
< span>This is a test< /span>.
< asp:HyperLink id="HyoerLink1" runat="server" NavigateUrl="http">Click to read more< /asp:HyperLink>.
< span>Thanks for watching this test< /span>.

Translation

  • This is a test
  • Click to read more
  • Thanks for watching this test


Above will force developer to add "span" elements (or other html elements). Even though span elements are most likely harmless, in theory the web designer could choose to make span less harmless. It could easily ruin the vertical alignment or something worse - and then we "ask" the web designer to take care of this "problem" instead of the developer/translator. Not sure it's any better.

On the other hand, we could add a css class to containing element, to allow/ignore placeholder logic (a lot like //MLHide). Could look like:

aspx
< div id="Content" class="MLNoPlaceHolder">
This is a test.
< asp:HyperLink id="HyoerLink1" runat="server" NavigateUrl="http">Click to read more.< /asp:HyperLink>
Thanks for watching this test.
< /div>

Translation

  • This is a test.
  • Click to read more.
  • Thanks for watching this test.


Again: I'm not saying this is better than what the framework provides. I'm saying it's another strategy to solve your query.

I won't be the one to judge if you make a change to your logic. It makes sense to try to satisfy both developer, web designer and translator. But the way I see it, it will come at some sort of cost no matter what - and you need to ask yourself what's best: You (Jollans/ML tool) making special logic or the developer to use hacks allowed within the standard framework (either using aspx.cs or inline C# in .cshtml).

Well.. Hope you got something out of reading this. Good luck making a decision ;-)

Nick