Adding Twisties to Help Generated by DITA-OT


October 2011

Adding Twisties to Help Generated by DITA-OT

CIDMIconNewsletterBill Marcotte, Radialpoint

A “twisty” is a not-so-common term for links inside HTML that expand to display more text. When a twisty’s title is clicked, the content is revealed, and the rest of the page moves down. Click the twisty’s title a second time and the content is hidden once again. The reader avoids having to flip back and forth between web pages. Twisties aren’t replacements for separately linked pages, but I find them very useful in certain situations.

DITA-OT’s HTML conversion does not support twisties natively. Fortunately, thanks to the “chunkiness” of DITA and of DITA-OT’s HTML output, you can easily turn anything into a twisty using a little JavaScript backed up by jQuery (jQuery is a JavaScript library that makes coding much easier for non-professional-coders like myself).


  • If you want a copy of the sample code discussed in the article, email me at I’d love to hear your comments as well.
  • The following instructions apply to DITA-OT 1.5. To avoid having to redefine classes in your CSS, DITA-OT 1.5.3 is recommended; an explanation is provided later in this article.
  • I’m using Oxygen Author Professional to edit DITA files and to run DITA-OT conversions. The integration of scripts and CSS can also be added to ant scripts, but this is not demonstrated.
  • XHTML is used in the example, but the same concepts apply to CHM/HTMLHelp since it’s still HTML you are using.

First, a demonstration.

Create a DITA File with Sections

  1. Start a new DITA file, using Composite or Concept.
  2. Add 3 sections with titles to the body.
  3. Add some dummy paragraphs inside each section.

Convert To xHTML

  1. Create a ditamap and add your new file to it.
  2. Transform your files to HTML. In Oxygen:
  • Click DITA Maps > Configure Transformation Scenario.
  • Select DITA Map XHTML.
  • Click Transform Now.
  1. Open the HTML file in a browser to make sure it converted properly.

Before continuing, open the HTML file in a text editor and inspect the HTML. DITA-OT converts <section> elements to “div chunks”, that is, <div class=“section”>….</div>.

For example, the following DITA code:


<title>testing twisties</title>

<p>This is a twisty text.</p>

<p>Hope it works.</p>



<div class=”section”><h2 class=”title sectiontitle”>testing twisties</h2>

<p class=”p”>This is a twisty text.</p>

<p class=”p”>Hope it works.</p>


The important point to remember is that the content you are targeting is inside a single unit that we can manipulate easily; the title will be used as the anchor that shows or hides text.

When you use twisties for your help content, you can use any element. In this case we’re using section as an example. As we’ll see later, you can also use the outputClass attribute to make a single element into a twisty.

Add JavaScript to the HTML Page

Next you’ll add the JavaScript that performs the work.

  1. Add the following lines to the <head> portion of the HTML:

<script src=”jquery.js” type=”text/javascript”></script>

<script type=”text/javascript”>


var targets = new Array()


for (var i in targets)


chunks = targets


chunkidentifier = chunks[0];

chunktitle = chunks[1];



$(chunktitle).click( function()


if ( $(this).parent().find(“:last”).css(“display”) == “none”)











  1. Download jQuery from
  2. Save the jQuery JavaScript file to the same location as your DITA file.
  3. Rename the file jquery.js.
  4. Copy jquery.js to the same folder as your DITA-OT output.

Try It!

Open the example HTML file in any browser. (In Internet Explorer, be sure to allow blocked content when asked.) For the section chunks, the title is visible but the contents are not. Click the title and the content appears. Click the title again and the content disappears.

Making the Twisties Look “Clickable”

The twisty “links” won’t appear to be clickable (not blue, not underlined). This is because the titles aren’t links. If you want to complete the illusion, add the following code to the end of the <head> portion of the HTML, after the <link> statement:


h2.sectiontitle { cursor: pointer; color: blue; text-decoration: underline; }


Note: Before you continue, you may want to make a copy of your output. The next time you generate your HTML, the changes you just made will be lost.

How It Works

The twisty code uses the following logic:

  1. Find all div container elements that have a certain class (in this case, the class was section). We don’t want the script to look for all div elements because div’s are found throughout the file.
  2. Hide everything inside the div elements found, but not the containers themselves.
  3. Show the title (h2 with class sectiontitle), since it was hidden with the rest of the content.
  4. Attach a script to the title (h2.sectiontitle) that shows or hides the content when clicked. This could be done in a number of ways; this is how my code works:
  • If the last element of the div container is visible, hide the content.
  • If the last element of the div container is hidden, show the content.

Note: This test relies on the fact that there is at least one title and one other element of content inside the div. The code doesn’t test for this situation because there is no use for a section with a title and no content. If your twisties are disappearing or look funny, this is one source of error.

Integrating the Twisty Code Into DITA-OT Conversion

For conversion purposes, you will want to have the scripts inserted into every HTML document automatically. Initially the code will again target only section containers; later we will customize the code to target whatever you want to turn into a twisty.

Unlike CSS, there is no specific method for adding JavaScript code to the HTML output. However, the args.hdf parameter can be used to automatically add content to the head section of HTML documents.

Adding the JavaScript Code

  1. In the same folder as your DITA files, create a new text file called twisty.js.
  2. Add the same script as before—the one that starts with $(function()—to this file. Important: Don’t include the <script> tags.
  3. In the same folder as your DITA files, create a new text file called includeinheadsection.txt.
  4. Add the following code to this file.


<script src=”jquery.js” type=”text/javascript”><!–filler–></script>

<script src=”twisty.js” type=”text/javascript”><!–filler–></script>



  • The extra div elements and the ‘filler’ text are important. There are some bugs related to how DITA-OT treats this file; the divs and filler are necessary to make sure the code makes it through intact.
  • Instead of linking to external files, you could insert a copy of the jQuery and twisty code into every file, but this would dramatically increase the file size of your help system.
  1. Configure the transform to add the contents of includeinheadsection.txt to each HTML file.

In Oxygen:

  • Click DITA Maps > Configure Transformation Scenario.
  • Select DITA Map XHTML, and then click Duplicate.
  • Double-click the parameter args.hdf.
  • Click the little folder button.
  • Select your includeinheadsection.txt file.

Adding the Twisty CSS

To ensure the twisties look clickable, you can configure DITA-OT to copy a custom CSS and automatically add a CSS statement to each HTML page.

  1. In the same folder as your DITA files, create a new file named twisty.css.
  2. Add the following code:

h2.sectiontitle { cursor: pointer; color: blue; text-decoration: underline; }

  1. Save the file.
  2. Configure the transform to include your custom CSS.

In Oxygen:

  • Click DITA Maps > Configure Transformation Scenario.
  • Select DITA Map XHTML Duplicate.
  • Double-click the parameter args.copycss. Change to yes.
  • Double-click the parameter args.css.
  • Point to twisty.css.

Transform and Try It

Next run the transform.

  1. In Oxygen, run the DITA-OT conversion using DITA Map XHTML Duplicate.
  2. Copy the files jquery.js and twisty.js to the output folder. (Neither DITA-OT nor Oxygen copy these files automatically.)

Every section on each HTML page should now be a twisty.

Note: Likely you will want to automate the copying of the two JS files to the output. You can use the ant copy command to do this, for example. Post-conversion copying doesn’t seem to be something you can easily do in Oxygen without modifying ant scripts or tacking on some batch file processing after conversion is finished; this is beyond the scope of this article.

Using Twisties In Your Help Content

Now that you have twisties working for sections, it’s time to think about how you will use twisties with your help content. There are two approaches, which you can combine:

  • Target DITA elements that are transformed into div containers with standard class names. As we saw in the previous example, section elements are converted to <div class=“section”>.
  • Define an outputClass attribute for any element you want to become a twisty.

Targeting DITA elements is simpler in that you don’t have to do any special labeling of chunks in the DITA file. The disadvantage is that all such elements are indiscriminately made into twisties, which is perhaps not what you want.

Targeting elements that use an outputClass attribute of your choosing means that only specific containers are made into twisties; however, you must go through all your help content and set the attribute for each container individually.

The DITA-OT output is the same in both cases: you target elements with specific classes. It’s more about the time you must spend tagging your DITA elements if you use the outputClass method.

A note about using DITA-OT 1.5.3: An important fix in 1.5.3 is in how the outputClass attribute is applied to elements during conversion. In releases 1.5.2 and earlier, if you set the outputClass attribute of an element, the class attribute of the HTML was replaced completely. For example, in DITA-OT 1.5.2, a section element with no outputClass attribute was converted to <div class=“section”>. However, if you set the outputClass to “twisty”, the output became <div class=“twisty”> (the section class was omitted from the HTML). In DITA-OT 1.5.3, if you add an outputClass attribute to a section, the output contains both class attributes: <div class=“section twisty”>. The difference is that, in DITA-OT 1.5.3, your CSS file does not have to include a class twisty defined as a duplicate of section.

The most important point to remember is that each twisty chunk must have a title that can be easily targeted. The reader clicks the title to show or hide the twisty content.

Modifying the Twisty Code for Your Specific Help Content

The provided twisty JavaScript code is written in a way to make it easy to change or add new targets.

Look for the following line:


The “div.section,h2.sectiontitle” portion defines what to look for. The first part (“div.section”) is the tag.class of the container in HTML. The second part (“h2.sectiontitle”) is the tag.class of the title in that container. The two pieces are separated by a comma.

  • To change what to look for, simply edit the “div.section,h2.sectiontitle” part.
  • To target more than one tag.class, duplicate the entire “push” line, and then change what’s in the quotation marks. In the following example, both <section> elements and subtopics (DITA topics inside topics, in a composite DITA document) are made into twisties. (The easiest way to find out what tag.class you need to specify is to convert your document and inspect the HTML.)



The chunkiness of DITA and its output makes the addition of subtopics easy. The DITA for the subtopic would look like this:

<topic id=“subtopic”>



<p>Body intro</p>

<p>More body text</p>



The HTML output for the subtopic is contained in a div element with the class name nested1 (the primary topic is nested0):

<div class=”topic nested1” id=”subtopic”><a name=”subtopic“>

<!– –></a>

<h2 class=”title topictitle2“>Subtopic</h2>

<div class=”body”>

<p class=”p”>Body intro</p>

<p class=”p”>More body text</p>



As a negative proof of why chunkiness makes this much easier to deal with, this approach does not work with definition lists (dl). This is because each term and definition combo is not a chunk but appears one after another: term, definition, term, definition, and so on. Each term and definition combo is not inside a container. Not to say it can’t be done, just not with the script I’ve supplied. One workaround is to create a new dl element for each term, which is a bit cumbersome.

Further Improvements

A nice visual you can add to your twisties is an arrow that points right when the content is hidden and down when the content is visible. Simply add the background image of an arrow to the title, and then switch the image when the twisty is displayed or hidden.


While this article was focused on implementing a specific feature, there are many other applications. Thanks to the fact that DITA is already chunked and that the DITA-OT HTML retains this chunkiness, you can use JavaScript to target any particular element or section to do anything you require.

One example for Windows is the ability to add links that open Control Panel items from within Internet Explorer (or CHM files). Instead of instructing the user to click Start > All Programs > Control Panels > Windows Update, you could write “Click here to open the Windows Update control panel.” If you make “Click here” an xref with a unique outputClass attribute, you could target these links and change them so that they execute ActiveX code that opens the control panel.

I hope you find this technique useful. Send any questions or comments to CIDMIconNewsletter

Bill_MarcotteBill Marcotte


Bill Marcotte has been messing around with improving online help through scripts since discovering WebWorks in 1999. Besides technical writing, Bill also performs software usability testing and wishes all companies would test paper prototypes on users before doing any coding. Bill has started a few blogs—you can see a list at <>.