Skip to content

Commit

Permalink
[Framework] New "See also" column in summary tables
Browse files Browse the repository at this point in the history
The framework can now render a "See also" column that contains useful links to
resources related to the specification, notably:
- a link to the Editor's Draft
- a link to the repository that contains the Editor's Draft
- specific links defined in the description of the spec.

The "See also" column is only rendered in the (currently unused) `versions`
type of summary table. The exact links that need to be rendered can be
customized in the `toc.json` file. The README explains how to customize the
summary tables.

See related need expressed in w3c#90

NB: The framework more or less already supported a `versions` column but that
wasn't flexible enough, and name seemed badly chosen.
  • Loading branch information
tidoust committed Jun 22, 2018
1 parent f7b9673 commit b972677
Show file tree
Hide file tree
Showing 8 changed files with 194 additions and 8 deletions.
46 changes: 46 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ It aims at simplifying the creation and maintenance of such roadmaps by collecti
* [Creating a new roadmap page or a new single-page roadmap](#creating-a-new-roadmap-page-or-a-new-single-page-roadmap)
* [Creating the index of a new multi-page roadmap](#creating-the-index-of-a-new-multi-page-roadmap)
* [Creating an About this document page](#creating-an-about-this-document-page)
* [Customizing summary tables](#customizing-summary-tables)
* [Repository branches](#repository-branches)
* [Generate content locally](#generate-content-locally)
* [Translating a roadmap](#translating-a-roadmap)
Expand Down Expand Up @@ -60,10 +61,12 @@ Depending on the advancement of the underlying specification, the JSON object ca
* `feature`: in case the reference to the specification would benefit from being more specific than the specification as a whole, the `feature` property allows to add the name of the specific feature (see e.g. the [reference to the HTMLMediaElement interface in the HTML5 specification](data/htmlmediaelement.json)).
* `title`: when the specification is unknown to the [W3C API](https://w3c.github.io/w3c-api/) and to [Specref](https://www.specref.org/), the `title` property should be set to the title of the specification.
* `edDraft`: when the specification is unknown to the [W3C API](https://w3c.github.io/w3c-api/) and to [Specref](https://www.specref.org/), or when these APIs do not know the URL of the Editor's Draft for the specification, the `edDraft` property should contain the URL of the Editor's Draft of the specification.
* `repository`: when the repository of the specification cannot be determined automatically, the `repository` property should contain the URL of the repository that contains the source of the Editor's Draft of the specification
* `wgs`: when the specification is unknown to the [W3C API](https://w3c.github.io/w3c-api/) and to [Specref](https://www.specref.org/), the `wgs` property should be an array of objects describing the groups that are producing the spec; each such object should have a `url` property with a link to the group's home page, and a `label` property with the name of the group.
* `publisher`: the organization that published the specification. The framework automatically computes the publisher for W3C, WHATWG, and IETF specifications.
* `informative`: when the specification is unknown to the [W3C API](https://w3c.github.io/w3c-api/), set the `informative` property to `true` to tell the framework that it only contains informative content or that it will be (or has been) published as a Group Note and not as a Recommendation.
* `evergreen`: from time to time, specifications remain as drafts indefinitely but are continuously updated and can be considered stable whenever a new version is published. Set the `evergreen` property to `true` when the specification can always be used as a reference, no matter where it is on the Recommendation track.
* `seeAlso`: a list of other resources that could be worth looking at in relation with the specification. The `seeAlso` property should be an array of objects that have a `url` property set to the URL of the resource, a `label` property set to the title of the resource, and optionally a `kind` property that specifies the kind of resource as a string. The links are rendered in the "See also" column. The whole list is rendered by default, the `kind` value can be used to filter resources in some cases. See [Customizing summary tables](#customizing-summary-tables) for details.

Here is an example of a JSON file that describes the "Intersection Observer" specification:
```json
Expand Down Expand Up @@ -238,6 +241,7 @@ The following settings may be added to the `toc.json` file to generate the appro
* `publishedVersion`: The URL of the latest published version. Generates a "Latest Published Version" link.
* `previousVersion`: The URL of the previous published version. Generates a "Previous Version" link.
* `publishDate`: The date of the publication, following a `YYYY-MM` format. Generates a subheading under the page's title with the date.
* `tables`: Custom summary tables, see [Customizing summary tables](#customizing-summary-tables))

The above settings may also be passed to the page as query string parameters, which can be useful to generate specific snapshots (in particular to pass the `publishDate` parameter). For instance, supposing the page can be served over a local HTTP server running at port 8080, you could use the following to view a "complete" Document Metadata section:

Expand Down Expand Up @@ -311,6 +315,48 @@ Children of the `<main>` element in the about page are automatically appended to
</html>
```


## Customizing summary tables

The framework automatically generates and renders summary tables at the end of sections that are flagged with a `featureset` class. Summary tables contain one entry per feature mentioned in the prose of the section. The columns rendered in the summary table are also determined by the `class` attribute of the `<section>` tag. Recognized values are:

- `well-deployed`: Typically used to talk about well-deployed technologies. The summary table will be composed of the following columns: Feature, Specification / Group, Maturity, and Current Implementations.
- `in-progress`: Typically used to talk about technologies that are progressing along the Recommendation track. Same summary table as for well-deployed sections.
- `exploratory-work`: Typically used to talk about technologies that are being incubated somewhere without any official status. The summary table will be composed of the following columns: Feature, Specification / Group, Implementation intents.
- `versions`: Typically used to talk about specifications that convey guidelines, requirements, notes. The summary table will be composed of the following columns: Feature, Specification / Group, Maturity, and See also.

Roadmap authors may customize the columns displayed and create new types of tables through the `tables` property of the `toc.json` file. That property must be set to an object indexed by the class identifier that will trigger the use of the table (e.g. `well-deployed` to override the default definition of the `well-deployed` table, or a new name to create a new type). For each type, the list of columns to render must be given in an array of objects that describe the column to render.

That object must contain a `type` property that identifies the type of column. It may also contain a `title` property to override the default column's title, and other parameters (which depend on the type of column).

The framework recognizes the following column types:

- `feature` - Feature: Renders the name of the features that appear in `data-feature` attributes. A feature cell may span multiple rows.
- `spec` - Specification / Group: Renders the spec title and the name of the group that develops it.
- `maturity` - Maturity: Renders the maturity status of a spec as an icon. The list of icons is e.g. described in the [About page of the mobile roadmap](https://w3c.github.io/web-roadmaps/mobile/about.html#maturity-levels).
- `impl` - Implementation status: Renders the implementation status of the specification in main browsers. The icons and info that get represented are e.g. described in the [About page of the mobile rodmap](https://w3c.github.io/web-roadmaps/mobile/about.html#implementation)
- `seeAlso` - See also: Renders the list of related resources, including a link to the Editor's Draft, and a link to the repository. The exact kinds of resources to render can be specified in a `kinds` property. Default value is `all` to render all links, but the property can be set to an array of strings. Possible string values are:
- `edDraft`: renders a link to the Editor's Draft, when known
- `repository`: renders a link to the repository that contains the Editor's Draft, when known
- `seeAlso`: renders all resources in the `seeAlso` property of the specification
- some token: renders all resources in the `seeAlso` property of the specification whose `kind` property is equal to the token

For instance, to add the `seeAlso` column with all possible links to the summary table rendered at the end of well-deployed sections, and to create a new type of section for reference documents that also renders a `seeAlso` column with only the Editor's Draft and links flagged as `ref` in the definition of specifications, you may add the following to your `toc.json` file:

```json
"tables": {
"well-deployed": ["feature", "spec", "maturity", "impl", "seeAlso"],
"reference": ["spec", "maturity", {
"type": "seeAlso",
"title": "Reference documents",
"kinds": ["edDraft", "ref"]
}]
}
```

With these definitions, the `reference` table will be generated at the end of sections that have a `class` attribute set to `featureset reference`.


## Repository branches

The source of the roadmaps is in the `master` branch. This is the default branch of the repository, and the branch against which you should be sending pull requests. Whenever content is pushed onto the `master` branch, a Travis script will run, fetch information and implementation data for all features listed in `data`, and eventually update the `gh-pages` branch accordingly.
Expand Down
4 changes: 4 additions & 0 deletions assets/css/theme.css
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,10 @@ th.feature[rowspan] {
td.maturity { text-align: center; }
td.maturity img { vertical-align: middle; }
td.impl { min-width: 220px; }
td.seeAlso {
min-width: 200px;
font-size: 90%;
}
td img + img { margin-left: 0.25em; }
td ul {
list-style-type: none;
Expand Down
61 changes: 55 additions & 6 deletions js/generate-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ const tableColumnsPerType = {
'well-deployed': ['feature', 'spec', 'maturity', 'impl'],
'in-progress': ['feature', 'spec', 'maturity', 'impl'],
'exploratory-work': ['feature', 'spec', 'impl-intents'],
'versions': ['feature', 'spec', 'maturity', 'versions']
'versions': ['feature', 'spec', 'maturity', 'seeAlso']
};

/**
Expand Down Expand Up @@ -314,16 +314,65 @@ const createImplCell = function (column, featureId, featureName, specInfo, implI
return cell;
};

const createVersionsCell = function (column, featureId, featureName, specInfo, implInfo, translate, lang, pos) {
const createSeeAlsoCell = function (column, featureId, featureName, specInfo, implInfo, translate, lang, pos) {
let cell = document.createElement('td');
(specInfo.versions || []).forEach((version, pos) => {
if (version.url && version.label) {
cell.classList.add('seeAlso');
if (column.class) {
cell.classList.add(column.class);
}
let renderLink = (link, pos) => {
if (link.url && link.label) {
if (pos > 0) {
cell.appendChild(document.createElement('br'));
}
fillCell(cell, version);
fillCell(cell, link);
}
};
let links = specInfo.seeAlso || [];
let kinds = null;
if (!column.kinds || (column.kinds === 'all')) {
kinds = ['seeAlso', 'edDraft', 'repository'];
}
else if (isArray(column.kinds)) {
kinds = column.kinds;
}
else {
kinds = [column.kinds];
}
let linkPos = 0;
kinds.forEach(kind => {
switch (kind) {
case 'repository':
if (specInfo.repository) {
renderLink({
label: translate('metadata', 'Repository'),
url: specInfo.repository
}, linkPos);
linkPos += 1;
}
break;

case 'edDraft':
if (specInfo.edDraft) {
renderLink({
label: translate('metadata', 'Editor\'s Draft'),
url: specInfo.edDraft
}, linkPos);
linkPos += 1;
}
break;

default:
links.forEach(link => {
if ((kind === 'seeAlso') || (link.kind === kind)) {
renderLink(link, linkPos);
linkPos += 1;
}
});
break;
}
});

return cell;
};

Expand All @@ -333,7 +382,7 @@ const tableColumnCreators = {
'maturity': createMaturityCell,
'impl': createImplCell,
'impl-intents': createImplCell,
'versions': createVersionsCell
'seeAlso': createSeeAlsoCell
};


Expand Down
2 changes: 1 addition & 1 deletion js/translations.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"maturity": "Maturity",
"impl": "Current implementations",
"impl-intents": "Implementation intents",
"versions": "Development versions"
"seeAlso": "See also"
},
"implstatus": {
"shipped": "Shipped",
Expand Down
2 changes: 1 addition & 1 deletion js/translations.zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"maturity": "成熟度",
"impl": "现有实现",
"impl-intents": "实现意向",
"versions": "Development versions"
"seeAlso": "See also"
},
"browsers": {
"chrome": "Chrome",
Expand Down
25 changes: 25 additions & 0 deletions tools/extract-spec-data.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,29 @@ function getSpecUrl(spec) {
}


/**
* Construct the URL of the repository from the Editor's Draft URL
* (only works for GitHub repositories for now)
*
* @function
* @param {Object} spec The spec object to parse
* @return {String} The URL of the repository
*/
function getRepositoryFromEdDraft(edDraft) {
edDraft = edDraft || '';
let tokens = edDraft.match(/^https?:\/\/([^\.]+)\.github\.io\/([^\/$]+)/i);
if (tokens) {
return 'https://github.com/' + tokens[1] + '/' + tokens[2];
}
else if (edDraft.match(/^https?:\/\/drafts\.csswg\.org\//)) {
return 'https://github.com/w3c/csswg-drafts';
}
else {
return null;
}
}


/**
* Return the URL to use to search for additional info about the given spec in
* Specref.
Expand Down Expand Up @@ -260,6 +283,7 @@ async function extractSpecData(files, config) {
trInfo = {
url: latestInfo.shortlink,
edDraft: latestInfo['editor-draft'],
repository: getRepositoryFromEdDraft(latestInfo['editor-draft']),
title: latestInfo.title,
status: latestInfo.status,
publisher: 'W3C',
Expand All @@ -281,6 +305,7 @@ async function extractSpecData(files, config) {
let info = {
url: getSpecUrl(spec) || trInfo.url || lookupInfo.href,
edDraft: spec.data.edDraft || spec.data.editors || trInfo.edDraft || lookupInfo.edDraft,
repository: spec.data.repository || trInfo.repository || lookupInfo.repository,
title: spec.data.title || trInfo.title || lookupInfo.title,
status: spec.data.status || trInfo.status || lookupInfo.status || 'ED',
deliveredBy: spec.data.wgs || trInfo.deliveredBy || lookupInfo.deliveredBy || [],
Expand Down
31 changes: 31 additions & 0 deletions tools/spec.jsons
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@
"type": "string",
"format": "uri"
},
"repository": {
"title": "URL of the repository",
"description": "URL of the repository that contains the Editor’s Draft of the specification.",
"type": "string",
"format": "uri"
},
"impl": {
"title": "Implementation info",
"description": "For specifications for which browser implementations are expected, the impl property explains where to look for implementation info",
Expand Down Expand Up @@ -149,6 +155,31 @@
"informative": {
"description": "The spec contains only informative content or is/will be published as a Note.",
"type": "boolean"
},
"seeAlso": {
"title": "See also",
"description": "Other resources worth looking at in relation to this spec",
"type": "array",
"additionalItems": false,
"items": {
"type": "object",
"additionalProperties": false,
"required": ["url", "label"],
"properties": {
"url": {
"type": "string",
"format": "uri"
},
"label": {
"type": "string",
"minLength": 1
},
"kind": {
"type": "string",
"minLength": 1
}
}
}
}
}
}
31 changes: 31 additions & 0 deletions tools/tr.jsons
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@
"type": "string",
"format": "uri"
},
"repository": {
"title": "URL of the repository",
"description": "URL of the repository that contains the Editor’s Draft of the specification.",
"type": "string",
"format": "uri"
},
"title": {
"title": "Title of the specification",
"description": "Title of the specification.",
Expand Down Expand Up @@ -71,6 +77,31 @@
"informative": {
"description": "The spec contains only informative content or is/will be published as a Note.",
"type": "boolean"
},
"seeAlso": {
"title": "See also",
"description": "Other resources worth looking at in relation to this spec",
"type": "array",
"additionalItems": false,
"items": {
"type": "object",
"additionalProperties": false,
"required": ["url", "label"],
"properties": {
"url": {
"type": "string",
"format": "uri"
},
"label": {
"type": "string",
"minLength": 1
},
"kind": {
"type": "string",
"minLength": 1
}
}
}
}
}
}
Expand Down

0 comments on commit b972677

Please sign in to comment.