Conditional content in DITA
This post provides an overview of techniques you can use to handle conditional content in DITA. The need for complex conditions is a common reason organizations choose DITA as their content model. As conditional requirements get more complex, the basic Show/Hide functionality offered in many desktop publishing tools is no longer sufficient.
Conditional processing is especially interesting–or maybe problematic—when you combine it with reuse requirements. You identify a piece of content that could be reused except for one small bit that needs to be different in the two reuse scenarios.
The first step in establishing a strategy for conditional content is to clarify your requirements and ensure that you understand what you are trying to accomplish.
Classes of text variants
DITA offers two basic types of variants:
- Variables (implemented through DITA keys): a short snippet, like a product name, that often changes.
- Conditional information: an element or group of elements that needs to be included or excluded selectively. Conditional information can occur at the topic, block, or inline level. Graphics and tables can also be conditionalized.
In DITA, your conditional assignments need to correspond to an element. In unstructured desktop publishing tools, it’s possible to assign conditions to an arbitrary chunk of content. This is not the case in DITA because you need to attach the conditional labeling to an element. (In theory, it’s possible to use processing instructions to mimic the arbitrary labeling, but just…don’t.)
Here’s what a simple variable looks like. First, you define the variable as a key (in this case, clientname) in the map file.
<title>DITA Topic Map</title>
<keyword>My First Client</keyword>
Inside the topics, you reference the key:
<p>When we deliver this information to <keyword keyref=“clientname”/>…
You use a placeholder for the keyword in your text, and you use the map file to define the value of the placeholder. Therefore, you can use a single topic with a keyref along with multiple map files. The result will be different output for the key reference for each of the maps. (DITA 1.3 adds scoped keys, which allow you to change the key’s value inside a single map file.)
In DITA, you use attributes to identify conditional content:
<p>This paragraph is for everyone.</p>
<p audience=“advanced”>This paragraph is only for advanced users.</p>
It’s possible to do conditional content at the phrase level<ph platform=“badidea”>, but it’s a really terrible idea</ph>.
If you have more complex combinations, you use more than one attribute:
product=“X”>content goes here</p>
product=“X Y Z”>other content here</p>
Do not use conditions below the sentence—preferably paragraph—level.
Why not, you ask?
<p>The colo<ph xml:lang=“en-uk”>u</ph>r of money is a very speciali<ph xml:lang=“en-uk”>s</ph><ph xml:lang=“en-uk”>z</ph>ed topic.</p>
- Your translator will hate it.
- You will go insane.
Specifying conditional output
Once you have assigned your attribute values, you use a ditaval file to specify what to include and exclude when you generate output through the DITA Open Toolkit. Here is a simple example:
<prop action=“include” att=“audience” val=“expert”/>
<prop action=“include” att=“product” val=“X”/>
Markup is the small(er) challenge
You assign attributes to an element to make it conditional. You can assign conditions, therefore, to anything that has an element, all the way down to phrases, words, or even letters (but again, don’t go below sentences). DITA gives you three attributes out of the box (audience, product, platform) for conditional processing. If you need more or different attributes, you’ll need to specialize.
Establishing a reasonable taxonomy and information architecture presents a much more difficult challenge that the actual assignment of conditional markup. You have to figure out which attributes to create, what values they should have available, and how you might combine the attributes to generate the variants you need.
Consider the case of information that is applicable only to a specific region, like California:
<p> This product contains chemicals known to the State of California to cause cancer and birth defects or other reproductive harm.</p>
This works, provided that your regions are limited to the fifty U.S. states. If you needed to flag information for Canada, that “ca” designator would suddenly become problematic. Perhaps you’d try specifying the country in addition to the state:
<warning audience=“usa-ca”>…California content… </warning>
<warning audience=“ca”>…Canada content…</warning>
As long as you planned for California and Canada, everything will be OK. The problem occurs when you start with a list of states and an assumption that you’ll never need non-US regions, and then suddenly you do.
Conditions and reuse
The combination of conditional variants and reuse is especially problematic. One interesting solution is to use a conref push. A conref push allows you to insert (or “push”) information into a topic.
We use this technique in some of our software assessments. We have a general overview of a particular piece of software with information our clients need, like cost, licensing terms, supported platforms, and so on. But we also need to include our overall recommendation for or against that software. This final bit of information is different for each customer.
To accommodate this, we set up the location where the information is needed with an ID. In our case, this is the last paragraph in the assessment of XYZ tool:
<p id=“xyz”>We recommend XYZ if ABC is a critical requirement.</p>
We then create another topic, referenced in the parent map file as a resource, that provides the information to be inserted:
<p conref=“file.dita#id/xyz” conaction=“mark”/>
<p conaction=“pushafter”>Using XYZ would eliminate the manual formatting that currently takes up so much production time at ClientA.</p>
For another client, we have a different map file and a different piece of content to be inserted:
<p conref=“file.dita#id/xyz” conaction=“mark”/>
<p conaction=“pushafter”>XYZ does not support right-to-left languages (such as Arabic), which ClientB needs.
What are your experiences with DITA conditional content?