Extracting the base character from a character marked with a diacritic

Ever wondered how you can translate European national characters with diacritics such as å, ä, ö, ó etc into their base characters (a and o)? This can be useful for example when constructing filenames from user-given strings.

This is one way to do it:

string s = "ö";
string normalizedString = s.Normalize(NormalizationForm.FormD);

Console.WriteLine("Composite character: " + s[0]);
if (normalizedString.Length > 1)
{
   Console.WriteLine("Base character: " + normalizedString[0]);
   Console.WriteLine("Diacritic character: " + normalizedString[1]);
}

The result will be:

Composite character: ö
Base character: o
Diacritic character: ¨

Obviously, the key is the String.Normalize function. When we pass it NormalizationForm.FormD as the requested Unicode normalization form, it will separate all composite characters into their constituents. If the char is not a composite, then nothing will happen to it.

Note that the resulting string will be longer that the original if characters were separated. If needed it’s easy to iterate over the characters to filter our non-letters using conditions such as

if (CharUnicodeInfo.GetUnicodeCategory(c) == UnicodeCategory.LowercaseLetter ||
    CharUnicodeInfo.GetUnicodeCategory(c) == UnicodeCategory.UppercaseLetter)
{
   ...
}

Happy character-mangling!

Signalling events from a class

For easy reference, here’s how to create an event in a class that listeners can react to:

class DeleteSubOrderEventArgs : EventArgs
{
    public int SubOrderId;
    public DeleteSubOrderEventArgs(int subOrderId)
    {
        SubOrderId = subOrderId;
    }
}

class Foobar
{
    public delegate void DeleteEventDelegate(object sender, DeleteSubOrderEventArgs e);
    public event DeleteEventDelegate DeleteSubOrderClick;
    
    protected void DeleteButton_Click(object sender, ImageClickEventArgs e)
    {
        // Signal to listeners
        if (DeleteSubOrderClick != null)
        {
            DeleteSubOrderClick(this, new DeleteSubOrderEventArgs(SubOrder.SubOrderId));
        }
    }
}

How to embed an Xslt-file in an assembly

Problem
How do I embed an Xslt file into an assembly so that I won’t have to deploy the file together with the assembly, set configuration options to refer to the file, etc?

Solution

  1. Create a resource (.resx) file in the project
  2. In the resource designer, click “Add Resource” and choose “Add Existing File…”. Select the Xslt file.
  3. Give the new resource a describing name, such as “FilterContentXslt”. The contents of the Xslt file will be available in a string property with this name in the Resource manager.
  4. Code that performs the transformation:
    // Parse the content into an XmlDocument
    XmlDocument doc = new XmlDocument();
    doc.LoadXml(xmlValue);
    
    // Retrieve the embedded resource containing the XSLT transform
    XmlDocument xsltDoc = new XmlDocument();
    xsltDoc.LoadXml(Resources.FilterContentXslt);
    
    XslCompiledTransform trans = new XslCompiledTransform();
    trans.Load(xsltDoc);
    
    // Perform the transformation
    StringWriter writer = new StringWriter();
    trans.Transform(doc, writer);
    string newXmlValue = writer.ToString();
    

Simple, and it works.

/Emil

Databinding with a GridView

Here’s how to call a codebehind function for the rows of a GridView. No rocket science, but useful for reference…

ASPX:
< %# GetStatusImage(Container) %>

Code behind:
protected string GetStatusImage(IDataItemContainer row)
{
}

or

ASPX:
< %# GetStatusImage(Container as GridViewRow) %>

Code behind:
protected string GetStatusImage(GridViewRow row{
}

/Emil

Get the Url to the EPiServer start page incl. language branch

This is how to retrieve the address to the startpage including the currently active language branch (e.g. “/sv/” or “/en/”):

PageData pagedata = Global.EPDataFactory.GetPage(Global.EPConfig.StartPage);
string url = pagedata.DetermineAutomaticURL(LanguageContext.Current.CurrentLanguageBranch);

This code looks simple but it actually took me an hour or so to get it right (I haven’t worked with globalization before) so I thought it’d make a good blog post…

/Emil

Databinding with a Repeater

This is simple stuff, but I wanted to store these code snippets somewhere for easy re-use…

This is how to do databinding with a Repeater control in ASP.NET.

In the ASPX file:

<asp :Repeater runat="server" ID="rptPuffar">
   <itemtemplate>
          <h1>< %# GetTitle(Container) %></h1>
          <p>< %# Eval("XYZ") %></p>
   </itemtemplate>
</asp>

In the code-behind file:

protected override void Page_Load(object sender, EventArgs e)
{
   if (!IsPostBack)
   {
      PageDataCollection puffar = GetChildren(this.PuffContainer);
      rptPuffar.DataSource = puffar;
      rptPuffar.DataBind();
   }
}



protected string GetTitle(RepeaterItem item)
{
   PageData page = (PageData)item.DataItem;
   return page.PageName;
}

In Page_Load(), we connect the repeater to a datasource (in this case a collection of pages from EPiServer).

GetTitle() is a function that is called by the ItemTemplate in the repeater for extracting the string to include in the page (in this case the name of the page). Eval() can also be used directly in the ASPX file to display the value of a property.

As I said, easy stuff, but now I don’t have to write the code again the next time I need it…

How to detect if an EPiServer page is presented in DOPE mode

In some cases it may be useful to detect when an EPiServer page is displayed in DOPE (Direct On-Page Editing) mode rather than the “normal” View mode. This is how to do it:

string dopemode = Request.Params["DopeMode"];
if (!String.IsNullOrEmpty(dopemode) && dopemode.ToLower() == "enable")
{
   // DOPE mode detected!
}

This is the only way I have found to do this, but it feels like there should be a DOPE flag somewhere in the EPiServer API. If anyone has found it, please leave a comment 🙂

Resizing the Action Window panel in an EPiServer plugin

Have you ever written en EPiServer plugin for the Action Window? If so, you have probably noticed how irritatingly narrow it is. Luckily, the width can easily be adjusted by your plugin using this code:

<script>
  if (window.parent!=null && window.parent.parent!=null &&
    window.parent.parent.document.all['epCustomDIV']!=null)
  {
    window.parent.parent.document.all['epCustomDIV'].parentElement.style.pixelWidth = 500;
  }
</script>

This is the same code that the built-in EPiServer File Manager uses, so I think we can regard it as well tested. It has worked well for me, hope it helps you as well.

How to refer to an EPiServer page

Often you have to refer to a given page in a site. For example, on each page you may want to have a footer with a link to a page that describes the site’s usage of cookies. Note that this is different than linking to pages in the navigation menus since those links are created by traversing all non-hidden pages automatically. It’s also different from links created by the editors in edit mode, since they use the link tool to select the individual pages they want to link to.

The problem we have is instead how to identity a given page in code that we want to create a link to, and the question is what the best way to do that is. As always, the answer depends on the requirements. There are several alternatives, which I will now describe.

Hard-coding the page Url
The easiest way is of course to just hard-code the page’s address (we’re using EPiServer’s friendly Url function here):

<a href="/AboutCookies/">About cookies</a>

That works well, as long as we don’t move the page from the site’s root. If we move it, we will have to adjust all links to that page:

<a href="/InfoPages/AboutCookies/">About cookies</a>

That is obviously not all that great, especially since the page can be moved by a web site editor without thought of the consequences. You can also get into similar problems if you rename the page.

If you don’t use friendly Url’s you won’t have these problems since the page Url in that case will identify the page by its Id. In this case, this solution may be enough for you.

Referring to pages using page properties
The next alternative, and perhaps the most common, is to use page properties to refer to the page in question. In our example we could create a page property called “CookiePage” of the “Page” property type so that the web site editor could select the page which stores information about the cookie policies of the site.

On the page we then use code similar to this:

<episerver:property runat="server" PropertyName="CookiePage"></episerver:property>

Now we can move or rename the page without breaking the link. As an added bonus, EPiServer will now keep track of the reference to the page so if we try to delete it, EPiServer will warn us that the page is referenced.

Referring to pages using dynamic properties
Nothing is perfect though, and one problem with the above approach is that if the page is to be referenced from more than one page (remember, we want the link on all pages) we would need to put the page property on all pages, which of course would be ridiculous. To get around that we use EPiServer’s “dynamic property” functionality. A dynamic property works just like a page property, except that it’s not associated with a page type, but can be set on any page.

So instead of creating a page property called “CookiePage” we create a dynamic property “CookiePage” and set it’s value on the start page of our site. We can then use the same code as before in the ASPX page:

<episerver:property runat="server" PropertyName="CookiePage"></episerver:property>

Now, this works well but we risk having to create a lot of dynamic properties for different settings (there are probably more pages we need to reference than the “cookie page”). We therefore risk having a lot of dynamic properties which can be bewildering for web site editors. It can also be unclear which page these properties should be set on. Furthermore, the values of dynamic properties can normally only be edited by administrators, not by editors. If that is not wanted, we have to choose another solution.

This leads us to the next alternative…

Referring to pages using a settings page
Instead of using a lot of dynamic properties in our web site, we can create a special settings page (with its own page type). On this page we collect all our site-wide settings, such as a reference to our cookie page (i.e. we create a page property called “CookiePage” on the settings page). We then create a dynamic property called “SettingsPage” and set it’s value on the start page for our site so that it points to our settings page.

Finally, we modify our ASPX page so that it now reads

<episerver:property runat="server" PropertyName="CookiePage" PageLinkProperty="SettingsPage"></episerver:property>

This will still read the value of the property “CookiePage”, but now the value will come from the page referenced by the dynamic property “SettingsPage”. This can be seen as a form of property redirection. It’s a minimal code modification and we have gained

  • a clean separation of site settings from normal properties (page and dynamic ones)
  • web site editors can now modifiy the values (this can of course be denied using EPiServer security settings)

In many cases, this is probably the best solution as it’s scalable and gives clean page code. However, code in the code-behind files becomes a little more complicated if you want to retrieve settings from the settings page. Essentially you first have to retrieve the value of the “SettingsPage” property, then open the page it references and then finally read the property value from the loaded page.

If the settings stored in the settings page are mainly page references that are farily static (such as our cookie page) there is one more alternative.

Simple adresses
Each page in EPiServer has, in addition to the “normal” page address (friendly Url or normal), a shortcut address. This is editable on the “Advanced information” tab when editing a page:

cookiepage_property.gif

If you set this property on the cookie page to for example “cookiepage”, this page is accessible as “http://host/cookiepage”. This fact can be used in our page footer by creating a link like this:

<a href="/cookiepage">About cookies</a>

This looks a lot like our first, simple example, but now we can move or rename the page without problems. And in code-behind files we now don’t even have to read property values, we know beforehand what the page address is:

Response.Redirect("/cookiepage");

Very simple and very efficient code. Just what I like 🙂

This alternative is also useful if you have several pages that should be visited in sequence, for example when the user is ordering an item in a web shop. If you set the simple address on each form page, you always know what the address to the next page in the sequence is. If you select one of the other alternatives, it will be a lot of administration before you get all page properties right.

This post got longer than I thought when I started it, the subject may be more complicated than first expected. Maybe you guys out there have opinions on this matter? Please add comment to this post if that is the case 🙂

Cheers,

Emil