Why Tcm Id is appended in SDL Tridion images

SDL Tridion/Web provides media management within the Tridion GUI by having Multimedia Schema for various Multimedia Types, which allow you to create media component and upload your images/videos etc.

You store your media files in Tridion GUI as multimedia components.  Tridion stores these media files in a database/filesystem (mostly all Binaries are published in the same location by default). The path where it saves your files can be set in your Publication Properties. /Images has been the default location so far, but you can set it as anything.

These images appear on your page to the end users, when a multimedia component is created and linked to a component which is then published with a page. This blog aims to highlight certain facts on the process of a media item through this journey.

You would have noticed (and you knwo if you are working with Tridion) all the media urls that you see in front end might have the appended text – “sports-town_tcm4-123“. Here _tcm4-123 is appended with the image name, which is tcm uri of your multimedia component in Tridion system.

What community experts says:

The reason why the file names (and URLs) of Binaries are suffixed with a TCM URI (or actually something that resembles a TCM URI) is to ensure that the file name (and URL) is sufficiently unique to distinguish it from other Binaries. The first part of the file name is taken from the (original) file name of the Binary Content of the Multimedia Component. However, the system does not enforce that those (original) file names are unique. Since (by default) all Binaries are published in the same location, only the (original) file name may not be sufficiently unique. – Rick Pannekoek

So now, It’s clear that this behavior avoids duplicacy of binaries and is default nature. It also appends width & height in some case (Ex: ballon-burner_tcm5-258_w1024_h311_n.jpg).

To have more clarity let’s have little bit of background on this

Your Templates contains a Default Finish Action Template, which contains a TBB called – Publish binaries for component It uses a PublishBinariesComponent, which calls ConstructFileName of BinaryPublisher.

private static string ConstructFileName(Component mmComp, string variantId)
    {
        Regex re = new Regex(@"^(.*)\.([^\.]+)$");
        string fileName = mmComp.BinaryContent.Filename;
        if (!String.IsNullOrEmpty(fileName))
        {
            fileName = Path.GetFileName(fileName);
        }
        return re.Replace(fileName, string.Format("$1_{0}_{1}.$2", mmComp.Id.ToString().Replace(":", ""), variantId.Replace(":", "")));
    }

This method returns the binary file name at Rendering –engine.PublishingContext.RenderedItem.AddBinary(). One of the overload method AddBinary(Stream, String, String, Component, String) also give liberty to set filename of your choice but this is limited i believe.

Look at the code below: If you see the else part – ConstructFileName(mmComp, currentTemplate.Id) is called when targetStructureGroupUri is not null, this value comes from your parameter schema of Publish binaries for component TBB.

    if (targetStructureGroupUri == null)
    {   
    ....
    Binary binary = engine.PublishingContext.RenderedItem.AddBinary(mmComp);
    publishedPath = binary.Url;
    log.Debug(string.Format("binary is published to url {0}", publishedPath));
    }
    else
    {
    Component mmComp = (Component)engine.GetObject(item.Properties[Item.ItemPropertyTcmUri]);
    string fileName = ConstructFileName(mmComp, currentTemplate.Id);
    StructureGroup targetSG = (StructureGroup)engine.GetObject(targetStructureGroupUri);
    itemStream = item.GetAsStream();
    ....
    log.Debug(string.Format("publishing mm component {0} to structure group {1} with variant id {2} and filename {3}", mmComp.Id, targetStructureGroupUri.ToString(), currentTemplate.Id, fileName));
    Binary b = engine.PublishingContext.RenderedItem.AddBinary(item.GetAsStream(), fileName, targetSG, currentTemplate.Id, mmComp, mmComp.BinaryContent.MultimediaType.MimeType);
    publishedPath = b.Url;    
    log.Debug(string.Format("binary is published to url {0}", publishedPath));
    }

 

I believe now it is clear that what is happening in background when an image is published. Now if you have certain requirement, you still can leverage Tridion flexibility to have the image name appears as you like. (not recommended)

I see two possibilities to do that:

  1. Write an Storage Extension, which probably is the best way forward
  2. Write a your custom DefaultFinishAction with a TBB  which does this for you.

I will cover “Storage Extension” in upcoming blogs in details, which is a topic in itself. Here i will focus on highlighting a high level overview of how this can be done using custom TBB.

Write a TBB (Create your custom default finish action Template) and add it.. right after Publish Binary for Component TBB to process received Output from Publish binaries for componentTBB.

The output should have publishedPath which is what you would need to get to your desired url.

Your Publish binaries for component parameter schema has all the values i guess which is used in the final binary url. Specially sg_PublishBinariesTargetStructureGroup value in your case.

Did you expect code here, I don’t think so!!

Happy coding.. 🙂

If you still need help, Please post your question on Tridion Stack Exchange (Trex)

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s