New Community Website

Ordinarily, you'd be at the right spot, but we've recently launched a brand new community website... For the community, by the community.

Yay... Take Me to the Community!

The Community Blog is a personal opinion of community members and by no means the official standpoint of DNN Corp or DNN Platform. This is a place to express personal thoughts about DNNPlatform, the community and its ecosystem. Do you have useful information that you would like to share with the DNN Community in a featured article or blog? If so, please contact .

The use of the Community Blog is covered by our Community Blog Guidelines - please read before commenting or posting.

DNN LocalizationEditor Released on CodePlex

Since its incubation as ‘Bring2mind LocalizationEditor’ this module had raised interest in the non-English speaking part of the DNN community. Unfortunately, due to time constraints I did not find the time to properly advertize this module, nor devote serious hours to perfecting it. But it has been serving my own business already for a while and regularly I’d be asked what this module was. It wasn’t until this summer when Ernst-Peter Tamminga from Xcess came along and offered to have his apprentice DNN programmers sharpen their skills on this, that things started moving. The summer is a great moment to pick up dying open source projects and try to revive them. Erik van Ballegoij was kind enough to also chip in with some hours and together we now completed a first release of this module under the more neutral ‘DNN Europe’ banner:


The idea for this module was born at a French DNN Usergroup meeting in Paris back in 2005 or before (I can’t remember exactly when, but it was in the early days of DNN). I was chatting with a number of people that were responsible for the French translation of DNN and they had some very valid grievances. They could not delegate translation properly among themselves as a team. In fact, if you wanted to translate, you need host access on the DNN installation, so they ended up having a DNN installation somewhere that they used. But they felt it was not optimal to work like this. Plus, some were doing just the core, while others were doing individual modules (did you know the amount of translations to be done for the forums module rivals that for the core as a whole?). It was clear that the core language editor was fine for occasional translation use, but not really designed for this type of application. Another grievance was that translators did not have access to prereleases of the platform. The latter is not addressed in this project, but in another project that I’m working on for DNN.

And things start getting more complex …

Later, DNN Corp took the decision to separate the core from the (core) modules. This has been a gradual but persistent process. So whereas before having a framework version X.Y.Z meant you were running Announcements A.B.C, that is now history. As a result the language packs for modules and the core have to be managed separately. This means a lot of management overhead for those doing translations. There is a related problem regarding the uploading of packs into your DNN installation, but that issue will be addressed somewhere else. This project is first and foremost targeted at the production side of language packs.

Generic languages

Another observation of mine at the time concerned generic languages and the lack of support for them in ASP.NET/DNN. I live in Switzerland which has four official languages. The biggest 3 are German, French and Italian. The locale that uses is a combination of language and country: xx-YY. So in our case de-CH, fr-CH, and it-CH. This is to distinguish them from the original cultures de-DE, fr-FR and it-IT. The underlying reason is that every culture has its specifics. There is quite a bit of difference between the French of France (fr-FR) and that of Québec (fr-CA). In practice, however, having a language pack of your own language, even though it’s produced somewhere else, is already a big help in the DNN world. This is because there are not that many translators. So there is no dedicated de-CH translation, for instance. The Swiss would just use a de-DE pack. In fact, the producer of the German packs, Sebastian Leupold, would tag his files appropriately so they’d be downloadable as de-CH and de-AT (Austria) as well. Ideally, a translation help would be able to do this tagging automatically.


  • Allow delegation of translation to individual users based on user X can translate module Y/core into locale Z.
  • Packs are created on the fly based on the latest translations.
  • Proper version management of texts and translations. We must be able to edit an old pack and download old packs.
  • Support for generic languages. A user can do the translation for ‘fr’ and those translations will download into the fr-FR pack.
  • Allow the translation of non-installed items. The manager will upload a new version of module X/core into the module and the module will extract the resources.


It quickly became clear that editing resx files online was not a forward bound solution. What was needed was to break out the data from the resource files and start managing them in a database. You have texts in the original files that have a resource key, an original (i.e. en-US) text, a filename of the resx file, and a version of the module/core. For each text there are x translations for the various locales in the translations table. Finally there are 2 more support tables, one for the objects (modules/core/etc) and one for permissions (who can edit which locale for which object).

Delegation of translation permissions

The manager assigns users to objects and locales. From that moment on those users are able to translate that ‘node’ (i.e. intersection of object and locale).

Version control

When a new version is uploaded of a module/core, the existing texts are checked against the new input. If:

  1. the text key is not longer there in the new version, the record in the Texts table is marked as deprecated in the new version,
  2. the original text has changed for the text key in the new version, the old record is marked as deprecated as above and a new record is created as starting with this new version,
  3. the text key was not already there in the first place, then it’s created starting at this version.

This allows us to accurately recreate any pack for any version.

Support for generic languages

A user can be assigned for a specific locale (e.g. fr-FR) or a generic language (fr). Upon creation of a pack, the generic translations are first gathered and overridden by any present specific translations. So the way you could use this is to have some people editing ‘fr’ and to delegate Canadian translations to someone else by specifying them to edit fr-CA. When the fr-CA pack is made all translations of this last team are taken and supplemented with any missing translations by those of the original team. So the fr-CA team would only make translations for those texts where they felt the fr was not sufficient for their specific locale.

Other features

  • Google translate hook in. Very useful.
  • Output caching. The module is able to detect any changes to the translations for a specific language pack, so the output can be cached as zip file on disk.
  • Support for DNN 4 and 5 pack manifests. This includes the additional DNN 5 elements relating to owner. For modules hybrid packs are created that will upload on both DNN 4 and 5 with full features.
  • Ability to upload existing packs.



  • DNN 05.01.01 or above
  • SQL 2005


Install as regular module and instantiate on a page of your site. Note two new permissions are created: Manage Permissions and Manage Objects.


The module settings also reveal the DNN 5 pack settings:


Management of Objects

Before we go anywhere we need objects to manage


Either add objects that are already installed, or add them by uploading. Note you should only add higher versions for those that you already installed.

Management of Permissions

Now we are going to manage who can do what





You can add either 2 letter codes for locale or 2-2 codes. Note the username textbox is autosensing and will suggest usernames that match.


The user that has particular edit permission will see the relevant links on the module:


Here the user can edit nl-BE. Clicking on this will bring up the following screen:


The block at the top shows the state of this pack. The version dropdown shows all versions of that module that are in the system. The selection dropdown is used to make a selection on which texts the user would like to edit. The source locale is useful for those doing a specific translation (like nl-BE). They can bring up not only the original texts, but also the texts from the generic language for instance.

Now we click ‘Edit Pack’ to bring up the edit screen.


The translations are grouped under their resource file heading. These can be opened as collapsed. Clicking Translate All or the magic wand icon will start translating via Google translate. Transfer will put the original text into the translated text box for further editing. This can be useful when translating HTML and you want to import the HTML structure first.

Click OK to save the translations.


Finally the user can download the language pack of their choice. They are directed to either the module or a fixed aspx that is also part of the module: DesktopModules\DNNEurope\LocalizationEditor\RequestPack.aspx. The querystring parameters will load up the form correctly.


Either they opt to download directly the specific pack, or they type in their locale and download this through ‘Get Pack’. This then redirects to the pack page: DesktopModules\DNNEurope\LocalizationEditor\Pack.aspx. Again the querystring parameters inform the module what to do. As you can see this means you could integrate the module into a more sophisticated download matrix and directly call this page to provoke downloads.


I want to thank Ernst-Peter Tamminga and Jan van der Gaag from Xcess as well as Erik van Ballegoij from Apollo Software. Without them the module would not have been where it is today. We hope you find the module a useful aid in translation work. For now we are not gathering feedback yet. We will be once we have a forum set up for this module. In the meantime, please hold on to your improvement thoughts and let us know then.


Comment Form

Only registered users may post comments.


Aderson Oliveira (22)
Alec Whittington (11)
Alessandra Davies (3)
Alex Shirley (10)
Andrew Hoefling (3)
Andrew Nurse (30)
Andy Tryba (1)
Anthony Glenwright (5)
Antonio Chagoury (28)
Ash Prasad (37)
Ben Schmidt (1)
Benjamin Hermann (25)
Benoit Sarton (9)
Beth Firebaugh (12)
Bill Walker (36)
Bob Kruger (5)
Bogdan Litescu (1)
Brian Dukes (2)
Brice Snow (1)
Bruce Chapman (20)
Bryan Andrews (1)
cathal connolly (55)
Charles Nurse (163)
Chris Hammond (213)
Chris Paterra (55)
Clint Patterson (108)
Cuong Dang (21)
Daniel Bartholomew (2)
Daniel Mettler (181)
Daniel Valadas (48)
Dave Buckner (2)
David Poindexter (12)
David Rodriguez (3)
Dennis Shiao (1)
Doug Howell (11)
Erik van Ballegoij (30)
Ernst Peter Tamminga (80)
Francisco Perez Andres (17)
Geoff Barlow (12)
George Alatrash (12)
Gifford Watkins (3)
Gilles Le Pigocher (3)
Ian Robinson (7)
Israel Martinez (17)
Jan Blomquist (2)
Jan Jonas (3)
Jaspreet Bhatia (1)
Jenni Merrifield (6)
Joe Brinkman (274)
John Mitchell (1)
Jon Henning (14)
Jonathan Sheely (4)
Jordan Coopersmith (1)
Joseph Craig (2)
Kan Ma (1)
Keivan Beigi (3)
Kelly Ford (4)
Ken Grierson (10)
Kevin Schreiner (6)
Leigh Pointer (31)
Lorraine Young (60)
Malik Khan (1)
Matt Rutledge (2)
Matthias Schlomann (16)
Mauricio Márquez (5)
Michael Doxsey (7)
Michael Tobisch (3)
Michael Washington (202)
Miguel Gatmaytan (3)
Mike Horton (19)
Mitchel Sellers (40)
Nathan Rover (3)
Navin V Nagiah (14)
Néstor Sánchez (31)
Nik Kalyani (14)
Oliver Hine (1)
Patricio F. Salinas (1)
Patrick Ryan (1)
Peter Donker (54)
Philip Beadle (135)
Philipp Becker (4)
Richard Dumas (22)
Robert J Collins (5)
Roger Selwyn (8)
Ruben Lopez (1)
Ryan Martinez (1)
Sacha Trauwaen (1)
Salar Golestanian (4)
Sanjay Mehrotra (9)
Scott McCulloch (1)
Scott Schlesier (11)
Scott Wilkinson (3)
Scott Willhite (97)
Sebastian Leupold (80)
Shaun Walker (237)
Shawn Mehaffie (17)
Stefan Cullmann (12)
Stefan Kamphuis (12)
Steve Fabian (31)
Steven Fisher (1)
Timo Breumelhof (24)
Tony Henrich (3)
Torsten Weggen (3)
Tycho de Waard (4)
Vicenç Masanas (27)
Vincent Nguyen (3)
Vitaly Kozadayev (6)
Will Morgenweck (40)
Will Strohl (180)
William Severance (5)
What is Liquid Content?
Find Out
What is Liquid Content?
Find Out
What is Liquid Content?
Find Out