How This Site Works

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

Anatomy of A Web Request

The rhino3d.com 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 www.rhino3d.com 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 https://github.com/mcneel/rhino3d.com-appengine

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 (https://www.rhino3d.com/es/...) 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 www.rhino3d.com 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 www.rhino3d.com 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 www.rhino3d.com 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 www.rhino3d.com domain (except, of course, for external links).

Hugo

Starting in 2020, this repository (https://github.com/mcneel/rhino3d.com) became the home for all static content for www.rhino3d.com. The content is authored in markdown, and compiled using Hugo into HTML, CSS, and JS files. The site is published to S3.

Viewer

[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

Overview

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

Workflow

[TODO]

GitHub

[TODO]

Markdown

[TODO]

Hugo

[TODO]

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

Deployment

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

The Deploy rhino3d.com TeamCity build gets the newest source, and then runs The script/deploy.sh which uses script/deploy.py 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 rhino3d.com TeamCity build
  2. Click ... next to Run.
  3. In the Parameters tab, set env.FULL_DEPLOY=1
  4. Click Run Build

Frontmatter

[TODO]

Types of Content

[TODO]

Authors

[TODO]

Admin

These fields govern the editorial process used - internally - to draft, edit, and localize the page.

  • TODO: (string) A note on what specifically needs to be done next. It shows up in the Site Admin page
  • origin: (string) Used if the page is a conversion from a previous page. The origin field contains the URL address of the original source material. It is often used when setting up redirects from older content to the newer content.
  • picky_sisters: (string) These are comments made by the Picky Sisters as editorial feedback to the author.
  • state: (string) State identifies the part of the process that a document is in. It shows up in the Site Admin page page. The states we use are:
    • In Progress: This page is a work-in-progress, not yet ready for review, let alone translation.
    • To Edit: This page is ready for “Picky Sisters” review and editing, but not yet ready for translation.
    • Complete: This page is “substantially” complete and ready to be translated. It will show up in the translators' localization status pages.

Page Options

These fields govern optional page features such as:

  • toc: (boolean) Determines whether or not to display the Table of Contents widget.
  • byline: (boolean) Set to true to display a byline and the date this page was last edited.
  • block_webcrawlers: (boolean) This controls whether or not the page is crawled by search-engine robots: it adds the appropriate html to the head to prevent search engine robots from crawling the page. This is frequently used for draft content. If not set, it defaults to false, allowing the page to be indexed.

_Build

This is a field to specify whether a page is listed as a page on the website - especially when iterating through pages in layouts/templates. The most common use of the list field is to set it to "never" like this:

[_build]
  list="never"

[TODO]

A minor change to test deployment…