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)[http://lesscss.org] 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 https://github.com/concrete5/bedrock.
  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
Customize locale icons
Oct 29, 2024
By myq.

How to customize locale (language region) flags

Concrete CMS Caching Guide
Oct 16, 2024

An overview of types of caching in Concrete and considerations when using them.

Redirect all requests to HTTPS
Oct 9, 2024
By myq.

How to follow best practices for a secure web

Upgrade Concrete versions 9.3.1 and 9.3.2
Sep 10, 2024
By myq.

How to get past a bug in versions 9.3.1 and 9.3.2 that prevents upgrading the Concrete core through the Dashboard

How to use Composer with Marketplace extensions
Aug 22, 2024

Composer can be used to manage third-party extensions from the marketplace

Controlling Google Tag Manager Tags Based on Concrete CMS Edit Toolbar Visibility
Aug 13, 2024

This document provides a step-by-step guide on how to control the firing of Google Tag Manager (GTM) tags based on the visibility of the Concrete CMS edit toolbar. It explains how to create a custom JavaScript variable in GTM to detect whether the edit toolbar is present on a page and how to set up a trigger that ensures GTM tags only fire when the toolbar is not visible. This setup is particularly useful for developers and marketers who want to ensure that tracking and analytics tags are not activated during content editing sessions, thereby preserving the accuracy of data collected.

Improvements?

Let us know by posting here.