EPiServer

Create ShareThis Add-On for EPiServer 7

Background for this post. I wanted to learn how to create EPiServer 7 MVC Add-On and quick googling basically had 2 results. So this blog post will be based on Dmytro Duk blog posts Developing simple add-on for EPiServer 7 preview and Sharing widget for EPiServer 7

Not going to copy paste his texts and code here but I’m going to add a few things to his solution. Mainly the usage of EPiServer NuGet packages (which weren’t available during the preview version) and how those affect your NuGet package creation.

I also demonstrate the usage of .AtHeader() for javascript inclusion (also you can use it to include css etc, I hope everyone has spotted the SDK documentation about it : Rendering Areas (2 required rendering areas that should be implemented by all templates)).

Also I use the Hidden template functionality in the MVC implementation to implement the Controller for the Add-On view.

Creating and preparing the Add-On solution

  • Create a new ASP.NET MVC 4 Web Application (targeting .Net framework 4.0)
  • Use Empty project template
  • (Notice that Visual Studio has used NuGet packages to add the ASP.NET MVC 4 and other libraries)
  • Delete the Global.asax
  • Delete from App_Start: FilterConfig.cs, RouteConfig.cs and WebApiConfig.cs (unless you know you will need these and want to setup Initialization module)
  • Use NuGet package manager to install EPiServer.CMS.Core package
  • Open the web.config file under the Views folder and add your assembly to the compilation
    <compilation>
       <assemblies>
          <add assembly="[YOUR_ADDON_ASSEMBLY_NAME_HERE]"/>
       </assemblies>
    </compilation>

Add-On implementation

  • Grab and add the ViewRenderTemplate<T> from Jonas post to your Controllers folder
    • Notice that the GetOriginalType() extension method comes from EPiServer-namespace (currentContent.GetOriginalType().Name line in code)
    • Use this class as the base class for your Controller class
  • Create your ShareThis model class
  • Rebuild solution
  • Add a View for the ShareThis block (Partial view)
    @model Swapcode.Creuna.AddOn.ShareThis.Models.ShareThisSomeBlock
    @using EPiServer.Framework.Web.Resources
    
    @{
    // the template has to implement the
    // Header and Footer named areas
    // below using the dependencies to ensure that
    // they are rendered in correct order to client
    ClientResources.RequireScriptInline(@"var switchTo5x=true;", "shareThisInit", null).AtHeader();
    ClientResources.RequireScript("http://w.sharethis.com/button/buttons.js", "shareThisScript", new string[] { "shareThisInit" }).AtHeader();
    ClientResources.RequireScriptInline(string.Format(@"stLight.options({{publisher: ""{0}"", doNotHash: true, doNotCopy: true, hashAddressBar: false}});", this.Model.PublisherId), "shareThisConfig", new string[] { "shareThisScript" }).AtHeader();
    }
    
    <div>
    <span class='st_sharethis_vcount' displayText='ShareThis'></span>
    <span class='st_facebook_vcount' displayText='Facebook'></span>
    <span class='st_fblike_vcount' displayText='Facebook Like'></span>
    <span class='st_twitter_vcount' displayText='Tweet'></span>
    <span class='st_googleplus_vcount' displayText='Google +'></span>
    <span class='st_linkedin_vcount' displayText='LinkedIn'></span>
    </div>
  • Add your block Controller remember to inherit from the abstract ViewRenderTemplate you created and implement the Render-method
    protected override void Render(ShareThisSomeBlock currentContent)
    {
       this.RenderPartialView(Paths.ToResource(typeof(ShareThisSomeBlockController), "Views/ShareThisSomeBlock/Index.cshtml"), currentContent);
    }
  • Please do remember that you need the PublisherId from ShareThis generator

Building the NuGet package

I used the NuGet documentation as the base how I wanted to build the Add-On package. I based my packaging procedure to the Convention based working directory.

If you just go ahead and use nuget spec in the project folder from command prompt, yes you get a nice generated *.nuspec file and you can modify it but if you then run nuget pack YOUR_PROJECT_FILE_NAME.csproj what happens is that nuget uses your projects packages.config and creates dependencies to those packages. Now when you try to install your Add-On to EPiServer (at east when manually installing) it will fail because it thinks those dependencies are not installed and it can’t find those or doesn’t know how to install them (when I first did it this way it was funny because the error message was about EPiServer.CMS.Core).

NuGet package preparation

As I’m using the Convention based working directory approach I need to create a root folder for the package and have some post-build events in the project.

  • Create a new folder under the solution folder on disk (create the new folder to disk in Windows explorer)
    • This folder is the root folder for the convention based package
  • Create content named folder under the root
    • Here you put the content for the package
    • The strcucture under the content folder will be the same as your Add-On structure (Views, CSS, JS, etc)
      • Something like /Views/YourBlockName/ – here you copy the index.cshtml for example
      • /Views/ – here you will copy the web.config
      • /Images/, /JS/ and /CSS/ and whatever you might have
  • Create lib folder under the root
    • Create a new folder net40 under the lib (as this Add-On is only targeting the .net framework 4.0 – AND YES the folder needs to be named net40, these are documented and explained in NuGet documentation)
      • You will copy your assembly / assemblies to this folder

Next step is to create the post-build events to Visual Studio

  • Create post-build events that copy your Add-On required files to the package structure
    • Copy your assembly to the /YOUR_PACKAGE_ROOT/lib/net40/ -folder
    • Copy the Views folders web.config to /YOUR_PACKAGE_ROOT/content/Views/ -folder
    • Copy view file to the /YOUR_PACKAGE_ROOT/content/Views/SomeBlock/ -folder
    • (Copy js, css, images etc to their correct places under the /YOUR_PACKAGE_ROOT/content/ -folder)
  • Build and make sure that the files are copied ok

If you don’t have the command line tool nuget.exe now is the last moment to get it. After download, remember to add it to your path variable.

Creating the package

  • Open command prompt and navigate to your YOUR_ROOT_PACKAGE -folder
  • Run the command: nuget spec
    • This creates the manifest for the package, by default the file name is : Package.nuspec
      • You can rename the file according to your Add-On name for example ShareThisAddOn.nuspec
    • Open the file in Visual Studio or a text editor and edit the values
      • id – your package id, for example CompanyName.EPi7.AddOnName (Notice this is something that you want to be globally unique)
      • version – your addon version number (initially 1.0.0)
      • authors and owners – your company name for example
      • description – enter the description of the Add-On
      • releaseNotes – enter something other than the default text or you get a warning about using the sample text when you try to pack
      • Remove the sample tags and use the EPiServer magic tags ( EPiServerPublicModulePackage for public Add-Ons OR EPiServerModulePackage for protected Add-Ons)
      • Delete the dependencies SampleDependency entry
      • Save your changes
      • Now you are ready to build the package. Run the command: nuget pack YOUR_FILE_NAME.nuspec
      • The command outputs the packed package named in the format of: package ID + version + .nupkg (like MyCompanyName.EPi7.MyAddon.1.0.0.nupkg)
  • Next step is to manually install the created package to EPiServer Add-Ons
  • As a side note when you need to update your Add-On code simply make your changes, rebuild, increase the version number in the *.nuspec file and re-pack

Download Add-On full source

I’ve placed the full source in zip file to Dropbox for the moment.

Update 16.8.2013

You could change the nuget packaging by removing the post-build copy events and edit your *.nuspec file to get the same results when packing the package.

Add these lines to your *.nuspec file after the metadata element

  <files>
    <file src="..\Swapcode.Creuna.AddOn.ShareThis\bin\Swapcode.Creuna.AddOn.ShareThis.dll" target="lib\net40" />
    <file src="..\Swapcode.Creuna.AddOn.ShareThis\Views\**\*.*" target="content\Views" />
  </files>