Skip to content

Commit 3862166

Browse files
authored
Port Handbook from Jekyll to 11ty, and from USWDS 2 to USWDS 3 (#3267)
* 11ty * add menu button in narrow view; fix footer links; fix link color * published images include original filename instead of JUST a hash/id * update dependencies; update heading links * validation fixes * add post-build step to statically generate page side navs and internal link markup * fix the header, thanks to @hbillings! * fix an issue with alignment and a missing border * remove unused file; fix header link (hopefully) * move tests of built content back to circleci * add dependabot * add Slack links; tweak README; add more info to CONTRIBUTING * change nav section overflow; update asset script to also rebuild the site so images get put back
1 parent fa2e71d commit 3862166

File tree

553 files changed

+51595
-19681
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

553 files changed

+51595
-19681
lines changed

.circleci/config.yml

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
version: 2.1
2+
jobs:
3+
build:
4+
docker:
5+
- image: node:16
6+
steps:
7+
- checkout
8+
- run:
9+
name: install dependencies
10+
command: npm install
11+
- run:
12+
name: build
13+
command: npm run build
14+
- persist_to_workspace:
15+
root: .
16+
paths:
17+
- node_modules
18+
- _site
19+
20+
validate html:
21+
docker:
22+
- image: node:16
23+
steps:
24+
- checkout
25+
- attach_workspace:
26+
at: .
27+
- run:
28+
name: validate HTML
29+
command: npm run test:html-validation
30+
31+
validate internal links:
32+
docker:
33+
- image: node:16
34+
steps:
35+
- checkout
36+
- attach_workspace:
37+
at: .
38+
- run:
39+
name: validate internal links
40+
command: npm run test:internal-links
41+
42+
validate links use helper:
43+
docker:
44+
- image: node:16
45+
steps:
46+
- checkout
47+
- attach_workspace:
48+
at: .
49+
- run:
50+
name: validate internal links use the {% page %} helper
51+
command: npm run test:prefixed-links
52+
53+
workflows:
54+
version: 2
55+
test the built static content:
56+
jobs:
57+
- build
58+
- validate html:
59+
name: validate HTML
60+
requires:
61+
- build
62+
- validate internal links:
63+
name: validate internal links
64+
requires:
65+
- build
66+
- validate links use helper:
67+
name: validate internal links use the {% page %} helper
68+
requires:
69+
- build

.eleventy.js

+181
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
const { DateTime } = require("luxon");
2+
const fs = require("fs");
3+
const { EleventyRenderPlugin } = require("@11ty/eleventy");
4+
const path = require("path");
5+
const pluginRss = require("@11ty/eleventy-plugin-rss");
6+
const pluginNavigation = require("@11ty/eleventy-navigation");
7+
const markdownIt = require("markdown-it");
8+
const markdownItAnchor = require("markdown-it-anchor");
9+
const yaml = require("js-yaml");
10+
const svgSprite = require("eleventy-plugin-svg-sprite");
11+
const {
12+
imageShortcode,
13+
imageWithClassShortcode,
14+
slackChannelLinkShortcode,
15+
uswdsIconShortcode,
16+
} = require("./config/shortcodes");
17+
const { headingLinks } = require("./config/headingLinks");
18+
const postbuild = require("./config/postbuild");
19+
20+
module.exports = function (config) {
21+
// Set pathPrefix for site
22+
let pathPrefix = "/";
23+
24+
config.addPassthroughCopy({ "js/publish/*.js": "assets/js" });
25+
26+
// Copy Netlify config straight through
27+
config.addPassthroughCopy({
28+
"config/netlify.yml": "admin/config.yml",
29+
});
30+
31+
// Copy USWDS init JS so we can load it in HEAD to prevent banner flashing
32+
config.addPassthroughCopy({
33+
"./node_modules/@uswds/uswds/dist/js/uswds-init.js":
34+
"assets/js/uswds-init.js",
35+
});
36+
37+
// Copy the favicon
38+
config.addPassthroughCopy({
39+
"favicon.ico": "favicon.ico",
40+
});
41+
42+
// Add plugins
43+
config.addPlugin(EleventyRenderPlugin);
44+
config.addPlugin(pluginRss);
45+
config.addPlugin(pluginNavigation);
46+
47+
//// SVG Sprite Plugin for USWDS USWDS icons
48+
config.addPlugin(svgSprite, {
49+
path: "./node_modules/@uswds/uswds/dist/img/uswds-icons",
50+
svgSpriteShortcode: "uswds_icons_sprite",
51+
svgShortcode: "uswds_icons",
52+
});
53+
54+
//// SVG Sprite Plugin for USWDS USA icons
55+
config.addPlugin(svgSprite, {
56+
path: "./node_modules/@uswds/uswds/dist/img/usa-icons",
57+
svgSpriteShortcode: "usa_icons_sprite",
58+
svgShortcode: "usa_icons",
59+
});
60+
61+
// Allow yaml to be used in the _data dir
62+
config.addDataExtension("yaml", (contents) => yaml.load(contents));
63+
config.addDataExtension("yml", (contents) => yaml.load(contents));
64+
65+
config.addFilter("readableDate", (dateObj) => {
66+
return DateTime.fromJSDate(dateObj, { zone: "utc" }).toFormat(
67+
"dd LLL yyyy"
68+
);
69+
});
70+
71+
// https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#valid-date-string
72+
config.addFilter("htmlDateString", (dateObj) => {
73+
return DateTime.fromJSDate(dateObj, { zone: "utc" }).toFormat("yyyy-LL-dd");
74+
});
75+
76+
// Get the first `n` elements of a collection.
77+
config.addFilter("head", (array, n) => {
78+
if (!Array.isArray(array) || array.length === 0) {
79+
return [];
80+
}
81+
if (n < 0) {
82+
return array.slice(n);
83+
}
84+
85+
return array.slice(0, n);
86+
});
87+
88+
// Return the smallest number argument
89+
config.addFilter("min", (...numbers) => {
90+
return Math.min.apply(null, numbers);
91+
});
92+
93+
function filterTagList(tags) {
94+
return (tags || []).filter(
95+
(tag) => ["all", "nav", "post", "posts"].indexOf(tag) === -1
96+
);
97+
}
98+
99+
config.addFilter("filterTagList", filterTagList);
100+
101+
// Create an array of all tags
102+
config.addCollection("tagList", function (collection) {
103+
let tagSet = new Set();
104+
collection.getAll().forEach((item) => {
105+
(item.data.tags || []).forEach((tag) => tagSet.add(tag));
106+
});
107+
108+
return filterTagList([...tagSet]);
109+
});
110+
111+
// Customize Markdown library and settings:
112+
let markdownLibrary = markdownIt({
113+
html: true,
114+
}).use(markdownItAnchor, {
115+
permalink: headingLinks, // use our custom heading links
116+
slugify: config.getFilter("slugify"),
117+
});
118+
config.setLibrary("md", markdownLibrary);
119+
120+
// Override Browsersync defaults (used only with --serve)
121+
config.setBrowserSyncConfig({
122+
callbacks: {
123+
ready: function (_, browserSync) {
124+
const content_404 = fs.readFileSync("_site/404/index.html");
125+
126+
browserSync.addMiddleware("*", (req, res) => {
127+
// Provides the 404 content without redirect.
128+
res.writeHead(404, { "Content-Type": "text/html; charset=UTF-8" });
129+
res.write(content_404);
130+
res.end();
131+
});
132+
},
133+
},
134+
ui: false,
135+
ghostMode: false,
136+
});
137+
138+
// If BASEURL env variable exists, update pathPrefix to the BASEURL
139+
if (process.env.BASEURL) {
140+
pathPrefix = process.env.BASEURL;
141+
}
142+
143+
// Set image shortcodes
144+
config.addLiquidShortcode("image", imageShortcode);
145+
config.addLiquidShortcode("image_with_class", imageWithClassShortcode);
146+
config.addLiquidShortcode("slack_channel", slackChannelLinkShortcode);
147+
config.addLiquidShortcode("uswds_icon", uswdsIconShortcode);
148+
149+
config.addLiquidShortcode("page", (link) => path.join(pathPrefix, link));
150+
151+
config.on("eleventy.after", async () => {
152+
await postbuild();
153+
});
154+
155+
return {
156+
// Control which files Eleventy will process
157+
// e.g.: *.md, *.njk, *.html, *.liquid
158+
templateFormats: ["md", "html", "njk"],
159+
160+
// Pre-process *.md files with: (default: `liquid`)
161+
// Other template engines are available
162+
// See https://www.11ty.dev/docs/languages/ for other engines.
163+
markdownTemplateEngine: "liquid",
164+
165+
// Pre-process *.html files with: (default: `liquid`)
166+
// Other template engines are available
167+
// See https://www.11ty.dev/docs/languages/ for other engines.
168+
htmlTemplateEngine: "liquid",
169+
170+
// Optional (default is shown)
171+
pathPrefix: pathPrefix,
172+
// -----------------------------------------------------------------
173+
174+
dir: {
175+
input: "pages",
176+
includes: "../_includes",
177+
data: "../_data",
178+
output: "_site",
179+
},
180+
};
181+
};

.eleventyignore

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
CONTRIBUTING.md
2+
LICENSE.md
3+
README.md
4+
.github
5+
config
6+
___old

.github/ISSUE_TEMPLATE/page-update.md

-22
This file was deleted.

.github/dependabot.yml

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# To get started with Dependabot version updates, you'll need to specify which
2+
# package ecosystems to update and where the package manifests are located.
3+
# Please see the documentation for all configuration options:
4+
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
5+
6+
version: 2
7+
updates:
8+
- package-ecosystem: "npm" # See documentation for possible values
9+
directory: "/" # Location of package manifests
10+
schedule:
11+
interval: "weekly"

.github/pull_request_template.md

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
## Changes proposed in this pull request:
2+
3+
-
4+
-
5+
-
6+
7+
## security considerations
8+
9+
[Note the any security considerations here, or make note of why there are none]

.github/workflows/codeql-analysis.yml

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
name: "CodeQL"
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
schedule:
9+
- cron: "20 22 * * 2"
10+
11+
jobs:
12+
analyze:
13+
name: Analyze
14+
runs-on: ubuntu-latest
15+
permissions:
16+
actions: read
17+
contents: read
18+
security-events: write
19+
20+
strategy:
21+
fail-fast: false
22+
matrix:
23+
language: ["javascript"]
24+
25+
steps:
26+
- name: Checkout repository
27+
uses: actions/checkout@v3
28+
29+
- name: Initialize CodeQL
30+
uses: github/codeql-action/init@v2
31+
with:
32+
languages: ${{ matrix.language }}
33+
34+
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
35+
# If this step fails, then you should remove it and run the build manually (see below)
36+
- name: Autobuild
37+
uses: github/codeql-action/autobuild@v2
38+
39+
# ℹ️ Command-line programs to run using the OS shell.
40+
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
41+
42+
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
43+
# and modify them (or add more) to build your code if your project
44+
# uses a compiled language
45+
46+
#- run: |
47+
# make bootstrap
48+
# make release
49+
50+
- name: Perform CodeQL Analysis
51+
uses: github/codeql-action/analyze@v2

.github/workflows/formatter.yml

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
name: pull request
2+
3+
on: [pull_request]
4+
5+
jobs:
6+
format:
7+
name: format code
8+
runs-on: ubuntu-latest
9+
steps:
10+
- uses: actions/checkout@v2
11+
with:
12+
# Use the branch commit instead of the PR merge commit
13+
ref: ${{ github.event.pull_request.head.sha }}
14+
15+
- uses: actions/[email protected]
16+
with:
17+
node-version: 16
18+
19+
- name: format markdown
20+
run: npx prettier .
21+
22+
- name: commit changes, if necessary
23+
id: commit
24+
uses: EndBug/add-and-commit@v7
25+
with:
26+
default_author: github_actions
27+
message: format files
28+
29+
- name: leave a comment, if necessary
30+
uses: actions/[email protected]
31+
if: steps.commit.outputs.committed == 'true'
32+
with:
33+
github-token: ${{secrets.GITHUB_TOKEN}}
34+
script: |
35+
github.issues.createComment({
36+
issue_number: context.issue.number,
37+
owner: context.repo.owner,
38+
repo: context.repo.repo,
39+
body: `I have formatted the code. Please @${context.actor} pull the last commit before pushing any more changes.`
40+
});

0 commit comments

Comments
 (0)