Show Menu
TOPICS×

Chapter 4 - Developing with the Style System

Covers using the Style System to extend Core Components with brand-specific CSS and advanced policy configurations of the Template Editor. Content Fragments are also integrated to create long form article text.

Prerequisites

This is Chapter 4 of the multi-part tutorial. Chapter 3 can be found here and an overview can be found here .
View the finished code on GitHub or download the finished package for the previous part of the tutorial: WKND Chapter Solutions .

Objective

  1. Understand how to use the Style System to apply brand-specific CSS to AEM Core Components.
  2. Learn about BEM notation and how it can be used to carefully scope styles.
  3. Use Content Fragments to support long-form article content.
  4. Apply advanced policy configurations with Editable Templates.

Article Template Planning

In this chapter we will use the Style System feature and Editable Templates to create a unified look and feel for the Article Template. To start, we will identify areas of the article mockup that will map to AEM components.
Core Components provide components that we can use. Instead of building our own components we will focus on styling the components to match the mockups. Below are the components that we will use:

Style System

The Style System allows developers and template editors to create multiple visual variations of a component. Authors can then in turn decide which style to use when composing a page. We will leverage the Style System throughout the rest of the tutorial to achieve several unique styles, while leveraging Core Components in a low code approach.
The general idea with the Style System is that authors can choose various styles of how a component should look. The "styles" are backed by additional CSS classes that are injected into the outer div of a component. In the client libraries CSS rules are added based on these style classes so that the component changes appearance.

Title Component

At this point the Title Component has been proxied into the project under /apps/wknd/components/content/title . We will add styles for the Title Component in the clientlib-site library: /apps/wknd/clientlibs/clientlib-site/components .

Inspect Title Component Example

As part of the generated project, the archetype embedded Core Component Examples project. For developers and content authors this contains an easy reference to understand all of the features available with Core Components. A live version is also available .
  1. Open a new browser and navigate to your local instance of AEM.
  2. From the start menu navigate to Sites > Core Components > Component Library > Title .
  3. Select the Title page and open it by clicking the Edit icon.
  4. The page that opens is a dedicated page with examples of the Title component. This is a live page and all of the components can be edited.
  5. Switch into Preview mode and select the Markup tab beneath one of the Title component examples.
    When styling Core Components, we will want to reference the markup generated, as well as the class names put on the individual elements.

Add a style to the Title Component

The mockups contain a unique style for the Title component with an underline. Instead of creating 2 components or modifying the component dialog, the Style System can be used to allow authors the option to add an underline style.
It is considered a best practice to always tightly scope styles to the target component. This ensures that extra styles don't affect other areas of the page.
All Core Components adhere to BEM notation . It is a best practice to target the outer CSS class when creating a default style for a component. Another best practice is to target class names specified by the Core Component BEM notation rather than HTML elements.
Compare the below BEM notation to the Markup on the example page viewed earlier.

Title Component BEM Notation

BLOCK cmp-title
    ELEMENT cmp-title__text

  1. In the previous chapter, some default styles were imported for the Title component. In the ui.apps module beneath /apps/wknd/clientlibs/clientlib-site/components/title . There is currently a default style defined by default.less :
    /* WKND Title Default style */
    
    .cmp-title {
    
        h1, h2, h3, h4 {
            font-family: @font-family-serif;
        }
    
        h1 {
            font-size: 48px;
    
            @media (max-width: @screen-medium) {
                font-size: @font-size-h1;
            }
        }
    
    }
    
    
    
  2. Create a file named underline.less beneath the styles folder: /apps/wknd/clientlibs/clientlib-site/components/title/styles/underline.less
    Add the following code to underline.less :
    /* WKND Title Underline style */
    
    .cmp-title--underline {
      .cmp-title__text:after {
        border-bottom: 2px solid @brand-primary;
        content: '';
        display: block;
        padding-top: 8px;
        width: 84px;
     }
    }
    
    
    
    This will add a partial underline beneath the title component with the WKND's brand primary color (yellow).
  3. Update /apps/wknd/clientlibs/clientlib-site/components/title/title.less with the following code to include the default and underline styles:
    /* WKND Title Styles */
    
    @import (once) "styles/default.less";
    @import (once) "styles/underline.less";
    
    
  4. Deploy the updated code base to a local AEM instance using the AEM Developer Tool plugin or using your Maven skills.
  5. Click the Title Component in the Layout Container to open its policy configuration:
  6. Update the Policy with the following values:
    Policy Title * : WKND Title - Article
    Properties > Sizes > : Check all sizes
    Properties > Styles Tab > : Add a new style
    Underline : cmp-title--underline
    Notice how cmp-title--underline added in the template policy matches top level CSS class rule specified in the underline.less file.
  7. You should now be able to add a new Title component to the a page and then apply the Underline style to the component.
    View the HTML source of the Title Component when no style is applied:
    <div class="title aem-GridColumn aem-GridColumn--default--12">
        <div class="cmp-title">
            <h2 class="cmp-title__text">New paragraph</h2>
        </div>
    </div>
    
    
    HTML source of the Title component when the Underline style is applied:
    <div class="title cmp-title--underline aem-GridColumn aem-GridColumn--default--12">
        <div class="cmp-title">
            <h2 class="cmp-title__text">New paragraph</h2>
        </div>
    </div>
    
    
    Note that CSS classes applied through the Style System always populate the outer div surrounding the component.

Text Component

Inspect the Text component example page to understand the features of the component:

Add a style to the Text Component

Next we will add some additional styles to the text component so that authors are able to create a Quote Block style, in addition to standard article text.

Text Component BEM Notation

BLOCK cmp-text
    ELEMENT cmp-text__paragraph (only present if text is NOT Rich Text)

  1. Beneath /apps/wknd/clientlibs/clientlib-site/components/text/styles create a new file named quote.less .
  2. Populate /apps/wknd/clientlibs/clientlib-site/components/text/styles/quote.less with the following:
    /* WKND Text Quote style */
    
    .cmp-text--quote {
        background-color:@brand-secondary;
        margin: 1em 0em;
        padding: 1em 3em;
    
        blockquote {
            border: none;
            font-size: 36px;
            margin: 0;
            padding: 14px 0px;
        }
    
        u {
            font-family: @font-family-sans-serif;
            text-decoration: none;
    
            &:before {
                border-top: 2px solid @brand-primary;
                content: '';
                display: block;
                width: 80px;
            }
        }
    }
    
    
    
  3. Update /apps/wknd/clientlibs/clientlib-site/components/text/text.less to include the default.less and quote.less files:
    /* WKND Text Styles */
    
    @import (once) "styles/default.less";
    @import (once) "styles/quote.less";
    
    
    
  4. Deploy the updated code base to a local AEM instance using the AEM Developer Tool plugin or using your Maven skills.
  5. Click the Text Component in the Layout Container to open its policy configuration. Configure the following policy:
    1. Policy Title * = WKND Text - Article
    2. Plugins > Formatting > Check Show underline option
    3. Plugins > Paragraph Styles > Check Enable paragraph styles . Remove all elements except for Paragraph and Quote
    4. Styles > Add a new Style named Quote Block with a value of cmp-text--quote
  6. Navigate to the first article page and create a new text component:
    1. Edit the text component (pencil icon)
    2. Expand the RTE to full screen
    3. Use the Paragraph dropdown to create a Block Quote and add a famous quote.
    4. On a new line below the Block Quote create a paragraph element and add the name of the author
    5. Apply the Underline RTE style to the Author Name
    6. Save changes
    7. Change the Style to Quote Block style

List Component

Inspect the List component example page to understand the features of the component:

Add a style to the List Component

The List component as offered from the Core Component will be used to populate an Up Next list of articles. A List component will also be made a fixed part of the Article Page Template to promote consistency across Article Pages. The List component can be used for other parts of the site so a unique style will be created for the Up Next variation.

List BEM Notation

BLOCK cmp-list
    ELEMENT cmp-list__item
    ELEMENT cmp-list__item-link
    ELEMENT cmp-list__item-title
    ELEMENT cmp-list__item-date

  1. Beneath /apps/wknd/clientlibs/clientlib-site/components :
    1. Create a new folder named list
    2. Create a new file named list.less
    3. Create a new folder named styles beneath the list folder
    4. In the styles folder create a file named default.less
    5. In the styles folder create a file named upnext.less
  2. Populate default.less with the following:
    /* WKND List Default Style */
    
    .cmp-list {
        float:left;
        padding:0;
    
        .cmp-list__item {
            list-style: none;
            float:left;
            margin-bottom:1em;
            width:100%;
        }
    
        .cmp-list__item-link {
            float:left;
            font-weight: 600;
            padding: 0.5rem 1rem;
    
            &:hover {
                background: @brand-secondary;
            }
        }
    
        .cmp-list__item-title {
            float:left;
            width:100%;
        }
    
        .cmp-list__item-date {
            color: @gray-light;
            float:left;
            font-size: @font-size-small; 
            width:100%;
        }
    }
    
    
  3. Populate upnext.less with the following:
    /* WKND List Up Next Style */
    
    .cmp-list--upnext {
    
        .cmp-list {
            padding-left: 0em;
    
            .cmp-list__item {
                list-style: none;
                float:left;
                margin-bottom:1em;
                width:100%; 
            }
    
            .cmp-list__item-link {
                border-left: 6px solid @brand-secondary;
                font-weight: normal;
                height: 120px;
    
                &:hover {
                    background: @brand-primary;
                    border-color: @text-color;
                }
            }
    
            .cmp-list__item-title {
                color: @text-color;
                padding: 5px;
                text-transform: uppercase;
            }
    
            .cmp-list__item-date {
                color: @gray-light;
                font-size: @font-size-xsmall; 
                padding: 5px;
                text-transform: uppercase;
            }
        }
    }
    
    
  4. Update list.less with the following to include the default and upnext styles:
    /* WKND List Styles */
    
    @import (once) "styles/default.less";
    @import (once) "styles/upnext.less";
    
    
  5. Add a line to /apps/wknd/clientlibs/clientlib-site/main.less file to import the list.less file:
    /* Component Styles */
    @import "components/breadcrumb/breadcrumb.less";
    @import "components/contentfragment/contentfragment.less";
    @import "components/header/header.less";
    @import "components/image/image.less";
    @import "components/layout-container/layout-container.less";
    /* add list.less */
    @import "components/list/list.less";
    @import "components/text/text.less";
    @import "components/title/title.less";
    
    
  6. Deploy the updated code base to a local AEM instance using the AEM Developer Tool plugin or using your Maven skills.
  7. Click the policy icon for the List Component in the Layout Container to open its policy configuration. Configure the following:
    1. Policy Title * = WKND List - Article
    2. List Settings > Date Format > EEEE, d MMM y
    3. Styles > Add a new Style named Up Next with a value of cmp-list--upnext
  8. Navigate to the first article page and create a new List component:
    1. Drag + Drop a List Component on to the page
    2. Click the wrench icon to configure the List component
    3. List Settings > Build List Using > Fixed List
      1. Under Options for Fixed Lists > Add a couple of pages
    4. Item Settings > Check Link Items , Show date
    Several dynamic sources can be configured for the List component including:
    • Child pages
    • Tagged items
    • Query results.
    Full configuration details can be found in the List Documentation .
  9. Apply the Up Next style to the list component:

Layout Container

At this point, you may have noticed that the "body" of the Article template is spanning the full width of the page. The Layout Container, which we configured in Chapter 2, represents the body of the article and is used to allow authors to add components.
We can use the Style System with the Layout Container to create a new, fixed-width style to restrict the body of the pages.
  1. Beneath /apps/wknd/clientlibs/clientlib-site/components perform the following tasks to create a new structure to contain Layout Container styles:
    1. Create a new folder named: layout-container.
    2. Beneath this folder create a file named: layout-container.less
    3. Beneath the layout-container folder create a new folder named: styles .
    4. In the styles folder create a file named default.less
    5. In the styles folder create a file named fixed-width.less
  2. We will leave the default.less empty for now, but as a best practice we created it.
    Populate fixed-width.less with the following:
    /* WKND Layout Container - fixed-width.less */
    
    .cmp-layout-container--fixed {
        clear: both !important;
        display:block;
        float: unset !important;
        margin: 0 auto !important;
        max-width:  @max-width !important;
        padding: 0 @gutter-padding;
    
        @media (max-width: @screen-medium) {
            padding: 0 !important;
        }
    }
    
    
    The above snippet will center and restrict the Layout Container, with a class of .cmp-layout-container--fixed to a max-width using a LESS variable, @max-width . This variable is defined in the variables.less file and is set to: 1164px .
  3. Populate layout-container.less with the following:
    /* WKND Layout Container Styles */
    @import (once) "styles/default.less";
    @import (once) "styles/fixed-width.less";
    
    
  4. Next update /apps/wknd/clientlibs/clientlib-site/main.less to include the layout-container.less file:
    Update main.less with the following:
    /* Component Styles */
    @import "components/breadcrumb/breadcrumb.less";
    @import "components/contentfragment/contentfragment.less";
    @import "components/header/header.less";
    @import "components/image/image.less";
    /* add import of layout-container.less */
    @import "components/layout-container/layout-container.less";
    @import "components/text/text.less";
    @import "components/title/title.less";
    
    
  5. Deploy the updated code base to a local AEM instance using the AEM Developer Tool plugin or using your Maven skills.
  6. Click the Layout Container Component and then click it's policy icon to open up the policy dialog:
    The current policy title is WKND Content .
    Update the Styles tab:
    1. Styles > Add a new Style named Full Width (default)with no value
    2. Styles > Add a new Style named Fixed Width with a value: cmp-layout-container--fixed
  7. Finally, test out the Fixed Width style on the main layout container in the Article Page Template.
    If you view a page created by the Article Template, you might notice that the page's Layout Container does not have a fixed width. At the end of this chapter we will make some large updates to the Article Template to ensure that all pages created from this template has a fixed width.

Content Fragment Component

For the article body we will leverage AEM Content Fragments . Content Fragments are de-coupled from the presentation layer and promote reuse of content across channels. The editorial UI of Content Fragments lends itself to working with large amounts of text. We will add a component to the WKND application to be able to reference Content Fragments into an article page. To view an overview of Content Fragments click here.
The Content Fragment component was previously a separate module of AEM Core Components. Staring with Core Components 2.4.0 , the Content Fragment component is part of the main Core Component project and available to be used via a proxy component.
  1. There is a Content Fragment reference component in AEM Core Components. It was not included automatically by the AEM project archetype. Manually proxy the component into the WKND code base.
    Create a cq:Component node named contentfragment beneath /apps/wknd/components/content .
    Add the following properties to the node:
    Name
    Type
    Value
    componentGroup
    String
    WKND.Content
    jcr:description
    String
    Displays content from a referenced Content Fragment
    jcr:title
    String
    Content Fragment
    jcr:primaryType
    Name
    cq:Component
    sling:resourceSuperType
    String
    core/wcm/components/contentfragment/v1/contentfragment
    cq:isContainer
    Boolean
    true
    <?xml version="1.0" encoding="UTF-8"?>
    <jcr:root xmlns:sling="https://sling.apache.org/jcr/sling/1.0" xmlns:cq="https://www.day.com/jcr/cq/1.0" xmlns:jcr="https://www.jcp.org/jcr/1.0"
        cq:isContainer="{Boolean}true"
        jcr:primaryType="cq:Component"
        componentGroup="WKND.Content"
        sling:resourceSuperType="core/wcm/components/contentfragment/v1/contentfragment"
        jcr:title="Content Fragment"
        jcr:description="Displays content from a referenced Content Fragment"/>
    
    
  2. In the previous chapter, as part of the import, some default styles for the Content Fragment component were included beneath /apps/wknd/clientlibs/clientlib-site/components/contentfragment :
    /* WKND Content Fragment style - default.less */
    
    .cmp-contentfragment {
        font-family: @font-family-serif;
    
        p {
            font-size: 20px;
            line-height: (@line-height-base + 1);
            text-align: justify;
        }
    }
    
    
    
  3. Deploy the code base to a local AEM instance using AEM Developer tools or your maven skills.
  4. Enable the Content Fragment by updating the Layout Container Policy
    1. Select the main Layout Container and click its Policy Icon
    2. Update the Allowed Components to include the Content Fragment component under WKND.Content
  5. Navigate to the first article page . The Content Fragment component should now be enabled and allowed to be added to a page.
  6. You can create a new Content Fragment by navigating to http://localhost:4502/assets.html/content/dam and clicking the Create button > Content Fragment from the dropdown. More information about authoring Content Fragments.
    Content Fragment author UI.
  7. Navigate back to the content page in which the Content Fragment component was added (Step 4). Click the Wrench icon to bring up the dialog. Using the path finder you can navigate and select an existing content fragment from the DAM. Optionally you can use the Asset Finder filter to restrict the assets to only Content Fragments and Drag+Drop one of the Content Fragments on to the component.
    Editing the Content Fragment component dialog to reference a content fragment.
    You will notice that each paragraph of the Content Fragment has a drop-zone to embed additional components within the Content Fragment. You will also notice that the content of the Content Fragment is read-only. This is by design so that the Content Fragment can only be updating by editing the original fragment.

Putting It Together

Now that we have some more components to work with we can start to add some more structure to our Article Template. The powerful feature of Editable Templates is the flexibility to make some components of the page fixed and standard across all pages, while making other components editable at the page level. It is important to find a balance between what is editable at the page level and what needs to be managed at the template level.
Below is a diagram of the Article Template sliced into what is fixed, fixed and unlocked and what is fully editable.
Article Template component architecture
The following videos show how we can implement the above requirements with AEM's Template Editor and then author an article page:


Next Steps

Next part in the tutorial:
View the finished code on GitHub or download the finished package for this part of the tutorial: WKND Chapter Solutions