Kick Start Your CoreMedia Project With Living Style Guides

In the last few years, the Frontend Developers at ]init[ - a CoreMedia implementation partner - have built several projects based on Fractal, a new pattern library framework that helps you build and document web component libraries, and integrate them into your projects. We use these libraries as a Living Style Guide for a range of CMS systems – but especially for CoreMedia Content Cloud.

Living Style Guides are an increasingly important tool for web developers – particularly on large and complex projects. They provide a shared set of design standards to ensure a consistent look and feel – and to help keep the entire development team in sync. They make it possible for us to decouple our design implementation from the target system. Because Frontend Developers are now able to work independently from a CMS, we can kick-start projects faster and show results much earlier to the client. Here’s a brief introduction to how it works!

Initially, our Living Style Guides provided just two of the three main frontend resources to a CMS: a CSS (Bundled or SCSS) and JavaScript (Bundled). However, it provided HTML only in the form of examples. This led us to our main pain point: markup changes became difficult to maintain. Every time the markup was changed in the Living Style Guide, a backend developer had to manually implement it into the CMS. Since we needed to communicate changes very strictly and verify implementations — this generated a lot of overhead communication. We learned a lot from this, however, and set out to design a better approach.

Introducing Freemarker Living Style Guides

The first step on our journey towards true markup delivery was to implement a Freemarker adapter for Fractal. Because the configuration for content beans was too complex, we decided against implementing a template-resolver to address this challenge. There was just no easy way to resolve the context of a bean for our Fractal instance. So, rather than attempting to deliver all the templates for a theme, we decided to create a custom HTML Framework based on Freemarker, a free Java-based template engine. By using macros to create the HTML, we were no longer dependent on Backend Developers. Our Frontend Developers can now compose HTML as they need it!

CoreMedia and Freemarker Packages

CoreMedia Content Cloud, release 9, introduced a new Frontend Developer Workflow, whereby a package-manager and a bundler generate a theme-archive along with all bundled resources, including Freemarker templates from node modules. This was implemented because bricks are installed as a node module and imported or included in the final template hierarchy. And this is where we dive into the process. One thing is important to note: Freemarker templates are only bundled into the theme archive when they come from a directory called "freemarkerLibs". Our current development process is as follows:

diagram2

Using Freemarker in Fractal

Using Fractal as a tool for our component libraries provides us with many benefits. We are able to structure and organize our components as we need them. The only requirement for a component in Fractal is a template file. Our components, however, usually come with the following files:

  • component.ftl (Template file)
  • component.macro.ftl (Macro file)
  • component.config.yml (Fractal model and component configuration)
  • component.scss (CSS file)
  • component.js (JS file)
  • README.md (Documentation file)

We have based our Style Guides on the Atomic Design pattern, which establishes a clear and systematic hierarchy based on biological concepts such as atoms, molecules, and organisms – as well as higher level structures for templates and pages. We start by putting the components into collections of atom macros, which contain macros for links, input elements or taglines, and headlines. These macros are then assembled into the next level of macros: molecules. At the molecule-level, we build more complex markup structures that include various combinations of inputs and labels. Molecule macros are then used to build organism macros that serve as functional modules. Since we don't need templates for this concept, we skip the next level level and go directly to pages that are made up of macros from our atoms, molecules and organism collections.

Here’s an example of a simple component:

component.macro.ftl

1

2

3

4

5

6

<#macro myComponent title text="">

    <h1>${title}</h1>

    <#if text?has_content>

        ${text}

    </#if>

</#macro>

Using this component in a template may look like this:

component.ftl

1

2

3

4

5

6

7

8

<#include "./component.macro.ftl />

 

<@myComponent title="CMArticle Title" text="<p>CMArticle Detail Text</p>" />

 

<#-- OUTPUT -->

 

<h1>CMArticle Title</h1>

<p>CMArticle Detail Text</p>

Mocking CoreMedia Content Bean Interfaces

Once we had our macros, we needed to adopt some additional information in order to use them. The first versions of our macros used several parameters, which were usually optional. Unfortunately, because many of them had properties that were differently named or were from different interfaces, they required a great deal of restructuring to the content bean interface while rendering the interface-template. This meant that we had to find a new approach.

When we designed our first attempt, we had limited knowledge about interfaces, especially the CoreMedia Content Bean interfaces. Interfaces are the abstract types of a Java class, or in our case, a content bean Java class. They represent a data-type structure for content beans. This is something we don't have in our frontend environments, which use static data-structures like Objects, Arrays or Strings. An interface can be compared to a JavaScript object with defined properties, but no values in them. When we render a template with this context, all variables/properties are available, but have no output values.

In order to solve this problem, we needed to mock the CoreMedia content bean interfaces. Mocking is a testing process that is designed to focus on the code being tested independent of any external dependencies. By replacing these dependencies with tightly controlled “mock” objects, you can more accurately simulate the behavior of real ones.

This is our mock for the CMPicture interface:

picture.config.yml

context:

  image:

    content:

        type: CMPicture

    data: "../path/to/image.png"

    caption: "Some Caption for this picture"

    title: "Some title for this picture"

    teaserTitle: "Teaser Title for this picture"

    alt: "Important alternative text for this picture"

    copyright: "Copyright information"

 

---------------------------------------------------------------

<#-- picture.macro.ftl --#>

 

<#macro picture img>

    <#local src = cm.getLink(img.data!cm.UNDEFINED) />

    <figure class="pre-picture">

        <picture class="pre-picture__picture">

            <img class="pre-picture__img" src="${src}" alt="${img.alt!''}" />

            <#if img.copyright??>

                <div class="pre-picture__copyright">${img.copyright}</div>

            </#if>

        </picture>

        <#if img.caption??>

            <figcaption class="pre-picture__caption">${img.caption}</figcaption>

        </#if>

    </figure>

</#macro>

 

---------------------------------------------------------------

<#-- picture.ftl --#>

<#include "./picture.macro.ftl" />

 

<@picture img=image />

---------------------------------------------------------------

<#-- CMPicture.ftl --#>

<#-- @ftlvariable name="self" type="com.coremedia.blueprint.common.contentbeans.CMPicture" -->

 

<#import "~/node_modules/lsg/freemarkerLibs/_index.ftl" as lib />

 

<@lib.picture img=self />

This model is then provided to our rendering engine and put into our picture macro. We use the mock in our Living Style Guide, but fill the macro with the actual bean in the theme. This allows us to reduce all properties and methods to primitive data types, while still making them usable. Of course, we lose a lot of functionality when we change the data types; however, we don't require it at any sensible time in the workflow. We pick the properties we need, transfer them into data types we can handle, and pass them into our macro where we can use them. That way our macros can be utilized in Fractal and CoreMedia Themes respectively. The point is to write them independent from any environment.

Mocking CoreMedia Freemarker Helpers

As you have probably seen in the example above, we use a CoreMedia freemarker library function at some point in our macro. The cm.getLink freemarker function generates a URL while template rendering. At least, this is how it works in a CoreMedia Theme. However, since we don't have a Content Application Engine (CAE) or any Java-Service in our Fractal prototype, we have to mock them too.

Our mock for this function is quite simple. Whereas cm.getLink generates a URL to a specific content document, our mock just prints out a URL. Although other CoreMedia Library functions and macros do more complex things, we managed to reduce those features to the same functionality and result.

Conclusion

Developing our Living Style Guides was quite a journey and we overcame many obstacles along the way. We're excited about the initial results. But we’re not done yet! It's still a challenge to mock CoreMedia interfaces and we haven't even started to mock our customized interfaces. Nonetheless, we are on a good path to bring HTML responsibility back to Frontend Developers. In order to complete our journey will still have to adopt a new HTML-Engine on the frontend side. Freemarker provides Frontend Developers with a lot of new features that we still have to explore in order to increase our ability to deliver HTML to the end user. With these new powers, we also have to take that responsibility. But now at least we can update that incomplete list that we described at the beginning of this post. We can now successfully deliver: CSS (Bundled or SCSS), Javascript (Bundled) and, finally, HTML (Authored).

Post a comment

Comment

ABOUT THE AUTHOR

André Petrakow

André Petrakow

André Petrakow is a Senior Developer at ]init[ AG, based in Berlin, Germany. Andre used to be a Full-Stack Developer, but then he got a crush on Frontend Development. He learned Coding on TYPO3 and Wordpress and has grown up with CoreMedia CMS. He is committed to providing leadership for his projects and opening up new pathways for his teammates. GitHub: “petrakow”

Anastasia Eckstedt 

Hi, my name is Anastasia Eckstedt.

Feel free to call me at +49.40.325587.209  
or send me an email to info@coremedia.com