Upload Sitecore media items in selected languages

One day, one idea came in my mind to create media items in specific languages only, which is very useful thought. By default, Sitecore media item gets created in many languages, where we need actually one or two out of them. Want to know why? Then read why sitecore media item gets created in multiple languages.

Specific languages for Unversioned Media Item

How it's benefitial?
In Unversioned media item, item gets created in all languages exist under /sitecore/system/languages/. Creating its version in selected languages is benefitial:
  1. Less insert queries to DB tables, less records fetched while fetching media item details.
  2. DataCache and ItemCache will be created in selected languages only instead of all languages.
  3. Reduced Database size, where millions of media are stored.
  4. So, overall performance improvement while uploading media item and while using/fetching media item.
How to achieve it?
  1. Create your custom class inherited from the Sitecore.Resources.Media.MediaCreator one, say SitecoreTactics.Resources.Media.MediaCreator. In this class you should override CreateItem method to retrieve there the set of the languages from the web.config setting. This set should be used as the languageArray in the foreach cycle. Thus the unversioned mediaitem with certain language versions will be created.

    See how it looks:
    namespace SitecoreTactics.Resources.Media
    {
     using System.Reflection;
     public class MediaCreator : Sitecore.Resources.Media.MediaCreator
     {
      protected override Item CreateItem(string itemPath, string filePath, MediaCreatorOptions options)
      {
       // Override the CreateItem function method and write custom code to create selected language versions
      }
      }
    }
    
    
  2. Create your custom class inherited from Sitecore.Resources.Media.MediaProvider one. In the constructor of this class you should assign an instance of our custom MediaCreator class (from Step#1) to the MediaProvider "creator" private field using the Reflection. So, the MediaProvider will use our own code of MediaCreator.

    How the code looks:
     namespace SitecoreTactics.Resources.Media
     {
      using System.Reflection;
      public class MediaProvider : Sitecore.Resources.Media.MediaProvider
      {
       public MediaProvider() : base()
       {
        typeof(Sitecore.Resources.Media.MediaProvider).GetField("creator", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(this, new SitecoreTactics.Resources.Media.MediaCreator());
       }
      }
     }
    
    
  3. Change in config, register our custom mediaprovider class as below:
    <mediaLibrary>
        ...
        <mediaProvider type="SitecoreTactics.Resources.Media.CustomMediaProvider,SitecoreTactics.Resources" />
        ...
    </mediaLibrary>
    
    

Wow, it worked well!

Specific languages for Versioned Media Item

Versioned Media Item does not need an automated way to upload media in selected languages. The reason is, this kind of media does not share Media File. So, it is used only when we need to upload different files for different languages of same media item. If still someone need to achieve it, here is the way:
  1. Add a settings in the web.config file containing set of the pipe separated needed languages. For example:
    <setting name="SetOfLanguages" value="en|ru-RU|en-GB" />
    
  2. Add an extra checkbox "Versionable For Certain Languages" on the Media Folder Upload Form using this file: \Website\sitecore\shell\Applications\Media\MediaFolder\MediaFolder.xml
  3. Create a custom class inherited from Sitecore.Pipelines.Upload.UploadArgs and add here an extra "SpecialVersioned" property. This property will indicate to Sitecore.Pipelines.Upload.Save processor to execute the custom actions.
  4. Create a custom class based on Sitecore.Shell.Applications.FlashUpload.Advanced.UploadTarget one and define it in \Website\sitecore\shell\Applications\FlashUpload\Advanced\UploadTarget.aspx file instead of the default one.
  5. In this class you should assign a value to your custom UploadArgs.SpecialVersioned property similar to the UploadArgs.Versioned one.
  6. Create your custom class based on the Sitecore.Pipelines.Upload.Save one and register it in the web.config <uiUpload> pipeline instead of the default one.
  7. An example of its rewritten Process method is here: Expand Code
It's working great, isn't it?
And yes, many thanks to Yuriy Zakharov from Sitecore Support to provide such a nice solution!!

Comments