Eval Criteria # 14
Can content objects inherit from other content objects?
We’ve discussed the idea of content type inheritance, where we base one type on another. The inheriting type gets all the attributes of the inherited type, then adds some more of its own.
Sometimes, its helpful to have content object inheritance, where a object can inherit from another fully populated object, and maintain a reference back to it. Instead of the configuration of attributes, what’s being inherited are the actual attribute values.
In this model, attribute values for the derived object can override attribute values for the base object. Put another way, when values aren’t provided for the derived object, the base values will “bubble up.”
Imagine a base content object with its attribute labels and values printed on a piece of paper. Lay that piece of paper on a flat surface, then print another content object out in the same format. For values you want to inherit from the base object, simply cut them out of the second paper, leaving holes where they were. Lay the second object on top of the first, and some values from the base object will show through the holes, while others will be covered up.
Effectively, the base object provides default attribute values which can change in real-time. The derived object – which is sometimes called a variation – overrides those values when desired.
Channel-Specific Derived Objects
This can be helpful for channel-specific renditioning.
For example, if you want to publish your Article objects into a mobile app, you might want to change some attribute values to accommodate a smaller viewing area. You could create another Article object which overlays on our base article and becomes a variation for mobile. It might only supply an alternate value for Title, which hides the base title. All other attribute values should source from the base object.
This might seem similar to supplying a default value for an attribute, with one important difference – with variations, the link is active, and the defaults are provided when the object is retrieved from the repository. If values change on the base object at any time, the inherited values will changes on the derived object.
Back to our example from above – the Subtitle attribute value would source from the base object, since no value was provided in the variation. We can change this base subtitle – even years later – and that change will be reflected in real-time in the variation. Conversely, a default value would be populated when the derived object was created, and would then become just like any other attribute value on the object, never having any link back to the base object.
Localization and Personalization
Localization and personalization can also be achieved by use of derived object.
For the former, a content object can exist in a default language, and derived variations of that object for each language could be “overlaid” on top of it. The derived object might supply new values for some attributes which need to be translated – like the Title. Other attributes are universal to all languages – Image Alignment, for example – so the values from the base object are used.
In practice, localization is such a core feature of any CMS that there are specific subsystems built for it, but it illustrates the value that object inheritance provides: some objects are just mildly altered versions of other objects, customized slightly for a specific use case.
This is doubly true with personalization. We might have a Case Study object explaining how our new high-efficiency furnace cuts heating costs. Normally, the Image accompanying the text is of a single-family home. However, if we detect the user is visiting from mid-town Manhattan, we want to swap that image out for one of a brownstone.
In this case, we might create a derived variation of our case study where the only new attribute value supplied was the Image. Every other attribute value is the same.
Voiding Values in Derived Objects
Object inheritance gets logically difficult when trying to “void” an attribute value on the base object. The base object provides a Subtitle and you don’t want one for your derived object, how do you specify that? Not specifying a value for Subtitle would naturally be interpreted as wanting the base value to bubble up. How do you provide a value which is... no value?
By the same token, object inheritance clearly provides some challenges around validation, particularly with required values. It’s quite common for Title to be required, so any system offering this as a feature would need to provide options for circumventing validation when an object is inherited from a base.
Hacking Object Inheritance
If object inheritance is not offered by a system, it can often be hacked in at the API or template level in the specific cases when it’s needed. You might see a “base object” loaded alongside the desired object, and code executed to fill missing attributes from the base object.
At the template level, something as simple as an
if...then construct could display data from a “base” object when the operative object didn’t provide a value.
However, as noted in the prior section, validation gets complicated. If your system is ignorant of object inheritance, then it will blindly enforce all validation rules on your derived object, which makes overriding just one or two attributes very difficult.
Object inheritance is not particularly common, but can be very helpful in (1) highly granulated scenarios, where content is deeply customized for specific delivery requirements, or (2) high-volume scenarios, where large amounts of similar content need a set of default values that can be updated in real-time.
- Can objects inherit values from a base object?
- Is it possible to void/nullify an attribute value on the derived object when that value is provided by the base object?
- How is validation affected or circumvented in the derived object?
- Is the reference to the base object subject to dependency management or referential integrity checks?
This is item #21 in a sequence of 34 items.
You can use your left/right arrow keys or swipe left/right to navigate