Change Sitecore template on media upload

In one of our projects we recently had to swap the media template when a new item is uploaded so we can have extra fields against the media item.

Sean Holmesby has already posted a blog a while back on this and we used the concept as the starting point for our implementation but made it more flexible so it can be reused across different projects. Eventually I created a Sitecore module and uploaded to the market place as well as Github for everybody’s benefit and allowing to contribute.

Let’s have a look at theĀ configuration of the module first:

  <sitecore>
    <processors>
      <uiUpload>
        <processor patch:after="*[@type='Sitecore.Pipelines.Upload.Save, Sitecore.Kernel']" mode="on" type="Swissworx.Modules.MediaTemplateSwapper.TemplateSwapProcessor, Swissworx.Modules.MediaTemplateSwapper">
          <Name>Template swapper</Name>
          <MediaRootPath>/sitecore/media library</MediaRootPath>
          <SwapConfigurations hint="list">
            <Template type="Swissworx.Modules.MediaTemplateSwapper.SwapperConfiguration, Swissworx.Modules.MediaTemplateSwapper">
              <SourceTemplateId>{AB86861A-6030-46C5-B394-E8F99E8B87DB}</SourceTemplateId>
              <TargetTemplateId></TargetTemplateId>
            </Template>
            <Template type="Swissworx.Modules.MediaTemplateSwapper.SwapperConfiguration, Swissworx.Modules.MediaTemplateSwapper">
              <SourceTemplateId>{DAF085E8-602E-43A6-8299-038FF171349F}</SourceTemplateId>
              <TargetTemplateId></TargetTemplateId>
            </Template>
          </SwapConfigurations>
        </processor>
      </uiUpload>
    </processors>
  </sitecore>

We are patching the media swapper processor after Save pipeline for Sitecore.

The module allows to configure a media root path which comes in handy when you have a multi-site setup and you only want to swap templates for some sites.

The swap configurations are a straight forward mapping definition for the source template that is being swapped with the target template.

From the implementation side of thingsĀ I created a SwapperConfiguration class which allows us to configure the mapping and of course the pipeline processor which takes the UploadArgs.

And here is the processor:

public void Process(UploadArgs args)
{
    Assert.ArgumentNotNull(args, "args");
    using (new SecurityDisabler())
    {
        Item uploadedItem = this.database.GetItem(args.Folder);
        if (uploadedItem?.Paths != null)
        {
            string uploadPath = uploadedItem.Paths.ContentPath;
            if (!uploadPath.StartsWith(this.MediaRootPath, StringComparison.OrdinalIgnoreCase))
            {
                // Item has not been uploaded to the path configured in scope for this processor
                return;
            }

            foreach (Item item in args.UploadedItems)
            {
                // Check whether the processor has a swap config that matches the source template id
                SwapperConfiguration swapConfiguration = this.SwapConfigurations.FirstOrDefault(config => new ID(config.SourceTemplateId) == item.Template.ID);
                if (swapConfiguration != null)
                {
                    TemplateItem targetTemplate = this.database.Templates[swapConfiguration.TargetTemplateId];
                    try
                    {
                        item.ChangeTemplate(targetTemplate);
                    }
                    catch (Exception e)
                    {
                        Log.Error(
                            $"Failed changing source template {swapConfiguration.SourceTemplateId} to target template {swapConfiguration.TargetTemplateId} for item '{item.Name}'.",
                            e,
                            this);
                    }
                }
            }
        }
    }
}

Leave a Reply

Your email address will not be published. Required fields are marked *