In my previous article about ECL, I’ve discussed the possibilities of using product information in your CMS. This sort of a setup cries out for Dynamic Component Presentations and Broker queries, which isn’t a problem, unless you want to query the ECL Metadata in the Broker.
Depending on your templates (or entire implementation), you might have the ECL Metadata in the Broker in a usable format, for example when using DD4T you could simply add all ECL Metadata at publishing time to the XML of your Component, which would make it directly available on your website. But this doesn’t allow you to query it through the Broker. So it would be impossible to sort all your items on ECL Metadata or find an item by a SKU field which is part of the ECL Metadata for example.
Basically there is a single (and relatively simple) solution to this challenge, you add the ECL Metadata as part of the Multimedia (stub) Component Metadata at publishing time (since all Metadata is queryable by the Broker). Now while this indeed sounds simple, to implement it you have a choice of two options which some might consider bad practice. Your first option is to simply make sure the ECL Metadata fields are also available as Metadata fields in the stub Schema. The second option requires you write a Deployer or Storage extension and add the ECL Metadata into the (stub) Component Metadata right before it is being stored in the Broker. The first option requires you to have a Template update the Component while it is being Published, so a Template which performs a write action. While this is supported, it is not recommended (more about that later). The second option is possibly even more evil, you are not storing it in the CMS, but only in the Broker, but by doing this, you basically invalidate the Component against its Schema (in the Broker).
I’ll focus this article on the first option, as it is rather easy to implement. Considering both options have their own “evil” twist, you might as well go for the simple solution, right?
For starters you have to choose which ECL Metadata fields you want queryable, and then for every one of those fields, you need to add a Metadata fields to the ECL stub Schema. These fields will be non-mandatory and only be filled when the (ECL) Component is published. To accomplish this we need to write a Template Building Block which we can add in the (Dynamic) Component Template. As an example (and proof of concept) I’ve written a TBB which adds the SKU field of my ECL Metadata, so that I can after this query the broker on the SKU field. Adding more fields will be as simple as updating the code of this TBB (and updating the ECL stub Schema accordingly). The entire code of this TBB can be found on GitHub Gist.
Let me discuss a few of the concepts in detail. First of all, you need to enable write operations in your Templates for this to work, this means editing the
Tridion.ContentManager.config file, and adding an attribute
allowWriteOperationsInTemplates, set to
true, to the element called
tridion.contentmanager.security. More details about this can be found in the documentation (requires login).
That is the really evil part of this solution, to make its impact as minimal as possible, the ECL Metadata is only synced (written) when needed (meaning when the value in the Component differs from the value read from the external system). This is done in the
Transform method by checking if the field is
null or if its value is different compared to the ECL value. The
UpdateComponentMetadataField is called to actually update the Metadata XML of the Component and save it in there. It first makes sure it is dealing with the parent item (to handle Blue Printed scenarios) and then checks out the item, adds/updates the field and saves the changes (checking the Component in again). The TBB also adds/updates the ECL Metadata to the item in the Package, so that any additional TBBs have the change right at hand. But to make it available in the Broker, the actual Component has to be updated (read saved).
On a side note, this example TBB is written to just make a single ECL Metadata field available in the Broker, when more fields should be made available it can definitely benefit from some refactoring.