Search code examples
sitecoresitecore-media-library

Change Template of Uploaded File in Media Library in Sitecore


I've done some research into this but not sure I understand all the pieces that need to go into the following problem.

My client needs a special template to be used instead of the auto detected media templates in the Media Library if they upload to a certain Folder. The template has special fields. The template can also house different types of files (PDFs, vendor specific formats, executables).

For development purposes we are currently uploading the file and then doing a template switch afterwards but what really needs to happen is that file be uploaded to that template type in the first place. I was wondering if there was a way to hook into the upload process to make sure the special template is used when underneath a certain path in the Media Library? If so, where should I start?


Solution

  • We recently had to do something similar. Along the same line as techphoria414, I'd tap into the upload save pipeline. Then, to make it a bit more generic and reusable, use the power of Sitecore's configuration parsing to hook everything up to your handler. Here's what we ended up with.

    Main class with required "Process" method:

    public class ChangeTemplate
    {
        public string Name { get; set; }
        public string Path { get; set; }
        public List<ChangedMediaTemplate> Templates { get; set; }
    
        public ChangeTemplate()
        {
            Templates = new List<ChangedMediaTemplate>();
        }
    
        public void Process(UploadArgs args)
        {
            var db = Sitecore.Context.ContentDatabase;
    
            var uploadPath = db.GetItem(args.Folder).Paths.ContentPath;
            if (!uploadPath.StartsWith(Path))
            {
                // Not uploading to designated folder
                return;
            }
    
            foreach (var item in args.UploadedItems)
            {
                // Need to change template for this item?
                var changedTemplate = Templates.Where(t => t.Old.Equals(item.Template.FullName)).FirstOrDefault();
                if (changedTemplate != null)
                {
                    var newTemplate = db.Templates[changedTemplate.New];
                    try
                    {
                        item.ChangeTemplate(newTemplate);
                    }
                    catch (Exception e)
                    {
                        Log.Error("Unable to change {0} template on upload of {1} to {2}.".FormatWith(Name, item.Name, uploadPath), e, this);
                    }
                }
            }
        }
    }
    

    Minor supporting class:

    public class ChangedMediaTemplate
    {
        public string Old { get; set; }
        public string New { get; set; }
    }
    

    And then the config:

    <processors>
        <uiUpload>
          <processor patch:after="*[@type='Sitecore.Pipelines.Upload.Save, Sitecore.Kernel']" mode="on" type="Foo.Project.SitecoreX.Pipelines.Upload.ChangeTemplate, Foo.Project.Classes">
            <Name>Product Images</Name>
            <Path>/sitecore/media library/Images/Foo/products</Path>
            <Templates hint="list">
              <Template type="Foo.Project.SitecoreX.Pipelines.Upload.ChangedMediaTemplate, Foo.Project.Classes">
                <Old>System/Media/Unversioned/Image</Old>
                <New>User Defined/Foo/Product/Image/Unversioned/Product Image</New>
              </Template>
              <Template type="Foo.Project.SitecoreX.Pipelines.Upload.ChangedMediaTemplate, Foo.Project.Classes">
                <Old>System/Media/Unversioned/Jpeg</Old>
                <New>User Defined/Foo/Product/Image/Unversioned/Product Jpeg</New>
              </Template>
              <Template type="Foo.Project.SitecoreX.Pipelines.Upload.ChangedMediaTemplate, Foo.Project.Classes">
                <Old>System/Media/Versioned/Image</Old>
                <New>User Defined/Foo/Product/Image/Versioned/Product Image</New>
              </Template>
              <Template type="Foo.Project.SitecoreX.Pipelines.Upload.ChangedMediaTemplate, Foo.Project.Classes">
                <Old>System/Media/Versioned/Jpeg</Old>
                <New>User Defined/Foo/Product/Image/Versioned/Product Jpeg</New>
              </Template>
            </Templates>
          </processor>
        </uiUpload>
    </processors>
    

    Modifying or adding new template rules becomes as simple as editing the config as needed.

    Hope this helps!