To add a new job posting, first copy the template. The easiest way to copy it is to open this raw view, select all, and copy. Then create a new file by opening this link. On the page that opens, paste the template you copied earlier into the body. Add a filename (at the top), and then follow the instructions in the template.
If the job you're posting doesn't have opens or closes dates yet, leave them blank and you can add them later when you know. The job will show as "upcoming" until then. Once you add dates, you do not have to edit the job again to change it from upcoming to open to closed; it will updated automatically every night.
For the most part, the template should take care of all the formatting you will need to do. However, if you have an unusual job that doesn't fit neatly into the template, the site builder provides some tools that can be helpful when creating your custom job posting page.
-
If you want to include the opening date of a job, you can write this into your markdown to have it displayed nicely-formatted, based on the
opens
data at the top of the file:{% include jobs/open_date.html %}
-
Similarly, you can include the closing date. This one includes
at 11:59 pm ET
at the end:{% include jobs/close_date.html %}
-
For other dates, you can get a nicely-formatted output using the "human_friendly" filter. Be sure the date you provide is in the
YYYY-MM-DD
format in order for this to work:{% 2023-01-01 | human_friendly %}
...outputs
Sunday, January 1st, 2023
-
If you need to call a visitor's attention to some information, you can use a USWDS alert box. To make that easier, you can use this shortcut to put one on your page:
{% include alert.html heading="Alert heading, in big bold letters" body="The main content of your alert. Something the user needs to see." type="(info | warning | error | success)" icon="(true | false)" %}
The
body
portion is required. The rest may be omitted. If you do not includetype
, the alert will be an info box. These values are permitted fortype
:info
warning
error
success
If you do not include
icon
, the alert icon will be displayed. You can turn off the icon by settingicon="false"
.
The Join TTS site has a static API that provides a list of upcoming and open jobs. The static API is updated whenever the site is rebuilt, which includes when jobs are added or updated and the nightly automatic rebuild. As a result, the static API always reflects the same information as the site.
The Join TTS site is automatically redeployed every night. As a result, jobs
will automatically move from upcoming to open, and from open to closed, based on
the opens
and closes
dates in the job. Once both values have been set, the
job will go through the stages automatically. There is no need to manually
update them.
Once a job has closed, it will also be automatically archived. Archived jobs are
moved from the /positions
folder into the /archive
folder. A job is archived
by copying the job's BUILT directory from the _site/join/
directory into
the /archive
directory and adding this frontmatter:
---
layout: raw
title: "{{ the job title }}
Where {{ the job title }}
is taken from the SOURCE file for the job. The
automatic procedure runs every night and creates a
pull request to make the archival permanent. It
is not necessary to archive a job for it to be removed from the front page.
Archival is just a tool to help keep the repo tidy and easy to navigate.
IMPORTANT NOTE: The BUILT job is used for the archive so we can be certain it won't change in the future if we need to change the behavior of layouts, includes, or other components of the site. Archiving the original source could result in archives having different information in the future than they had at the time the position was posted.
This site is built with Jekyll using the uswds-jekyll theme, so you'll find configuration information there.
Docker is the preferred method of working on this site.
-
Install Docker : Try typing
docker version
in your terminal to see if it's already installed. If it's not, Docker Desktop is an easy way to install. -
Running the site:
docker-compose up
then open http://127.0.0.1:4000 -
Running tests:
docker-compose run --rm web bundle exec rake test
-
Debugging
- SSH into the Docker container with
docker-compose run web /bin/bash
- SSH into the Docker container with
Some developers have trouble getting Jekyll to run in Docker on certain Macs.
You may be able to run the site without Docker using Ruby directly. Getting the
right version of Ruby setup is an exercise left to the reader, but it should be
Ruby 2.7.*
.
Once Ruby is installed, run the following commands from the project directory:
gem install bundler
# Install gems into a local directory, to avoid global
# pollution. The .vendor directory is ignored from git
bundler config set path ./vendor
# Install dependencies. This could take a while.
bundle install
bundle exec jekyll serve --host 0.0.0.0 --livereload
Assuming everything goes well, you'll be able to view your development version live at http://localhost:4000.
The default layout
is provided by the USWDS theme and is used as the basis for
the page
and job
layouts. There is also a raw
layout which adds no markup
and outputs the contents alone.
layout | use |
---|---|
default | The index.md page, represeting the landing page for the site |
page | All pages in the pages/ directory. Adds a side navigation bar |
job | All pages in the positions/ directory. Adds info sessions and a side navigation bar |
raw | All pages in the archive/ directory. Does not add any markup to the provided content |
There are three general-purpose includes and several more that are only meant to be used on job pages. First, the general-purpose includes:
-
footer.html - Used by the USWDS
default
theme to add a site footer. -
meta.html - Used by the USWDS
default
theme to add meta content to pages. -
alert.html - Used to display a USWDS alert component. The
body
property is required, but the others are optional.type
defaults toinfo
andicon
defaults totrue
.{% include alert.html heading="Alert heading, in big bold letters" body="The main content of your alert. Something the user needs to see." type="(info | warning | error | success)" icon="(true | false)" %}
There are also several includes that should only be used on jobs pages. These
includes make assumptions that the page will have the frontmatter that is
expected on jobs pages. They do not accept any arguments and take all of their
input from the page
variable.
-
job/apply_button.html - Using the job's opens/closes dates and application link, displays a button linking candidates to the actual application page if the job is open. Otherwise displays a link to subscribe to the newsletter.
-
job/appointment_type.html - Displays appropriate text according to the job's appointment type.
-
job/close_date.html - Using the job's closes date, displays a nicely formatted date, with
at 11:59pm ET
appended to the end. -
job/full_info_on_usajobs.html - Displays text indicating that the full information for this job is or will be available on USAJOBS. If there is an application link for the job, it will be included in this text.
-
job/info_sessions.html Using the job's info sessions data, if any, to display the upcoming info sessions for the job.
-
job/key_objectives.html Using the job's key objectives, if any, to display those key objectives. This exists primarily to help enforce consistency.
-
job/open_date.html - Using the job's opens date, displays a nicely formatted date.
-
job/status_alert.html - Using the job's opens/closes dates, displays an alert banner announcing the job's current status (upcoming, open, or closed).
-
job/salary_range.html - Using the job's gs property, or the provided values, displays the salary range for the job.
{% include job/salary_range.html min="$10" max="$15" %}
Both arguments are optional. If omitted, the salary range will be taken from step 1 and step 10, respectively, of the lowest and highest locality areas, also respectively. This is taken from the
_data/pay_ranges.yml
file and must be updated whenever GS pay tables are modified.
-
human_friendly
- this filter can be applied to Date objects to turn them into nicely formatted strings. E.g.:{{ 2022-07-19 | human_friendly }}
produces
Tuesday, July 19th, 2022
-
open_positions
- this filter can be applied to a list of job postings and will return only the job postings that are currently open -
upcoming_positions
- this filter can be applied to a list of job postings and will return only the job postings that are upcoming -
job_posting_status
- this filter can be applied to a single job posting and will return a string indicating the posting's current status:upcoming
,open
, orclosed
. This is derived from the opens and closes data in the posting frontmatter. If either is missing or not a valid date, the job isupcoming
. -
future_info_sessions
- this filter can be applied to a list of info sessions (such as general info sessions) and will return a list of info sessions that are either today or in the future. -
future_info_sessions_for_job
- this filter can be applied to a single job posting and will return a list of info sessions for the job that are either today or in the future. -
string_is_link
- this filter can be applied to a text string and will returntrue
if the string begins withhttp://
orhttps://
, orfalse
otherwise.
This project is in the worldwide public domain.
This project is in the public domain within the United States, and copyright and related rights in the work worldwide are waived through the CC0 1.0 Universal public domain dedication.
All contributions to this project will be released under the CC0 dedication. By submitting a pull request, you are agreeing to comply with this waiver of copyright interest.
Special thanks to the team at 18F for their open and transparent model which benefits citizens, government and technology.