Adding Redactor custom styles in a theme (content block/rich text editor)

Apr 2, 2015

Custom styles work on a theme by theme basis.

1. You start by creating page_theme.php in your theme folder.

2. Add the namespacing and extend the Theme class.

Namespacing for a theme in application

namespace Application\Theme\Your_Theme_Name;
class PageTheme extends \Concrete\Core\Page\Theme\Theme 
{
    //...
}

Namespacing for a theme in a package

namespace Concrete\Package\Your_Package_Name\Theme\Your_Theme_Name;
class PageTheme extends \Concrete\Core\Page\Theme\Theme 
{
    //...
}

3. Add the getThemeEditorClasses() method.

public function getThemeEditorClasses()
{
    //...
}

4. Add an array with the custom style names and classes you want Redactor to use.

As an example, these are the arrays that come with the Elemental theme
"concrete\themes\elemental\page_theme.php"

public function getThemeEditorClasses()
{
    return array(
        array('title' => t('Title Thin'), 'menuClass' => 'title-thin', 'spanClass' => 'title-thin'),
        array('title' => t('Title Caps Bold'), 'menuClass' => 'title-caps-bold', 'spanClass' => 'title-caps-bold'),
        array('title' => t('Title Caps'), 'menuClass' => 'title-caps', 'spanClass' => 'title-caps'),
        array('title' => t('Image Caption'), 'menuClass' => 'image-caption', 'spanClass' => 'image-caption'),
        array('title' => t('Standard Button'), 'menuClass' => '', 'spanClass' => 'btn btn-default'),
        array('title' => t('Success Button'), 'menuClass' => '', 'spanClass' => 'btn btn-success'),
        array('title' => t('Primary Button'), 'menuClass' => '', 'spanClass' => 'btn btn-primary')
    );
}

5. getThemeEditorClasses() array keys

  • title - is the name that will be displayed in the custom styles dropdown in Redactor
  • menuClass - will be the class/classes applied to the dropdown title text (this makes the title text a preview of the style)
  • spanClass - will be the class/classes you want applied for that custom style (the classes applied to the selected text).

As an example, here I added a custom pina colada button that changes the text color and background along with a pina colada picture.

public function getThemeEditorClasses()
{
    return array(
        array('title' => t('Title Thin'), 'menuClass' => 'title-thin', 'spanClass' => 'title-thin'),
        array('title' => t('Title Caps Bold'), 'menuClass' => 'title-caps-bold', 'spanClass' => 'title-caps-bold'),
        array('title' => t('Title Caps'), 'menuClass' => 'title-caps', 'spanClass' => 'title-caps'),
        array('title' => t('Image Caption'), 'menuClass' => 'image-caption', 'spanClass' => 'image-caption'),
        array('title' => t('Standard Button'), 'menuClass' => '', 'spanClass' => 'btn btn-default'),
        array('title' => t('Success Button'), 'menuClass' => '', 'spanClass' => 'btn btn-success'),
        array('title' => t('Primary Button'), 'menuClass' => '', 'spanClass' => 'btn btn-primary'),
        array('title' => t('Pina Colada Button'), 'menuClass' => '', 'spanClass' => 'pina-colada')
    );
}

default Elemental custom styles

alt text

new Pina Colada Button style

alt text

new style applied

alt text

Refresh the theme when adding a page_theme.php to an existing theme or if settings in page_theme.php are not being applied

Dashboard > Pages & Themes > Themes
1. activate the default Elemental theme
2. remove the custom theme
3. install the custom theme
4. activate the custom theme

Writing custom style CSS that will display in the Custom Styles preview

It is a best practice to scope theme CSS with the .ccm-page class. This helps prevent theme CSS from overriding the CSS of the Concrete CMS interface. Scoping CSS this way, using .ccm-page or another class, will prevent custom style title previews from displaying. This can be addresed by creating a second selector for your custom style using #redactor-dropdown-holder.

Example:

#redactor-dropdown-holder .your-style-name,
.ccm-page .your-style-name {
    /*...*/
}

New in Concrete 5.7.5+

When defining custom styles, there is now the option to make the style inline or block. An inline style will wrap the selected text in a span tag and then apply the the custom style to the span. A block style will apply the custom style directly on the block level element tag of the selected text (examples of block level elements are p, h1-h6, etc.).

What makes a custom style inline or block is determined by a new getThemeEditorClasses() array key called "forceBlock". A 'forceBlock' value of -1 will make the style inline and a value of 1 will make the style block.

Example: the Elemental theme default styles

public function getThemeEditorClasses()
{
    return array(
        array('title' => t('Title Thin'), 'menuClass' => 'title-thin', 'spanClass' => 'title-thin', 'forceBlock' => 1),
        array('title' => t('Title Caps Bold'), 'menuClass' => 'title-caps-bold', 'spanClass' => 'title-caps-bold', 'forceBlock' => 1),
        array('title' => t('Title Caps'), 'menuClass' => 'title-caps', 'spanClass' => 'title-caps', 'forceBlock' => 1),
        array('title' => t('Image Caption'), 'menuClass' => 'image-caption', 'spanClass' => 'image-caption', 'forceBlock' => '-1'),
        array('title' => t('Standard Button'), 'menuClass' => '', 'spanClass' => 'btn btn-default', 'forceBlock' => '-1'),
        array('title' => t('Success Button'), 'menuClass' => '', 'spanClass' => 'btn btn-success', 'forceBlock' => '-1'),
        array('title' => t('Primary Button'), 'menuClass' => '', 'spanClass' => 'btn btn-primary', 'forceBlock' => '-1'),
    );
}

If you create a custom style that you want to use both as an inline style and a block style, then you can define the custom style twice. One approach is to add a "- Inline" or "- Block" suffix to the custom style title.

Example: a custom style used both as inline and block

public function getThemeEditorClasses()
{
    return array(
        array('title' => t('Title Thin - Block'), 'menuClass' => 'title-thin', 'spanClass' => 'title-thin', 'forceBlock' => 1),
        array('title' => t('Title Thin - Inline'), 'menuClass' => 'title-thin', 'spanClass' => 'title-thin', 'forceBlock' => '-1'),
    );
}
Recent Tutorials
How to update Add-Ons if not on the Update Add-Ons Menu item
Jul 4, 2022

How to manually download an add-on and update it when your site's core versions isn't considered compatible with the add-on version.

Generate a report with author information and form summaries in Concrete CMS.
May 9, 2022

In Concrete CMS, you can use a form to initiate contact between logged-in users and then create helpful reports. After form submissions are collected, they can be searched, sorted, and exported as a spreadsheet. This tutorial will detail how to add author information to a report using the advanced search.

How to clone and customize Atomik theme
Feb 14, 2022
By linuxoid.

How to clone and customize Atomik theme

Update jQuery to 3.5 on Concrete CMS version 8.5.x
Dec 1, 2021
By hissy.

If you have to take some time to fix your site to work with version 9 and want to update jQuery immediately, you can override it.

Add-On Developers: Get Your Add-Ons Ready for Concrete CMS 9.0
Aug 6, 2021
By andrew.

Concrete CMS 9.0 is coming! But there are some changes in version 9 that might affected your add-ons and themes. This document aims to answer questions about the most common ways that your add-ons might need to be changed, and common problems you'll run into.

Permissions for editors in a multilingual site
Jun 2, 2021
By myq.

How to set up a multilingual Concrete CMS site for groups of language-specific editors

Was this information useful?
Thank you for your feedback.