This repository houses the 18F website. We use the U.S. Web Design System for the front end interface. The site is built and served through the cloud.gov Pages platform.
Note: The cloud.gov Pages platform does not support the use of a predefined SHOME
environment variable which impacts the installation of the site's testing dependency pry
(See the issue). In order to build the cloud.gov Pages deployment and keep the tests working in CI, a cloud.gov Pages specific gemfile (GemfileFederalist
) was created to exclude the testing and development groups during install. The federalist script in the package.json
is run during the build time a creates a bundler config to install the GemfileFederalist
dependencies and not the default Gemfile
. Any updates to the production builds Gemfile
should be included in the GemfileFederalist
until a better fix is in place for the pry
dependency or the cloud.gov Pages platform.
Make sure you have Ruby 2.7.4 and Python 3.9 installed and active for the project directory. Python 3.7, 3.8, or 3.9 is required for some of the dependency builds.
Run each of the following steps to get the site up and running.
git clone [email protected]:18F/18f.gsa.gov
cd 18f.gsa.gov
bundle install
npm install
./serve
To reduce the build time, instead of ./serve
you can run ./serve-fast
. This will eliminate all of the blog posts and the search index, but generates all other pages
You should be able to see the site at: http://127.0.0.1:4000/site/
NOTE: If you are using an M-series Mac (M1, M2, etc.), you may need to configure bundler to use special build flags for eventmachine. To do that, run:
bundle config --local build.eventmachine "--with-ldflags=\"-Wl,-undefined,dynamic_lookup\""
You may also have to run the
bundle install
step 2 or 3 times for everything to finish building.
Using Docker can make dependencies management easier, but can also slow down your build time. You can find out more in this discussion.
To try this out on MacOS:
- Install Docker Desktop via the GSA Self Service or download from their website.
- Make sure Docker is running (you should see the whale icon in the taskbar or menu bar).
- Open a termninal window (CMD+Space on Mac, Start > Run > "cmd" on Windows) and navigate into your project folder
cd folder_name_with_code
. - Run
docker compose build
to build the docker image and its dependencies. - Run
docker compose up
. Note: if you want to run a single command and bypass yourDockerfile
for debugging purposes, you can do like sodocker compose run app <COMMAND>
(for instance, you can run bundledocker compose run app bundle install
). Our site is large, so this could take awhile. - Visit http://localhost:4000/site/ in your browser. Make sure that you include the trailing slash.
If there was an error with the build, rebuild using the --no-cache
option like so docker compose build --no-cache
to avoid using the old version of the docker image.
The site is a static website with HTML, CSS, and Javascript. Deployments are done through cloud.gov Pages.
- cloud.gov Pages runs in its own organization and space in cloud.gov, which piggybacks on AWS GovCloud.
- Federalist Admin.
- cloud.gov Pages responds to a webhook on GitHub and runs Jekyll to generate static web files and puts them in an S3 bucket.
- We map 18f.gsa.gov URL to the S3 bucket.
18f.gsa.gov is using several Ruby gems plugins:
Plugin gem | Description |
---|---|
jekyll-archives |
creates and manages blog-related pages. |
jekyll-feed |
generates an Atom (RSS-like) feed at /feed.xml . |
jekyll-paginate |
allows for pagination of blog pages, or pages with long lists of items. |
jekyll-redirect-from |
enables redirecting from pages that are no longer active. |
jekyll-seo-tag |
adds metadata tags for search engines and social networks. |
jekyll-sitemap |
generates a sitemap at /sitemap.xml . This makes it easier for search engines to find us. |
embed |
creates a Liquid tag that uses OEmbed |
The site relies primarily on USWDS version 3. We use uswds-compile to copy over USWDS assets and compile the css. We use a utility-class-first approach, using the appropriate USWDS utility classes to style components whenever possible. Please ensure that style updates are consistent with our brand's colors, typography, and iconography.
There are two main style files located in the _sass
folder:
styles.css
serves as the entry point for all of style files. This file forwards all of the other styles used in the project (i.e. the USWDS source code, the settings, and all custom stylesheets).uswds-theme-custom-styles.scss
contains global custom styles
When you’d like to make a style change, first check the USWDS settings to check if the setting could be adjusted, rather than creating a new style.
In addition to the style files listed above, the typography.scss
file sets site-wide styles for headings. There are also custom component specific style files in the _sass/_components
directory. Where possible USWDS components should be used in lieu of custom components, because they will be better maintained.
Finally, the variables.scss
file contains defined variables that are reused throughout the site.
We have a number of custom components that are used as repeatable elements throughout the site. Some components like the testimonial may be particularly useful when updating case studies.
This component outputs a small card with image and text. The whole card is a clickable link.
Expected arguments:
link_url
- the url the card will link to (href).
image_path
- the path to the image. Note that the partial will prepend the site baseurl. It should start with a leading forward slash (“/”).
text_content
- the text to be displayed next to the image.
Optional arguments:
card_color
- if set to "dark"
, will make the card background the primary-dark color. Otherwise the background will default to a white color.
image_alt_text
- will be the alt text for the image. If this argument isn’t provided, alt text will be set to “” and screen readers will ignore the image.
image_side
- if set to "right"
, will place the image on the right side of the card. Otherwise the image will default to the left side.
image_size
- if set to "md"
, will set the max image size to 8 units. Otherwise the image will default to a max size of 6 units.
Example A light card with the image on the left:
{% include card-with-image.html
img_path=”/asset/img/guides/accessibility-darker.svg”
img_size="md"
link_url= “https://accessibility.18f.gov”
text_content=”Accessibility”
%}
This component outputs a list of blog post previews to be displayed on pages other than the blog. Each preview will take up 12 columns on mobile screens, 6 columns on tablet screens, and 4 columns on screens larger than a tablet.
Expected arguments:
related_posts
- This is the computed list of posts that should be displayed as blog post previews.
Optional arguments:
color_mode
- If set to “dark”, the post previews will use a white text color and the primary-lightest border color.
max_num_posts
- Sets a limit on how many post previews to output.
show_excerpts
- If set to true, will show an excerpt from the blog post. The excerpt must be defined in the front matter of the blog post.
Example
{% assign matching_posts = page | match_posts | sort:'date' | reverse %}
{% include featured-posts.html
related_posts=matching_posts
max_num_posts=3
show_excerpt=true
%}
This component will output a styled component with an image and text below the image, and light border on the bottom.
Expected arguments:
body-text
- the text that will be displayed below the image.
image_path
- the path to the image. Note that the partial will prepend the site baseurl. It should start with a leading forward slash (“/”).
Optional arguments:
image_alt_text
- will be the alt text for the image. If this argument isn’t provided alt text will be set to “” and screen readers will ignore the image.
Example
{% include graphic-block.html
image_path="/assets/img/home/cando_illo_1.svg"
body_text="Modernize software development processes"
%}
This component will output a block with links to 18F’s social media pages, as well as the RSS feed. The data used to generate this component is in _data/social_media.yml
. This data file lists out the platforms, links, and the image path to the relevant social media icons to be displayed.
This partial will output a formatted block quote. The testimonial will be on a dark background with white text and a large, stylized open-quote mark.
Expected arguments:
quote
- the quoted text that will make up the testimonial.
attribution
- the quote’s author. Comma added dynamically.
Optional arguments:
size
- if set to “md”
, this will output a slightly smaller block quote that will fit within the project template’s main text. Otherwise it will default to the larger size.
position
- the quote author’s professional position. If organization
is defined, position
displays before it.
organization
- The quote author's organization. If defined, displays as the last element.
Example
{% include testimonial.html
size="md"
quote=" Our experience with 18F has been much different. They have helped us learn agile development as members of our team. The daily standups have really helped us form a close working relationship with them. They have introduced us to a new tools that I expect we will continue to use when our work with them is completed."
attribution="Monica Windom"
position="Director Division of Public Assistance"
organization="Health and Social Services, State of Alaska"
%}
The default layout serves as the base layout for all of the other layouts. It adds the header and footer elements, along with the styles and scripts tags.
The primary layout is used on Home, Work with us, and Our work pages. The layout will automatically add an h1
heading, along with the lead text, and the page image if those two options are set to the front-matter. The layout will add the remaining page content without adding any additional styling or containers to it.
The primary template uses Jekyll front matter heavily to account for variations within the site. Below are the the potential front matter attributes that you can use. Some are listed as (optional). These can be used to alter the appearance of a page.
Attribute | Type | What it does |
---|---|---|
title |
String | Title for the page visible in blue banner at the top of the page |
permalink |
String | Path that the page renders relative to the site's baseurl |
layout |
String | The type of layout to use for this page |
lead |
String | Large text that renders below the h1 heading |
image |
String | (optional) Path to hero image for the page. |
image_alt_text |
String | (optional) Accessibility text for the image. If not set the alt text will default to "" and the screen readers will ignore the image. |
This layout is based on the primary layout and is meant to be used with pages that are primarily composed of text without additional markup. The layout will place the page content into a 7 column container on tablet-sized screens and up.
In addition to the front matter options available in the primary
layout, the styled-container
layout has a few additional layout options:
Attribute | Type | What it does |
---|---|---|
side_cta |
Boolean | (optional) Set to false by default. When set to true , generates a rectangular banner with a call to action to the right side of the main content. The content for this component is in side-cta.html . |
social_media |
Boolean | (optional) Set to false by default. When set to true , generates a rectangular banner with links to 18F's social media (the social-media.html component). The data used to generate this component is in _data/social_media . |
subnav_items |
Object | (optional) Navigation items object that contains a list of subnavigation items that contain a permalink and text . Renders a sidenav. |
subnav_title |
String | (optional) Set if you want the subnav title or breadcumb text to differ from the page title . |
The post
layout is used for blog posts.
Attribute | Type | What it does |
---|---|---|
authors |
Object | The list of this post's authors |
date |
String | The publication date for the blog post. |
excerpt |
String | A short summary of the post that will appear on in lists of blog post previews. |
title |
String | The title for the blog post. |
tags |
Object | The list of tags that are relevant to this post |
image |
String | (optional) Path to hero image for the page. |
image_alt |
String | (optional) Accessibility text for the image. If not set the alt text will default to "" and the screen readers will ignore the image. |
The layout for case studies. This layout is automatically applied to any case study in the_products_projects
or the _services_projects/
folders.
Attribute | Type | What it does |
---|---|---|
agency |
String | The agency partner for the project. |
title |
String | The title for the case study. |
subtitle |
String | The subtitle for the case study. |
permalink |
String | Path that the page renders relative to the site's baseurl . |
redirect_from |
String or Object | Path that should be redirected to this page. |
excerpt |
String | A short summary of the project. This text will be displayed as a preview in the card-project . |
mini_excerpt |
String | (optional) An even shorter, tweet length summary of the project. This summary is used in a card_with_image . |
image |
String | (optional) Path to hero image for the page. |
image_alt |
String | (optional) Accessibility text for the image. If not set the alt text will default to "" and the screen readers will ignore the image. |
project_url |
String | (optional) A url to the project website. |
github_repo |
String | (optional) A url to the github repo for the project. |
resources |
String | (optional) A url to any relevant resources for the project. |
A number of layouts are used for pages that are dynamically and automatically created when a blog post is added. In general these layouts should not be used for manually created pages.
The layout for displaying blog post previews by author.
A list of all of the tags used by the blog.
The layout for displaying blog post previews by tag.
See the blogpost example file for a template and instructions on how to create a new post.
- Determine if the project is a service or a product and find the corresponding directory
- Create a new file within either the
_products_projects
or_services_projects
directory and name it with the following format:[agency acronym]-[project-name].md
. - Set the values for the relevant front matter as it applies to this case study. Please see the documentation on the project-page layout to see the available options.
It really helps to have good pictures to help us highlight project work — but you might need a little more guidance about how to get pictures that will tell a story best. Here are some helpful tips:
If possible:
- Image should relate to the project title, the department, or the process (in order of preference)
- Show real users that benefit from this project
- Show a screenshot from the project
- Mix it up! Look at the current project list. Do you see too many of the same type of image (for example, mostly screenshots, mostly brainstorming sessions)
Consider accessibility and try to avoid images that:
- Are low-contrast
- Have wording on them
Consider the audience (government employees and potential partners!) and try to avoid images with the following:
- Sensitive subject material (for example, children when writing about Child Protective Services)
- Uninteresting subjects
- Super meta imagery (too much of a cognitive leap when relating to subject matter)
Size: Future guidance to come.