This repo contains the website for Race Condition Running http://raceconditionrunning.com/
You should use virtual environments to isolate dependencies for Python.
uv is a great way to simplify dependency
and virtual environment management, and it enables you to use per-project
Python versions.
- Install
uv. Runuv helpto make sure your installation was successful. - Run:
uv syncandbundle install. - Install
entr, either via running:brew install entr(for macOS) orsudo apt install entr.
After you've installed the Python (uv sync ),
Ruby (bundle install) dependencies and entr (see section above for commands),
run:
make serve
From the root of this directory.
A successful deployment will serve a local instance of raceconditionrunning.github.io
on http://localhost:4000.
The live site is built and deployed by a GitHub action and served by GitHub pages.
Schedules are YAML files stored in the _data/schedules/ directory. Each schedule contains a list of plans. Check out the long-run scheduler if you'd like to automatically generate a schedule.
A plan represents a long run that may be broken into multiple legs. While uncommon, there can be multiple distinct plans on the same day.
Each plan is a dictionary containing:
date- Date inYYYY-MM-DDformatplan- List of leg dictionaries (see below)highlight_image- (Optional) Absolute path to an image displayed inline with the plannotes- (Optional) String displayed as a note for the plan
Each leg in a plan's plan list contains:
time- Start time in 24-hour format (HH:MM)routeORroute_id- Route information (see Route Options below)
You can specify routes in two ways:
Option 1: Reference existing route
route_id- String key matching a route in_data/routes.yml
Option 2: Inline route definition
route- Dictionary containing:name- Route name (string)map- Web map URL (string)distance_mi- Distance in miles (float)
When a route hasn't been chosen yet,
omit route_id and either leave out route entirely or
include an inline route with just a name of TBD.
The schedule layout will render these entries with a "TBD" placeholder.
Example TBD schedule entry:
- date: 2024-07-14
plan:
- time: "08:30"
route:
name: TBDBoth plans and individual legs can include a cancelled key:
- Any value (including empty string) causes strikethrough display
- The value content is shown as the cancellation reason
Add a GPX file to the routes/_gpx/ directory. The build will fail with a descriptive error if any route doesn't meet the minimum formatting requirements which get checked by _bin/make_routes_table.py.
- The file's
<gpx>tag must include the RCR extension:<gpx xmlns="http://www.topografix.com/GPX/1/1" version="1.1" creator="Race Condition Running" xmlns:rcr="http://raceconditionrunning.com/extensions"> <name>- lowercase, hyphenated name of the route. Ends withloopif the route is a loop orobif the route is an out-and-back.<desc>- The presentation name of the route, e.g. "Lake Union Loop".- You must include an
<extensions>tag in the<metadata>section, with<rcr:last_updated>YYYY-MM-DD</rcr:last_updated>.
Before you commit changes to a route, run make normalize-routes-in-place to ensure the route is formatted correctly.
To supply elevation data, run make replace-route-elevations and make normalize-routes-in-place.
If your route starts or ends at a new location, add a new feature to the routes/locations.json file.
Here are the concrete steps for making and adding routes to the repo:
-
Make a new route via OnTheGoMap. Please be careful when making them, pay attention, think carefully whether the route is actually runnable and safe. For example, if a route involves running alongside traffic (i.e., on the shoulder of a road) for long stretches, it is likely not very safe. Use Street View on Google Maps to help scope out a run.
-
Go to the hamburger menu at the top-right corner of OnTheGoMap and select "Export as GPX". Save the "shortened link" of the route for later use in Step 4 for
rcr:map). -
Move the GPX file to
routes/_gpxand give it a name based on its type (e.g., out-and-back, point-to-point, loop, etc.) and where it starts and what main areas it goes through. If the route is a loop, put-loopand if it is an out-and-back, put-obat the end. -
Edit the GPX (which is just XML) like so: from any existing route in
routes/_gpx, take all the content down to the<trkseg>tag and replace all the content in the original GPX file up until the start of<trkseg>with it. Then modify the fields specific to the route. This includes:- metadata
name(same as GPX file name) - metadata
desc - metadata
linkincludingtext - Only
rcr:mapandrcr:last_updatedunderextensions - track
name(same as GPX file name) - track
desc
- metadata
-
Run
./_bin/gpx-inplace-fixup.sh routes/_gpx/recently-added-route.gpxto add elevation data to the route. Make sure you have python installed since this script invokes other python scripts. -
Follow the instructions for
Building and Developing Locally. Then runmake serveto check that it works locally and the site looks right. -
If you are making more than one route, commit and push once for batching. The CI build is somewhat slow.
_bin/mkical.pygenerates an iCalendar file for the current schedule.- Routes are in
_data/routes.yml. - The current schedule is in
_data/schedule.yml. This is a symlink to the current season's schedule in_data/schedules/. - To create a new brunch review, add a new file to the
_brunch-reviewsfolder.
Use ImageMagick to compress images. Converting to high quality AVIF with a max edge length of 2000 works well:
mogrify -quality 90 -resize 2000x2000 -format avif -auto-orient *.jpg