Drupal Development made easier with Qt Assistant - Part 4

Welcome to the fourth and final part of this series of blogs. Last time we created and finished our PHP preprocessor, which helped us overcome some quirks in the Drupal documentation. Before that, in part one we prepared our system and in part two we configured the most important pieces of Doxygen. Read part 3a and part 3b for the work we did on the PHP Preprocessor. This time, we'll use my own DoxyAssist tool to have lots of work done for us automatically. Time to make the documentation useful!

Good base

Having fully configured and fixed most of Doxygen last time, for Drupal in its entirety, there is a nice base to work from. The next step is now to install the DoxyAssist scripts to a location you like. DoxyAssist will help - especially Drupal projects - to build modular documentation. Rather than just ending up with one big bundle, DoxyAssist will split core and contributed modules from each other. The contributed modules will each get their own Doxygen run which creates separate sets of help pages.

Next, DoxyAssist automatically combines all those separate files back into one Qt Help Collection. This collection can be used nicely in the Qt Assistant. Making use of filters in the UI of the Assistant, it becomes possible to view all documentation together, or documentation of just the specific modules.

Project File

DoxyAssist uses projects and subprojects to determine what part of a source code project to include or exclude in each separate run of Doxygen. Special support is available for Drupal, which makes DoxyAssist automatically discover the subprojects (contributed modules, themes, etc) in the "sites" directory.

So we create an XML file which tells DoxyAssist where to find the source code, which base Doxyfile it has to use as a base, and which options to override. Additionally it also specifies some options for Qt Assistant. These last options will determine what features are available in the assistant when opening the collection.

In this example I assume the base Doxyfile is correctly set up for Drupal. See part 3b if you want to download the latest version, but make sure you adapt it to your environment. Next open up your text editor, and paste in the following as a start:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <DoxyAssist xmlns="http://simply-life.net/doxyassist/doxyassist.xsd"
  3.             xmlns:da="http://simply-life.net/doxyassist/doxyassist.xsd"
  4.             version="1.0" type="drupal" name="Drupal API">
  5.     <doxygen doxyfile="/home/cheetah/public_html/drupal/Doxyfile" />

As you can see in the part above, we first set up some base things like XML Namespaces. We say the project is of a "drupal" type, and we use version 1.0 of the DoxyAssist configuration format. We have a name for the configuration, and finally tell DoxyAssist which base doxyfile we use. Make sure you edit the path there!

The next part we add are the options for Qt Assistant:

  1.     <qtHelp collectionFile="/home/cheetah/.local/doc/drupal-6.qhc"
  2.             projectFile="/home/cheetah/.local/doc/drupal-6.qhcp"
  3.             storage="qch" copyAction="copy">
  4.         <title>Drupal API Documentation (6.x)</title>
  5.         <startPage>qthelp://org.drupal.6-x/org.Drupal.6-x/main.html</startPage>
  6.         <applicationIcon>drupal.png</applicationIcon>
  7.         <enableFilterFunctionality visible="true">true</enableFilterFunctionality>
  8.         <enableDocumentationManager>false</enableDocumentationManager>
  9.         <enableAddressBar>false</enableAddressBar>
  10.         <cacheDirectory>drupal6/api</cacheDirectory>
  11.     </qtHelp>

The paths to the collectionFile and projectFile are somewhere where they won't be in the way during every day tasks. The separate qch files will be kept within a "qch" subdirectory (the "storage" attribute), and they will be copied from the Doxygen output directories. Other options include "move" (which will move the compressed help files away from their original Doxygen directories) and "symlink" (create a symbolic link to the original location).

The options that follow define the interface of the Assistant. More details about those options are available in the Qt documentation. Note the applicationIcon: this has to exist in the same directory as where the collectionFile is placed. It will allow you to use a special icon for your Drupal assistant - you can also just omit it if you don't want to spend any time on it.

Now for the interesting stuff: defining our Drupal (6) project:

  1.     <drupal>
  2.         <name>Drupal</name>
  3.         <version>6.x</version>
  4.         <versionSpecific>true</versionSpecific>
  5.         <input>/home/cheetah/public_html/drupal</input>
  6.         <exclude>/home/cheetah/public_html/drupal/backup</exclude>
  7.         <exclude>/home/cheetah/public_html/drupal/doc</exclude>
  8.         <output>/home/cheetah/public_html/drupal/doc</output>
  9.         <logDirectory>/home/cheetah/public_html/drupal/doc/log</logDirectory>
  10.         <namespace>org</namespace>
  12.         <!-- The following are Drupal specific options! -->
  13.         <groupBy>name</groupBy>
  14.         <buildCore>true</buildCore>
  15.         <buildModules>true</buildModules>
  16.         <buildThemes>false</buildThemes>
  17.         <latestContribOnly>true</latestContribOnly>
  18.     </drupal>
  19. </DoxyAssist>

Oh, and we close up the open DoxyAssist tag as well. But before that, we define our project with a name and version tag. We want version specific builds, which means the project version names will be included in the final output. It makes it just a bit easier to find out the versions later on. In the input option, we tell DoxyAssist where to look for the Drupal source code. We also add some directories which we want to skip. That includes our output directory, where Doxygen will write all its files to. There is also a separate directory where the log files of Doxygen will be written to, such that each (failed) documentation build can be investigated separately, if the need arises.

Finally, the namespace is the base namespace used in Qt Assistant. DoxyAssist will automatically append the project name ("Drupal") and version ("6.x") to this. For modules, this will be followed by the module name and version in a similar way. In Qt Assistant, these full names will help the Assistant to distinguish all the pages, since there will be some overlap - especially for common pages.

So far the options have been largely the same as for any (generic) DoxyAssist project. The next set is specific for Drupal. They will determine which items to build (Core, contributed modules and/or themes), and whether to include all versions of a project, or just the latest version. The latter is especially useful if you have a multi-site install, where some sites still run older versions of modules.

The groupBy option is especially important: this identifies how to group documentation of contributed modules. The value is a key in the .info file of modules. Good values are "name" or "package".

DoxyAssist comes with an example configuration for Drupal projects, that contains some more elaborate explanations of each option in XML comments. You can use that as a base. See the doc/examples directory in the DoxyAssist package to get that example.

Save the XML file you just created to somewhere where you can find it again. The file extension doesn't matter much, although I recommend plain .xml or .doxyassist. I'll use /home/cheetah/public_html/drupal/drupal6.xml in this example.

Running DoxyAssist

Whew, everything's set up. Our preprocessor of the previous parts is (hopefully) still in place, so it's time to get this thing working. The project file is done, so we better keep that safe for a bit. If you don't have it already, install Python 2.7 now (Python 3.x is not yet supported, 2.6 will work just fine though).

Fire up a command line and enter the following:

python /home/cheetah/usr/share/doxyassist/doxyassist.py /home/cheetah/public_html/drupal/drupal6.xml

Naturally, change the path to wherever you have DoxyAssist installed. If this throws some odd (syntax) error, replace "python" with "python2" - you're probably running Python 3.x by default.

Once you got the command right, DoxyAssist will process the configuration and do its magic. This may take a little while. If you have PyQt4 installed as well, the Assistant cache will be cleared. This means custom changes you made in the Assistant with the same collection (an earlier build) will be reset. Such changes will be lost, but this step is required to get rid of left-over filters. Without this step, older tags (e.g. old versions of modules) will remain in the filter list, even though they are of no use at all anymore.

Finally, check the collectionFile setting in the qtHelp part of the DoxyAssist configuration file. You're gonna need this to finally open up the Drupal Assistant:

assistant -collectionFile /home/cheetah/.local/doc/drupal-6.qhc

The result is best shown in the following set of screenshots:

Drupal Assistant (1)
Drupal Assistant (2)
Drupal Assistant (3)

Finally, if you ever add new modules, update Drupal, or need to rebuild the documentation again: just re-run DoxyAssist with the same project file as before. Everything will be updated, and next time you run your Drupal Assistant you will see the refreshed documentation with all updates - including newly installed or updated modules. Quick and painless.

The End

This concludes this series of blog posts (finally). From scratch we set up Qt Assistant to become our main assistant in Drupal coding. All of this with the help of Doxygen, a special preprocessor and DoxyAssist. I hope you found it helpful.

Feel free to comment if you run into problems. Of course, also contact me if you'd like to discuss DoxyAssist, report bugs or request features etc!

Other posts in this series: