Skip to main content

Consolidate & Govern part 2: Republishing Docs-as-Code Content with a Developer Hub CMS

Solutions Architect
Jun 30, 2023

Is your technical developer documentation strewn about into microsites, all of it slightly off-brand and looking a little dated? Do you have a number of teams that are authoring documentation in a docs-as-code fashion that you need to consolidate and publish to a broader public?

For example, do you have:

  • - produced with MkDocs
  • - produced with Doxygen
  • - produced with Sphinx
  • - produced with a DITA tool

And do you wish you could expose all of it in a single place in a consistent and up-to-date way? And while you are at it, add granular access and editorial control?

We encounter these kinds of problems on a regular basis in our devportal practice. And while we believe it is important to do UX work to explore all the requirements that your portal’s information architecture will need to address, we will be sharing in this article an example of a unified content strategy that addresses these requirements in a generic way. All of which can be executed using a Drupal-based developer portal like our Zero Gravity Developer Portal Solution.

Navigation and Information Architecture

A closer inspection reveals that all of these documentation systems produce static HTML sites with a main navigation menu across the top, and often a sidebar navigation down the left. This is fine for a standalone site just for ProductA, but on a consolidated developer portal the main navigation is reserved for sitewide navigation. This necessitates moving all menu entries into the left sidebar. In practice this turns out to be a nonissue, the resulting unified sidebar menu looks familiar and is easy to navigate.

Pictured here are examples from Doxygen, MkDocs, and Sphinx.
Most docs-as-code systems have a similar information architecture: a main menu across the top, and often a sidebar menu. Pictured here are examples from Doxygen, MkDocs, and Sphinx.


In a consolidated developer portal, we can expose documentation packages in a tree structure:

  • /doc - a landing page with links to individual documentation packages, ideally also with built-in search, linked to from the main developer portal navigation menu
    • /doc/productA - productA’s landing page, including a left sidebar with the entire navigation as used to be seen across the top and down the left
      • /doc/productA/[subpage] - as the name implies, productA’s documentation pages
    • /doc/productB
    • /doc/productC
    • and so on…

Breadcrumbs reflect the same hierarchy and assist navigation through the often deep hierarchy.

Exceptions or extensions to this navigation model can be made based on an information architecture workshop or UX research.

Documentation Import

The Drupal CMS has a very mature content migration framework that we can leverage to import content that is produced by the various documentation teams. Source content can be in practically any format, as long as it is consistent. The documentation generators mentioned above - MkDocs, Doxygen, Sphinx, and others - all ensure predictability and consistency, albeit each in its own way.

The migrate framework in Drupal has an ETL (extract, transform, load) architecture to split an import process into logical steps.

Extract: we typically ask a documentation team to expose a documentation package on a known and accessible URL (this can be done automatically as part of a build process from your code repository). This reduces data fetches to a single operation instead of possibly hundreds or more. We then download and unpack the package.

Transform: a plugin is written that maps the unique data structure from each tool to Drupal’s own data structures. Title, body content, menu structure(s), and metadata (such as author, creation date, tags and more) are mapped in this step, and if necessary, transformed into what Drupal expects internally. Dates and time are one data type where we almost always apply a transformation from whatever the source is to html_datetime in Drupal. This ensures a uniform internal structure that lends itself to all future uses.

One unique tweak we applied here is that we are bypassing Drupal’s menu system and map navigation data to a simple hierarchical array. With datasets of hundreds or even thousands of entries, the menu subsystem would become unwieldy and ultimately not manageable. Thanks to a strict approach of “the single source of truth is the Git repository of the documentation team”, we do not need the overhead, flexibility, and interactive manageability of Drupal’s menu system, while still outputting what looks and behaves like a menu.

With data mapping taken care of, the load step is relatively straightforward and well-documented. It is important to note that we drop any and all CSS and Javascript that comes with the source documentation, and only retain the actual text and media, and their hierarchical relationship. If in-line styling was present, we retain classes in the case of HTML source, but no actual styling.

In terms of data source formats, we have ingested HTML, JSON, XML, and different types of MarkDown from a range of different tools thus far.

Look and Feel

With all product documentation stored in Drupal, the CMS takes care of theming the output. Thus all imported documentation will now have the desired uniform and branded look.

In practice we find that each new migration needs a couple of minor tweaks to cover edge cases and improve the overall look and feel of the newly imported documentation package. However, this is a one-time effort only.

Access Control

With all product documentation managed by Drupal, we can now apply the full range of access controls a mature CMS affords. This can be traditional role-based access control on a per package basis, or more fine grained access control on a per page basis.

A wide range of opportunities are now open. For example:

  • productA - fully open and accessible to anyone.
  • productB - accessible to logged in users only, but the link from the documentation landing page is visible and leads to a nice “we are sorry, you need to register to see this content” page if an anonymous visitor tries to access it.
  • productC, main pages - open to registered users of the portal, same as productB
    • productC, detail pages - accessible to registered productC users only, product registration is mapped from the identity provider system via single sign-on,
    • productC, next release preview pages - accessible to select partners only.

This is where a CMS really empowers a developer relations team, in that very complex access control scenarios are feasible, while all content is managed by one comprehensive system.

Quick Content Fixes

Even though we normally operate under a strict “the single source of truth is the Git repository of the documentation team” approach, the developer portal editorial team still has the power to apply quick fixes. For example, embarrassing typos or slight inaccuracies in the docs can be quickly fixed in situ, while being passed upstream to be fixed at the source. In that way, a DevRel team can take advantage of the best of both worlds. Upon the next import, the local fix will be overridden by the (hopefully) now-fixed source documentation.


To summarize, importing standalone developer documentation packages into a Drupal developer portal affords these advantages:

  • a single, comprehensive portal under a well known URL,
  • single sign-on via enterprise IDP,
  • consistent branding and styling,
  • consistent accessibility regardless of provenance,
  • consistent user experience,
  • governance and editorial control,
  • sophisticated access control,
  • SEO benefits of the Drupal CMS.

As an interesting side note, our approach closely resembles what Fabrizio Ferri Benedetti describes as the Docs-and-Code repos cooperate model, except for the fact that Drupal is not a code repository and therefore results in different, and dare we say, more benefits.

Do you need help with your docs-as-code content? As you can see, the Zero Gravity Developer Portal Solution offers several possibilities. If you would like to know more, get in touch with us.

Developer Documentation Hub creates a bridge between the isolated documentation islands.


If you try to build a unified documentation experience for your (internal or external) customers, or your documentation landscape is a heterogenous mess, or you are fighting political battles over tooling choices, it is possible that, in the end, your company will have isolated documentation islands. 


All Pronovix publications are the fruit of a team effort, enabled by the research and collective knowledge of the entire Pronovix team. Our ideas and experiences are greatly shaped by our clients and the communities we participate in.

Christoph is a creative and versatile technical leader who can present complex subjects in plain English. He has extensive experience managing demanding computing projects and partnering with stakeholders of all stripes to optimize solutions. He is also a regular speaker at technical events, and in his spare time builds furniture that align with his penchant for simplicity.


Articles on devportals, DX and API docs, event recaps, webinars, and more. Sign up to be up to date with the latest trends and best practices.