Integrating the Oxygen WebHelp Plugin into the DITA Open Toolkit

I led a project earlier this year to convert my organization’s legacy Eclipse Help Center builds to HTML5 builds using Oxygen’s new WebHelp plugin for the DITA Open Toolkit. By changing the build output, we achieved the following:

  • Completely eliminated the costly Eclipse server maintenance
  • Improved our analytics results and potentially our SEO
  • Brought our output into HTML5 compliance

Unfortunately, actually implementing the plugin wasn’t just a matter of plopping the plugin into the Plugins directory. I had to upgrade the toolkit, rework scripts, and restructure directories to create a less-confusing, easily upgradeable build. Read on to understand my choices and learn from my experience.

Don’t look here to find a step-by-step procedure for implementing the Oxygen WebHelp plugin. Instead, read this blog post if you want help preparing for this process.

Upgraded the Toolkit

First, I upgraded our toolkit, which I was happy to do because it’s good practice, as well as nice to take advantage of the latest that DITA has to offer. Unfortunately, I couldn’t upgrade it too far, because the plugin only supports DITA-OT 1.7.5, which is still better than the 1.5.4 version we’d been using.

This time, I customized using the Customization directory only. My first experience with DITA was a highly customized DITA OT 4.2.1 that still makes me twitch when I look at it. It worked fine and it had some decent customizations, but upgrading a hacked-up toolkit is about as simple as string theory.

Reworked the Scripts

I reworked the .sh script and our ant scripts. The WebHelp plugin includes a file that you need to edit in order to set environmental variables for the build. This replaces the toolkit’s OOB and was actually a little tricky to figure out because I was retrofitting to an existing build layout.

The instructions from Oxygen tell you how to use the, but don’t mention anything about ant builds, which is how we build here (via Jenkins). Oxygen’s support team was also less familiar with this approach. The reason I didn’t want to use only the was that I didn’t want to have every writer set TRANSTYPE or DITAVAL_FILE or DITA_DIR  as environment variables every time she ran it from the command line.

For example, here’s what it would look like if the writer had to set all of the variables from the command line each time she ran a build:

"/usr/bin/java" -Xmx512m -classpath "docs/DITA-OT1.7.5LBC/tools/ant/lib/ant-launcher.jar" "-Dant.home=docs/DITA-OT1.7.5/tools/ant" -lib "docs/DITA-OT1.7.5LBC/" -lib "docs/DITA-OT1.7.5LBC/lib" -lib "docs/DITA-OT1.7.5/lib/saxonb9-1-0-8j/saxon9.jar" -lib "docs/DITA-OT1.7.5LBC/lib/saxonb9-1-0-8j/saxon9-dom.jar" -lib "docs/DITA-OT1.7.5/plugins/com.oxygenxml.webhelp/lib/license.jar" -lib "docs/DITA-OT1.7.5LBC/plugins/com.oxygenxml.webhelp/lib/log4j.jar" -lib "docs/DITA-OT1.7.5/plugins/com.oxygenxml.webhelp/lib/resolver.jar" -lib "docs/DITA-OT1.7.5plugins/com.oxygenxml.webhelp/lib/ant-contrib-1.0b3.jar" -lib "docs/DITA-OT1.7.5LBC/plugins/com.oxygenxml.webhelp/lib/lucene-analyzers-common-4.0.0.jar" -lib "docs/DITA-OT1.7.5/plugins/com.oxygenxml.webhelp/lib/lucene-core-4.0.0.jar" -lib "docs/DITA-OT1.7.5/plugins/com.oxygenxml.webhelp/lib/xhtml-indexer.jar" -f "docs/DITA-OT1.7.5/build.xml" "-Dtranstype=webhelp" "-Dbasedir=docs/sbs/7_0/trunk/src/dita/" "-Doutput.dir=docs/sbs/7_0/trunk/src/dita/out/webhelp" "-Ddita.temp.dir=docs/sbs/7_0/trunk/src/dita/temp/webhelp" "-Dargs.filter=docs/filters/on_prem_sys_admin_7_0.ditaval" "-Ddita.input.valfile=docs/filters/on_prem_sys_admin_7_0.ditaval" "" "-Ddita.dir=docs/DITA-OT1.7.5" "-Dargs.xhtml.classattr=yes" "-Dargs.input=docs

Instead, I was able to revise the script so the build command now looks like this:

ant -Dargs.filter=docs/filters/on_prem_sys_admin_7_0.ditaval

My Goals for Reworking the Scripts

  • Simplify the build script so more than one user can build from their own environment
  • Automate the build
  • Produce PDFs along with HTML5 output
  • Make it possible to build using numerous maps, filters, and help sets

My Solutions for the Scripts

To reach these goals, I set the variables at build time using a series of build files that are triggered in one simple call on the command line that passes only the DITAVAL_FILE filter. Any writer, or build automation tool, can now use this command because the build scripts are no longer dependent on absolute paths to the DITA-OT or to an SVN repo.

On the command line or in Jenkins, any writer can run the new command in any help set directory, and the local build files reach out to a shared build file for all help sets. I put all of the targets in that one shared file, single-sourcing it like a good writer would.

I also wanted to preserve a previously-used script in our new build. It starts with a simple ant target that calls some .jars for creating PDFs. This target and its supporting .jars comb the main ditamap for submaps and create PDFs for each submap. This Chapter PDF output has been popular with our users, so I made sure we kept it.

Restructured the Directories

Because I was rewriting build files and creating new Jenkins scripts anyway, I figured it was a good time to flatten our directory structure a bit. I removed some unused directories, including some old build cruft and unnecessary branches (all highlighted in red).

Our former structure with extra layers:

  • productA/feature/ (used for eclipse output).
  • productA/version1/trunk/src/dita/
  • productA/version1/trunk/src/build/
  • productA/version1/trunk/output/
  • productA/version1/trunk/src/temp/

Here’s our new simpler way:

  • productA/version1/dita/
  • productA/version1/build/
  • productA/version1/output/
  • productA/version1/temp/

A next step is to research best practices for directory structures and DITA to further simplify our structure, but I’m happy to work in this slightly less cluttered place.

Customized WebHelp CSS and JavaScript

Knowing the hell of a customized toolkit made me extra concerned with customizing the Webhelp plugin. Although the plugin offers a lot, it does not provide a Customization directory. In order to change the look and feel of our HTML5 output, we had to edit the CSS and some JavaScript directly. This means that when/if we upgrade, it will take some work to transfer the changes to the new plugin. I already saw a huge reorg of files and directories between the pre-release and January versions of the same release.

Out of the box, Oxygen WebHelp plugin output looks pretty good:

Oxygen OOB Output

But I wanted to change our help to match our corporate style:
Jive Help Screen

Things to Ponder

  • Customizing the plugin might cause future headaches, but who wants OOTB?
  • Speaking of customizations: If you want to change the banner/header, brace yourself!
  • You will become an expert if you customize this plugin.
  • Upgrading even a non-customized toolkit is not always simple.
  • Oxygen Support is in Romania — an entire workday of waiting for responses is frustrating. But they are helpful and thorough, so ask them lots of questions.
  • Read the Oxygen Support forums ( There are some nuggets out there.
  • Hold out for the most stable version of the plugin, no matter how excited you are about it.
  • The Search and CSS are way better than in any other product we evaluated, but still clunky.
  • My last gripe about customizing this plugin is the utter lack of documentation. The paragraph on customizing the CSS cracked me up because they make it sound like you can use any ol’ CSS file, but you still need to point to the html elements that the plugin uses, such as 5 nested UL elements!

Was It Worth It?

Hell, yeah! I’m known for jumping head first into complicated projects, and this was no exception. (Someday, I’ll blog about improving PDF output using XSLT.) But, should YOU use this plugin? The answer is yes if you:

  • Want HTML5 output for an okay price.
  • Like the out-of-the-box look, or you want to learn (or already know) JavaScript and CSS.
  • Are comfortable using Support forums or Technical Support for help.

Have any of you had to implement the Oxygen WebHelp plugin? If yes, I’d love to hear your challenges and how you overcame them.