Sharing Widget for EPiServer 7

Sharing Widget add-on provides easy way to get ShareThis buttons on EPiServer 7 site. Just create new block, specify your publisher ID and drop it on a page. Both Web Forms and MVC are supported.

SharingWidgetOnPage2

Please download Sharing Widget add-on package to install using Manual Upload option.

Source code is available on GitHub.

This module was developed as a sample add-on for EPiServer 7 Preview. Now it is rebuilt for RTM version. Please see details about most important fixes below if you are interested.

Feedback

Your feedback is highly appreciated. Please let me know if you are interested in further add-on development and which features you would like to see (selecting required buttons, size, other settings?). Don’t hesitate to report bugs and issues or leave a comment here.

Known issue with add-on block rendering on MVC site

There is a known issue with shared block rendering when the block is deployed as an add-on/module on EPiServer 7 MVC site. You will get similar error when viewing a block or page that contains add-on block in content area:

Server Error in '/TestMvc' Application. 
--------------------------------------------------------------------------------
The controller for path '/TestMvc/UIPath/CMS/en/,,183_207/' was not found or does not implement IController.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.Web.HttpException: The controller for path '/TestMvc/UIPath/CMS/en/,,183_207/' was not found or does not implement IController.

Source Error: 

Line 23:         public virtual void RenderAction(HtmlHelper helper, string action, string controller, object routeValues)
Line 24:         {
Line 25:             helper.RenderAction(action, controller, routeValues);
Line 26:         }
Line 27:     }

As far as I can see the problem is that MVC has a cache of known controllers and this cache is created based on the list of assemblies defined in system.web/compilation/assemblies section in web.config. It also includes the main application assembly that is associated with global.asax code.

MVC uses that cache to find block controller by name convention (FooBlock -> FooBlockController) and it fails because controllers from module/add-on assemblies are not listed in that cache since add-on system does not change the configuration files.

Updated: the fix is available in EPiServer 7 Patch 1 update (bug #91052).

Solution

Go get and install EPiServer 7 Patch 1. That's it.

Simple workaround

Consider installing EPiServer 7 Patch 1! No? Then the simple workaround is to add add-on assembly in system.web/compilation/assemblies section in web.config manually:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
… 
  <system.web>
    <compilation … >
      <assemblies>
         …
        <add assembly="EPiServer.Samples.SharingWidget" />
      </assemblies>
    </compilation>
  </system.web>
</configuration>

Tricky workaround

Another workaround for real geeks is to implement initialization class which registers required add-on/module assembly programmatically. For example, it could register all assemblies in modulesbin folder to fix this issue for all add-ons.

Assembly that contains initialization class should be marked with PreApplicationStartMethodAttribute and should reside in site bin folder. Please see more information about this attribute here.

Rebuilding the add-on for EPiServer 7

To keep it simple I decided to not introduce any new functionality and tried to concentrate on what should be changed to make it work with EPiServer 7.

Surprisingly, there was not so much to update. You can see most of changes in this commit.

Block controller

This is probably the only one required change: the name of block data parameter in Index method is changed from blockData to currentBlock, otherwise current block data is not passed in action method and you get NullReferenceException when rendering content in the view.

public class SharingWidgetBlockController : BlockController<SharingWidgetBlock>
{
    public override ActionResult Index(SharingWidgetBlock currentBlock)
    {
        // Hint for MVC to find the view in modules folder:
        return PartialView(Paths.ToResource(GetType(), "Views/SharingWidget/SharingWidget.cshtml"), currentBlock);
    }
}

That was not so obvious, huh?

Translation for content type and property names and descriptions

Embedded language file for English is added. Titles and descriptions for Sharing Widget block type and properties are defined in /language/blocktypes/blocktype and /language/pagetypes/common/property nodes.

<?xml version="1.0" encoding="utf-8" ?>
<languages>
  <language name="English" id="en">
    <blocktypes>
      <!-- Blocks -->
      <blocktype name="SharingWidgetBlock">
        <name>Sharing Widget</name>
        <description>Adds ShareThis widget on pages where block is placed.</description>
      </blocktype>
    </blocktypes>
    <pagetypes>
      <common>
        <!-- Sharing block properties -->
        <property name="PublisherId">
          <caption>Publisher ID</caption>
          <help>Register on ShareThis.com to get your Publisher ID. You can also use "Get sharing tools" wizard on ShareThis.com to generate button code and get publisher ID without registration.</help>
        </property>
      </common>
    </pagetypes>
  </language>
</languages>

It’s a bit strange to describe block properties in pagetypes structure; hopefully it will be fixed in one of the next platform updates.

Module manifest for add-on

Add-on assembly is explicitly specified in module.config file to avoid automatic discovering of available assemblies in add-on bin folder.

Restricting prerequisites version

Dependency on EPiServer assembly is specified in add-on nuspec file. For this version the prerequisite is more strict and it requires EPiServer platform from version 7.0 (including) up to 7.1 (excluding) to avoid any incompatibility with new platform releases.

<?xml version="1.0"?>
<package >
  <metadata>
    <id>$id$</id>
    <title>Sharing Wigdet</title>
    <version>$version$</version>
    <authors>$author$</authors>
    <owners>$author$</owners>
    <projectUrl>https://github.com/dmytroduk/SharingWidgetAddOn</projectUrl>
    <iconUrl>http://w.sharethis.com/images/sharethis_32.png</iconUrl>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>Enables site visitors to share the content in social networks and communities using ShareThis.com widget.</description>
    <tags>EPiServerPublicModulePackage Social Sharing ShareThis</tags>
    <dependencies>
      <dependency id="EPiServer" version="[7.0,7.1)" />
    </dependencies>
  </metadata>
</package>

Creating add-on package after build

Project file contains after build target which creates new add-on package every time you rebuild the project.

<?xml version="1.0" encoding="utf-8"?>
<Project ...>
<!-- ... Ommited project file content ... -->

  <Target Name="CreateAddOnPackage">
    <PropertyGroup>
      <NuGetExePath>..\Dependencies\NuGet.exe</NuGetExePath>
    </PropertyGroup>
    <Exec Command="&quot;$(NuGetExePath)&quot; pack $(ProjectFileName) -OutputDirectory $(OutDir)" Condition="Exists('$(NuGetExePath)')" />
  </Target>
  <!-- Creating add-on package after build. -->
  <Target Name="AfterBuild">
    <CallTarget Targets="CreateAddOnPackage" />
  </Target>
</Project>

NuGet command line tool should be placed in Dependencies folder on solution root level.

Tags: EPiServer, Add-Ons, ShareThis, Social

Add a Comment
  1. (used to show your gravatar; will not be published)