August 31, 2017

Quick Tip: Localized Strings in Episerver Attributes

I have a few blog posts I want to get done, but for now I'm starting with a quick tip I wanted to put out there for any newbie developers working in Episerver or working with translations in the authoring environment. I'm rather new to it at the moment, so every little bit helps.

This post is a quick solution to providing translated (or translatable) text that's being set within one of Episerver's class or property attributes - where only constants are expected.
Now, I'll admit my ignorance and maybe what I did was unnecessary. I honestly don't know for certain. I just know it worked. If you have corrections or improvements, please comment! :)

I knew that I wanted the component I was writing to be as usable as possible and to follow as many best practices as I could manage. So not having translatable text really wasn't an option. So at first, I tried to use the LocalizationService inside the attribute. If you do this, then you'll see an error like this:


Might show up a bit small, but it says that I can only use a constant, typeof, or array to assign a value to an attribute parameter. Bollocks.

What's a developer to do? Why, inherit and put in my own implementation of course!

So here's the quick (and dirty?) solution I came up with. Create my own attribute, inherit the one I want, and override the properties where I want to insert my own logic.

using EPiServer.Framework.Localization;
using EPiServer.Shell.ViewComposition;
using System;

namespace eGandalf.Epi.PagePreview
{
    [AttributeUsage(AttributeTargets.Class)]
    public class LocalizedComponentAttribute : ComponentAttribute
    {
        public override string Title
        {
            get
            {
                return LocalizationService.Current.GetString(base.Title);
            }
            set
            {
                base.Title = value;
            }
        }

        public override string Description
        {
            get
            {
                return LocalizationService.Current.GetString(base.Description);
            }
            set
            {
                base.Description = value;
            }
        }
    }
}

The value gets stored the same as the base, but the return for each property passes the stored parameter through Episerver's LocalizationService to get the value it should use.

Here's the implemented component attribute:

using EPiServer.Shell;

namespace eGandalf.Epi.PagePreview
{
    [LocalizedComponent(
        PlugInAreas = PlugInArea.Assets, 
        Categories = "cms", 
        WidgetType = "egandalf/PagePreview", 
        Title = "/egandalf/pagepreview/componentTitle", 
        SortOrder = 1000,
        Description = "/egandalf/pagepreview/componentDescription"
        )]
    public class ComponentDefinition
    {
    }
}

Again, not 100% sure I did everything correctly here (probably 85% sure I didn't) and I'm happy to know what I could have done better (and update both the code and this post). But this served as a quick solution that met my immediate need.

Happy coding!

UPDATE: Someone mentioned that Episerver's attributes may be set up to use these translation paths already. I gave this a quick shot and apparently not. Here was the result.

3 comments:

Valdis Iljuconoks said...

oh really!? xpath for resources? are you kidding? do you really want to trigger me to think how this can be achieved in strongly typed way?? :)

eGandalf said...

Yes. As a matter of fact, that's exactly what I want.

Unknown said...

Hi eGandalf, this is what i m looking for can you post the code from xml file as well and the folder structure where your xml file resides. That would be helpful to clearly understand the path you've used in this post.
Thanks in advance