Creating a NuGet-package for ETF

EPiServer has announced the well sought after NuGet feed. In this post we’ll take a look at how to create a NuGet package for ETF (if you want to know how this could be done using a module installer take a look at this post).

This post assumes that you already have the nuget client installed in visual studio (check the announce post for a link to download it) and that you have added the EPiServer feed.

nuget.exe

To actually create packages you need a command line tool called nuget.exe. This can be downloaded here.

Adding assemblies

In the case of ETF we only want to add the dll TemplateFoundation.dll. This will be added to a folder called lib (which would contain all assemblies you’d want to include).

The NuSpec manifest file, .NuSpec

This files which the package is built from specifies some metadata about the project as well as all the other packages that it depends upon. In the case of ETF it’s only dependency is PageTypeBuilder (which in turn is dependant upon StructureMap and Castle.Core). Since this is Microsoft and enterprise ready the file is in the form of an xml.

<?xml version="1.0" encoding="utf-8"?> 
<package> 
  <metadata> 
    <id>ETF</id> 
    <version>1.1</version> 
    <authors>Ted Nyberg</authors>
    <dependencies>
      <dependency id="PageTypeBuilder" version="1.3" />
    </dependencies>
    <description>EPiServer Template Foundation builds on top of Page Type Builder to provide a framework for common site features such as basic page type properties, RSS support, tags and date folders, MetaWeblog support for Live Writer, and various helpers for creating custom property types etc.</description> 
    <language>en-US</language>
    <licenseUrl>http://etf.codeplex.com/license</licenseUrl>
    <projectUrl>http://etf.codeplex.com/</projectUrl>
  </metadata> 
</package

As you can see on line 8 we only need to specify our direct dependency (PageTypeBuilder) and NuGet will handle the dependencies of that dependency.

Config transformations

NuGet can also perform the neccessery config transformations for us. This file (called web.config.transform) is placed in a folder called content. ETF adds a few controls and handlers and this is a good thing since NuGet transformation capabilities is pretty basic and only supports adding / merging the config files.

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

	<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" />
			<add name="PageTypeIconHandler" preCondition="integratedMode" verb="GET" path="/TemplateFoundation/Images/PageIcons/*" type="TemplateFoundation.Handlers.EmbeddedImagesHandler" />
			<add name="TemplateFoundationImagesLoader" type="TemplateFoundation.Handlers.EmbeddedImagesHandler" path="/TemplateFoundation/images/*" verb="GET" />
			<add name="TemplateFoundationHtmlLoader" type="TemplateFoundation.Handlers.EmbeddedHtmlHandler" path="/TemplateFoundation/*.html" verb="GET" />
			<add name="MetaWeblog" type="TemplateFoundation.MetaWeblog.MetaWeblogHandler" path="/metaweblog" verb="*" />
			<add name="LiveWriterManifest" type="TemplateFoundation.MetaWeblog.ManifestHandler" path="/wlwmanifest.xml" verb="*" />
			<add name="ReallySimpleDiscovery" type="TemplateFoundation.MetaWeblog.ReallySimpleDiscoveryHandler" path="/rsd.xml" verb="*" />
		</handlers>
	</system.webServer>

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

The current folder structure

Just to recap, we have the following files and folders now:

ETF.Nuget (folder)
  ETF.nuspec (manifest file)
  NuGet.exe (command line tool)
  lib (folder)
    TemplateFoundation.dll
  content (folder)
    web.config.transform

Creating the package

To actually generate the package you navigate to the ETF.Nuget folder and execute the tool the following way

nuget pack ETF.nuspec

This will generate the package ETF.1.1.nupkg in the root folder (the 1.1 is from the version we specified in the manifest file).

Testing the package

To accomplish this we will need to add an additional feed that contains our newly created package. Luckily this is quite easy since you can create a feed that simply points to a folder. In Visual Studio navigate to Tools / Library package manager / Package manager settings. Simply add another feed that points to the folder where your package file is located. It should look something like this:

Adding the package to a project

Now that the feeds are in order we can start adding ETF to our project. This works the same way as you’d normally add packages using NuGet. Simply right click on your project and select Add library package reference.

In the popup that opens make sure that you select the All option in the Online choice. This will search and fetch from all the nuget feeds you have added. This is needed since we don’t have the PageTypeBuilder in our ETF.NuGet feed (and EPiServer wouldn’t have a need for StructureMap and Castle.Core in theirs).

Simply search for ETF and click install to install it.

and you’re done!

If you want to take a look at the files and folder as a whole here’s a zip file that contains everything you need to create your own ETF package.

But wait, there’s more!

NuGet can handle a few more scenarios which is not needed for ETF. I will hopefully come back to them in later posts or if you can’t wait for that, do read up on the nuget documentation.

Oh, and to publish your NuGet package on the EPiServer feed you should follow the instructions on the EPiServer nuget site. I’m a somewhat firm believer in that the creator of the project is probably the best person to handle the package too.

So, here’s hoping we’ll see some real innovation surrounding EPiServer in the near future!