Web Part Framework for EPiServer tuned and polished
<p>Today I committed quite a chunk of changed and new code to the <a href="https://www.coderesort.com/p/epicode/wiki/EPiWebParts" target="_blank">Web part Framework for EPiServer</a>. At first glance you won’t notice any visible changes, so what’s new?</p>
Table of Contents
- My motivation for doing this
- Bug fixed
- Non user-friendly issue fixed
- Search engine issue fixed
- New editor
- New chrome for zones
- Some refactoring recommended
- Write simpler code for your web parts
- Write more editor-friendly web parts and yet simpler code
- Restored Layout orientation
- Please frontend developers
- Getting started with ease
- AJAX-enable web part editing
- Summary
My motivation for doing this
I’ve been a great fan of the Web part Framework for EPiServer ever since the first time I saw it. It was originally written by Steve Celius a few years ago, but several other developers have contributed since. In my opinion it has two significant strengths in comparison to Microsoft’s standard web part framework.
- It enables web parts to expose EPiServer properties which are editable directly in EPiServer’s view mode (not browse mode of web parts). This means that whenever you need to edit a property of your web part, the framework will present you with EPiServer's GUI for that specific property type.
- As it doesn’t render any tables in browse mode, your web part enabled pages validates contrary to the standard Microsoft web part framework.
Still it’s pure Microsoft and relies on a widely used and standardized framework. So by using it you don’t risk running down a dead end, as you might with other proprietary frameworks.
Until now the framework had a more or less cumbersome flaw. I had to dig a bit under the hood in order to pin point and resolve this issue. As the defected part was located and replaced, I realized that other parts of the framework law scattered around. So I decided to polish some chrome and tune some other parts before reassembling it again. Like Adam Najmanowicz I didn’t want to mess things up for those of you who are happy with framework as it is. Although developers will notice some changes, the editors won’t. That is unless you activate and take advantage of the new features for them.
Bug fixed
As the ticket at coderesort describes, existing instances of web parts where not capable of persisting newly added properties. This is now resolved.
Non user-friendly issue fixed
The framework had a feature often commented by editors I’ve spoken with. Whenever you add a web part to a zone the edit dialog pops up. If you at this point want to undo your action and press cancel, the web part still resides in the zone. This issue is now fixed.
Search engine and availability issue fixed
The editor dialog for editing web part properties is hidden inside each web part enabled template. This is true even for users lacking access to edit web parts. Try to google: "Edit Web Part Contents" or the Norwegian version "Rediger innhold for webdel" and you’ll see what I mean. Since visitors on your site don’t have access to edit your web parts there is no reason to render the hidden editor dialog. Thus the dialog is now only rendered for logged in users with access to edit web parts.
New editor
The most extreme makeover was done to the "Edit web Part Contents" dialog. If you haven’t altered the default style sheet it should look something like this:
In order to activate the new chrome you’ll need to change the namespace from where you load your "WebPartManagmentConsole". This is normally either done inline in ManagementConsole.ascx or in the <pages><controls> section of your web.config. This example illustrates the inline approach.
Change:
<%@ Register TagPrefix="EPiCodeWP" Namespace="EPiCode.WebParts" Assembly="EPiCode.WebParts.Core" %>
To:
<%@Register TagPrefix="EPiCodeWP" Namespace="EPiCode.WebParts.EPiChrome" Assembly="EPiCode.WebParts.Core" %>
And you're done. The polished chrome gives the dialog a more EPiServer look and feel:
Apart from the obvious change of appearance there are a few nifty things worth mentioning:
- The dialog is movable and is position is saved in a cookie.
- Description for the selected web part is now visible. -I it’s been missing for quite a while.
- Focus is automatically set to the first editable field.
- Rendering is now done by EPiServer’s own "PropertyDataForm" which handles wide layout and other things exactly as you would expect when editing properties in edit mode.
- Pressing enter now has the same effect as clicking OK (and doesn't execute search or any other default button on your page)
New chrome for zones
Conformity with the new editor the web part zones has been polished and the new chrome is again activated by changing a namespace either inline in your .aspx/.ascx or in web.config. Using default style sheet and settings an old fashioned zone looks like this in edit mode:
The following example demonstrates how to change namespace in .aspx. The new zone does also automatically sets defaults to a selection of zone properties which helps you keep your markup tidy, so let’s change that as well.
Before:
<%@Register TagPrefix="EPiCodeWP" Namespace="EPiCode.WebParts" Assembly="EPiCode.WebParts.Core" %>
<EPiCodeWP:ZoneLowUiImpact runat="server" ID="MainZone" CssClass="WebPartZone"
PartChromeType="TitleOnly"
WebPartVerbRenderMode="TitleBar"
HeaderText="Main content"
WebPartZoneId="MainZone"
CatalogZoneId="ThemeCatalogZone"
Width="99%"
>
<HeaderStyle CssClass="WebPartZoneTitleArea" Wrap="true"/>
<SelectedPartChromeStyle CssClass="WebPartSelectedArea" />
<PartTitleStyle CssClass="WebPartTitleArea" />
</EPiCodeWP:ZoneLowUiImpact>
After:
<%@Register TagPrefix="EPiCodeWP" Namespace="EPiCode.WebParts.EPiChrome" Assembly="EPiCode.WebParts.Core" %>
<EPiCodeWP:ZoneLowUiImpact runat="server" ID="MainZone" CatalogZoneId="ThemeCatalogZone" />
And the result:
Some of the changes are:
- The new low ui impact zone is inherited from the previous version so you’re still able to tamper with appearance through your favorite properties.
- That annoying title ("Main content") is gone. Did it provide the editor with any useful information? If you miss it, turn it back on again by setting HideHeader="false"
- Tired of entering the same id in both ID and WebPartZoneID? Don’t bother anymore.
- If you prefer not to display a catalog in your zone simply omit the CatalogZoneId
- Besides that the menu text is changed into icons their positions have moved from right to left. This is makes sense in narrow zones when the menu often is forced out of reach. If you don’t like it simply set MenuPosition="Right"
Some refactoring recommended
The IPropertyDataWebPart interface is Obsolete and will generate compiler errors if you’ve used it, but my experience is that its rarely used. Beside from that your web parts should build and run exactly as before after upgrading the EPiCode.WebParts.Core.dll.
Nevertheless you’ll end up with a bunch of complier warnings, in your web parts, and I recommend that you carry out some degree of refactoring. A lot of code that previously had to go into each web part is now abstracted to its ancestor class as is therefore obsolete. What I recommend you to do is this:
- Remove "WebPartEditorDescription()".
- Replace "ShouldShowEditorAfterNew()" with class attribute [AllowEdit(false)]
- Remove your overridden Title and Description properties and use the new WebPartdataLanguage attribute. This makes it possible to skip translations during development as the class names are used if translations are not provided.
- Remove all your SetDirty() calls. This caused a lot of unnecessary stress for the underlying provider.
- Replace:
public override string Title { get { return Translate("/webparts/parts/ flash /title"); } }
Width:
public override string Description { get { return Translate("/webparts/parts/flash/description"); } }[WebPartDataLanguage("/webparts/parts/flash/title", "/webparts/parts/flash/description")]
public partial class FlashPart: UserControlWebPartBase
Write simpler code for your web parts
Having got rid of all your complier warnings, now’s the time to scrap some more superfluous code. Taking advantage of Auto-properties in C# 3.0 and reflection, there is no longer need for private variables storing your editable properties. Where the traditional web part code would look like:
private PropertyString _headerText = new PropertyString();
[Personalizable]
[PropertyDataLanguageAttribute("/webparts/properties/headertext/title", "/webparts/properties/headertext/description")]
public PropertyString HeaderText
{
get { return _headerText; }
set { _headerText = value; SetDirty(); }
}
It’s now enough with:
[Personalizable]
[PropertyDataLanguageAttribute("/webparts/properties/headertext/title", "/webparts/properties/headertext/description")]
public PropertyString HeaderText { get; set; }
During your development process you might also postpone adding the language attribute as property name are displayed when translations are missing.
Whenever you need to initialize properties with default values it should be done in the constructor. E.g:
public PageListPart()
{
MaxCount = new PropertyNumber(5);
}
Write more editor-friendly web parts and yet simpler code
Consider you’re developing a web part that requires a root page for listing its children. It won’t make much sense to render the web part if the editor didn’t enter a valid root page. Typically you would write code to validate that the root page is not null or empty. In a more complicated web part you might need to validate some other properties as well. And what does really happen when an editor enter text in a "PropertyNumber" field? Both these scenarios are now dealt width. Add a "IsRequired" attribute to your required properties; other properties are now validated as you are familiar with from EPiServer’s edit mode.
[IsRequired, Personalizable]
public PropertyPageReference ListRoot { get; set; }
And in your render logic simply test if the editor has done what you asked for:
if (!IsValid())
{
return; //Don't bother to do any more testing
}
//Do your stuff here
GetChildren(ListRoot.PageLink);
...
And leave it to the editor dialog to reprimand the editor:
Restored Layout orientation
The low UI impact zone is great as it does not render any tables, but it came with a cost. The support for horizontal layout orientation was lost, but is now supported. Just set LayoutOrientation="Horizontal". The framework wraps each web part inside a <div class="webpart" style="float:left;"> for webparts inside horizontal zones.
Please frontend developers
In most cases you need some space between web parts residing inside the same zone. And it makes no difference if the zone layout is vertical or horizontal. The simple way has been to apply some bottom (or right) margin to each web part. Dependent on how picky your markup coder is you’ve probably gotten away with it, even though this approach would apply some unwanted margin at bottom (or right). I’ve seen numerous different approaches to this problem, some good and some bad. Each web part is now wrapped inside a div with a class name describing its position within the zone; first, last and single. This gives pixel pushers capabilities to style spacing with a high level of precision. Editors are still able to reorganize web parts within a zone without breaking the design as the class names are calculated and not bound to a specific web part.
Getting started with ease
The threshold to start using the framework in your project is now lowered. I’ve spent hours helping other developers getting started with previous versions of the framework. One recurring problem was that the editor dialog wasn't displayed. The reason was due to a missing style sheet. All javascript, style sheets and images are now embedded inside the library and automatically loaded whenever needed (and not loaded for visitors). Thus there is no longer necessary to include any other files than the dll. (Just in case you didn’t know: You are still able to apply styling with your own custom style sheet, without recompiling the library). All these files previously used by the framework are no longer necessary and you can safely evict them from your existing projects. That is of course only true if you use the new chrome.
AJAX-enable web part editing
In my latest EPiServer project I’ve AJAX-enabled the framework which improves the editor experience considerably. A pleasant side effect is that drag & drop is supported in Firefox. What you need to do is make sure AJAX is properly configured in your web.config. This matter is described in countless articles on the web so I won’t explain it in this article. Secondly you must make sure your web part manager is type of: "Microsoft.Web.Preview.UI.Controls.WebParts.WebPartManager" (After my understanding the preview namespace will gone when asp.net 4.0 is released) Finally you must build the framework with one of the new build configurations; Debug Ajax or Release Ajax.
Summary
As earlier mentioned I’m a big fan of this framework and benefit from it in nearly all my EPiServer projects. Based on feedback from developers and editors I’ve addressed some of the deficiencies it had, according to my subjective comprehension. I hope you experience these changes as improvements. Even though I made an effort not to break existing code, you might encounter some problems. Please feel free to contact me, if you do.