November Happy Hour will be moved to Thursday December 5th.

Dmytro Duk
May 11, 2011
  6233
(1 votes)

Localization workaround for EPiServer CMO 2.0

Globalization support is improved in CMO next version for EPiServer CMS 6 R2. Current users of CMO 2.0 can use the following workaround to solve localization issues in campaign and LPO test settings (see details here and here). After these changes you should be able to operate dates and numbers in your current culture format. This solution doesn’t require code recompilation. It is applicable to CMO 2.0 release version published on world.episerver.com.

Let’s consider the simple scenario, when Swedish language is set as default on your site,  for example in culture and uiCulture properties of globalization section in your web.config file.

Language files

You probably will see “[Missing text...]” warnings if language file is missing for your current culture, in our case Swedish.
CMO_EN.xml file contains all CMO string resources in English and can be found in lang directory of your site. Make a copy of this file, rename corresponding to your language. In our case it is Swedish, so rename new language file to CMO_SV.xml, open file and update name and id properties of language node:

<?xml version="1.0" encoding="utf-8" standalone="yes" ?> 
  <languages>
    <language name="Svenska" id="sv">
      ...
    </language>
</languages>

Now you should get English texts instead of [Missed text …] warnings. Optionally texts in language file can be translated to get CMO UI in required language.

The one change is required in node /cmo/lpo/settings/datepickerformat. Please define jQuery date format that corresponds to .NET short date format for your culture. Yes, tricky one :)
Example: Swedish short date string is something like 2011-05-25. Corresponding jQuery date format for Swedish culture is yy-mm-dd:

<datepickerformat>yy-mm-dd</datepickerformat>

Norwegian short date string 25.05.2011 corresponds to jQuery pattern dd.mm.yy and so on. Refer to jQuery documentation: http://docs.jquery.com/UI/Datepicker/formatDate

It is important to have language files both for current culture and current UI culture on your site, if they are different.

CMO UI controls

Go to directory where CMO UI is installed. Typically it is somewhere like this: C:\Program Files (x86)\EPiServer\CMS\6.0.530.0\Install\Modules\CMO2.0.0.0\CMO\

Need to update settings controls for LPO tests and campaigns to make sure that date picker is initialized with required date format.

LPO Test settings

Update arguments in Cmo.SetupDatePicker method calls inside $(document).ready function in LpoTestSettings.aspx file:

// On document load finished
$(document).ready(function () {
// … omitted code … 
 
    Cmo.SetupDatePicker($(Cmo.dateFrom), '<%= TranslateForScript("/cmo/lpo/settings/datecountryformat") %>', '<%= LanguageManager.Instance.TranslateForScript("/cmo/lpo/settings/datepickerformat", System.Threading.Thread.CurrentThread.CurrentCulture.IetfLanguageTag.Substring(0, 2)) %>', '-1d');
    Cmo.SetupDatePicker($(Cmo.dateTo), '<%= TranslateForScript("/cmo/lpo/settings/datecountryformat") %>', '<%= LanguageManager.Instance.TranslateForScript("/cmo/lpo/settings/datepickerformat", System.Threading.Thread.CurrentThread.CurrentCulture.IetfLanguageTag.Substring(0, 2)) %>', '-1d');
 
});

Campaign settings

Open file Units\CampaignGeneralSettings.ascx, update arguments in Cmo.SetupDatePicker method calls inside $(document).ready function:

// On document load finished
$(document).ready(function() {
    Cmo.SetupDatePicker($(Cmo.dateFrom), '<%= TranslateForScript("/cmo/lpo/settings/datecountryformat") %>', '<%= LanguageManager.Instance.TranslateForScript("/cmo/lpo/settings/datepickerformat", System.Threading.Thread.CurrentThread.CurrentCulture.IetfLanguageTag.Substring(0, 2)) %>', '0d');
    Cmo.SetupDatePicker($(Cmo.dateTo), '<%= TranslateForScript("/cmo/lpo/settings/datecountryformadt") %>', '<%= LanguageManager.Instance.TranslateForScript("/cmo/lpo/settings/datepickerformat", System.Threading.Thread.CurrentThread.CurrentCulture.IetfLanguageTag.Substring(0, 2)) %>', '0d');
}); 

KPI settings

Update \Units\Kpi\KpiSettingsEditor.ascx to make sure that decimal KPI values are processed correctly in the current culture format. Add CultureInvariantValues="true" option for KPI values validators:

<asp:CompareValidator runat="server" ValidationGroup="<%# ValidationGroupName %>" ID="CompareValidatorValue" Display="Dynamic" 
    ErrorMessage="<%$ Resources: EPiServer, cmo.campaignMonitor.settings.kpi.valueerrorcompare %>" Text="*" 
    Type="Double" ControlToValidate="TextBoxValue" ValueToCompare="0.01" Operator="GreaterThanEqual" CssClass="kpiEditorValidator"
    CultureInvariantValues="true" />
 
<asp:CompareValidator runat="server" ValidationGroup="<%# ValidationGroupName %>" ID="CompareValidatorExpectedValue" Display="Dynamic" 
    ErrorMessage="<%$ Resources: EPiServer, cmo.campaignMonitor.settings.kpi.expectedvalueerrorcompare %>" Text="*" 
    Type="Double" ControlToValidate="TextBoxExpectedValue" ControlToCompare="TextBoxValue" Operator="GreaterThanEqual" CssClass="kpiEditorValidator" 
    CultureInvariantValues="true" />

JavaScript code in this control must be updated to fix decimal separators in KPI data for current culture. Add following code just in the beginning of initializeKpiEditor function:

$(function () {
        
    var initializeKpiEditor = function ()
    {
        var kpiData = eval($("#<%= KpiData.ClientID %>").val());
        var defaultDecimalSeparator = ".";
        var currentDecimalSeparator = "<%= System.Globalization.NumberFormatInfo.CurrentInfo.NumberDecimalSeparator %>";
        $.each(kpiData, function(index, kpi) { 
            kpi.value = kpi.value.toString().replace(defaultDecimalSeparator, currentDecimalSeparator);
            kpi.expectedValue = kpi.expectedValue.toString().replace(defaultDecimalSeparator, currentDecimalSeparator);
        });
 
        // … omitted code … 
    };
    // … omitted code …
}); 

Then find the following line below in initializeKpiEditor function:

kpiList: eval($("#<%= KpiData.ClientID %>").val()),

and change it to:

kpiList: kpiData,

Scripts

Go to Scripts directory inside CMO UI folder. It should be somewhere like: C:\Program Files (x86)\EPiServer\CMS\6.0.530.0\Install\Modules\CMO2.0.0.0\CMO\Scripts\
Open cmo.min.js file. This is compressed script, so be careful when updating it. Find string:

c.datepicker("option","duration",0);

and after this string insert following code:

if(b) c.datepicker('option',"dateFormat",b);

As a result updated Cmo.SetupDatePicker function in cmo.min.js must looks like this:

Cmo.SetupDatePicker=function(c,d,b,e){var a=c.val();c.datepicker({showOtherMonths:true,showOn:"button",buttonImageOnly:false});c.datepicker("option",$.extend({showMonthAfterYear:false},$.datepicker.regional[d]));c.datepicker("option","minDate",e);c.datepicker("option","duration",0);if(b) c.datepicker('option',"dateFormat",b);c.focus(function(){if(c.val()==""){c.datepicker("show")}});c.change(function(){EPi.PageLeaveCheck.SetPageChanged(true)});c.val(a);if(c.val()!=""){c.val(Cmo.getDateInSpecifiedFormat(c.val(),b))}if(c.attr("disabled")){c.datepicker("disable")}};

Open CmoScripts.js in the same folder Scripts and define date format option for datepicker inside Cmo.SetupDatePicker function, just after the line element.datepicker('option', 'duration', 0);

Cmo.SetupDatePicker = function (element, locale, format, mindate) {
// … omitted code …
    element.datepicker('option', 'duration', 0);
 
    if (format) {
        element.datepicker('option', "dateFormat", format);
    }
 
// … omitted code …
}

Clear cache

Since changes where made in JavaScript and control markup, previous versions of scripts and compiled controls can be cached by browser, proxy, IIS or in Temporary ASP.NET Files folder. Decide how to clear that caches depending on your environment.

Download

Replace your existing files or use it to compare and make changes manually, it’s up to you. Don’t forget to backup your files before update ;)

Feedback

Please let me know if this workaround doesn’t work for you, I will try to find the solution.

May 11, 2011

Comments

May 12, 2011 06:02 AM

Great work Dmytro!
Have tested the fix, worked like a charm!

May 12, 2011 02:50 PM

well its nice to have this workaround.thanks

May 15, 2011 08:47 PM

When can we expect an official patch or a new CMO version which fixes this?

Eivind Hodneland
Eivind Hodneland May 16, 2011 10:39 AM

Thanks. This worked well. However, I also had to apply an updated EpiServer.Cmo.Ui.Dll (v. 2.0.0.10) to not have the dates in LPO test and campaign listings display garbage.

May 16, 2011 02:54 PM

I've tried to limit changes and make sure that user is able to enter values in required culture format.
We are working on CMO next version and hopefully it will be available soon.

Please login to comment.
Latest blogs
Optimizely SaaS CMS + Coveo Search Page

Short on time but need a listing feature with filters, pagination, and sorting? Create a fully functional Coveo-powered search page driven by data...

Damian Smutek | Nov 21, 2024 | Syndicated blog

Optimizely SaaS CMS DAM Picker (Interim)

Simplify your Optimizely SaaS CMS workflow with the Interim DAM Picker Chrome extension. Seamlessly integrate your DAM system, streamlining asset...

Andy Blyth | Nov 21, 2024 | Syndicated blog

Optimizely CMS Roadmap

Explore Optimizely CMS's latest roadmap, packed with developer-focused updates. From SaaS speed to Visual Builder enhancements, developer tooling...

Andy Blyth | Nov 21, 2024 | Syndicated blog

Set Default Culture in Optimizely CMS 12

Take control over culture-specific operations like date and time formatting.

Tomas Hensrud Gulla | Nov 15, 2024 | Syndicated blog