Creating an module installer for EPiServer Template Foundation

As I was reading Ted’s introduction post to installing Template Foundation I realised that this could be created as an EPiServer module.

Nitpickers corner: Ok, so I screwed up slightly and called it EFT rather than ETF in the solution.

Creating the installation package

First create a folder structure that resembles what you want copied into the site your module is installed to. In the case of ETF it’s only a matter of placing the relevant dll:s in a bin folder.

Start by downloading the EPiServer PowerTools (only available for Visual Studio 2008) here. When you’ve installed the MSI-package a new template is available in Visual Studio

This template will open another dialog that looks like this

Click Browse on the Packages files from this location row and point to the root of your application files. In the case of EFT that would be a directory that only contains another directory called bin.

Enter the target version (for this example we’re targeting CMS 6 R1, 6.0.530.0).

Click next and you’ll get a list of what files will be included. Click next again to finish the wizard.

The installation project

The template has now created a number of files for you (the names of these files will differ depending on what you named your project).

  • Eft.Installer.metadata – Contains metadata, the name of the module and it’s display name can be changed here.
  • Install Eft.Installer.ps1 – Powershell installation that gets run as part of the installation. Should not be changed, see this post as to why not
  • Product.wxs – Contains wix metadata about which files should be included in the final package
  • web.config.xmlupdate – Contains a skeleton file for doing web.config transformation as part of the installation of the module

Doing config transformations

As you can see from Teds blog post we need to add some EFT specific information to the config file. This can be done through the web config transformation that is run as part of the installation of your module. The first gotcha with this is that this file is not by default included in the Product.wxs file (which means it won’t be included in the msi-file that is generated) so let’s start by adding it

    <DirectoryRef Id="ModuleDir">
      <Component Id="InstallScriptComp" Guid="aa5d5ac8-7193-4849-b60f-620f09e504e1">
        <File Id="PowerShellScript" Name="Install Eft.Installer.ps1" Source="$(sys.SOURCEFILEDIR)"/>
        <File Id="ModuleMetaData" Name="Eft.Installer.metadata" Source="$(sys.SOURCEFILEDIR)"/>
        <File Id="XmlFileUpdate" Name="web.config.xmlupdate" Source="$(sys.SOURCEFILEDIR)"/>
      </Component>
    </DirectoryRef>

The actuall transformation language is pretty straight forward and documentation is available here. In our case we want to add the three handlers for images

  <remove path="/configuration/location[@path='PageFiles']/system.webServer/handlers/add[@name = 'wildcard']"/>

  <addBlock path="/configuration/location[@path='PageFiles']/system.webServer/handlers">
    <add name="png" verb="GET,HEAD" path="*.png" type="TemplateFoundation.Handlers.DynamicImageProcessor.Processor" __keyAttributes="name" />
    <add name="jpg" verb="GET,HEAD" path="*.jpg" type="TemplateFoundation.Handlers.DynamicImageProcessor.Processor" __keyAttributes="name" />
    <add name="gif" verb="GET,HEAD" path="*.gif" type="TemplateFoundation.Handlers.DynamicImageProcessor.Processor" __keyAttributes="name" />
    <add name="wildcard" path="*" verb="*" type="EPiServer.Web.StaticFileHandler, EPiServer" __keyAttributes="name" />
  </addBlock>

Notice that we remove the wildcard and then add it again. This is because we want it to be the last handler and new items are by default added last to the list.

Then we add the rest of the handlers

  <addBlock path="/configuration/system.webServer/handlers">
    <add name="ScriptResource" verb="GET,HEAD" path="ScriptResource.axd" preCondition="integratedMode" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" __keyAttributes="name" />
    <add name="PageTypeIconHandler" preCondition="integratedMode" verb="GET" path="/TemplateFoundation/Images/PageIcons/*" type="TemplateFoundation.Handlers.EmbeddedImagesHandler" __keyAttributes="name" />
    <add name="TemplateFoundationImagesLoader" type="TemplateFoundation.Handlers.EmbeddedImagesHandler" path="/TemplateFoundation/images/*" verb="GET" __keyAttributes="name" />
    <add name="TemplateFoundationHtmlLoader" type="TemplateFoundation.Handlers.EmbeddedHtmlHandler" path="/TemplateFoundation/*.html" verb="GET" __keyAttributes="name" />
    <add name="MetaWeblog" type="TemplateFoundation.MetaWeblog.MetaWeblogHandler" path="/metaweblog" verb="*" __keyAttributes="name" />
    <add name="LiveWriterManifest" type="TemplateFoundation.MetaWeblog.ManifestHandler" path="/wlwmanifest.xml" verb="*" __keyAttributes="name" />
    <add name="ReallySimpleDiscovery" type="TemplateFoundation.MetaWeblog.ReallySimpleDiscoveryHandler" path="/rsd.xml" verb="*" __keyAttributes="name" />
  </addBlock>

and finally the tag for using ETF web controls

  <add path="/configuration/system.web/pages/controls">
    <add tagPrefix="ETF" namespace="TemplateFoundation.WebControls" assembly="TemplateFoundation" __keyAttributes="tagPrefix" />
  </add>

Notice that I haven’t done anything to add the tag prefix for controls in edit / admin UI. This is because you don’t know what the prefix the user has chosen and that information is unfortunatly not available to you when the transformation is performed.

Building the solution

When you build the solution your output dir will now contain an msi-file that installs your module.

Simple install this package and your module will appear as a install choice in the deployment center, both as a stand alone choice and when installing a site + database.

A closer look

Here’s a rar file containing the entire project > EtfInstaller

  • http://tedgustaf.com Ted Nyberg

    Great work! Looking into this right now! I’m thinking an MSI should probably be published on Codeplex?