-
Notifications
You must be signed in to change notification settings - Fork 9
The Big Tech Doc
Do you prefer to dive right into the code instead? Please read the README for instructions to run the prototype locally.
Table of contents:
- Background and Goals
- Why Hugo?
- Getting access
- Keeping the repository healthy
- A tour of the Guides theme
- Pushing changes to production
This document is for engineers new to the Guides and Methods Team. It also benefits anyone that wants to learn about Hugo as a static site generator, why it’s a good option for our partners, and best practices for building software for content editors.
If you prefer to just get started and explore on your own, follow the repository README for local development instructions. At the time of this writing, there are 10 guides in 10 separate repositories. The Guides and Methods team created a prototype to demonstrate how to centralize the guides into one repository while improving performance and maintenance.
Following the 18F model, we used this opportunity to address the content across the guides. This prototype demonstrates how a new, centralized information architecture could be implemented.
We had a lot of technical hypotheses, which this prototype can continue to test: Airtable of hypotheses with the Technical label. Full list of architectural hypotheses. For a list of the existing Guides and their GitHub repositories, see the 18F guides index (18F Only 🔒)
The Guides and Methods team needed a JAMstack git-based framework that can run on cloud.gov Pages to replace Jekyll. It has to be easy to learn, fast for prototyping, easy for vendor developers to pick up and manage in sandboxes and in production. We identified common developer tasks and examined how quickly and easily different frameworks allowed us to implement them. Hugo stood out by having excellent documentation and many pre-built (out-of-the-box) functions to perform these tasks. See Benefits.
A collection of Technical Requirements for the Guides & Methods: Technical Requirements
A presentation on the decision process: Engineering Huddle - Replacing Jekyll for our Guides & MethodsEngineering Huddle - Replacing Jekyll for our Guides & Methods
You don’t have to know Go. Although Hugo is written in the Go programming language to support multiple platforms, you don’t have to be a Go developer. You don’t even have to install Go. Just grab a precompiled binary from Hugo’s Releases page. [Explain how this works on Pages]
Git-based. Independent of Git version control provider (GitHub, which is low FISMA, GitLab which is moderate FISMA)
Easy to follow documentation. I installed Go locally on a Mac with Homebrew, following Hugo’s Getting Started guide. Within minutes I had a working local site. It took me __ days from initially poking around the documentation to having a fully fledged prototype. See snapshots of my progress in the GitHub repository.
Standardized functions to create new content using archetypes.
Archetypes are content template files in the archetypes directory that contain preconfigured front matter and even content disposition for the Guides and Methods content types. These are used when you run the hugo new
command. See how we implemented archetypes in Creating new pages and Creating new sections.
Having archetypes allows us to potentially connect these functions to content management system actions.
Live reload by default allows us to make the changes to the site configuration, (or any other file in the Guides and Methods site) while the Hugo server is running, and instantly see changes in the browser.
This means we don’t have to stop/start the server to pick up config changes. You’ll see the log message Change of config file detected, rebuilding site
.
You might have to hard reload your browser cache once in a while.
Git submodule support. Use these to add themes without worrying about maintaining them. Updating the theme is as simple as running a git command, instead of manually updating files.
Template partials can be used for USWDS components. This allows us to update USWDS HTML separately.
Simple multi language support. Jekyll notoriously made multi language support hard and had no out of the box options. Various plugins had to be installed and not all of them were maintained. Hugo offers not only makes setting up multi language easy on Guides and Methods, it handles URL permalinks and redirects flawlessly and has options to spin up servers per language. Since all URLs are generated from the root, the English home page .Permalink is set to https://example.com/, not https://example.com/en. If a file has no language code, it will be assigned the default language of English.
Page resource handling allows images, pdfs, and other documents, can have page-relative URLs and their own metadata. Page resources are only accessible from page bundles, the directories with index.md or _index.md files at their root. Page resources are only available to the page with which they are bundled. You can create page bundle archetypes, which is a superb feature! It allows us to create entire sections with default content just by running a script. Imagine adding an entirely new guide with preloaded content, pages, and navigation just by running a one-line script. Not only is this a time saver for engineers, but this script can be tied to a content management system action. Potentially, a product owner could start a new guide with no engineering work. Read about Creating new sections to learn how we implemented this.
Dynamic menus. Hugo makes no assumptions about how your rendered HTML will be structured. Instead, it provides all of the functions you will need to be able to build your menu however you want.
Section page templates are a HUGE asset. They allow us to create custom layouts for a specific section. Just by giving the custom layout the same name as a section, Hugo automatically recognizes it and will apply the customized template layouts instead of the parent theme layouts. This is a powerful tool to create a section that has a different “look and feel” but maintains the same infrastructure behind the scenes. See the “fancy theme” description to see how we implemented this.
Blocks allow you to override parts of the base template (for example, a footer) in other templates. This feature makes templates more powerful and layouts more modular. **Goldmark **is the default Markdown parser as of Hugo 0.60. Hugo creator Bjørn Erik Pedersen (also known as @bep) says it’s “fast, it’s CommonMark compliant and it’s very flexible.”
Cached partials for header and footer Partial Templates | Hugo
Google Analytics. Provide your tracking ID in your configuration file. Also Internal Templates | Hugo
Fingerprinting for any asset. The default hash function is sha256. Other available functions are sha384 (from Hugo 0.55), sha512 and md5.
Other cool benefits
- Image minification and resizing
- Simple sitemap generation
- cloud.gov Pages requires
config.yml
, notconfig.toml
, Hugo’s default. - See digital.gov config.yml
- and the USWDS template.
- cloud.gov Pages requires a .hugo-version file. You can use one of Hugo’s command line converter tools.
- Different case best practices: PascalCase, camelCase and snake_case ii.com: Variable and Parameter Names in Hugo (featuring camelCase🐫 and snake_case🐍)
- Commonmark Unfortunately, attribute syntax {.classNameHere} can only be applied to headings
- Hugo does not offer official Hugo images for Docker, but they do recommend these up to date distributions: https://hub.docker.com/r/klakegg/hugo/, as stated in their Install Hugo documentation.
- Commonmark claims to support creating paragraph breaks using a \ backslash passed through the
markdownify
filter, but when I tried it, it didn’t work. - Sitemaps are created per language. You’ll have to navigate to guide.18f.gov/en/sitemap.xml for the English sitemap.
- Learning new basic syntax
- Iteration uses range instead of
for
- Conditional with instead of
if
- Multilingual archetypes
- Can you have two themes for different sections of a site?
- Technically, no. There has been some discussion around the best way to do this. You can only have one theme at a time, which is set in the site configuration. However, we accomplished the same outcome by adding section-specific layouts, which are awesome.
Read how we did this in the ‘fancy’ layout template.
This repository is public and visible to anyone, per 18F’s open source policy.
To grant someone access, go to Settings > Collaborators and teams. After multi-factor authentication, you’ll see the list of groups and people with access. We created the guide-admins
group for members with an Admin role. You can also add members with more limited Read and Write roles.
The Guides and Methods Hugo site runs on cloud.gov Pages. To access see build history and logs, visit your Pages dashboard at https://pages.cloud.gov/sites
.
- Click Add site.
- Paste
https://github.com/18F/guides-and-methods-hugo
as the repository URL. - Select 18F as the organization.
- Click
Add repository-based site
.
Once the site is successfully added, you should see 18f/guides-and-methods-hugo
in your site list. Click the title to view the site build history for every branch. Build logs will only be available for 180 days after the build completes.
If you need access to cloud.gov Pages, email [pages-support@cloud.gov](mailto:pages-support@cloud.gov). You can also ask for help in the Slack #pages-support channel or fill out the [Pages Contact](https://federalist.18f.gov/contact/) form. Make sure you provide your GitHub username and our repository URL.
Every branch is built by Pages with a site preview. The preview link is auto-generated within a [pull request](https://github.com/18F/guides-and-methods-hugo/pull/29), also known as a PR. At the bottom of a PR, click on Show all checks > pages/build > Details. Note that previews are only available after a complete build, which is super fast with Hugo. Share these URLs when you’re asking for feedback or approval on a change. It’s good practice to include the site preview link in your PR. Your reviewer does not need a GitHub account to view a preview link. [screenshot of How to get a Federalist preview URL] You can also find links to site previews under each branch name after logging into Pages.
Since the prototype is not live, Google Analytics was not implemented. To access analytics for the existing Guides using the Digital Analytics Program (DAP) dashboard, visit https://analytics.usa.gov/general-services-administration/data/. You’ll have to download the csv or json file and manually search for 18f.gov domains. For targeted data with real-time reports, visit the Google Analytics dashboard. Ask Julie Strothman - QUEACG to add you to the 18F Analytics Account. You’ll find views for each Guide under the Microsites (Pages) property. Read more about How analytics work for the Guides doc. Watch a walkthrough of analytics recording.
Since the prototype is not live, Search.gov was not implemented, but should be before it launches. To access search.gov results for the existing Guides, email [search@gsa.gov](mailto:search@gsa.gov) with the URL of sites you’d like to review. Once you have access, log into https://search.usa.gov/ and select a site. You can generate reports based on queries, clicks, and referrals.
Currently, only the existing Methods site uses [Touchpoints](https://touchpoints.app.cloud.gov/touchpoints/d028f982/submit).
To access the Touchpoints form and results, please contact Julie Strothman - QUEACG, Anne Petersen - QUEACA, or Melissa Braxton - QUEACI. Once you get access to Touchpoints, you must log in once every 90 days or your account will be deactivated, requiring you to email Touchpoints staff for reactivation. These deactivations happen at the end of each month.
As a site administrator, you should receive email notifications for Dependabot alerts. Dependabot will create a new branch and a pull request but you have to merge it into the main
branch.
Regularly merging in dependabot updates not only keeps you up to date with dependencies and security. This activity prevents your repository from being auto-archived or “frozen”. Plus, having outstanding pull requests is just a bad look since these are public repositories.
Make sure you enable branch protection to the main
branch. Go to Settings > Branches and apply the following options:
- Require a pull request before merging
- Require approvals (at least one)
- Require status checks to pass before merging
- Require branches to be up to date before merging: pages/build
- Currently
Build deployment – pages/build (cloud.gov)
is the only check set on the main branch. See Future work for next steps.
Once this setting is updated, you’ll the the build status under “View all checks”
This repository includes the topic maintained
to prevent auto-archival.
If you’re an 18F organization manager in cloud.gov Pages, you can add users and assign them roles of manager or user. You’ll need their id (for example, mine is 902).
Pages also provides sandboxes which are useful as a staging environment outside of the public 18F organization. This is especially helpful when testing out workflows that send out notifications.
The following are the repository Webhook settings for Pages, found at Settings > webhooks:
Payload URL: https://pages.cloud.gov/webhook/github
.
Content Type: application/json
Secret: provided by Pages team
If you need to make changes or add another webhook, you'll notice a check icon in front of the webhook with the label “Last delivery was successful”.
After a successful merge, delete the branch.
Run the following command locally. Hugo’s default port is 1313.
pa11y-ci -s http://localhost:1313/en/sitemap.xml --sitemap-find "//localhost:[PORT]" --sitemap-replace "http://localhost:[PORT]/"
Components: themes/guides/layouts/partials, themes/guides/layouts/partials/uswds
Layouts: themes/guides/layouts
- homepage
- list
- basic
- fancy
- sitemap
Link title: string
Hero: false
Breadcrumb: true
Side navigation: true
In-page Navigation: true
Wordcount: # words
ReadingTime: # minutes read
Aliases: array
BundleType:
Publish date: today
Last modified: January 1, 0001
Sort weight: 0
Is translated: false
Previous page: Page With Code
Next page: In-Page Navigation Page
Tags: accessibility methods
Summary: string
We separated custom components from USWDS components intentionally. They are named just as they are in USWDS documentation. Since there is yet no push/pull mechanism for updating HTML from USWDS, this practice allows us to keep our HTML clean and reuse components.
Example: identifier.html
Menus | Hugo - here’s how navigation works in Hugo in more detail.
In general, Hugo will generate certain lists based on the type of page you’re creating: the first page in a section will list all the pages within that section, which is powerful. Hugo’s menu creation abstracts relationships between content no matter what that content is.
Independent of the type of content that you have, Hugo has functions to recursively examine that content and generate things like the page title, URL, author, front matter, and metadata from the content there.
Hugo has menu templates, or you can create your own.