DITA 1.2 feature article: conref push
White paper from the OASIS DITA Adoption Committee. Authored by Kristen James Eberlein, Eberlein Consulting. Published 26 October 2009; updated 22 November 2009. Note that the offical version of this document is the PDF file that is located in the document repository for the OASIS DITA Adoption Committee.
Conref push
DITA 1.2 introduces the conref push feature, which enables users to insert or replace content in DITA topics and maps. This is accomplished by the introduction of a new @conaction attribute with four values: pushreplace, pushbefore, pushafter, and mark.
Overview
The conref (content reference) mechanism is a core feature of the Darwin Information Typing Architecture (DITA). An elegant transclusion device, the conref mechanism enables significant reuse of DITA elements, topics, and maps, thus reducing translation costs and increasing consistency.
Until DITA 1.2, the conref mechanism only used a pull feature, that is, you could only pull content into DITA topics and maps. With DITA 1.2, you now have the ability to push content into DITA topics and maps, provided that the topics and maps contain elements with @id attributes that identify the places where the content is to be pushed.
This article contains screen captures of DITA source files (as viewed in <oXygen/> XML Editor 10.0) and output generated by the DITA Open Toolkit, version 1.5, milestone 17. This article does not include examples of pushing content into DITA maps. While that functionality is part of the DITA 1.2 standard, it has not yet been implemented in a milestone build of the DITA Open Toolkit.
Example of pushing content after an element in a topic
Imagine that you are updating a version of the sample files that ship with the DITA Open Toolkit. This information set contains a helpful topic about changing oil in an automobile.
Figure 1. "Changing the oil" topic: HTML Help output
However, the topic fails to address a critical legal issue in your locality: Used motor oil must be properly disposed of. With DITA 1.2, you can push a new <step> element into the "Changing the oil" topic, so that you can generate the following HTML output:
Figure 2. "Changing the oil" topic: HTML Help output after a conref push operation
How was this done? What was required?
The person working with the DITA source files only needed to make the following changes to the information set:
- Ensure that the original "Changing the oil" topic had an @id attribute for the <step> element that contained the instruction to "Drain the old oil." If she had access to that file, she could add an @id attribute; otherwise, she'd need to request that the person who owns the file add the necessary attribute.
- Create the <step> element that contains the content to be pushed into the "Changing the oil" topic.
This content either could be added to an existing conref topic or created in a new topic. A conref topic stores DITA elements that are addressed by the @conref attribute and designed to be used in more than one location. A conref topic also is often called a reuse or resource topic; it must be a valid DITA document. - Modify the DITA map to reference the conref topic, if it does not already include it.
Adding the @id attribute
The writer arranges for an @id attribute to be added to the applicable <step> element in the "Changing the oil" topic. The modified topic now looks as follows; note the @id attribute that is highlighted in yellow:
Figure 3. "Changing the oil" topic with @id attribute added
Creating the content to be pushed
The writer now creates a DITA topic to hold the content to be pushed: conref-file.dita. (She also could use an existing conref topic, if one existed.)
Figure 4. Topic that contains the content to be pushed after
Here is an explanation of the content of the topic.
The first <step> element identifies the <step> element after which the content is to be pushed. This happens in two parts:
- The @conref attribute uses standard syntax to identify the <step> element.
- The @conaction attribute (new with DITA 1.2) is set to "mark". Setting the @conaction attribute to "mark" indicates that a conref push operation is indicated.
Note that the <cmd> element is empty; the content model for the <step> element requires that a <cmd> element be present.
The second <step> element specifies the content that is to be pushed into the "Changing the oil" topic. The <cmd> element contains the content, and the @conaction attribute indicates that the <step> element is to be pushed after the element with a @conaction attribute set to "mark".
Modifying the DITA map
The writer then modifies the DITA map for the deliverable so that it references the conref topic that contains the content to be pushed:
Figure 5. Modified DITA map that references the conref topic
The conref-file.dita topic is referenced in the DITA map by a <topicref> element. Note that the @processing-role attribute (new with DITA 1.2) is set to "resource-only". This attribute indicates that the topic referenced should be used only to resolve conref, keyref, or xref operations; it should not appear in the table of contents (TOC), be found in a search operation, or be linked to.
Note also that the <topicref> element appears at the top of the DITA map and is marked with a comment. This is not necessary – the <topicref> element could be placed anywhere in the DITA map – but reflects best practices and helps to make the DITA map easy for humans to read and scan. If a DITA map contains many <topicref> elements that reference conref or keyref resources, consider building a separate DITA map to contain those references.
Example of pushing content before an element in a topic
The writer also could push the <step> element before the <step> element with the @id attribute. (Let's ignore for the moment that this doesn't make sense, as one would not recycle the used motor oil before draining it from the automobile.) All this would require is a modification to the conref-file.dita topic; the changes that previously were made to the "Changing the oil" and the DITA map would work here, too.
Here is what the conref topic would look like, if the writer wanted to push the new <step> element before the <step> element with the @id attribute:
Figure 6. Topic that contains the content to be pushed before
Note that the <step> element that contains the content to be pushed is placed before the <step> element with the conaction="mark" attribute; it also has a @conaction attribute that is set to "pushbefore".
When the DITA map that references the modified conref-file.dita topic is processed, the following output is generated:
Figure 7. "Changing the oil" topic: HTML Help output after a push before operation
Example of replacing an element in a topic
The writer also could simply choose to replace the <step> element in the "Changing the oil" topic. Here is what the conref topic would contain:
Figure 8. Topic that contains the content to be used as a replacement
Note that for a conref pushreplace operation, only one element is needed. The @conref attribute specifies the element to be replaced, and the @conaction attribute is set to "pushreplace".
Here is a screen shot of the HTML Help that is generated by the DITA Open Toolkit:
Figure 9. "Changing the oil" topic: HTML Help after a push replace operation
Use cases for conref push
Here are some scenarios in which companies use the conref push mechanism.
Adding content to auto-generated DITA topics
A software company generates hundreds of API reference topics every night, using an automated process that builds the topics from the product source code. The company’s technical writer wants to add some additional content to the files, to make them more useful for end readers, but he knows that his edits would be overwritten every evening.
The conref push mechanism provides a solution. The writer drafts the content to be pushed into the API reference topics by referencing persistent @id attributes in the auto-generated topics. Every night the topics are regenerated, and every night the human-authored text is pushed into the topics.
Providing a temporary fix for a documentation issue
A printer manufacturer discovers that Microsoft has changed a configuration setting in Windows; this change invalidates the manufacturer’s instructions for installing a printer driver. They need to issue a patch to the installation topic on their Web site. Since the company will have an updated driver in a matter of days, they do not want to change the source for the installation topic. Using the conref push mechanism, they can create a temporary fix that will be simple to remove once the printer driver is updated.
Reusing topics between documentation teams
A large company uses DITA for their technical documentation. One product, an integrated development environment (IDE), is the basis for another software product. The installation process for the two applications is almost (but not quite) identical; there is one extra window for the second product. The IDE is released before all the development work on the second product is completed. However, since the information developers for the IDE know that another documentation team will reuse their installation topic, they added @id attributes in the necessary places. The technical writers for the second product then use conref push to add the content for the additional installation step.
Modifying third-party documentation
A hardware company provides their customers with a documentation package that includes some third-party documentation. They need to add a warning to the third-party documentation, but for contractual reasons, they do not want to ask the third party to make the change. Since all the documentation is sourced in DITA – and the third-party documentation contains @id attributes in the necessary places, the hardware company can use conref push to add the warning.
Rules and restrictions
All the rules and restrictions are designed to ensure that the result of the push operation is valid DITA. This section uses the following terminology:
The referenced element is the element addressed by the @conref attribute; it is the element that is replaced, preceded, or followed by the content that is pushed.
The referencing element is the element with the @conref attribute.
- In the case of a push and replace operation, the referencing element contains the content that is pushed.
- In the case of a push before or a push after operation, the referencing element specifies the location where content is pushed; a second element contains the content that is pushed.
- A <step> element is the referencing element, and a <step> element is the referenced element. This is what is demonstrated in the examples in this feature article.
- A <step> element is the referencing element, and a <li> element is the referenced element. This is possible because the <step> element is specialized from the <li> element. During processing, the <step> element is generalized back to a <li> element.
However, the referencing element cannot be more generalized than the referenced element. For example, one cannot push a <li> element into a <step> element. The content model for a <li> element permits many children elements (for example, <p> elements) that would not be valid within the <step> element.
- The element that specifies the conaction="mark" attribute must be of the same type as the element that specifies the push operation (either conaction="pushbefore" or conaction="pushafter). Both elements will appear in the output.
- The parent of the referencing element must be of the same type as (or more specialized than) the parent of the referenced element. This ensures the validity of the target; for example, comparing the parent elements will prevent a <title> element that is a child of <section> from being pushed before (or after) a <title> element that is a child of <figure>.
What happens if multiple push operations target the same element?
It is an error for two or more elements to attempt to replace the same referenced element. According to the DITA 1.2 specification: "Applications may, but need not, warn users if more than one element attempts to replace a single target."
If two or more elements attempt to push content before the referenced element, the order in which the pushed content is processed is undefined.
If two or more elements attempt to push content after the same referenced element, the order in which the pushed content is processed is undefined.