Sage 10 on Pantheon, a guide and method

Sage 10 on Pantheon as of Jan 30, 2021. These are the steps I used to get things running on Pantheon. There are brighter minds here, if you can look this over and see if I am missing anything, if anything could use clarification, or for random, “YOU USE PANTHEON DAS GARBAGE!” trolling I would appreciate it.

  1. Add node_modules/ to the Pantheon .gitignore
  2. Clone Sage 10 in themes folder git clone
  3. cd sage/
  4. gco log1x/next (If you want Tailwind 2 from Brandon’s fantastic work)
  5. rm -rf /.git
  6. yarn && composer install && yarn build
  7. Update config/view.php to, 'compiled' => wp_upload_dir()['basedir'].'/storage/framework/views',),
  8. git add -f vendor/
  9. git add -f public/
  10. mv storage/ ../../uploads/storage
  11. ln -sfn ../../uploads/storage
  12. composer install --no-dev
  13. Updated local url in webpack.mix.js (for Lando or Localdev)
  14. Git commit all these changes
  15. SFTP Mode: Upload storage/ folder to /code/wp-content/uploads
  16. Git push!

Now I use Lando, and pointed the above local url to the Lando URL for Browsersync. YMMV. This worked locally, on Lando, always – without any changes.

I wonder now, because I haven’t had time to go further yet, when I make changes from here on out, do I need to upload the storage/ folder again due to changes? Or can I leave that the way it is now that it’s working. This is the black magic of the process I am not 100% familiar with. Composer and it’s relation to making changes/deploying. I’ll find out soon enough I suppose… and update this thread.


Acorn v2.0.0, Laravel 8.x, TailwindCSS

PR (with upgrade instructions)

log1x/next branch

Note: going to try this myself, will update. Thanks @Log1x

1 Like

You get it working @Atari?

7 above needs updating: 'compiled' => wp_upload_dir()['basedir'].'/storage/framework/views',

I tried these steps from scratch on a new theme, using the master branch since this has been merged in, in the same WordPress install as above, using storage2/ folder where I mentioned storage/ folder above regarding symlink and mv and simply could not get it working. I got the same error message I saw before.

I am not sure it’s because I cannot use storage2/ as a folder name even though the view.php was pointing correct as was the symlink, or what.

Everything seems to work fine when I have just storage/. I stated a fresh new project with the master branch now that @Log1x’s PR was pulled in.

I did run into an issue adding log1x/sage-svg:

On the left is my local with Lando and yarn start. The SVG loads just fine with the directive @svg('svg.bars', 'w-5'). On the right is Pantheon. Frustrating. I really love working in Sage but this is rough.

What got me to a broken SVG state:

  1. composer require log1x/sage-svg
  2. Create resources/svg folder
  3. Add .copyDirectory('resources/svg', 'public/svg'); to webpack.mix.js
  4. Test functionality adding @svg('svg.bars', 'w-5') to a blade template
  5. yarn build:production && composer install --no-dev
  6. Commit all changes & push

EDIT: I can get this working by replacing the above directive with the helper <?php $bars = get_svg('svg.bars', 'w-5'); echo $bars ?>. I would prefer the directive, and I am using other directives with log1x/sage-directives just fine locally and on Pantheon. I also updated the log1x/sage-svg/svg.php to look in the public/ folder instead of the dist/ folder. It was working before, and after locally but neither on Pantheon.

Updated directions now that the original post’s PR is merged in.

  1. Add node_modules/ to the Pantheon project repo’s .gitignore
  2. Clone Sage 10 in themes folder git clone
  3. cd sage/
  4. rm -rf /.git
  5. rm -rf /.github
  6. yarn && composer install && yarn build
  7. Update config/view.php to, 'compiled' => wp_upload_dir()['basedir'].'/storage/framework/views',
  8. mkdir ../../uploads/ (if it doesn’t exist)
  9. mv storage/ ../../uploads/storage
  10. ln -sfn ../../uploads/storage
  11. composer install --no-dev
  12. Edit .gitignore in theme and remove vendor/ and public/ folders from it
  13. git add -f vendor/
  14. git add -f public/
  15. Updated local url in webpack.mix.js (for Lando or Localdev)
  16. Git commit all these changes
  17. SFTP Mode: Upload storage/ folder to /code/wp-content/uploads
  18. Git push!

Create themes/sage/config/svg.php and set your base path there.


use function Roots\base_path;

return [

    | Path
    | This value is the default path used by SageSVG for finding SVG files.
    | This path is then resolved internally if an absolute path is not being
    | used.

    'path' => base_path('public'),

    | Class
    | Here you can specify a default class to be added on all inlined SVGs.
    | Much like how you would define multiple classes in an HTML attribute,
    | you may separate each class using a space.

    'class' => '',

I’ll push a 2.0.0 to SVG Sage to make it work out of the box.

1 Like

Thanks for the reply @Log1x. I reset the vendor/logi1x/sage-svg/config/svg.php back to dist/, and created the themes/sage/config/svg.php with the base_path as you mentioned. However, I am getting the same results as before. The directive’s aren’t parsing, instead they are outputting the actual text, @svg('svg.bars', 'w-5') as shown in the screenshot above.

In the screenshot below, the yellow arrows will output as if they were text, the purple arrows will properly output the icon.

What is weird about that is I am using your other package, sage-directives (thank you), to output other directives of ACF fields successfully on the same site. This code below works fine.

I’ve run into the same issue deploying to WPE through Github actions. The latest version of @Log1x’s sage-svg works a-ok locally but the directives aren’t parsed in production. I haven’t had too much time to fiddle yet, but for a quick fix {{ get_svg() }} seems to work and is almost as elegant as the @svg directive. Just an FYI!

1 Like

oof okay weird.

I’ll take a look when I can.


:pray:t3: you are too kind! I am happy to help troubleshoot / test, not sure exactly where to start.

1 Like

Latest Pantheon Sage 10 Setup directions
Version 3.0-beta - Mar 5, 2021

  1. Add node_modules/ to the Pantheon project repo’s .gitignore
  2. Clone Sage 10 in themes folder git clone
  3. cd sage/
  4. rm -rf /.git
  5. rm -rf /.github
  6. rm -rf /.gitignore
  7. composer install --prefer-dist --no-dev
  8. yarn install && yarn build && yarn build:production
  9. Update config/view.php to, 'compiled' => wp_upload_dir()['basedir'].'/storage/framework/views',
  10. mkdir ../../uploads/ (if it doesn’t exist)
  11. mv storage/ ../../uploads/storage
  12. ln -sfn ../../uploads/storage
  13. mv bootstrap/cache ../../uploads/bootstrap/cache
  14. cd bootstrap/
  15. ln -sfn ../../../uploads/bootstrap/cache
  16. composer install --no-dev
  17. Updated local url in webpack.mix.js (for Lando or Localdev)
  18. Git commit all these changes
  19. SFTP Mode: Upload storage/ folder to /code/wp-content/uploads
  20. SFTP Mode: Upload bootstrap/cache/ folder to /code/wp-content/uploads
  21. Git Mode: Git push!

This topic was automatically closed after 42 days. New replies are no longer allowed.

Latest Pantheon Sage 10 Setup directions
Version 10.2.0 - Jul 20, 2022

Note: The steps for deployment are mostly identical to what posted above by @frankstallone, but with some minor changes. Acorn was embedded into the Sage at that time, but in current Sage versions, Acorn is available as a plugin. So we will embed Acorn into the Sage again (which means we will not use it as an external WP plugin), change its config and then we are good to go. Please note we we use WP-CLI for this purpose, so please preinstall it before.

  1. Clone your Wordpress Pantheon project to local and set it up on your local. Open the project and navigate to themes directory within terminal.
  2. Clone Sage 10 in themes folder git clone
  3. cd sage/
  4. rm -rf /.git
  5. rm -rf /.github
  6. composer install --prefer-dist --no-dev
  7. yarn
  8. composer require roots/acorn
  9. wp acorn acorn:init
  10. wp acorn vendor:publish --tag=acorn
  11. After you run above command, you will get a config folder in your Sage project. Open the file config/view.php and find for the word 'compiled'. Update the whole line to 'compiled' => wp_upload_dir()['basedir'].'/storage/framework/views',
  12. mkdir ../../uploads/ (if the uploads folder doesn’t exist in wp-content/)
  13. mv storage/ ../../uploads/storage
  14. ln -sfn ../../uploads/storage
  15. Update proxy in bud.config.mjs (for Lando or Localdev)
  16. Optionally, you can run yarn dev to run your project in local environment.
  17. composer install --no-dev
  18. yarn build
  19. Remove vendor and public folder from .gitignore
  20. Git commit all these changes
  21. SFTP Mode: Upload storage/ folder to /code/wp-content/uploads
  22. Git Mode: Git push!

NOTE: Again, if someone does not wish to not embed Acorn in Sage, and use it as a plugin, they can just install it as WP plugin and activate it from dashboard. Then, you don’t need to follow steps 8-10. Instead, update the config/view.php in your wp-content/plugins/acorn with the same line as mentioned in step 11. Then all is set and you are good to go with further steps.

Let me know if some steps are causing issues and not working properly. Thanks again!


Maybe I’m doing it the wrong way, but I’m seeing a lot of effort to deploying amongst the answers here. So I’ll share my low effort solution.

First the .circleci/config.yaml (sorry I can’t upload files here)

version: 2.0
  working_directory: &working_directory
  container_config: &container_config
      - image: circleci/php:7.4-node
    working_directory: *working_directory
  attach_workspace: &attach_workspace
      at: *working_directory
    <<: *container_config
      - checkout
      - run:
          name: Install dependencies
          command: composer install -n -o
      - persist_to_workspace:
          root: .
            - '*'
    <<: *container_config
      - *attach_workspace
      - run:
          name: Remove development dependencies
          command: composer install --no-dev -n -o
      - run:
          name: Deploy to Pantheon
          command: .circleci/
  version: 2
      - build
      - deploy_pantheon:
            - build

I’ll leave you to configure CircleCI or whatever build platform you prefer. Just be sure to check the only build PR requests (that setting includes pushing to master but will otherwise break because who knows.)

Now the uglier bit, .circleci/

#!/usr/bin/env bash

if [[ -z "$CIRCLECI" ]]; then
    echo "This script can only be run by CircleCI. Aborting." 1>&2
    exit 1

if [[ -z "$TERMINUS_SITE" ]]; then
    echo "Terminus site not set. Aborting." 1>&2
    exit 1

if [[ -z "$TERMINUS_TOKEN" ]]; then
    echo "Terminus token not set. Aborting." 1>&2
    exit 1

if [[ ${CIRCLE_BRANCH} == "master" ]]; then
elif [[ ! -z "$CIRCLE_PULL_REQUEST" ]]; then

# Add global composer bin directory to $PATH variable
export PATH=$HOME/.config/composer/vendor/bin:$PATH

# Configure git
git config --global "${}"
git config --global "${GIT_NAME:-Circle CI}"

# Configure SSH
mkdir -p "$HOME/.ssh"
touch "$HOME/.ssh/config"
echo "StrictHostKeyChecking no" >> "$HOME/.ssh/config"

# Convert uploads directory to a symlink
sed -i '/web\/app\/uploads.*/d' .gitignore
sed -i '/web\/app\/cache.*/d' .gitignore
rm -r web/app/uploads
[ -d "web/app/cache" ] && rm -r web/app/cache
ln -s ../../../files web/app/uploads
mkdir -p ../../../files/cache
ln -s ../../../files/cache web/app/cache

# Install Terminus globally
composer global -W require pantheon-systems/terminus:^2.6

# Install Terminus plugins
mkdir -p $HOME/.terminus/plugins
composer create-project --no-dev -d $HOME/.terminus/plugins pantheon-systems/terminus-build-tools-plugin:^2.0.4

# Authenticate with Terminus
terminus -n auth:login --machine-token="$TERMINUS_TOKEN"

# Wake up the main development environment
terminus -n env:wake "$"

# Write environment variables from terminus to .env file
database_env () {
    dbconn=$(terminus connection:info "$TERMINUS_SITE.$TERMINUS_ENV" --format='json' --fields='mysql_username,mysql_password,mysql_host,mysql_port,mysql_database')
    echo $dbconn | php -r '$a = json_decode(stream_get_contents(STDIN),true);$env=array_map(function($key) use ($a){return strtoupper($key) . "=\"" . $a[$key] . "\"\r\n";},array_keys($a));file_put_contents(".env",$env);'
    sed -i "$ a WP_HOME=\"https://$TERMINUS_ENV-$\"" .env
    sed -i "$ a WP_SITEURL=\"https://$TERMINUS_ENV-$\"" .env

# Update assets path in config files
sed -i "s/home\/circleci\/build/code/g" web/app/themes/constructive-core/.budfiles/bud/*

# Push code to Pantheon
if [[ ${CIRCLE_BRANCH} == "master" ]]; then
    # Write environment variables to .env file

    # Push the build directory to Panthoen's dev environment
    terminus build:env:push -n "$"

    # Flush permalinks
    terminus wp "$" -- rewrite flush

elif [[ ! -z "$CIRCLE_PULL_REQUEST" ]]; then

    if [[ -z $(terminus multidev:list "$TERMINUS_SITE" --field='id' --format='string' | grep -o "$TERMINUS_ENV") ]]; then
        # Check if pr-# multidev exists and if not create it to allow generating the .env variables
        terminus multidev:create -- "$" "$TERMINUS_ENV"
        # Do a search/replace on the DB for dev URLs 
        terminus remote:wp "$TERMINUS_SITE.$TERMINUS_ENV" -- search-replace "dev-$" "$TERMINUS_ENV-$" --all-tables

    # Write environment variables to .env file

    # Push the build directory to Pantheon's multidev environment
    terminus build:env:push -n "$TERMINUS_SITE.$TERMINUS_ENV"

    # Flush permalinks
    terminus wp "$TERMINUS_SITE.$TERMINUS_ENV" -- rewrite flush

    # Run update-db
    terminus -n wp $TERMINUS_SITE.$TERMINUS_ENV -- core update-db

    echo "Something is wrong...print environment variables"

# Clear caches
terminus -n env:clear-cache "$TERMINUS_SITE.$TERMINUS_ENV"

# Clean up unused PR environments (if GITHUB_TOKEN is set)
if [[ ! -z "$GITHUB_TOKEN" ]]; then
    terminus -n build:env:delete:pr $TERMINUS_SITE --yes

Plus side, it takes 3-5 minutes to build everything, handles DB settings, writeable permissions, and editing config files on the fly so your local needn’t change.