I need to make a form that have to suport two languages (for now).
the two languages dont have the same look and also half of the form is not a like but it still have some similiarity beetwen them.
what is the best way to deal with this problem in a case of two different languages and above?
by the way, the program language that I use is C#.
10x
First, configure your project default language, you do this in the Project Properties, in the Assembly Information dialog, there's a "Neutral Language" setting at the bottom.
Set this to be your "default" language, the "main" language if you wish.
Then, make sure the form as it is now, is in that language.
To start translating and changing the form to comply with a different language, first set the "Localizable" property of the form to true, and then change the Language property to your second (or third, fourth, etc.) language.
Once you have changed that, you can start making changes. Make sure you don't delete items on the form, instead just set them invisible. Deletion is done for all languages, but invisible will thus only be set for the current language.
Keep switching back and forth between the languages to make adjustments.
To test your program in a specific language, execute this at the start of your Main method:
Thread.CurrentThread.CurrentCulture = new CultureInfo("code of that other language");
Thread.CurrentThread.CurrentUICulture = new CultureInfo("code of that other language");
For instance, to test it with "Norwegian, Bokmål" language, which is my main language, the code you would use would be "nb-NO". To find the code you need to use, once you've changed the language of your form to the language you want to localize for, and saved, a new file will be added to the solution explorer with the right name.
For instance, for Form1, the following files will be present:
Form1.cs
Form1.designer.cs
Form1.nb-NO.resx <-- here's the localized content
Form1.resx
Now, having done this, there's plenty of other things you need to be aware of when making a localized application, I suggest you go read other questions on SO and on the web with more information, like these:
Best practice to make a multi language application in C#/WinForms?
Parsing DateTime on Localized systems
Pluralising and Localizing strings in C#
How do I best localize an entire app to many different languages?
I think a single global resource file for each language is better than having a resource file for each form for each language.
I recently did globalization of a winforms app with the help of the following link "Globalization of Windows Applications in 20 Minutes". Here are the steps for simplicity :
Create a text file say "data.en-US.txt" in the solution (<filename>.<culture string>.txt) in the format below :
Hello=Hello
Welcome=Welcome
This file "data.en-US.txt" is a resource text file in the English language.
Create a similar file in your desired language say German, so its filename will be data.de-DE.txt
Hello=Halo
Welcome=Willikomen
The first column are the labels which will be used as keys for referring the text.
Create a "data-en-US.resource" file out of the text files by using the command "resgen.exe data.en-US.txt",
Do this for all language files. Now in your solution you have 2 (or more, depending on the languages you want to support) data.<culture string>.resource files
Click all the .resource files and set "Build Action" property to "Content".
Click all the .resource files and set "Copy to Output Directory" property to "Copy Always / Copy If new".
Get the localized string using the code below in any of the forms :
string label = "Hello";
string cultureString = "de-DE" // [or "en-US"]
string strResourcesPath = Application.StartupPath;
CultureInfo ci = new CultureInfo(cultureString); ['cultureString' represents your desired language]
ResourceManager rm = ResourceManager.CreateFileBasedResourceManager("data", strResourcesPath , null); ["data" is the first part of the filename]
var answer = rm.GetString(label, ci); // here ans="Halo" as we selected de-DE
Related
I'm writing an extension to provide basic project statistics (e.g. lines of code). It's simple enough to iterate a Solution tree and find the ProjectItems that correspond with files.
The Document structure has Kind and Language properties, but the latter is marked for internal use only, and both require the file to be opened in the editor first.
So... is there a way to:
See what files Visual Studio will classify as text files.
See what language Visual Studio associates with a given file name / file extension.
without opening the file?
I have written such statistics (although only for C# and VB.NET) and both questions are very tricky for all project types / file types / languages. First of all, if you need, you can open an EnvDTE.Document / EnvDTE.TextDocument from an EnvDTE.ProjectItem using the ProjectItem.Open(view) method, which returns an EnvDTE.Window. That doesn't make the window visible, by default is invisible, you would need to call Window.Visible = true to make it visible. When done, you close the (invisible) window with Window.Close, unless it was already opened (you can know calling first ProjectItem.get_IsOpen(view) and later closing or not accordingly).
Now:
It is very difficult to know if a file is text or not because VS supports many projects, and each project type can consider its files/extensions as text files or not. The best approach that I found is to consider all files as text files unless known extensions that are not text files (.jpg, etc.). Also, notice that not all text files are code files (ex: .txt files). For some features such as a find text feature you may be interested in text files but for an statistics feature you may be interested in code files, not just text files.
You can know the guid of the language of a file using EnvDTE.ProjectItem.FileCodeModel.Language (and EnvDTE.Project.CodeModel.Language). Alas, some project / files have language but do not provide a code model, so you may need to use known extensions to map to a language.
Some useful language guids:
const string LANGUAGE_CSHARP = "{B5E9BD34-6D3E-4B5D-925E-8A43B79820B4}";
const string LANGUAGE_IDL = "{B5E9BD35-6D3E-4B5D-925E-8A43B79820B4}";
const string LANGUAGE_MANAGED_C = "{B5E9BD36-6D3E-4B5D-925E-8A43B79820B4}";
const string LANGUAGE_VBNET = "{B5E9BD33-6D3E-4B5D-925E-8A43B79820B4}";
const string LANGUAGE_VISUAL_C = "{B5E9BD32-6D3E-4B5D-925E-8A43B79820B4}";
const string LANGUAGE_PYTHON = "{888888A0-9F3D-457C-B088-3A5042F75D52}";
const string LANGUAGE_FSHARP = "{F2A71F9B-5D33-465A-A702-920D77279786}";
const string LANGUAGE_R = "{DA7A21FA-8162-4350-AD77-A8D1B671F3ED}";
Notice that being VS so extensible, there is no enum for languages. New languages provide new guids.
I would like to localize the VirtualKey for Control.
Currently there is code like this:
using Windows.System;
var message = "Press " + VirtualKey.Control.ToString() + " + D for deletion!";
Is there an API which can be used to have the following?
Press Control + D for deletion! (on an English system)
Press Steuerung + D for deletion! (on a German system)
As VirtualKey is an enumeration, you cannot translate a member of an enumeration directly, but you can use it as the key for resource files, building up a localization system:
I followed this tutorial to build up a simple localization system on a Windows 8.1 Application; these are the steps I followed (summed-up)
Create a folder called "Strings"
Inside the folder, create a folder for the default language you want to support and name it accordigly (see a full list of possible codes here)
Create a Resources.resw file in that folder
Add the strings you want to add - If you want to support the use of VirtualKey.xxx.ToString(), I strongly suggest you to use the same identifiers of the enumeration; for instance: if you want to translate the control character, call the new resource "Control" - (this is what I did):
Copy and paste that folder for a number of times equal to the number of languages you want to support (I did it twice):
Edit the Resource.resx file accordingly to the language you're translating to.
In code, refer to each translated string with
var loader = new Windows.ApplicationModel.Resources.ResourceLoader();
loader.GetString(VirtualKey.xxx.ToString());
That's what I did on a TextBlock in MainPage.xaml:
var loader = new Windows.ApplicationModel.Resources.ResourceLoader();
this.txbCtrl.Text = String.Format("Press {0}-Z to undo", loader.GetString(VirtualKey.Control.ToString()));
And that's the result for the language it-IT:
To test it for other languages, I followed the tutorial, even if I don't like it:
Open the Control Panel and go to Clock, Language, and Region > Language
Note that the language that was displayed when the app was ran is the top language listed that is, on my system, Italian.
To test the app with another language, select the language in the list and click Move up until it is at the top. Then run the app.
NB: If you do not have all three of these languages on your machine, add the missing ones by clicking Add a language and adding them to the list.
In my case I have italian listed for first and English (UK) as the second one, but if I swap them:
and run again the application, this is the result
and if I add de-DE:
with these resource files:
en-GB:
and it-IT:
and de-DE:
Notice that I've called the English Control key "Control" and the Italian one "Ctrl"; it works perfectly
I Hope this helped.
If you have more questions, just ask!
LuxGiammi
EDIT: this is a solution, even though I recognize this is not a good one (anyway, it's the best I could think of). Anyway, as stated here for WinForm applications, it is not necessary to do it because evrybody would understand you if you use the defualt names for the keys (i.e., the one in the enumeration, just like you're doing now).
EDIT2: this solution, however, sets everything up for a future "full" localization for your application. This way half of the effort is made at the beginning of the developemnt process.
Currently I'm finishing my very first iPhone application with MonoTouch. Localization through the "*.lproj" folders works as expected.
Having an UIWebView that displays some user guidelines, I'm populating this one with the LoadHtmlString() method. (I.e. no internet connection is required).
Since the text is a bit longer, I do not want it to be placed inside the "Localizable.strings" file but being swapped out to a completely separate file (as I'm doing it for Windows .NET applications, too):
In the above screenshot, I would have one "help.html" file inside each language folder and call the LoadHtmlString method to read from the appropriate file in a way that would be similar to NSBundle.MainBundle.LocalizedString.
My question:
Is it possible to have per-language files and access them from within a MonoTouch application?
Follow-up to Dimitris' solution
Based on Dimitris' solution, I solved it by this code:
var localizedHtmlFile = NSBundle.MainBundle.PathForResource("help", "html");
var text = File.ReadAllText(localizedHtmlFile);
helpTextView.LoadHtmlString (text, null);
Yes, of course it is possible. You can get the path of the localized file like this:
string localizedHtmlFile = NSBundle.MainBundle.PathForResource("help", "html");
You can use the PathForResource method for various different types of resources (PDFs, images, etc.). The first parameter is the file name and the second one is its extension. Check the other overload of the PathForResource method for more options.
I have a new piece of software I'm working on for my company that potentially will need some localization options for our plant in Mexico. As far as the application goes, C#/.NET has some great localization features that I will utilize. The new program will be making use of scripts that will have messages pop-up to the user, and those are probably the most important ones for localization. They'll be written in [Iron]Python and we are currently, for other scripts/software, maintaining two separate scripts for localization (and some other small changes that could be implemented via logic). What's the best way to localize a script so we can have just one script?
The simplest way is to remove all of the user-facing strings from your script, and instead look up what string is to be shown based on the current language. For example, instead of:
print 'Hello, World'
use
print _('Hello, World')
def _(key):
if currentlang == 'es':
return localized_text_es[key]
else:
return key
localized_text_es = { 'Hello, World': '¡Hola, mundo' }
You could fill localized_text at startup from en.txt/es.txt files, or you could hardcode both languages into the scripts, or whatever other method you choose.
I have developed a large business portal. I just realized I need my website in another language. I have researched the solutions available like
Used third party control on my website. (Does fit in my design. Not useful regarding SEO point of view. Dont want to show third party brand names.)
Create Resource files for each language.( A lot of work required to restructure pages to use text from resource files. What about the data entered by the user like Business Description. )
Are there any Other options available.
I was thinking of a solution like a when a page is created on server side then I could translate it before sending back to client. Is there any way I can do that?(to translate everything including data added from databases or through a code. And without effecting design. )
If you really need to translate your application, it's going to take a lot of hard, tedious work. There is no magic bullet.
The first thing you need to do is convert your plain text in your markup to asp:Localize controls. By using the Localize control, you can leave your existing <span> tags in place and just replace the text inside of them. There's really no way around this. Visual Studio's search and replace supports regular expression matching that may help you with this, or you can use Resharper (see below).
The first approach would be to download the open source shopping application nopCommerce and see how they handle their localization. They store their strings in a database and have a UI for editing languages. A similar approach may work well for you.
Alternatively, if you want to use Resource Files, there are two tools that I would recommend using in addition to Visual Studio: Resharper 5 (Localization Features screencast) and Zeta Resource Editor. These are the steps I would take to accomplish it using this method:
Use the "Generate Local Resource" tool in visual studio for each page
Use Resharper's "Move HTML to resource" on the text in your markup to make them into Localize controls.
Use Resharper to search out any localizable strings in your code behind and move them to the resource file as well.
Use the Globalization Rules of Code Analysis / FXCop to help find any additional problems you might face formatting numbers, dates, etc.
Once all text is in the resx files, use Zeta Resource Editor to load up all of your resx files, add new languages, and export for translation (or auto translate if you're brave enough).
I've used this approach on a site translated into 8 languages (and growing) with dozens of pages (and growing). However, this is not a user-editable site; the pages are solely controlled by the programmers.
a large switch case? use a dictionary/hashtable (seperate instance for each a language), it is much, much more effective and fast.
To Convert The Page To Arabic Language Or Other Language .
Go to :
1-page design
2-Tools
3-Generate Local Resource
4-obtain "App_LocalResources" include "filename.aspx.resx"
5-copy the file and change the name to "filename.aspx.ar.resx" to convert the page to arabic language or other .
hope to helpful :)
I found a good solution, see in http://www.nopcommerce.com/p/1784/nopcommerce-translator.aspx
this project is open source and source repository is here: https://github.com/Marjani/NopCommerce-Translator
good luck
Without installing any 3rd party tool, APIs, or dll objects, I am able to utilize the App_LocalResources. Although I still use Google Translate for the words and sentences to be translated and copy and paste it to the file as you can see in one of the screenshots below (or you can have a person translator and type manually to add). In your Project folder (using MS Visual Studio as editor), add an App_LocalResources folder and create the English and other language (resx file). In my case, it's Spanish (es-ES) translation. See screenshot below.
Next, on your aspx, add the meta tags (meta:resourcekey) that will match in the App_LocalResources. One for English and another to the Spanish file. See screenshots below:
Spanish: (filename.aspx.es-ES.resx)
English: (filename.aspx.resx)
.
Then create a link on your masterpage file with a querystring that will switch the page translation and will be available on all pages:
<%--ENGLISH/SPANISH VERSION BUTTON--%>
<asp:HyperLink ID="eng_ver" runat="server" Text="English" Font-Underline="false"></asp:HyperLink> |
<asp:HyperLink ID="spa_ver" runat="server" Text="Español" Font-Underline="false"></asp:HyperLink>
<%--ENGLISH/SPANISH VERSION BUTTON--%>
.
On your masterpage code behind, create a dynamic link to the Hyperlink tags:
////LOCALIZATION
string thispage = Request.Url.AbsolutePath;
eng_ver.NavigateUrl = thispage;
spa_ver.NavigateUrl = thispage + "?ver=es-ES";
////LOCALIZATION
.
Now, on your page files' code behind, you can set a session variable to make all links or redirections to stick to the desired translation by always adding a querystring to urls.
On PageLoad:
///'LOCALIZATION
//dynamic querystring; add this to urls ---> ?" + Session["add2url"]
{
if (Session["version"] != null)
{
Session["add2url"] = "?ver=" + Session["version"]; //SPANISH version
}
else
{
Session["add2url"] = ""; // ENGLISH as default
}
}
///'LOCALIZATION
.
On Click Events sample:
protected void btnBack_Click(object sender, EventArgs e)
{
Session["FileName.aspx"] = null;
Response.Redirect("FileName.aspx" + Session["add2url"]);
}
I hope my descriptions were easy enough.
If you don't want to code more and if its feasible with google translator then You can try with Google Translator API. you can check below code.
<script src="http://translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"></script>
<script>
function googleTranslateElementInit() {
$.when(
new google.translate.TranslateElement({pageLanguage: 'en', includedLanguages: 'en',
layout: google.translate.TranslateElement.FloatPosition.TOP_LEFT}, 'google_translate_element')
).done(function(){
var select = document.getElementsByClassName('goog-te-combo')[0];
select.selectedIndex = 1;
select.addEventListener('click', function () {
select.dispatchEvent(new Event('change'));
});
select.click();
});
}
$(window).on('load', function() {
var select = document.getElementsByClassName('goog-te-combo')[0];
select.click();
var selected = document.getElementsByClassName('goog-te-gadget')[0];
selected.hidden = true;
});
</script>
Also, Find below code for <body> tag
<div id="google_translate_element"></div>
It will certainly be more work to create resource files for each language - but this is the option I would opt for, as it gives you the opportunity to be more accurate. If you do it this way you can have the text translated, manually, by someone that speaks the language (there are many companies out there that offer this kind of service).
Automatic translation systems are often good for giving a general impression of what something in another language means, but I would never use them when trying to portray a professional image, as often what they output just doesn't make sense. Nothing screams 'unprofessional!' like text that just doesn't make sense because it's been automatically translated.
I would take the resource file route over the translation option because the meaning of words in a language can be very contextual and even one mistake could undermine your site's credibility.
As you suggest Visual Studio can generate the meta resource file keys for most controls containing text but may leave you having to do the rest manually but I don't see an easier, more reliable solution.
I don't think localisation is an easy-to-automate thing anyway as text held in the database often results in schema changes to allow for multiple languages, and web HTML often need restructuring to deal with truncated or wrapped label and button text because, for example, you've translated into German or something.
Other considerations:
Culture settings - financial delimitors, date formats.
Right-to-left - some languages like arabic are written right to left meaning that the pages require rethinking as to control positioning like images etc.
Good luck whatever you go with.
I ended up doing it the hard way:
I wrote an extension method on the string class called TranslateInto
On the Page's PreRender method I grab all controls recursively based on their type (the types that would have text)
Foreach through them and text.TranslateInto(SupportedLanguages.CurrentLanguage)
In my TranslateInto method I have a ridiculously large switch statement with every string displayed to the user and its associated translation.
Its not very pretty, but it worked.
We work with a Translation CAT tool (Computer Assisted Translation) called MemoQ that allows us to translate the text while leaving all the tags and coding in place. This is very helpful when the order of words change when you translate from one language to another.
It is also very useful because it allows us to work with translators from around the world, without the need for them to have any technical expertise. It also allows us to have the translation proof read by a second translator.
We use this translation environment to translate html, xml, InDesign, Word, etc.
I think you should try Google Translate.
http://translate.google.com/translate_tools
Very easy and very very effective.
HTH