# Case study: NuFirewall documentation

## Overview

NuFirewall's documentation, praised by the press as a notable strength of the product, was developed using [DITA XML](https://docs.redaction-technique.org/en/formats/).

By adopting a format that maximizes information reuse, I was able to focus more on the content itself.

The practices that made this reuse work, at a glance:

- **[Centralize conrefs in a single file](#centralize-conrefs-in-a-single-file).** One dedicated DITA XML file for all conref sources is easier to search than content spread across files.
- **[Use the lowest-level XML node](#use-the-lowest-level-xml-node).** Place the conref on the smallest XML structure that contains the shared information.
- **[Consider translation constraints](#consider-translation-constraints).** Reuse complete sentences, or terms not intended for translation, never sentence fragments.
- **[Limit conref nesting](#limit-conref-nesting).** One conref within another is manageable; deeper nesting becomes cumbersome.
- **[Maximize conref use to reduce costs](#maximize-conref-use-to-reduce-costs).** Write only the unique titles and pull in everything else, especially in *task* sections.
- **[Protect confidential information](#protect-confidential-information).** Keep confidential content in a separate file that translators never receive.
- **[Provide targeted information with Ditaval conditional text](#provide-targeted-information-with-ditaval-conditional-text).** Include or exclude marked blocks at compile time instead of keeping separate files for minor variations.

## Reusing information blocks with conrefs

When a technical writer needs to reuse specific DITA XML information blocks smaller than a section, they should be shared within *dita* content files instead of *ditamap* table of contents structures, using the conref mechanism.

The *conref* principle is straightforward: when a *conref* is specified at a particular XML node, the content of the target node is replaced by the content of the source node.

> **Diagram: Sharing information blocks between ditamaps**
>
> Diagram showing ditamap A referencing 1.dita and 2.dita, and ditamap B referencing 2.dita and 3.dita, with 2.dita shared between both maps.

**Sharing of broad granularity information blocks between ditamaps**

A key difference between the *conref* mechanism and the XML xinclude mechanism is that the source node must comply with the XSD schema of both the source and target files. This formal rigor, while sometimes less flexible, enhances *conref* readability compared to *xinclude*, thereby encouraging its use.

> **Diagram: Sharing fine-grained information blocks with conref**
>
> Diagram showing shared.dita as the conref source, referenced by dita-1.dita and dita-2.dita as conref targets.

**Sharing of fine-grain information blocks between DITA XML sections**

### Centralize conrefs in a single file

> **Note**
>
> To promote and simplify conref usage within a team of technical writers, centralizing all conref in a single dedicated DITA XML file is highly effective.

While initially easier to reuse content by referencing existing DITA XML files without extracting them, one core content reuse principle is decontextualization. Extracting and placing reused content into a dedicated conref source file ultimately proves more efficient. It's easier to locate source elements in one repository than searching across numerous files.

> **Diagram: Decentralized conref management**
>
> Diagram showing three DITA files referencing each other in a circular pattern, with no central source file.

**Managing conrefs in a decentralized way is inefficient.**

Conrefs are resolved at compile time even if source files are not referenced in the ditamap file generating the deliverable. Thus, conref sources can reside in higher-level directories than the ditamap.

> **Diagram: Good conref management**
>
> Diagram showing shared.dita as the conref source, referenced by dita-1.dita and dita-2.dita as conref targets.

**Good conref management**

Content files in ditamap structures contain only target conref values, while a central file consolidates all source conref values, potentially with internal references to certain target values.

This central file should be of the same type (task, concept, reference, etc.) as the content files or at least composite, accommodating all types of DITA XML structures. I find it efficient, for organizational purposes, to create a central file for each DITA XML topic type to share type-specific information, reserving the composite type for a general-purpose file with cross-topic-type shared information.

Ensure each source conref in a file has a unique ID, using explicit human-readable names to maintain clarity in dita files with target conrefs.

### Use the lowest-level XML node

The technical writer should use the lowest-level DITA XML node containing the information to be shared as the conref source.

Given *conref*'s design for managing small information blocks, using the smallest XML structure encapsulating the information is logical, even if compatibility with the DITA XML section's XSD schema necessitates inclusion in larger structures.

> **Diagram: Conref on the lowest-level XML node**
>
> Diagram showing a conref placed on a low-level cmd node, referencing another cmd node.

**Placement on the lowest-level XML node.**

For instance, to reuse "Click OK," ensure your source *conref* file is structured as:

```xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE task PUBLIC "-//OASIS//DTD DITA 1.2 Task//EN"
"/usr/share/dita-ot/dtd/technicalContent/dtd/task.dtd">
<task id="shared" xml:lang="en-us">
  <title>Conref source</title>
  <taskbody>
    <steps>
      <step>
        <cmd>
          Click OK.
        </cmd>
      </step>
    </steps>
  </taskbody>
</task>
```

Assign an ID to the XML structure for reuse. It’s optimal to use:

```xml
<step>
  <cmd id="click-ok">
    Click OK.
  </cmd>
</step>
```

instead of:

```xml
<step id="click-ok">
  <cmd>
    Click OK.
  </cmd>
</step>
```

In the first method, *conref* usage is possible even if the top node (`<step>`) includes nodes beyond `<step>`, such as `<info>`.

> **Diagram: Conref on the highest-level XML node**
>
> Diagram showing a conref placed on a high-level step node, referencing another step node and replacing all of its content.

**Placement on top-level XML node.**

In the second scenario, the entire `<step>` node content is replaced by the source *conref*. Thus, the following code will omit node content in deliverables:

```xml
<step id="click-ok">
  <cmd/>
  <info>
    If you can't read, it's the green button.
  </info>
</step>
```

### Consider translation constraints

The smallest DITA XML information unit is the `<ph>` node. However, technical writers should apply the conref mechanism only for complete sentences or terms not intended for translation (e.g., company or product names). Otherwise, significant issues arise during [language translation](https://docs.redaction-technique.org/en/tech-writing-process/translation/).

> **Diagram: Sentence structure varies by language**
>
> Diagram showing the same conref segments assembled in a different order for two languages, illustrating why segment-level conref does not translate cleanly.

**Sentence structure varies by language.**

**Example**

If you set conref granularity at the segment level and define:

```xml
<ph id="click">Click the</ph>

<ph id="blue">blue</ph>

<ph id="arrow">arrow</ph>
```

You can then use:

```xml
<p>
  <ph conref="shared.dita/click"/>
  <ph conref="shared.dita/blue"/>
  <ph conref="shared.dita/arrow"/>.
</p>
```

to generate "Click the blue arrow."

To create a French version, you translate each segment in place:

```xml
<ph id="click">Cliquez sur la</ph>

<ph id="blue">bleue</ph>

<ph id="arrow">flèche</ph>
```

But the assembly order is fixed (click, blue, arrow), so it now yields "Cliquez sur la bleue flèche" — incorrect French, because the adjective *bleue* belongs after the noun *flèche*. The correct sentence, "Cliquez sur la flèche bleue," would need the segments assembled in a different order for this language.

Rearranging conref order per target language is impractical, so in the worst cases the only remedy is to drop segment-level conrefs entirely in the target language — a pitfall I’ve managed to avoid.

### Limit conref nesting

To facilitate DITA XML content maintenance and updates, technical writers should minimize excessive conref nesting. A single level (one conref within another) is generally manageable.

In the example below, source *conref* *see-admin-guide* includes target *conref* *admin-guide-title*:

**Example**

```xml
<p id="see-admin-guide">
  For further information, see the <ph
  conref="shared.dita/admin-guide-title"/>.
</p>
```

This level of complexity is navigable. But if *admin-guide-title* contains yet another target *conref*, the DITA XML becomes cumbersome (and you risk circular references). In theory the possible combinations are endless; in practice the problems multiply just as fast.

> **Diagram: Multi-level conref nesting is risky**
>
> Diagram showing three levels of conref nesting, one conref pointing to a conref pointing to another conref.

**Multi-level conref nesting: risky!**

Summary:

- Multiple source *conref* nesting is viable but impacts file readability.
- Source and target *conref* nesting is often unmanageable.
- Target *conref* cannot nest; top-level *conref* overrules lower-level values.

### Maximize conref use to reduce costs

> **Tip**
>
> Leveraging conref enables DITA XML technical writers to significantly cut costs and publishing times, especially in multilingual contexts — an important consideration when [choosing formats and tools](https://docs.redaction-technique.org/en/costs/formats-and-tools/).

*Task* sections, due to their nature, often see higher content reuse than *concept* or *reference* sections.

> **Diagram: Conrefs modularize small information blocks**

**Conrefs modularize small information blocks.**

A common pattern is to write only the unique titles and pull in everything else with *conref*.

**Example**

```xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE task PUBLIC "-//OASIS//DTD DITA 1.2 Task//EN"
"/usr/share/dita-ot/dtd/technicalContent/dtd/task.dtd">
<task id="display-trends" xml:lang="en-us">
  <title>Display trends</title>
  <taskbody>
    <context audience="basic">
      <note type="restriction" audience="advanced">
        <ul>
          <li>
            <ph conref="shared.dita/ip-control"/>
          </li>
        </ul>
        <ph conref="../../shared/shared.dita/see-user-guide"
        audience="no-user-guide"/>
      </note>
    </context>
    <steps>
      <step>
        <cmd audience="basic">
          <menucascade>
            <uicontrol conref="shared.dita/logs"/>
          </menucascade>
        </cmd>
        <choices audience="advanced">
          <choice>
            <ph conref="shared.dita/physical-appliance"/>
            <menucascade>
              <uicontrol conref="shared.dita/logs"/>
            </menucascade>
          </choice>
          <choice>
            <ph conref="shared.dita/virtual-appliance"/>
            <menucascade>
              <uicontrol conref="shared.dita/server"/>
              <uicontrol conref="shared.dita/logs"/>
            </menucascade>
          </choice>
        </choices>
      </step>
      <step>
        <cmd>
          <menucascade>
            <uicontrol conref="shared.dita/all"/>
            <uicontrol conref="shared.dita/editfile"/>
          </menucascade>
        </cmd>
        <info>
          <ul conref="shared.dita/drill-down">
            <li/>
          </ul>
          <note conref="shared.dita/randomnames"/>
        </info>
      </step>
    </steps>
  </taskbody>
</task>
```

Only the plain text content - not the surrounding markup - requires translation. Translating this type of DITA XML content involves translating just the title and the full set of source *conref*. Translators, lacking context for these discrete information units, require support. Ideally, translators work onsite, accessing both the technical writer and product designers.

> **Note**
>
> This is not a constraint solely from advanced content modularization. As a translation school graduate - trained in the *triangle of meaning* principle, whereby the translator must understand the source text well enough to reformulate it in the target language rather than transcribing words one by one - and with several years of technical translation experience, I've found that every successful project relies on collaboration among designers, writers, and translators.

You can also apply this to structural elements, like table headings, to present information consistently at lower costs without specialization.

### Protect confidential information

> **Tip**
>
> The robust conref mechanism in DITA XML can also protect sensitive information. A technical writer can hide information within the source code.

Consider a scenario where a file with confidential information requires translation, but cannot be accessed by the translator (due to client confidentiality clauses).

What can be done? The *ditaval* mechanism filters out information from the deliverables but not from the source files. Must you create separate source files for confidential and non-confidential information? That negates single-sourcing and content reuse - the very reasons for choosing DITA XML!

> **Diagram: Hiding confidential information from translators**
>
> Diagram showing a confidential source in language A split by translation into two branches, each filtered through ditaval, producing a language A deliverable that keeps the confidential information and a language B deliverable that excludes it.

**Hide confidential information from translators**

By placing confidential content in a separate file (e.g., `confidential.dita`) and setting conref with a filter key in the translatable file, you manage access. The translator processes only non-confidential text, and deliverables in the target language exclude confidential content, marked as conditional and explicitly excluded via the *ditaval* file during compilation.

## Provide targeted information with Ditaval conditional text

A ditaval file operates like 3D glasses: one lens masks one half of the information, the other lens the other half. Only the technical writer has complete information.

The information recipients have glasses showing either only left or right lens content. Though they see less, they access what they need without noise. This adheres to the minimalist principle "less is more."

> **Diagram: Conditional text filtering with ditaval**
>
> Diagram showing a source filtered by ditaval into two distinct targets, each receiving only the content selected for it.

**Conditional text with DITA XML**

The ditaval mechanism is based on binary logic: mark a block with an attribute and value, then include or exclude it in deliverables via a compile-time operand (default is inclusion without operand). This constitutes conditional text.

This mechanism negates the need for separate files for minor content variations, further reducing source content redundancy.

Combined filter keys (a logical AND) can be specified as space-separated values within an attribute such as product, audience, and so on.

**Example**

To profile information for both electricians and advanced users among these groups:

- Non-electricians
- Beginner electricians
- Expert electricians

Use the structure:

```xml
<step audience="electricians advanced">
  <cmd> Bring the intensity below the lethal dose of 150mA. </cmd>
</step>
```

> **Caution: Warning**
>
> A filter key placed incorrectly can cause a compilation error. A code block compliant with the unfiltered XSD DITA XML schema may not remain compliant once filtered.

**Example**

Correct before filtering:

```xml
<thead>
  <row product="a">
    <entry>Order</entry>
    <entry>Description</entry>
  </row>
</thead>
```

After filtering, the result is:

```xml
<thead>
</thead>
```

According to the XSD schema, table headers require at least one row:

```xml
<!ENTITY % thead.content "((%row;)+)">
```

This filtered code is incorrect and leads to compilation failure.

## Related articles

- [Case studies in using DITA XML](https://docs.redaction-technique.org/en/formats/dita-xml-case-studies/)
- [From document to modular document base](https://docs.redaction-technique.org/en/formats/modular-documentation/)
- [Too complex a document architecture?](https://docs.redaction-technique.org/en/formats/document-architecture-complexity/)
- [DITA XML and XSL-FO tutorials](https://docs.redaction-technique.org/en/tutorials/dita-xml-xsl-fo-tutorials/)

---

Source: https://docs.redaction-technique.org/en/formats/nufirewall-case-study/
