Follow

VRNet documentation

Heritage: a documentation site for a VR/network project

A documentation site for VRNet, built as a proper project: structured content, a Grunt-based build, templates, versioned releases and integration examples.

Smaller than the pattern labs, but the same discipline: documentation that is generated and released rather than written once and left to rot.


FactDetail
TypeDocumentation site
BuildRuby + Grunt pipeline, templated pages
PeriodJanuary – June 2019 · 237 commits

What's in it

Released like software

Versioned releases, including integration examples in the release.

Structured content

Templated pages and config, so a new section meant data, not markup.

In detail

What is actually inside it

Content as data

Templated pages and a config file meant adding a section was data, not markup — which is the same idea the later CMS work took much further.

Released like software

Versioned releases with integration examples bundled: the documentation shipped on a schedule, not whenever someone remembered.

DetailValue
BuildRuby + Grunt, templated pages, versioned releases
CIBamboo (`bamboo-specs`)
PeriodJanuary – June 2019 · 237 commits

Technical notes

The decisions behind it

How does this relate to the design-system work?
Same instinct, smaller scope: documentation should be generated and released, not written once and left to rot. Dachser scaled that idea up, kickstartDS scaled it up again.

By the numbers

Scale of the thing that got built

442
PHP fragments
Under dokumentation/module_templates/; 46 of them are the top-level page for one module, the rest are tab bodies and demo frames.
74
iframe demo pages
Each *-frame.php is compiled to a standalone page in dokumentation/demo/html/, so a demo can be shown at 320, 540 or 600 px without touching the docs layout.
4
theme stylesheets
default-theme, grey-theme, psd-theme and project.css, roughly 170 KB each, all compiled from one SCSS tree by Compass.
1
automated test
grunt-ie9-selector-counter over the compiled CSS — a selector count per stylesheet, because IE9 caps at 4095 per file.

Three toolchains, one repo

What the build actually does

Content here is written as PHP, 442 fragments under dokumentation/module_templates/. Each module gets one top-level file (accordion.php) that lays out the tabs Beschreibung / FAQ / API / Demo, sub-includes for each tab body, and a *-frame.php per demo that pulls in a shared iframe header and footer. Grunt's php2html (with processLinks: true) flattens all of it to HTML, and the frames land in dokumentation/demo/html/… as 74 standalone preview pages that the documentation embeds in iframes and can resize.

The result is not a multi-page site: dokumentation.html is one 26,890-line, 1.6 MB file holding all 142 module sections. The "Grundlagen" page is 1,541 lines and changelog.html compiles a 1,225-line Markdown changelog. No router, no client-side templating for the content itself.

Three runtimes cooperate. Ruby (.ruby-version pins 2.3.7) with sass 3.4.13 and compass 1.0.3 compiles system/scss into the four theme CSS files and generates the icon sprites. Node/Grunt 0.4.5 does the rest: uglify minifies the 76 files in system/js, amd_shim patches MediaElement into a jQuery-compatible AMD module, copy moves images and flattens css/themes, clean drops the intermediate folder afterwards. PHP never reaches the artifact.

config.rb carries two decisions worth knowing. Compass content-hashes its sprite filenames (icons-orange-s482e7be78d.png); the config hooks on_sprite_saved and on_stylesheet_saved to copy each sprite to a fixed name and rewrite every reference in the generated CSS — which is why asset_cache_buster :none and why the release copy rules exclude *-s<hash>.png all over again. And Sass::Script::Number.precision = 8 is set explicitly because the grid math is em/% based.

The single automated check is that IE9 selector counter over system/dist/css/*.css — a live concern with ~170 KB of CSS per theme. JSHint is loaded and wired, but commented out in every task (// 'jshint'), because the .jshintrc it reads was never added to the repo: the release still tries to copy a .jshintrc file that does not exist.

LayerWhat it is
Content442 PHP fragments → 46 module pages, 74 iframe frames
StylingRuby 2.3.7 · sass 3.4.13 · compass 1.0.3 → 4 theme CSS files
Assets & JSGrunt 0.4.5 · uglify · amd_shim · copy · clean
HTML outputgrunt-php2html 0.1.17, `processLinks: true`
Packaginggrunt-rename · grunt-zip 0.13 · grunt-text-replace

What went wrong shipping it

Release and CI archaeology

Why are compiled files committed to the repository?
Because the Bamboo build never runs Grunt. FrontendBuildPlanSpec defines a single job: a clean checkout, then a final script task that only tars the working copy. Anything a release needs must already be in git. On 2019-01-15 built output was removed ("remove built files from repo"); on 2019-06-06 it came back — system/dist/css, the compiled sprites and dokumentation/demo/dist/css/index.css were committed again ("add dist files to repo"). Committing generated CSS was the fix, not an accident.
What did the artifact script get wrong?
It took three one-line fixes over three weeks, all in generate-artifact.sh. The tar originally ran -C $working/dokumentation ., so the archive held the docs folder and none of the framework it links to. "Add compiled stuff, too" widened it to documentation system — which failed instantly, because the folder is spelled dokumentation ("Fix typo", one minute later). "Include additional folders" added img tests; the final commit of the project added integrationsdummy. A fourth commit existed only to touch bamboo-specs/README.md so Bamboo would re-import the plan.
What was in a release, and where did it go?
grunt release builds, then emits two trees: VRNW-OGR-Webframework_11.9.1_Dokumentation_<date> and …_Source_<date>. The Source tree ships system/ without dist/, a trimmed Gruntfile taken from release/Gruntfile.js (release-only tasks stripped), and renames _project.scss to _project-example.scss so an adopting project's own _project.scss survives the copy. The Documentation tree drops all .php sources, the raw SCSS and the hashed sprite PNGs, but keeps index-example.html — the example consumer page carrying the whole require.js path map — and the integration dummy. The zip step is declared and then commented out: the bundles left the build as directories. Deployment was per branch, develop to /srv/artifacts/static/tech (vrnw.static.ruhmesmeile.tech) and master to /srv/artifacts/static/review, scp with a shared "Bamboo" key and release names ${bamboo.version}-1.
How was the version number kept in sync?
Manually, in several places. package.json says 11.9.1, and the Gruntfile still carries a replace step meant to stamp {@VERSION} into dokumentation/*.html — but no committed page has ever contained that token; it only appears in the Gruntfile itself. The drift is visible in the artifact: changelog.html still shows 11.9.0 while index.html, basics.html, margins.html and dokumentation.html show 11.9.1. grunt-htmlhint, loaded for exactly this kind of check, is commented out of both the dev and build tasks.