A full reference for Content Components is available in the Components Templates Documentation.

 

Content Components

Detailed documentation for Content Component creation, config settings, render templates, and examples is available in the Component Templates Reference.

There are three types of components:

  • Content Components
  • Page Components
  • Site Components

Content Components can be used inside the editor to add new content

Page Components are part of the page template, for items like the sidebar or menus

Site Components are used to export files during publish, like an XML sitemap

Here we'll take a look at creating Content Components.

In the web snippet tutorial, we converted two of the items on the home page into web snippets.

Now let's take a look at converting the last two items - the banner and set of tiles, into the Content Components.

We're here in the Developer Preview.

We'll add "cms-component-template" script tags around the banner component

<script type="text/cms-component-template">

And let's add a component config at the top of the component to give it an ID and title

<cms-component-config>
{
  "id": "banner",
  "title": "Banner",
  "target": "content"
}
</cms-component-config>

For an icon, let's pick the "image" Google Material Icon:

"icon": "material:image"
  
Now the component should show up the listing, and we can select it from the dropdown.

Let's add Component Data Fields.

We will need an image, link, title, and body:

"data": {
  "fields": [
    { "name": "image", "caption": "Image", "control": "media_browser"},
    { "name": "link", "caption": "Link", "control": "link_browser"},
    { "name": "title", "control": "htmleditor" },
    { "name": "body", "control": "htmleditor" },
  ]
}
  
Now let's make the image required:

"validate": ["Required"]
  
And let's make that form pop up a little wider:
  
"popup": [1000, 400]
    
Now let's apply those fields to the render template.

<section class="banner" style="background-image:url(<%=item.image%>);">
  <div class="content">
    <h1 cms-content-editor="item.title">Ipsum sed lorem</h1>
    <div class="banner_body" cms-content-editor="item.body">Morbi in sem quis dui placerat ornare. Pellentesque odio nisi, euismod<br />sed arcu cras consecuat lorem ipsum dolor sit amet.</div>
    <ul class="actions">
      <li><a href="<%~item.link%>" class="button scrolly">Get Started</a></li>
    </ul>
  </div>
</section>

We'll add the image to the background using the style attribute.
We'll add the content editor to the title and body tags
And let's add the link to the button.

You'll notice that for the link, we're using the EJS slurp tags.  These will remove the containing HREF attribute if the field is blank.

Finally, let's add Component Property Fields:

"properties": {
  "fields": [
    { "name": "cssStyle", "caption": "CSS Style" },
    { "name": "cssClass", "caption": "CSS Class" },
  ],
}
  
Now, if we click "Configure", we'll get the Component Properties popup

Finally, let's apply the component property fields to the render template:

class="banner <%=component.cssClass%>" style="background-image:url(<%=item.image%>); <%=component.cssStyle%>"

 

Multiple Data Items

Next we have the tiles component.  Let's add the script tag

<script type="text/cms-component-template">

Now we'll add the config:

<cms-component-config>
{
  "id": "tiles",
  "title": "Tiles",
  "target": "content"
}
</cms-component-config>

And let's pick an icon - this time we'll go for "view_module"

"icon": "material:view_module"

Now let's add Component Data Fields:

"item_properties": [
  { "name": "image", "caption": "Image", "control": "media_browser"},
  { "name": "title", "control": "htmleditor" },
  { "name": "body", "control": "htmleditor" },
]

If we try this out, you'll notice an issue - there is just one editable item, while in the component, we have multiple items.

We'll need to set the multiple_items field in the config:

"multiple_items": true

Now when we go to edit, we'll start with a popup listing, and we can add / remove / reorganize items.

We'll also need to add the "jsh-foreach-item" attribute to add a repeating list to the render template:

<section class="tiles wrapper">
  <div class="inner flex flex-3">
    <div jsh-foreach-item class="flex-item box">
      <div class="image fit">
        <img src="<%=item.image%>" alt="<%=item.title%>" />
      </div>
      <div class="content">
        <h3 cms-content-editor="item.title" cms-content-editor-type="simple">Item Title</h3>
        <div cms-content-editor="item.body">Item Body</div>
      </div>
    </div>
  </div>
</section>

If we try this out, there is an issue, the items are one-third the size.

It looks like this flex-3 class is shrinking the items to one-third size.  This is good for the final render, but not good for the preview.

We can use the "cms-component-editor-remove-class" tag to fix that.  It will remove a class when previewing in the component editor:

cms-component-editor-remove-class="flex-3"

Let's also make the image container hide if the image is blank:

<% if(item.image){ %>
  <div class="image fit">

    <img src="<%=item.image%>" alt="<%=item.title%>" />
  </div>
<% } %>

Next, let's add some component properties so we can customize the style and class:

"properties": {
  "fields": [
    { "name": "cssStyle", "caption": "CSS Style" },
    { "name": "cssClass", "caption": "CSS Class" },
  ],
}
  
And apply those to the render template:

class="tiles wrapper <%=component.cssClass%>" style="<%=component.cssStyle%>"

Let's try this component out.  So far, this looks good with three items.

But if we add a fourth item, it doesn't work.  Our layout needs to create a new container if we exceed three items.

We can do that using the "jsh-group-items-into" tag.  This will repeat the container if the number of items exceeds a certain amount:

jsh-group-items-into="3"

As a last step, let's move these components out into their own files under "templates/components" so they can be used in any page template.

Loading
Loading