Navigatie

Contact

Send mail to the author(s) E-mail

View Richard Soeteman's profile on LinkedIn

RSS 2.0 | Atom 1.0 | CDF

Archief

Categorieën

Blogroll

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

Sign In

Zoeken

# Monday, 17 October 2011
Monday, 17 October 2011 12:00:49 (GMT Daylight Time, UTC+01:00) ( Umbraco )

This Blog is not active anymore, further posts will be available on my company website. Read new posts here

 

Last week I was triggered by a tweet from Sebastiaan Janssen mentioning the Dictionary Section Package was broken in 4.7.1

dictionarytweet

Moving the Dictionary to a separate section  is a technique that I use myself a lot when building solutions for clients, I don’t want to give content editor access to the settings section and I really don’t want to edit Dictionary items myself .I just finished a custom section where I used this, so I immediately logged in as an Editor and indeed I got a nice Exception. This hasn’t happened before so I assume this security check is introduced in 4.7.x.

userException 

It seemed that the page was throwing this error and indeed the constructor of EditDictionary sets the CurrentApp which will be used  in a later stage to validate User permissions.

 public EditDictionaryItem()
 {
     CurrentApp = BusinessLogic.DefaultApps.settings.ToString();
 }

So to fix this error we only need to set the CurrentApp property to either language or empty string (no validation at all). The easiest way is to modify the source and recompile, but I never modify the original Umbraco source to work around the Umbraco core. This is because you need to update the source code for every version update of Umbraco. So I needed a way to update the CurrentApp property using my own code. Lucky for us asp.net is an object oriented language and  so we can add our own page and only override the constructor to modify the CurrentApp property. This can be done by creating a custom aspx page where the codebehind class derives from the EditDictionaryItem class.

    /// <summary>
    /// Derive from EditDictionaryItem to use the existing Dictionary functionality
    /// </summary>
    public partial class LanguageDictionary : EditDictionaryItem
    {
        /// <summary>
        /// Use the constructor to set the current app
        /// </summary>
        public LanguageDictionary()
        {
            CurrentApp = "language";
        }
    }

Unfortunately we still some page directives and markup in our aspx page. Lucky for us the original aspx file only contains some basic markup (a placeholder), controls are rendered from codebehind so it’s not a crime to copy and paste that markup and update the Page Directives to use our new codebehind and inherit from LanguageDictionary class. Below you see all markup.

<%@ Register Namespace="umbraco" TagPrefix="umb" Assembly="umbraco" %>
<%@ Register TagPrefix="cc1" Namespace="umbraco.uicontrols" Assembly="controls" %>
<%@ Page Language="c#" MasterPageFile="~/umbraco/masterpages/umbracoPage.Master" ValidateRequest="false"
    CodeBehind="LanguageDictionary.aspx.cs" AutoEventWireup="True" Inherits="DictionaryFix.LanguageDictionary" %>

<asp:Content ContentPlaceHolderID="body" runat="server">
    <cc1:UmbracoPanel ID="Panel1" runat="server" Width="408px" Height="264px">
    </cc1:UmbracoPanel>
    <script type="text/javascript">
        jQuery(document).ready(function () {
            UmbClientMgr.appActions().bindSaveShortCut();
        });
    </script>
</asp:Content>

So now we have a complete work around. Only thing is that this page will never be called from the tree. So we need to have a custom tree.The class responsible for rendering of Dictionary items tree  is the loadDictionary class. This class contains the Method RenderJS that renders the Javascript function to open the page. So we only need to override that method and point it to our new LanguageDictionary.aspx file, I store the aspx file in the already existing DigibizDictionarySection folder .

   public class LanguageDictionaryTree : loadDictionary
    {
        public LanguageDictionaryTree(string application) : base(application) { }

        public override void RenderJS(ref StringBuilder Javascript)
        {
            Javascript.Append(
                @"
                function openDictionaryItem(id) {
                UmbClientMgr.contentFrame('plugins/digibizdictionarysection/languagedictionary.aspx?id=' + id);
                }");
        }
    }

The last thing we need to update is the database table to use our new LanguageDictionaryTree  instead of the loadDictionary class. The database table to update is UmbracoAppTree , search for the row containing language as appAlias and update the treeHandlerAssembly and treeHandlerType values.

dbupdate

Copy the aspx page to the /umbraco/plugins/DigibizDictionarySection  folder and store the dll in the bin folder of your install. Then login as the editor again and see that you can access Dictionary items outside of the settings section again.

dictionaryfixed

Below you can find the links to the original package and the fix I’ve created. Jeroen Breuer mentioned he will implement this fix later in his package.