A theme scaffold that is theme.json-ready for WordPress 5.8+ and includes a built-in workflow for custom Gutenberg blocks.
- Download this repository and place the folder into your local
wp-content/themes/
directory. - Rename the folder to your theme's slug.
- Run a few search & replace actions:
It is recommended to ignore README.md and humans.txt
- WP Theme Scaffold: Theme name, title-case with spaces.
- ThemeScaffold: Theme namespace, pascal-case (no spaces).
- themescaffold: Theme slug, package name, text domain, and block namespace, lower-case with dashes.
- theme_scaffold: Function "namespace", lower-case with underscores.
- Edit the
style.css
file to include your Author/URL information. - Edit the
humans.txt
file to include your team information. - Remove the scaffold info from the top portion of this README.
WordPress theme scaffolds are a-dime-a-dozen, so why build another?
This scaffold is primarily meant to address pain points common to custom WordPress agency development work. Most theme scaffolds are very broad and are aimed at theme repository or premium theme developers. We needed a starting point that, among other things:
- Is custom post type ready. Template-parts like
content.php
are ready to be extended likecontent-customslug.php
, and different ways of viewing posts are accounted for withexcerpt.php
and potentially others. - Includes a workflow for custom Gutenberg blocks that are theme-specific.
- Includes a starting point with
theme.json
and a framework for utilizing the custom space for global properties.
In WordPress 5.8, the theme.json file was introduced as a way to configure a theme for interoperability with the Gutenberg editor. You can read the link for details, but one of the key aspects of theme.json
that we are making heavy use of in this scaffold is the automatic generation of CSS custom properties.
In this scaffold, we make use of the settings.custom
property to define all of our Design Tokens. This is a single source of truth for things that the Gutenberg editor will inherit, such as colors, font families & sizes, and layout widths, but also additional properties as needed. In general, we prefer to define "variables" for our theme here instead of in Sass.
The inc
folder houses the majority of the PHP files for the theme outside of the standard template hierarchy files.
Templates that are meant to be self-contained (not using contextual functions/template tags) and composable. Insert them with ThemeScaffold\Utilities\get_component()
.
See the Components README for more information.
Template parts for building page and post templates modularly. Unlike Components, these should make full use of contextual functions/template tags. The scaffolding includes a starting point for organizing these into subfolders.
See the file header of all of the templates below for more info.
These files are explicitly for outputting content for posts, pages, and custom post types. They are named according to their role:
entry.php
: For any post type that can by syndicated, meaning timestamped with author information. Create variations for different post types.page.php
: Not just for actual pages, but also any post type that is not syndicated, meaning not timestamped with author information and thus not compatible with an RSS-type feed. Create variations for different post types.excerpt.php
: For displaying a summary of a post meant to link to the content. Create variations for different styles of excerpt.
These files are for outputting content in a classic WP_Query
loop. Generally they are used on archive pages, but can also be used for template parts that display a list of recent posts, for example.
These files make up the modular components of the site structure.
The src
folder houses all files meant to be compiled into another form or otherwise put through a build process to end up in the dist
folder. These are generally client-side files like JavaScript and CSS.
A special folder structure for building custom blocks easier. See the blocks README for more information.
All JS files in the root of /src/scripts
are considered entrypoints and will be compiled and placed in the /dist/js
folder. The workflow utilizes the WebPack configuration from wp-scripts, so you can write ESNext and also import CSS/Sass to be compiled as well.
For a brief intro to the basic foundation of our scaffold styling system, see this article about scaling & maintaining legacy CSS. We are also making use of BEM syntax and utility classes.
There is a nod to SMACSS in our approach, but it is altered/extended for the WordPress theme context and ease-of-use. Most of the partial files throughout the folder structure are imported automatically without you having to remember to import them into an entrypoint file every time. This means that some ideas from SMACSS are bent or extended in order for automatic imports to work within the cascade.
Please be aware that this scaffolding makes use of the latest features of Sass, particularly Sass modules. Various tools are available that you muse @use
in order to import into the current file's context, and they are namespaced to avoid global context pollution.
An important tool you should familiarize yourself with is the context
tool that allows you to manage what styles are output in different entry stylesheets (ie style/editor/admin). You can add additional contexts as you see fit. See the tools/_context.scss file for usage information.
The folders in import order:
1. Base
global
: These are overarching styles or styles that need to appear as high up as possible in the cascade.
elements
: Styles set directly on HTML elements to serve as a basis for the theme.
typography
: Styles that are typography-focused. These might also contain plenty of element-only styles, but should only apply typographic properties like font family, sizes, weights, and styles, line heights, etc.
2. Utilities
Utility classes, which SMACSS doesn't really account for, are generally classes that focus on accomplishing one focused thing and are meant to be used liberally to form the basis of your styles. WordPress itself provides many classes that we need to account for that generally fall into this category, such as .alignright
, .has-background
, and .screen-reader-text
, along with a slew of recommended classes for themes submitted to the theme repository.
3. Modules
These are our main BEM component class files. Each module file should be named the same as the "block" (from BEM's Block-Element-Modifier) so that when you need to update a module it is easy to find the file it resides in.
Note that many of these files correspond to the structure of the template-parts
folder.
4. Blocks
Here is where there is an exception made to the standard concept of modules: Gutenberg blocks. Custom block style overrides should be added to the blocks
folder inside a namespace folder and named with their block name, i.e. /src/styles/blocks/core/paragraph.scss
. Note that the file name should not include an underscore—these are output as separate stylesheets to be linked/inlined on the front end only when the block is present on the page. See the block styles README for more information.
Many block styles may @extend
existing component styles from the modules
folder; remember you need to @use
the module file in order to @extend
a component class.
Other Folders
There are some other folders that are not imported in the entrypoint files. The tools
and settings
folders contain files that are meant to be used via the @use
Sass declaration and, most importantly, should not include styles that are output into the final CSS.
The dist
folder houses all compiled files. You might not see it yet if you've just downloaded the scaffolding and haven't run the build process.
The languages
folder is for translation files. The build workflow automatically generates a .pot
file that can be used to translate the theme wherever i18n functions have been used.
TODO: Boilerplate README info