Eval Criteria # 11
Can attribute values repeat?
Occasionally, an attribute might have more than one value. In a prior chapter, for example, I mentioned storing the names of my children:
These are three distinct strings of text. If you had a single attribute called “Children,” how would you store these?
You could simply put them in a simple text attribute, separated by some sort of marker (technically called a delimiter), like this:
- Alec, Gabrielle, Isabella
We discussed this in the chapter on content storage as something called “serialization.” In that instance the system was serializing a complex value into a simple one. In this instance, the human editor is doing the serialization. This the three separate values that a human is manually serializing into one.
This has limitations. If you wanted to work with the names separately, you’d have to retrieve this information, break up the text string on the commas and remove the whitespace. And, of course, you’d have to know in advance the delimiter was a comma, and all the editors would need to agree on this. If someone went rogue and did this –
- Alec | Gabrielle | Isabella
– then we’d have an invalid value. (Actually, we’d technically still have a valid value – since there are no commas, it would deserialize as a single “name” of “Alec | Gabrielle | Isabella”.)
You could, of course create three different attributes:
- Child 1
- Child 2
- Child 3
But this assumes you’re always going to have three children. What if you have four? What if you have 12?
Repeating Attribute Values
To improve the editorial experience and the resiliency of our model, you need to establish that each child has a name which is a distinct string of text, and this string can repeat a number of times.
This is a repeating attribute value or a multi-valued attribute. Note the usage of “value” in those terms. It’s not the attribute that’s repeating. You still have a single attribute, it just has multiple values.
A repeating list of dates in Episerver. The “+” sign at the bottom allows you to add a new value. The drag handles to the left of each value allow you to re-order the values. The dropdown menu on the right of each value allow you to delete the value.
What you’re modeling here is a “one to many” relationship, which is quite common in traditional relational database modeling. In our case we have one logical entity, related to many other logical entities. (Note that we’re talking about simple text strings in our example, but we could just as easily be talking about a referential attribute which points to other content objects.)
Not every system supports repeating attribute values, as they deeply complicate the underlying data model. Every CMS is supported by some data storage system, which is usually a relational database. Repeating properties can be a very hard thing to retrofit onto an existing system, so they’re something that usually has to be planned and implemented very early in a system’s development, not added at a later date.
The Universality of Repeating Values
Ideally, repeating attribute values are universal property of attributes, and available for any attribute type. For instance, consider our custom color picker from the last chapter. What if we wanted to specify a variable list of available colors for each product in our catalog – some might only have one, and others might have dozens.
Umbraco allows repetition of entire embedded content types.
Less helpful are specific repeating types, such as an attribute type for “List of Text.” Clearly, there are some situations where that works, such as in our example above. But we wanted to store a list of anything other than text, we need to enter and store it as text, which might work (technically, anything can be stored as a sequence of characters), but it couldn’t be validated or sorted as its logical data.
It’s helpful if the system offers specific validation around the characteristics of the repetition. These rules simply dictate the number of values allowed – do we have to have at least one? Is there a maximum number of values, or are they unlimited? Does each value have to be unique?
In addition to validation around the repetition, normally validation over any one single value should still apply. If a value is required or needs to conform to a regex pattern, that rule should still execute on each value in our list.
A further step up in functionality is if you can repeat sets of attributes. For example, what if you wanted to store the child’s date-of-birth, rather than just their name? You now have two distinct attributes for each child:
- Name (text string)
- Date of Birth (date)
You now need to repeat both of those, grouped together. You could just have two repeating attributes, and know that the first Name value matches the first Date of Birth value, but that’s brittle – what if we somehow get three Name values but only two Date of Birth values?
What you need to do is have each value consist of two distinct attribute values – Name and Date of Birth – as a set.
The Drupal module Field Collection allows for sets of attributes (which are called “Fields” in Drupal) to be grouped into repeating sets. (credit)
Ordering and Ordinal Manipulation
Finally, the ordering of values often matters. Referring back to the children example – the order that the children appears in the list might matter, as it might represent their relative dates of arrival. So, Alec needs to be appear before Gabrielle (he is, in fact, seven years older than she is).
I don’t think you’ll find a system that ignores order in repeating attribute values. Editorial interface support is helpful here, primarily in the form of drag-and-drop re-ordering. If you made a mistake and entered information out of order, it’s helpful to be able to simply drag it into the correct order, rather than re-entering data.
Similarly, if you need to remove a value from the middle of a list, it’s helpful to be able to simply delete that value, rather than having to move everything below it “up” one step (and potentially leave a blank value at the bottom).
Also helpful would be automatic ordering of values – alphabetically or numerically, for instance. This might be complicated by complex attribute types – how would you order a list of Article objects, or a list of referential attributes, for instance? What if not every object or reference in the list is the same type, so they all have different attributes? More commonly, repeating attributes are retrieved and placed into order in typed object or templating code.
The capability for repeating attribute values is not as common as it should be, given its utility. If it exists, it’s often in a limited form (example: “List of Text”). The lack of this feature often results in awkward workarounds.
- Can attribute values repeat?
- Can any attribute type allow repeating values, or is this restricted to specific repeatable attributes (i.e. – “List of Text”)?
- Can validation be specified around the nature of the repetition? Can minimums and maximums be specified?
- How is required validation handled for a repeating attribute? Does a single value satisfy the required validation?
- Can sets of attributes be repeated together, as a single unit?
- Can repeating attribute values be ordered? How is this ordering presented and managed in the editorial interface? Can values be removed from the middle of the list of values?
- Can derived ordering rules be specified on attribute values?