Nibble

.net usercontrols and the umbraco dictionary

With umbraco it is possible to create multilingual site. I’m not going to get into details on how to set this up (not in this post), but when you want to localize your templates and macro’s you need to create dictionary items. Your .net usercontrols can also use the umbraco dictionary.

You manually create a new dictionary item and then set the control’s text to the dictionary item (after referencing the needed assemblies).

MyControl.Text = umbraco.library.GetDictionaryItem(“mydictionaryitem”);
MySecondControl.Text = umbraco.library.GetDictionaryItem(“anotherdictionaryitem”);

 

This is owkey when you have a small usercontrol and don’t have to put in loads of dictionary items.

But image what a lousy task it would  be if you had 30,40, more controls on your usercontrol (creating all the dictionary items manually).

So to save me time I wrote some code that loops all controls in a usercontrol and sets the text of the control.

I created a base usercontrol class which inherits from the usercontrol class. And I make my usercontrols inherit from my base class.

This Is my BaseUserControl class:

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using umbraco.cms.businesslogic;
 
namespace TG.Umb.Library
{
    public class BaseUserControl: UserControl
    {
        private string _dictionaryId;
 
        protected void Page_Load(object sender, EventArgs e)
        {

            if (Request[“addtodictionary”] != null)
            {
                //create dictionary items

                createDictionaryItems(this.Controls);
                Response.Write(“Dictionary Items Created”);
            }
 
            if (!IsPostBack)
            {
                //set copy of controls
                setCopy(this.Controls);
            }
        }
 
        #region UmbracoDictionaryFunctions
 
        //loop all controls and set text
        public void setCopy(ControlCollection Controls)
        {
 
            foreach (Control ctrl in Controls)
            {
 
 
                if (ctrl is System.Web.UI.WebControls.Panel)
                {
                    setCopy(ctrl.Controls);
                }
 
                if (ctrl is System.Web.UI.WebControls.Literal)
                {
                    if (umbraco.library.GetDictionaryItem(dictionaryId + ((Literal)ctrl).ID) != string.Empty)
                    {

                        ((Literal)ctrl).Text = umbraco.library.GetDictionaryItem(dictionaryId + ((Literal)ctrl).ID);
                    }
                }
 
                if (ctrl is System.Web.UI.WebControls.HyperLink)
                {
                    if (umbraco.library.GetDictionaryItem(dictionaryId + ((HyperLink)ctrl).ID) != string.Empty)
                    {
                        ((HyperLink)ctrl).Text = umbraco.library.GetDictionaryItem(dictionaryId + ((HyperLink)ctrl).ID);
                    }
                }
 
                if (ctrl is System.Web.UI.WebControls.Button)
                {
                    if (umbraco.library.GetDictionaryItem(dictionaryId + ((Button)ctrl).ID) != string.Empty)
                    {
                        ((Button)ctrl).Text = umbraco.library.GetDictionaryItem(dictionaryId + ((Button)ctrl).ID);
                    }

                }
 
                if (ctrl is System.Web.UI.WebControls.CheckBox)
                {
                    if (umbraco.library.GetDictionaryItem(dictionaryId + ((CheckBox)ctrl).ID) != string.Empty)
                    {
                        ((CheckBox)ctrl).Text = umbraco.library.GetDictionaryItem(dictionaryId + ((CheckBox)ctrl).ID);
                    }
                }
            }
        }
 
        //loop all controls and create dictionary Item
        public void createDictionaryItems(ControlCollection Controls)
        {
            foreach (Control ctrl in Controls)
            {

                if (ctrl is System.Web.UI.WebControls.Panel)
                {
                    createDictionaryItems(ctrl.Controls);
                }
 

                if (ctrl is System.Web.UI.WebControls.Literal)
                {
                    createDictionaryItem(dictionaryId + ((Literal)ctrl).ID, ((Literal)ctrl).Text);
                }
 
                if (ctrl is System.Web.UI.WebControls.HyperLink)
                {
                    createDictionaryItem(dictionaryId + ((HyperLink)ctrl).ID, ((HyperLink)ctrl).Text);
                }
 
                if (ctrl is System.Web.UI.WebControls.Button)
                {
                    createDictionaryItem(dictionaryId + ((Button)ctrl).ID, ((Button)ctrl).Text);
                }
 
                if (ctrl is System.Web.UI.WebControls.CheckBox)
                {
                    createDictionaryItem(dictionaryId + ((CheckBox)ctrl).ID, ((CheckBox)ctrl).Text);
                }
            }
        }
 

        //create dictionaryItem
        private void createDictionaryItem(string name, string defaulttext)
        {
            try
            {
 
                Dictionary.DictionaryItem.addKey(name, defaulttext);

                Response.Write(“added “ + name + “<br/>”);
            }
            catch
            {
                //allready exists
            }
        }
 

        //identifier for umbraco dictionary
        //string dictionaryId = “frmLoginLogout”;
        public string dictionaryId
        {
            get
            {
 
                return _dictionaryId;


            }
            set
            {
                _dictionaryId = value;
            }
        }
 
        #endregion
    }
}
 

 

So all I need to do in my usercontrols is:

public partial class frmEditProfile : BaseUserControl
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            base.dictionaryId = this.GetType().Name;
            base.Page_Load(sender, e);
 
        }
    }

 

Inherit from the custom class instead of UserControl, set the dictionaryId and cal the page_load of the base class.

Now the next step is to trigger the usercontrol to loop its controls and add dictionary items.

You can do this by adding ?addtodictionary=true to the querystring on the page where you have your usercontrol.

So if you have a page http://www.examplesite.com/page.aspx you request http://www.examplesite.com/page.aspx?addtodictionary=true

And *boom* the dictionary items get created automaticly. This is an example of the dictionary items created:

dictionary

So the name will start with the usercontrol name followed by the control id;

Now you can start setting the correct copy for the dictionary items…

And as you will notice the text will be fetched from the dictionary.

The loops in the class will only work on  literal, hyperling, button and checkbox, you can add other types of controls in the loops.

BaseUserControl class: download

10 Comments so far

  1. Paul on April 16th, 2008

    Exactly what I was looking for this morning…thanks!

    -Paul

  2. Tim Geyssens on April 16th, 2008

    Glad it was helpful to you Paul

  3. ismail on April 17th, 2008

    Not done mutlilingual sites yet although i knew i could use the dictionary and pass through labels etc through template and dictionary but this is brilliant solution to mass create the labels before populating.

    Pure genious!!

  4. Tim Geyssens on April 17th, 2008

    Hi Ismail, thanks for the comment

    Well i live in Belgium so multilingual sites are quite common here (dutch, french). So because I use the dictionary so often I was looking for a fast way of creating the items.

  5. Lee Kelleher on April 20th, 2008

    Excellent way of populating the dictionary!

    Recently I was thinking of other ways of managing the text/labels for Controls in Umbraco. My thought was to use a local resource file (.resx) and build an Umbraco template to output the XML to replace it (at runtime).

    The way you outlined is a much better solution!

    Thanks,
    - Lee

  6. Thomas Stock on October 28th, 2010

    you can do
    DictionaryId = this.GetType().Name;
    in the base class and it will also use the derived type. no need to do this in every usercontrol.

    you can also avoid having to call base.Page_load() in every derived usercontrol by adding this to the default constructor of the base class:
    this.Load = Page_Load;

    when you did these 2 things, you don’t have to worry anymore at all about forgetting to do things in your usercontrols (except inherting from BaseUserControl ofcourse)

    I also moved the code from BaseUserControl’s Page_Load to Page_Init because that seemed more appropriate.

    Oh and I added Label as one of the controls that will be translated.

    Here’s my adjusted version:

    using System;
    using System.Data;
    using System.Configuration;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using umbraco.cms.businesslogic;

    namespace OrbitOne.Umbraco
    {
    public class BaseUserControl : UserControl
    {
    public BaseUserControl()
    {
    this.Init = Page_Init;
    }

    protected void Page_Init(object sender, EventArgs e)
    {
    DictionaryId = this.GetType().Name;

    if (Request[”addtodictionary”] != null)
    {
    //create dictionary items

    createDictionaryItems(this.Controls);
    Response.Write(”Dictionary Items Created”);
    }

    if (!IsPostBack)
    {
    setCopy(this.Controls);
    }
    }

    #region UmbracoDictionaryFunctions

    //loop all controls and set text
    public void setCopy(ControlCollection controls)
    {

    foreach (Control ctrl in controls)
    {

    if (ctrl is Panel)
    {
    setCopy(ctrl.Controls);
    }

    if (ctrl is Literal)
    {
    if (umbraco.library.GetDictionaryItem(DictionaryId ctrl.ID) != string.Empty)
    {
    ((Literal)ctrl).Text = umbraco.library.GetDictionaryItem(DictionaryId ctrl.ID);
    }
    }

    if (ctrl is HyperLink)
    {
    if (umbraco.library.GetDictionaryItem(DictionaryId ctrl.ID) != string.Empty)
    {
    ((HyperLink)ctrl).Text = umbraco.library.GetDictionaryItem(DictionaryId ctrl.ID);
    }
    }

    if (ctrl is Button)
    {
    if (umbraco.library.GetDictionaryItem(DictionaryId ctrl.ID) != string.Empty)
    {
    ((Button)ctrl).Text = umbraco.library.GetDictionaryItem(DictionaryId ctrl.ID);
    }

    }

    if (ctrl is CheckBox)
    {
    if (umbraco.library.GetDictionaryItem(DictionaryId ctrl.ID) != string.Empty)
    {
    ((CheckBox)ctrl).Text = umbraco.library.GetDictionaryItem(DictionaryId ctrl.ID);
    }
    }

    if (ctrl is Label)
    {
    if (umbraco.library.GetDictionaryItem(DictionaryId ctrl.ID) != string.Empty)
    {
    ((Label)ctrl).Text = umbraco.library.GetDictionaryItem(DictionaryId ctrl.ID);
    }
    }
    }
    }

    //loop all controls and create dictionary Item
    public void createDictionaryItems(ControlCollection Controls)
    {
    foreach (Control ctrl in Controls)
    {

    if (ctrl is Panel)
    {
    createDictionaryItems(ctrl.Controls);
    }

    if (ctrl is Literal)
    {
    createDictionaryItem(DictionaryId ctrl.ID, ((Literal)ctrl).Text);
    }

    if (ctrl is HyperLink)
    {
    createDictionaryItem(DictionaryId ctrl.ID, ((HyperLink)ctrl).Text);
    }

    if (ctrl is Button)
    {
    createDictionaryItem(DictionaryId ctrl.ID, ((Button)ctrl).Text);
    }

    if (ctrl is CheckBox)
    {
    createDictionaryItem(DictionaryId ctrl.ID, ((CheckBox)ctrl).Text);
    }

    if (ctrl is Label)
    {
    createDictionaryItem(DictionaryId ctrl.ID, ((Label)ctrl).Text);
    }

    }
    }

    //create dictionaryItem
    private void createDictionaryItem(string name, string defaulttext)
    {
    try
    {

    Dictionary.DictionaryItem.addKey(name, defaulttext);

    Response.Write(”added ” name “”);
    }
    catch
    {
    //allready exists
    }
    }

    //identifier for umbraco dictionary
    //string dictionaryId = “frmLoginLogout”;
    public string DictionaryId { get; set; }

    #endregion
    }
    }

  7. K.Garrein on February 29th, 2012

    You rule :)

  8. Dean Matthews on June 14th, 2012

    Brilliant info. Sure this will help with SEO also.

  9. Mounhim Tahtahi on September 3rd, 2013

    Is there not another way to determine if the key already exists. I hate having exceptions to find out that something already exists. I believe having exceptions thrown is also a performance killer.

  10. Tim Geyssens on September 11th, 2013

    @Mounhim it’s pretty old code so yeah definitely do it without the exception catching :)

Leave a Reply