How This Site Works

The site content is authored using Markdown, generated by Hugo, stored on GitHub, editable on Forestry, buildable on your computer, and deployed by TeamCity to Amazon Web Services.

Anatomy of A Web Request

The website is served up using several major pieces of back-end infrastructure. You don’t need to understand all of it, bit it helps to recognize that not everything lives in one place.

Amazon CloudFront

Amazon CloudFront is a content delivery network. It does two things for us:

  1. Its caches responses from our back-end servers in edge servers very close to the end-user’s computer. This makes common web requests very fast, all over the world.
  2. It determines, based on rules we configure, which back-end server should receive the request. It does this by looking at the URL, request headers, and the country of the end user.

Google App Engine

Starting in 2007, all of has been hosted on Google App Engine. This is a combination of python code, templated dynamic pages generated with HTML and Jinja, and fully static HTML, CSS, JS, and images. The source for this project is at

The web server handles both language and region detection of the end user, to render appropriate content.

  1. To detect language, the server looks at the HTTP Accept-Langauges header, a cookie set by the user, or an explicit language in the URL ( and picks the most appropriate language supported by our server.
  2. To detect region, the server looks at the CloudFront-Viewer-Country header. This is mapped to a McNeel region, and is used to display, for example, regional currency values on the sales page.

This server is responsible for dynamically generated content, such as:

  • /download/* pages
  • /sales/* pages
  • Login and logout handling
  • /licenses/* pages

Python Proxy

Starting in 2020, sections of started to be hosted on back-end infrastructure besides Google App Engine. In order to make this work, Brian Gillespie wrote a HTTP reverse proxy in python that rewrites content from all the back-end servers to have links, images, and URLs that are on the top-level domain. This proxy is responsible for:

  1. Detecting the user’s language, and requesting the proper localized page from the proper back-end resource
  2. Rewriting requests coming in on the domain to the proper back-end service URL.
  3. Rewriting the contents of pages served up from the back-end services so that all the static content and links stay within the domain (except, of course, for external links).


Starting in 2020, this repository ( became the home for all static content for The content is authored in markdown, and compiled using Hugo into HTML, CSS, and JS files. The site is published to S3.


[TODO] How the viewer works. Link to github repo

Rhino Inside Revit

[TODO] How the RiR page works. Link to github repo

[TODO] Defunct. Gallery moved to Discourse


[TODO: animation of an overview of how the site works: Hugo processing markdown and producing html etc.]









A nice introduction to Hugo can be found here: Concepts of Hugo: What is What.


Forestry is a web-based WYSIWGY editor that makes commits to the repository. Forestry also allows us to standardize and organize our frontmatter (metadata) templates and apply them in a consistent manner.

Avoiding conflicts in Forestry

When you click Save in Forestry, a commit is made. Before clicking Save, forestry is holding onto your changes and will display the following on the page:

Document Status

These changes won’t end up being “final” until you click Save.

Because Forestry is always committing to the master (main) branch of the repository, there is the potential for conflicts. In addition, the way we are using Forestry - with direct links from the content back to the Forestry editor - may give rise to potential for lost work. There are a couple best-practices to avoid conflicts and lost work:

  1. When you are done, always click Save, especially for draft content or content that is a WIP. This tells Forestry to commit those changes to GitHub.
  2. When you are done working, close your browser tab. This tells Forestry that you are not working in this content right now and other users will be able to edit the content without fear of conflicts.

But we are all forgetful sometimes! Sometimes you might encounter these messages:

Someone updated this document

This dialog has two known variations:

Forestry Gotchya 1


Forestry Gotchya 2

Your only option is to click the Gotchya (OK) button and continue.

The first of the two is often encountered while you are viewing content but have not yet edited it yet. Someone else has changed the content and Forestry is telling you that it has changed.

The second of the two contains the “If you save, you might overwrite their changes” warning. This occurs when you have Unsaved Changes and someone else has changed the content file. This is a more dangerous situation as, if you click Save you might delete their changes. In this case, it is best to ask on slack who is editing the content, or - if you are comfortable - visit the content folder on GitHub and see who has recently changed the file you are working on and talk with them before proceeding.

Autosaved Document

This dialog:

appears when you are opening some content that someone else is already in the process of editing (but has not yet saved). The safest choice, by far, is to click Continue Editing. When you click Continue Editing, the changes that are in-progress - but not yet saved/committed - are there for you to continue working on.

WARNING: Clicking Discard Changes is dangerous and should be avoided; this will discard all the in-progress changes and you will be back at the state of the content before any changes have been made).


This site deploys automatically when pushed to the master branch of this GitHub repository.

The Deploy TeamCity build gets the newest source, and then runs The script/ which uses script/ to do some of the string formatting for the AWS uploads.

The build process maintains a previous copy of the deployed content so that it can quickly generate a list of changed files. Only the changed files are uploaded to the production website, and only the associated URLs are invalidated on CloudFront.

Occasionally deployments are incomplete. If this happens, force a full deployment.

To force a full deployment:

You should never need to do this; if you do, please let Brian Gillespie know you’re doing it, and tell him what problem you are trying to solve.

  1. Open the Deploy TeamCity build
  2. Click ... next to Run.
  3. In the Parameters tab, set env.FULL_DEPLOY=1
  4. Click Run Build

Types of Content




TODO and Origin Fields


Picky Sisters