Submitting User Interface Pull Requests for Concrete CMS Version 9

This tutorial is over a year old and may not apply to your version of Concrete CMS.
Mar 26, 2020

Concrete CMS version 9 features a number of interface improvements geared toward lightening the UI, making things more accessible, increasing contrast and feedback performance. The dashboard is getting a refined UI as well. All of these updates are based on the new Bedrock Asset System, a system for managing core UI dependencies, third party theme asset dependencies, assets for core features and much more.

The Concrete asset bedrock is a superset of Bootstrap; as of this writing Concrete version 9 in the develop branch is based off of Bootstrap 5.1. This means that a lot has to happen in the core to make things look nice: everything in the Dashboard in 8.5.7 and below is built for Bootstrap 3. While most everything still functions, a lot of small UI improvements need to happen, since Bootstrap 4 and 5 have changed the name of some of its core alignment and button classes. That means we need help cleaning things up.

Dashboard Pull Requests

See a broken button in the develop branch? Something that uses the old btn-default class instead of the new btn-secondary, or something that handles float with pull-right instead of the new float-end? Send us a pull request? You may just have to update the view layer in the Dashboard. We'll happily accept it.

Core JS or CSS Requests

See something that isn't working in the core, but that can only be fixed by modifying a CSS or JS file? That's gonna be more difficult. We definitely want help fixing these issues, but you'll need to understand how Bedrock works in order to help fix them.

The Old Days

In every version of Concrete up til version 9, the JS and CSS files that you'd need to change to affect the core ship with the core itself. For many years you could edit the JS and CSS files found in concrete/css and concrete/js directly. Awhile ago, however, we switched to a build process that took source JavaScript and (LESS)[] files and compiled them into minified JS and CSS files. That means editing the files within concrete/css and concrete/js wasn't really possible anymore; instead you'd edit files within concrete/css/build and concrete/js/build and run grunt in your local environment in order to see the changes.

While this process was more complex than in the old days, it let us write JS and CSS in more modular ways; and the code still shipped with Concrete, so it was easy for anyone to edit and submit pull requests for.

The New School

In version 9, we're providing not just core assets for things like the toolbar or the dashboard, but we're actually providing a framework for creating a Concrete theme will full support for Concrete's many features. In the past, we'd just have developers include bootstrap in their theme, and go on with their day. But if you read the Bedrock document, you'll see that Bedrock is designed to power the assets within the core, along with third party themes. That was always the goal.

What that means, then, is that Bedrock itself can't be included with the core. Third party themes shouldn't have to download a full copy of the core in order to get access to its UI assets. Instead, Bedrock is a separate npm package. The core includes it, and third party themes can include it. The core still includes all the outer SCSS and JS files (oh, yeah, in version 9 – we're switching to SASS), but the assets that those files include are downloaded by Bedrock. Bedrock also takes care of downloading all the third party assets that we require, like jQuery, jQuery UI, etc...

Practical Example: Add Container Panel

Let's take a practical example of how the process of update the "Add Container" panel might work in this new system. Containers are a new feature of version 9, and as such they don't have much of a nice style.

(Note: This is an old, somewhat contrived example. Since version 9 actually has shipped since this tutorial was written the Add Container panel definitely doesn't look this way anymore. The principles still apply, however.)

Currently, in the develop branch the containers panel looks like this:

while our new design requires that they look like this:

(See - much nicer.).

What will the process of fixing this be like?

  1. Clone the Bedrock repository to your local machine from
  2. Within the bedrock repository, create a new git branch with git checkout -b feature/container-panel-ui-updates.
  3. Within your local concrete5 version, check out the developbranch withgit checkout develop`.
  4. Install npm dependencies in your local Concrete project, if you haven't already done so: from within the build/ directory of your Concrete project, type npm i.
  5. Since Concrete relies on Bedrock, Bedrock has been downloaded into your build/node_modules directory. It can be found in build/node_modules/@concretecms/bedrock.
  6. Link your local bedrock repository to your Concrete development environment: Delete the build/node_modules/@concretecms/bedrock directory installed above. Then create a symlink from your local bedrock root directory to build/node_modules/@concretecms/bedrock.
  7. Now that you're on the release/9.0.0 branch, create a new git branch with git checkout -b feature/container-panel-ui-updates.
  8. Rebuild your local assets: from within the build/ directory, run npm run prod.

See what's going on here? We now have two feature branches - one for the Concrete core and one for the bedrock.

Now, let's make UI changes that we need to make.

  1. Within the bedrock repo, find the panels SCSS assets. The panels are all within the cms domain, so look within assets/cms/scss. You'll see that _panels.scss exists, and it's including _panels/_shared.scss. Add a new file _add_container.scss within panels/, and update the _panels.scss file to include it.
  2. Make container specific SCSS updates within this _add_container.scss file.
  3. Since you've run npm link, your changes will be symlinked into the Concrete repo even though you're changing them within the bedrock repo.
  4. To test your updates, run npm run prod or npm run dev from within your Concrete repository build/ directory.
  5. Clear your browser cache and test your updates. You should start seeing changes.
  6. You will very likely also need to make changes to the panel PHP/JS code itself, which you'll do by finding it within the concrete5 repository (for the add container panel, its view is found at concrete/views/panels/add.php.

When you're done, now it's time to submit the pull request. Pay attention to this part too so you don't accidentally undo all your hard work.

  1. Commit changes in the bedrock repo, and then run git push origin feature/container-panel-ui-updates.
  2. Now, submit a pull request against the bedrock repo updates, and make a note that this requires a companion pull request in the core.
  3. From within your Concrete core repo, do the same thing: commit your change and push to feature/container-panel-ui-updates.
  4. Create the pull request.

At this point you should have two pull requests. One contains the changes within the bedrock code, and one contains the changes within the core code that use those CSS changes.

Aside: What about npm link?

In the steps above, we manually create symlinks from our local bedrock repository into our Concrete project. Why? Doesn't npm have a tool named npm link that will do this for us? It does! But unfortunately, it doesn't work. As of this writing I have no idea why – but after our adoption of Bootstrap 5 instead of Bootstrap 4 this tool stopped working for us. If anyone has any idea why, or how to fix – please reach out!

Aside: Where should I make my changes?

SCSS and Bootstrap 5 give you a lot of options when it comes to ensuring that components are styled properly? Want to style something to match our new version 9 designs, but you're not sure how that style should make its way into the core? Try to follow these guidelines?

  1. Is this directly controlled by a variable defined in bootstrap's _variables.scss? Then you should make it from within assets/cms/scss/_bootstrap-overrides.scss. This file is specifically designed to contain overridden BS4 variables. If something is defined here, it will directly affect the Bootstrap 5 components that Concrete uses. By defining
  2. Is this something that's shared between the Dashboard and the front-end CMS layer? Examples of this include form elements, base components like buttons, panels, and more. If this is true, then make sure you include it in a file that's included within assets/cms/scss/_base.scss. This file is included by the cms.scss endpoint that's used on the frontend of the site when showing the editing interface, but it's also included within the Dashboard. If this is something that's only shown in the Dashboard, you can include it within the SCSS files included by the Dashboard theme in the Concrete repository.

Happy Hunting!

Is this process more complicated? Yes. We really don't want to deter core development, but in this case the benefits of bedrock – much easier ability to keep third party assets up to date, a solid foundation for themes and addons, a faster and more flexible way to ensure that themes include only the files they need – outweigh the increased learning curve.

Recent Tutorials
Create custom Site Health tasks
Apr 19, 2024
By myq.

This tutorial will guide you through the creation of a new Site Health task

Reusing the same Express entity in multiple associations
Apr 11, 2024
By myq.

How to create and manage multiple associations in Express

Express Form Styling
Apr 11, 2024
By myq.

Different ways to style Express forms

Setting addon/theme version compatibility in the marketplace
Jan 9, 2024

For developers worn out with setting the latest addon or theme version manually across too many core versions, here is a JavaScript bookmarklet to do it for you.

How to get the locale of a page
Jan 8, 2024
By wtfdesign.

Now, why don't we just have a getLocale() method on Page objects beats me, but here's how you work around it

Using a Redis Server
Jun 16, 2023
By mlocati.

How to configure Concrete to use one or more Redis servers to persist the cache.


Let us know by posting here.