Friday, February 24, 2012

Prevent pages from being created below a pagetype

Sometimes you may want to prevent editors from creating sub pages to specific page types. By default in EPiServer you can let the editor create all types of pages or just a select amount of page types below a page but you can't prevent the editor from creating any pages but with a small "hack" you can achieve this.

1. Create a new unused page type and mark it as unavailable in edit mode.
2. On the page type you don't want any sub pages on set the page type in step 1 as the only available page type.
3. Now no sub pages can be created in edit mode.

Wednesday, February 22, 2012

Tuesday, February 21, 2012

Context-aware CMS, det nästa efter CXM

Vad blir det nästa efter smart personalisering baserad på vedertagen autenciering och identitet via t ex Facebook Graph? Det som ofta kallas CXM idag har även det en framtid.

På Nansen tror vi att ni kommer höra termen Context-aware flera gånger under hösten 2012 och vintern 2013.

I teorin innebär det att CMS mallarna, content och dess funktionalitet blir smartare och bättre på att se sitt specifika syfte och sina samhörigheter. Då kan CMS:et automatiskt hjälpa och påminna redaktörer att placera rätt innehåll, utan dubletter eller ett alltför otydligt samband med annat content. Placera innehåll i rätt plats i navigation eller sajtstrukturer. Eller av sig själva addera upp funktionalitet som passar ihop med varandra.

Det går så klart att kombinera med mer klassisk personalisering baserat på t ex beteende, inlänkningsväg, personalia medlemsinställningar, Twitter/sociala nätverk etc.

Med allt "renare" standarder inom både frontend och backend, bättre RESTful tillämpningar av alla API:er känns det inte alltför avlägset.

Wednesday, February 15, 2012

PageTypeBuilder and EPiServer edit-on-page (DOPE)

So I needed to implement DOPE on a page for a client today. DOPE is the on page editmode of EPiServer where you can edit the content directly on the page without entering edit (or quick edit) mode. This only works if a few conditions are met:

  • Viewstate must be enabled
  • Requestvalidationmode (in the httpruntime element of web.config/system.web) is set to 2.0, only applies if you run your site in .net 4.0
  • You must use the control <EPiServer:Property /> to render your property data.

The problems that directly arise is that <EPiServer:Property> require you to enter a property name to be rendered. This is bad in the sense that we use PageTypeBuilder to create our properties and we want to be able to refactor and whatnot in our code. Now raise your hand everyone of you that have forgotten to update a Codebefore element that had a magic string reference to a EPiServer property after changing the property name.

So to get around that, I found one way that (my colleague Andreas tipped me is similarly implemented in entity framework) uses some reflection and lambda magic to achieve our goal of having no magic strings in codebefore.

We first define our property in codebefore, note that we use a ID instead of the PropertyName magic string property:

<EPiServer:Property runat="server" ID="MainBody" DisplayMissingMessage="False" Editable="True" />

Next, we create a extension method to retrieve the name of a class property:

public static string GetPropertyName<T, TResult>(this T obj, Expression<Func<T, TResult>> property)
where T : TypedPageData
var body = (MemberExpression)property.Body;
return body.Member.Name;

And finally we connect our property to our control and enable viewstate only when needed, this is done in our page codebehind:

protected override void OnInit(EventArgs e)
if (CurrentPage.QueryDistinctAccess(AccessLevel.Edit))
EnableViewState = true;
MainBody.PropertyName = CurrentPage.GetPropertyName(p => p.MainBody);

Now if we refactor our MainBody property in our page type, the text on our page will not be broken until we change the magic string to reflect the new name. Since a property refactoring will also change the lambda expression to retrieve the property name. Pretty neat, huh?


The extension method above already exists in PageTypeBuilder (in the PageTypeBuilder namespace), so just refer to that namespace and you can use the extension method on any object inheriting PageData.

Tuesday, February 14, 2012

When donken-friday became donken-monday

I have no idea how I got into this, but as of last week I'm an offical member of McDonald's Monday. This is the US version of the strange old habit originating from some guys at Dropit called Donken (short for McDonald's) Friday. Only, here it's on Mondays.

And yes, I can almost appreciate this food with from a strict price vs. quality-prespective. It is actually better here than back home, or maybe that is because we are visiting the flag ship restaurant in the city where McDonald's has its Head Quarters.

Anyhow, the whole thing is made worthfull because of the childish reactions the whole day before going, during and under the visit from the one and only Tomas Unestad. Priceless!


I'll let this stay as todays "picture guess" (as in KP)

Tuesday, February 7, 2012

Tuple<T1,T2> + EPiServer = Fail!

One of the dll's you need to reference in your project when using code from EPiServer Framework, for example the InitializableModule attribute, is the System.ComponentModel.Composition dll for .NET 2.0. If you do this in a .NET 4.0 project and then try to use Tuple<T1,T2> you will get an error message letting you know that Tuple<T1,T2> is declared in both System.ComponentModel.Composition.dll and mscorlib.dll. This is because System.ComponentModel.Composition declare a struct in the "System" namespace with the same name and function(?) as the new Tuple<T1,T2> struct in .NET 4.0.
To fix this problem you can add an alias to the reference of System.ComponentModel.Composition in your project, this can be done in Visual Stuio by opening the Properties window for the reference and add an alias. It can also be done in the project file with the following code,

<Reference Include="System.ComponentModel.Composition">
<HintPath>..\Solution Items\References\System.ComponentModel.Composition.dll <Aliases>episerver</Aliases>

After that we have "Tuple<T1,T2> + EPiServer = Success!"
As we only have the reference to this dll becuase EPiServer Framework uses it this will not have an impact on the function of EPiServer.

EPiServer Commerce Associations

In the last couple of Commerce projects I have had trouble with associations, when saving them I get an exception. The cause for this error is two missing rows in the commerce database, the table should in a normal installation only contain this two rows and when I have had the problem the table has been empty.
INSERT INTO [AssociationType]([AssociationTypeId],[Description]) VALUES('OPTIONAL','Optional');
INSERT INTO [AssociationType]([AssociationTypeId],[Description]) VALUES('REQUIRED','Required');

Wednesday, February 1, 2012

Say hi to the Chicago office

So guys, as of today I intend to report from the Chicago office, from an "everyday life at the office"-point of view. So here I'll give you the first of a series of pictures and stories from one of our US crews, located at 400N State Street, Chicago:

Showing the office in a panoramic version with Ricardo and the wrath of a hungry Tomas in the center.