Bikeshed Documentation

Living Standard,


13. Boilerplate Generation

The processor automatically generates nearly all of a spec’s boilerplate, the text that is repeated nearly identically across all specs.

Generally, you won’t need to understand what’s going on here in order to use the processor—​it’ll just automatically do the right thing as long as your doctype (the Org, Group, and Status metadatas) is set correctly.

For help in creating new boilerplate files for your organization, see § 13.6 Creating New Boilerplate Files For Your Organization.

13.1. Rearranging and Excluding "Spec Metadata"

An important part of the boilerplate is the "spec-metadata" section. This will likely be at the top of your header boilerplate, as it contains a bunch of useful information about your spec.

Bikeshed generates a lot of these automatically for you, based on the metadata you provide and other things detected from your document, and you can supply "custom" items as specified near the end of § 4 Metadata. There’s a predefined ordering of these, but if you’d like a slightly different order, or to omit some of the automatically-generated items, you can use Metadata Include and Metadata Order to control this.

Metadata Include takes a comma-separated list of names and boolish values, where the names are the strings that show up in the dt in the spec metadata. Everything defaults to "on" currently, but you can explicitly turn them "off" to omit them from the spec metadata section.

Metadata Order instead controls the ordering of the spec metadata section. It’s a comma-separated list of names, where the names are the strings that show up in the dt in the spec metadata (same as Metadata Include). Two special "names" are recognized as well: the * name stands in for "all the standard keys that aren’t otherwise explicitly specified", while !* stands in for "all the custom keys that aren’t otherwise explicitly specified". (The default value is thus Metadata Order: *, !*, listing all the standard keys in the default order, followed by all the custom keys in the default order.)

If a name is specially pluralized when there are multiple entries (such as "Editor" vs "Editors"), use the singular version in either of these metadatas.

For example, Metadata Include: This version off will make Bikeshed omit the "This version" entry from the spec-metadata section, which is otherwise auto-generated by the ED metadata.

If you wanted to make sure that editors were listed before anything else, you could set Metadata Order: Editor, *, !*.

13.2. Conditional Inclusion

If you have multiple boilerplate files for publishing with different document statuses (like WD vs CR), but the only difference is that some sections are added/omitted between them, you can greatly simplify things by instead making a generic boilerplate for everything, and then adding/removing the variant bits with a conditional inclusion.

To mark an element as "conditionally included", put an include-if and/or exclude-if attribute on it, each of which takes a comma-separated list of inclusion conditions.

An element that fails will be removed from the output entirely, along with its contents.

Inclusion conditions can be:


Normally the conditional attributes go on an existing element in your page, which’ll show up in the output assuming it passes the tests. If there’s not a natural wrapper element, or adding such an element would mess with the semantics or styling of the page, you can instead wrap the conditional content in an if-wrapper element.

The if-wrapper element is a standard block-level element that can contain any flow markup. It must have one of the conditional attributes. If it fails the conditions, it and its contents are removed from the document, as normal; if it passes the conditions, it is still removed from the document, but its children are left behind in its place.

if-wrapper is still parsed as a standard unknown "custom" element by the HTML parser, and so can only appear in places where such elements are allowed; it cannot, for example, be used in the head of a document, or as a child of table.

It’s also considered "block level" by the Markdown parser. It can be used inline in text (tho you probably want to instead make the entire block conditional, for readability/editability), but it won’t parse as intended if it’s the very first content in a paragraph.

13.3. Boilerplate Sections

The location of the boilerplate sections are indicated by elements with data-fill-with='' attributes. If the elements contain anything, they’re emptied before being filled with the appropriate boilerplate. The valid data-fill-with='' values are:

Additionally, "header" and "footer" boilerplate files are used to put content at the start and end of your document. Most or all of the above boilerplate sections should actually show up here, in the header and footer, rather than being manually specified in your source file.

13.3.1. Default Boilerplate

Some sections listed above are generated by default; if you don’t put an explicitly data-fill-with container in your document, they’ll generate anyway (if they have anything to fill themselves with), appending themselves to the end of the body. These sections are:

Again, these will only auto-generate if there is something for them to do; if your spec doesn’t define any CSS properties, for example, the "property-index" boilerplate won’t generate. If you want to suppress their generation even when they do have something to do, use the Boilerplate metadata, like:

<pre class="metadata">
Boilerplate: idl-index no, property-index no
</pre>

13.3.2. Custom/Overriding Boilerplate

Sometimes a file-based boilerplate (see below) that is appropriate for most of the specs in your group isn’t quite right for your specific spec. Any boilerplate, file-based or Bikeshed-generated, can be overridden by custom text of your choosing. Just add an element to your source document with the content you’d like to show up in place of the offending boilerplate, and add a boilerplate="foo" attribute to the container, specifying which boilerplate section is being replaced.

Bikeshed will automatically remove that element from your document, and instead inject its contents in place of the boilerplate that it would normally provide.

The boilerplate attribute isn’t limited to just the predefined boilerplate section names; you can supply whatever section name you want, and if there’s a data-fill-with attribute somewhere in the document with the same name, the element’s contents will be moved there.

13.4. Table of Contents

The headings in the spec are automatically numbered, and a table of contents automatically generated.

Any heading h2 to h6 (that is, skipping only the document-titling h1) is automatically numbered by having a <span class='secno'>...</span> prepended to its contents. You can avoid this behavior for a heading and all of its subsequent subheadings by adding class="no-num" to the heading.

Similarly, a ToC is generated to match. Headings and their subheadings can be omitted from the ToC by adding class="no-toc" to them.

Headings also automatically gain a self-link pointing to themselves, to enable people to easily link to sections without having to return to the ToC.

13.5. File-based Includes

Several of the data-fill-with values (those that are static, rather than generated from in-document data) actually come from sets of .include files in the bikeshed-data project.

The base files are simply named "foo.include", where "foo" is the name of the data-fill-with value. They can be specialized, however, to particular working groups, and to particular document statuses.

Putting the boilerplate in a folder named after the group, like csswg/header.include, specializes it for that Group. Adding a "-STATUS" to the filename specializes it for the Status. These can be used together, like "csswg/status-CR.include". Orgs can also have default boilerplates, which are stored in the same way, and will be used if the Group doesn’t have a specific boilerplate.

The processor will first look for the "GROUP/foo-STATUS.include" file, failing over to "GROUP/foo.include", then "ORG/foo-STATUS.include", then "ORG/foo.include", then "foo-STATUS.include", and finally "foo.include".

13.6. Creating New Boilerplate Files For Your Organization

Bikeshed’s default boilerplate generates a functional and reasonably attractive spec, but if your group has specific style requirements, you can produce your own boilerplate files. This section is a basic guide to developing these files.

The most important part of the boilerplate is the header.include and footer.include file. These define the parts of the spec HTML that precede and follow your actual spec content, so the source file can contain only the actual spec text, and all specs in the same organization can look similar.

Here is a basic example header.include file:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <title>[TITLE]</title>
  <style>
  ...
  </style>
</head>
<body class="h-entry">
<div class="head">
  <p data-fill-with="logo"></p>
  <h1 id="title" class="p-name no-ref">[TITLE]</h1>
  <h2 id="subtitle" class="no-num no-toc no-ref">[LONGSTATUS],
    <span class="dt-updated"><span class="value-title" title="[CDATE]">[DATE]</span>
  </h2>
  <div data-fill-with="spec-metadata"></div>
  <div data-fill-with="warning"></div>
  <p class='copyright' data-fill-with='copyright'></p>
  <hr title="Separator for header">
</div>

<div class="p-summary" data-fill-with="abstract"></div>
<div data-fill-with="at-risk"></div>

<nav data-fill-with="table-of-contents" id="toc"></nav>
<main>

This uses several of Bikeshed’s boilerplating features:


12 Testing Integration With WPT Table of Contents 14 Railroad Diagrams