Guide 03 · Developer docs

The theme repo and the asset pipeline

Everything a developer changes on a Core dna site lives in its theme repository. This guide covers the repository and its build, printing records in templates, stylesheets and client-side code, and the parts of a site around the main content.

L1–L2
Unit 01 · Anatomy of a theme repo

What is in a theme repository

A theme repository holds templates, front-end source, the committed build output and a few files served as they are. What each folder is for, where the parts you expect from an application framework live instead, and which committed files anyone can download.

Who this is for. A developer who knows application frameworks and has just cloned a Core dna site's repository. Afterwards you will know where each kind of file belongs, where to look for the things a repository like this does not contain, and which of its files the site will hand to anyone who asks.

The first-day tour is The shape of a theme repo; this page is the reference behind it.

What is not in it

A theme repository has no controllers, no models, no migrations and no routing table. The platform matches a URL to a record, its controller loads the record and assigns it to the template, and the record's layout names the template file. Your repository decides how the result looks, and nothing else runs from it on the server. When you look for the usual parts, this is where they are:

You look forOn Core dna
RoutesThe platform's module routes plus each record's slug or custom URL, set in the admin. Redirects are rewrites, also in the admin.
ControllersThe platform's. A template receives what they assign: What the controller hands the template.
Models and migrationsContent types, layouts, layout areas, custom entity types and custom fields, configured in the admin or through the API. A change to them is a change to records, not a deploy.
Server-side logicJobs (the Orchestration module, formerly Hooks), and custom endpoints built from synchronous jobs.
ConfigurationSettings in the admin: System › Global Settings and each module's own settings.

Older repositories can still carry an index.php, loose PHP files or a modules/ folder from an earlier version of the platform. The platform neither runs nor serves them. Do not add to them, and do not delete them until someone has confirmed what they were for.

The folders

Folder or fileWhat belongs in it
templates/Every Smarty or Twig template, laid out by module: pages/pages/, blogs/posts/, components/, includes/, errors/. Read by the platform when it renders; never served as a file.
src/Authored front-end source: SCSS, JavaScript or TypeScript, fonts and design images. Its inner layout varies: src/app/{js,scss}, src/static/{js,scss} and src/{js,scss} are all in use.
dist/, static/ or build/The build output, committed: Source and build output.
assets/Files served as they are, outside the build: a vendored script, per-brand images, a font you do not process.
translations/XLIFF files that replace or add interface strings: Translation files in the theme repo.
.build/, config/ or the rootBuild configuration: webpack.common.js and its siblings, or config/gulp.js.
failover/, on some sitesA static page for when the site cannot answer: Maintenance and failover pages.
The rootpackage.json and its lock file, robots.txt, favicons, a README, and on some sites .static-assets.json and .settings.json.

A site's .settings.json overrides settings made in the admin: the platform reads it after the database and lets it win. Some repositories track it, for example to set the template engine. Keep anything secret out of it: What must never be committed.

What the web can reach

The platform serves a file from the repository at its own path, dist/app.css as /dist/app.css, when its extension is on this list:

HTML Served extensions
css  js  map  svg  png  jpg  jpeg  webp  gif  ico
woff  woff2  ttf  otf  txt  csv  xml  webmanifest  icc

On a production environment these files are sent with Cache-Control: public and a one-year max-age, which is why every asset URL needs a cache-buster (Cache-busting asset URLs).

Some files are never served, whatever the site asks for:

  • anything under templates/;
  • any path with a part that starts with a dot: .env, .settings.json, .environment.json, .git/, .idea/;
  • PHP and template sources and server configuration: .php and its variants, .tpl, .twig, .smarty, .ini, .env, .htaccess;
  • package.json, package-lock.json, composer.json, composer.lock, yarn.lock, pnpm-lock.yaml and tsconfig.json.

A site that must serve another type, such as PDF, lists it in .static-assets.json at the repository root. Additions cannot re-enable a refused type or change the MIME type of a built-in one:

JSON .static-assets.json
{
  "allowedTypes": {
    "pdf": "application/pdf"
  }
}

Two consequences are easy to miss:

  • src/ is public. On this documentation site, /src/app/js/index.js answers 200. Nothing in src/ should be private, and no page should link to it: link the built file.
  • Committed source maps are public. .map is a served type, so a committed app.js.map gives anyone your original source, comments included. Commit maps only if you are content for that to be read.

Images that editors upload belong in the file manager, which serves them under /files/, not in the repository. The repository is for images that are part of the design.

A notes file is a public file

.txt, .csv and .xml are served types. A committed export, a list of redirects or a notes.txt at the root can be downloaded by anyone who guesses its name.

Go deeper

Was this page helpful?

Your answer goes to the docs team.