Roots Sage is an advanced WordPress starter theme with a modern development workflow. It's built with Laravel Blade, Tailwind CSS and bud.js and is available on the Roots website.
Before running the Sage installation script, you must have the following:
- A fully installed WordPress website on Pantheon. A site that has been deployed but not set up will fail during the installation process.
- Git
- Composer
- Terminus
- Terminus Build Tools Plugin
- Homebrew
- Node.js
- jq (optional, will be installed with Brew if it does not alredy exist)
Note: The script assumes a Mac OS X environment. If you are using a different operating system, you will need to install Sage manually, skip to How it Works to understand what the script is doing so you can recreate the process.
You will also need a copy of the site cloned to your local environment as the script will be run locally. You may use git clone or terminus local:clone site-name to clone the site.
If you have all the above requirements, including a copy of the site locally, cd into the root directory of the project and run:
composer install-sage
The script does a lot of things and each step builds onto the last. You can look at the script in private/scripts/sage-theme-install.sh if you're interested in the precise commands that are being run. This overview will walk through each step.
The first thing the script will do is check to see if you are logged into Terminus with a terminus whoami command. If you are not logged in, the script will end and you will be prompted to log in first.
Once we know you are logged into Terminus, the script can run a terminus site:info command. From this, the script is able to extract the site name and ID and stores them in variables that we can use in the next step.
If the script was able to identify the site ID and Name, the only thing the script will prompt you for is the name of the theme that you want to create. If it was not able to identify that information, the prompt will ask for Site Name, SFTP username and hostname, and the theme name. Once this information is entered, a confirmation prompt is displayed to ensure that the information is correct. You can type y to accept the information or n to start the prompts over. If the defaults were used, they will be cleared on a n entry, but they will be displayed in their respective prompts.
It's important at this step, when choosing a theme name, to use a name that does not include spaces. This name will be used as the directory name and slug for the theme and will be used in bash commands which could error or fail if spaces were entered that it was not expecting.
The first change the script actually makes is updating the PHP version in the pantheon.upstream.yml file to 8.0 as required by Sage. This is done with a sed command and immediately pushed on completion.
php_version: 8.0The next step is to install Sage. Before this is done, the script will check to see if a directory already exists in web/app/themes that matches the name of the theme you entered. If it does, the script will end immediately with a Directory not empty error. Otherwise, the script will continue by running the following composer commands:
# Create the new Sage theme
composer create-project roots/sage $sagedir
# Require Roots/acorn
composer require roots/acorn --working-dir=$sagedir
# Install all the Sage dependencies
composer install --no-dev --prefer-dist --working-dir=$sagedirNote: In the code snippet above, $sagedir refers to the full path of the Sage theme that you are creating. If you are performing the steps manually, you can save that variable name by entering sagedir=web/app/themes/<your-theme-name> before running the commands.
Once the Composer processes are done, the NPM processes kick in, The script will run the following to build and install all the Sage NPM dependencies.
npm install --prefix $sagedir
npm run build --prefix $sagedirWhen this completes, the .gitignore file inside the new Sage theme is modified to remove the line ignoring the /public/ directory, which should exist on the Pantheon environment.
Then, the newly created theme is added to Git and committed.
git add $sagedir
git commit -m "[Sage Install] Add the Sage theme ${sagename}."
git push origin masterThe next part of the script adds a symlink to point web/app/cache to web/app/uploads/cache. Sage assumes the web/app/ directory is writeable, but on Pantheon it is not. However, we can get around this by creating a symbolic link so web/app/cache points to web/app/uploads/cache.
First, the script switches to the Pantheon site to SFTP mode, which we will need to make changes to the filesystem before creating the symlink.
terminus connection:set $sitename.dev sftpThen, it checks the existance of and creates the web/app/uploads and web/app/uploads/cache directories if they do not exist. Then, it connects to the site over SFTP to create the /files/cache directory with the following command:
sftp -P 2222 $sftpuser@$sftphost <<EOF
cd /files
mkdir cache
EOFThe script then switches back to Git mode so we can commit our symbolic link:
terminus connection:set $sitename.dev git
Finally, the symlink is created and committed to Git:
cd web/app
ln -sfn uploads/cache
git add .
git commit -m "[Sage Install] Add symlink for /files/cache to /uploads/cache"
git push origin master
cd ../..The next step is to update the composer.json file to include a post-install-command to run composer install on Sage every time a composer install is run on the site. To do this, the script uses the jq command:
jq -r '.scripts += { "post-install-cmd": [ "@composer install --no-dev --prefer-dist --ignore-platform-reqs --working-dir=%sagedir%" ] }' composer.json > composer.new.json
sed -i '' "s,%sagedir%,$sagedir," composer.new.json
rm composer.json
mv composer.new.json composer.jsonIf you are doing this manually, you can add the following to your composer.json in the scripts section:
"post-install-cmd": [
"@composer install --no-dev --prefer-dist --ignore-platform-reqs --working-dir=web/app/themes/<your-theme-name>"
]Once the change is made, it's committed and pushed to the site.
The last steps are to activate the theme and verify that it displays as expected.
For WordPress multisites, we need to first Network Enable the theme before it can be activated, so the script runs the following command:
terminus wp $sitename.dev -- theme enable $sagename --networkThen, the theme is activated:
terminus wp $sitename.dev -- theme activate $sagenameFinally, the script will open the site in your default browser to verify that the theme is displaying as expected.
terminus wp -- $sitename.dev theme enable $sagenameFor single sites, this will produce an error, but it will not exit the script. This is normal and expected. Once we know that the theme is enabled (if applicable), the script will run a wp theme list to ensure it appears in the list of themes:
terminus wp -- $sitename.dev theme listIf you are performing these steps manually, take time to make sure that your new theme shows up in the theme list. If it does not, you may want to retrace your steps.
Assuming it shows up, the next step is to activate the theme. This is also done via WP-CLI.
terminus wp -- $sitename.dev theme activate $sagenameOnce it's activated, the script will attempt to open your site in your default browser. If you are performing these steps manually, you can open the site in your browser and verify that the theme is displaying as expected. It's possible here that you may need to flush your browser cache or use a different browser if you did not see the new sage theme show up. If you continue to see a different default theme, ensure the theme is activated by going to your wp-admin/themes.php page. Otherwise, you should see something like this:
If you see a fresh Sage starter theme, the setup worked and you're ready to start building! Refer to the Sage documentation for more information on how to use Sage now that it's been installed.
This script was written with the assumption that you are only using a single Sage theme. If you install multiple Sage themes, you will need to manually update the composer.json file to include the post-install-cmd for each theme as the script will update the existing entry if one exists already. Additionally, some steps (like creating directories and symlinks) will naturally fail if those things have been done already.
