Component Config :: cms-component-config

The component config defines the Component title, icon, Data fields, Property fields, and other options.  More information can be found in the cms-component-config reference.

<cms-component-config>...</cms-component-config>
<script type="text/cms-component-config">...</script>

Render HTML For One Item :: jsh-for-item

The "jsh-for-item" attribute only renders an HTML tag if a source variable is defined.  It will set a local variable "item" to the value of the source variable.

If the source variable is blank or not defined, no HTML will be rendered.

<element jsh-for-item="source_variable">
  <%=item%>
</element>

<!-- How it works -->
if(source_variable){
  set item = source_variable
  render <element>
}

<!-- Example -->
<div jsh-for-item="sitemap.root">
  <a href="<%~item.href%>"><%-item.html%></a>
</div>

If "jsh-for-item" is used without a source variable deifned, "item" will be used as the source variable.

Custom Local Variable Name :: jsh-for-item-variable

By default, "jsh-for-item" uses the local variable "item".  The name of the local variable can be customized with the "jsh-for-item-variable" attribute:

<element jsh-for-item="source_variable" jsh-for-item-variable="local_variable">
  <%=local_variable%>
</element>

<!-- How it works -->
if(source_variable){
  set local_variable = source_variable
  render <element>
}

<!-- Example -->
<div jsh-for-item="sitemap.root" jsh-for-item-variable="root">
  <a href="<%~root.href%>"><%-root.html%></a>
</div>

Render HTML For Each Item in a List :: jsh-foreach-item

The "jsh-foreach-item" attribute repeatedly renders an HTML tag for each item in a list.  It will set a local variable "item" to the value of each item.

If the list is empty, no HTML will be rendered.

<element jsh-foreach-item="list_variable">
  <%=item%>
</element>

<!-- How it works -->
foreach(item in list_variable){
  render <element>
}

<!-- Example -->
<div jsh-foreach-item="menu.topItems">
  <a href="<%~item.href%>"><%-item.html%></a>
</div>

If "jsh-foreach-item" is used without a list variable defined, "items" will be used as the list variable.

Custom Local Variable Name :: jsh-foreach-item-variable

By default, "jsh-foreach-item" uses the local variable "item".  The name of the local variable can be customized with the "jsh-foreach-item-variable" attribute:

<element jsh-foreach-item="list_variable" jsh-foreach-item-variable="local_variable">
  <%=local_variable%>
</element>

<!-- How it works -->
foreach(local_variable in list_variable){
  render <element>
}

<!-- Example -->
<div jsh-foreach-item="menu.topItems" jsh-foreach-item-variable="menuItem">
  <a href="<%~menuItem.href%>"><%-menuItem.html%></a>
</div>

Separators Between Items :: jsh-foreach-item-separator

Add a separator between items with the "jsh-foreach-item-separator" attribute:

<element jsh-foreach-item="list_variable" jsh-foreach-item-separator="separator_html">
  <%=item%>
</element>

<!-- How it works -->
foreach(item in list_variable){
  render <element>
  if(not last item){
    render <separator_html>
  }
}

<!-- Example -->
<div jsh-foreach-item="menu.topItems" jsh-foreach-item-separator=" | ">
  <a href="<%~item.href%>"><%-item.html%></a>
</div>

<!-- Result -->
<div>
  <a href="/item1.html">Item 1</a>
</div>
 | 
<div>
  <a href="/item2.html">Item 2</a>
</div>
 | 
<div>
  <a href="/item3.html">Item 3</a>
</div>

Start at List Item # :: jsh-foreach-item-start

Skip the first few items in the list using the "jsh-foreach-item-start" attribute.

For example, if "jsh-foreach-item-start" is set to "3", the first two items in the list will be skipped.

<element jsh-foreach-item="list_variable" jsh-foreach-item-start="start_index">
  <%=item%>
</element>

<!-- How it works -->
foreach(item in list_variable){
  if(item # < start_index) skip
  render <element>
}

<!-- Example -->
<div jsh-foreach-item="menu.topItems" jsh-foreach-item-skip="2">
  <a href="<%~item.href%>"><%-item.html%></a>
</div>

End at List Item # :: jsh-foreach-item-end

Only render up to a certain item in the list using the "jsh-foreach-item-end" attribute.

For example. if "jsh-foreach-item-end" is set to "5", all items after the fifth item in the list will be skipped.

<element jsh-foreach-item="list_variable" jsh-foreach-item-end="end_index">
  <%=item%>
</element>

<!-- How it works -->
foreach(item in list_variable){
  if(item # > end_index) skip
  render <element>
}

<!-- Example -->
<div jsh-foreach-item="menu.topItems" jsh-foreach-item-end="5">
  <a href="<%~item.href%>"><%-item.html%></a>
</div>

Skip # List Items :: jsh-foreach-item-skip

Skip every N items in the list using the "jsh-foreach-item-skip" attribute.

For example, if "jsh-foreach-item-skip" is set to "2", only one in every three items will be rendered, for example items #1, #4, #7, #10, and so on.

All odd-numbered items can be rendered by setting "jsh-foreach-item-skip" to "1", and all even-numbered items can be rendered by setting "jsh-foreach-item-skip" to "1" and "jsh-foreach-item-start" to "2".

<element jsh-foreach-item="list_variable" jsh-foreach-item-skip="skip_count">
  <%=item%>
</element>

<!-- How it works -->
foreach(item in list_variable){
  render <element>
  skip next skip_count items
}

<!-- Example -->
<div jsh-foreach-item="menu.topItems" jsh-foreach-item-skip="1">
  <a href="<%~item.href%>"><%-item.html%></a>
</div>

Custom Index Variable Name :: jsh-foreach-item-index

By default, "jsh-foreach-item" uses the index variable "jsh_item_index" to keep track of its current item #.  The name of the index variable can be customized with the "jsh-foreach-item-index" attribute:

<element jsh-foreach-item="list_variable" jsh-foreach-item-index="index_variable">
  Item #<%=index_variable%>: <%=item%>
</element>

<!-- How it works -->
foreach(item in list_variable){
  render <element>
}

<!-- Example -->
<div jsh-foreach-item="menu.topItems" jsh-foreach-item-index="idx">
  <a href="<%~item.href%>"><%=idx%>. <%-item.html%></a>
</div>

Group lists into rows or subgroups :: jsh-group-items

The "jsh-group-items" attribute splits a list into smaller lists, and renders a container for each subgroup.

The subgroup is set to the local variable "items", which can then be used to further render the individual items.

For example, a list of items can be split into groups of 3, so that they can be rendered three to a row.

The "jsh-group-items" tag also requires either a "jsh-group-items-into" or "jsh-group-items-by" tag to describe how to group the list items.

<element jsh-group-items="list_variable" jsh-group-items-into="subgroup_count">
  <%=JSON.stringify(items)%>
</element>

<element jsh-group-items="list_variable" jsh-group-items-by="subgroup_key">
  <%=JSON.stringify(items)%>
</element>

<!-- How it works -->
group(list_variable into subgroups){
  items = subgroup
  render <element>
}

<!-- Example -->
<div jsh-group-items="menu.topItems" jsh-group-items-into="3">
  <a jsh-foreach-item href="<%~item.href%>"><%-item.html%></a>
</div>

<!-- Results -->
<div>
  <a href="/item1.html">Item 1</a>
  <a href="/item2.html">Item 2</a>
  <a href="/item3.html">Item 3</a>
</div>
<div>
  <a href="/item4.html">Item 4</a>
  <a href="/item5.html">Item 5</a>
</div>

If "jsh-group-items" is used without a list variable defined, "items" will be used as the list variable.

If the list variable is "items", the "jsh-group-items" variable can be skipped, and only either the "jsh-group-items-by" is "jsh-group-items-into" attribute is required.

Group items into fixed-size rows :: jsh-group-items-into

The "jsh-group-items-into" attribute can render a list of items in fixed-size groups.  For example, a list can be rendered in rows of three items per row, by setting the "jsh-group-items-into" attribute to "3".

<element jsh-group-items="list_variable" jsh-group-items-into="subgroup_count">
  <%=JSON.stringify(items)%>
</element>

<!-- How it works -->
group(list_variable into subgroups of subgroup_count){
  items = subgroup
  render <element>
}

<!-- Example -->
<div jsh-group-items="menu.topItems" jsh-group-items-into="3">
  <a jsh-foreach-item href="<%~item.href%>"><%-item.html%></a>
</div>

Group items by item property :: jsh-group-items-by

The "jsh-group-items-by" attribute can render a list of items, split into groups based on an item property.  For example, a list of job positions can be grouped by department, by setting the "jsh-group-items-by" attribute to "item.department".

<element jsh-group-items="list_variable" jsh-group-items-by="subgroup_key">
  <%=JSON.stringify(items)%>
</element>

<!-- How it works -->
group(list_variable into subgroups by subgroup_key){
  items = subgroup
  render <element>
}

<!-- Example -->
<div jsh-group-items="items" jsh-group-items-by="item.department">
  <h3><%=item.department%></h3>
  <div jsh-foreach-item>
    <h4><%-item.title%></h4>
    <%-item.body%>
  </div>
</div>

Separators Between Items :: jsh-group-items-separator

Add a separator between items with the "jsh-group-items-separator" attribute:

<element jsh-group-items="list_variable" jsh-group-items-separator="separator_html">
  <%=JSON.stringify(items)%>
</element>

<!-- How it works -->
group(list_variable into subgroups){
  items = subgroup
  render <element>
  if(not last subgroup){
    render <separator_html>
  }
}

<!-- Example -->
<div jsh-group-items="menu.topItems" jsh-group-items-into="3" jsh-group-items-separator="<hr/>">
  <a jsh-foreach-item href="<%~item.href%>"><%-item.html%></a>
</div>

<!-- Results -->
<div>
  <a href="/item1.html">Item 1</a>
  <a href="/item2.html">Item 2</a>
  <a href="/item3.html">Item 3</a>
</div>
<hr/>
<div>
  <a href="/item4.html">Item 4</a>
  <a href="/item5.html">Item 5</a>
</div>

Custom Subgroup Variable Name :: jsh-group-items-subgroup

By default, "jsh-group-items" uses the local variable "items" for the subgroup.  The name of the subgroup variable can be customized with the "jsh-group-items-subgroup" attribute:

<element jsh-group-items="list_variable" jsh-group-items-subgroup="subgroup_variable">
  <%=JSON.stringify(subgroup_variable)%>
</element>

<!-- How it works -->
group(list_variable into subgroups){
  subgroup_variable = subgroup
  render <element>
}

<!-- Example -->
<div jsh-group-items="menu.topItems" jsh-group-items-into="3" jsh-group-items-subgroup="menuRow">
  <a jsh-foreach-item="menuRow" href="<%~item.href%>"><%-item.html%></a>
</div>

Custom Index Variable Name :: jsh-group-items-index

By default, "jsh-group-items" uses the index variable "jsh_group_index" to keep track of its current subgroup #.  The name of the index variable can be customized with the "jsh-group-items-index" attribute:

<element jsh-group-items="list_variable" jsh-group-items-index="index_variable">
  Item #<%=index_variable%>: <%=JSON.stringify(items)%>
</element>

<!-- How it works -->
group(list_variable into subgroups){
  subgroup_variable = subgroup
  render <element>
}

<!-- Example -->
<div jsh-group-items="menu.topItems" jsh-group-items-into="3" jsh-group-items-index="idx">
  Row #<%=idx%>:
  <a jsh-foreach-item href="<%~item.href%>"><%-item.html%></a>
</div>

Render Template :: jsh-template

The "jsh-template" attribute designates an HTML block as a template that can be rendered on-demand.  The "jsh-template" attribute makes for cleaner code if rendering the same HTML block multiple times, and enables nested, or recursive, rendering, for example in a multi-level menu or sitemap.

<element jsh-template="template_name">
  ...HTML/EJS Code...
</element>

<!-- How to use a render template -->
<%-renderTemplate('template_name', items_data)%>

<!-- How it works -->
renderTemplate(template_name, items_data) =>
  items = items_data
  render <element>

<!-- Example -->
<ul jsh-template="menu">
  <li jsh-foreach-item>
    <%-item.html%>
    <%-renderTemplate('menu', item.children)%>
  </li>
</ul>
<%-renderTemplate('menu', menu.tree)%>

Custom Items Variable Name :: jsh-template-items

By default, "jsh-template" uses the local variable "items" for the list data.  The name of the local variable can be customized with the "jsh-template-items" attribute:

<element jsh-template="template_name" jsh-template-items="items_variable">
  ...HTML/EJS Code...
</element>

<!-- How to use a render template -->
<%-renderTemplate('template_name', items_data)%>

<!-- How it works -->
renderTemplate(template_name, items_data) =>
  items_variable = items_data
  render <element>

<!-- Example -->
<ul jsh-template="menu" jsh-template-items="menuItems">
  <li jsh-foreach-item="menuItems">
    <%-item.html%>
    <%-renderTemplate('menu', item.children)%>
  </li>
</ul>
<%-renderTemplate('menu', menu.tree)%>

Editable Content Area :: cms-content-editor

Make an HTML element editable by adding the "cms-content-editor" attribute.  The attribute value should be the name of the content data field that will be edited.  Each content data field must be defined in the Component Config "data.fields" property.


<element cms-content-editor="item.field_name">
  Default Value
</element>

<!-- Example -->
<cms-component-config>
  {
    "title": "Banner",
    "icon": "material:view_module",
    "data": {
      "fields": [
        { "name": "content", "control": "htmleditor" }
      ]
    }
  }
</cms-component-config>
<div>
  <div cms-content-editor="item.content">Default Content</div>
</div>

Editable Content Area Type :: cms-content-editor-type

Two content editor types are supported - "full" and "simple". 

  • The "full" editor type has all the features of the standard page content editor, enabling web snippets, tables, and components. 
  • The "simple" editor can be used in elements that are meant for shorter blocks of content, and supports only basic images, links, and text.

By default, if "cms-content-editor-type" is not defined, the Editable Content Area will use the "full" editor.

<element cms-content-editor="item.field_name" cms-content-editor-type="editor_type">
  Default Value
</element>

<!-- Example -->
<cms-component-config>
  {
    "title": "Banner",
    "icon": "material:view_module",
    "data": {
      "fields": [
        { "name": "title", "control": "htmleditor" },
        { "name": "content", "control": "htmleditor" }
      ]
    }
  }
</cms-component-config>
<div>
  <h2 cms-content-editor="item.title" cms-content-editor-type="simple"></h2>
  <div cms-content-editor="item.content">Default Content</div>
</div>
Custom Styles for Component Editor Popup

In some components, it may be desired to add / remove classes in the Component Editor popup - for example when items are grouped three-per-row in the page, but displayed only one-per-row in the Component Editor popup.

Add Class in Component Editor Popup :: cms-component-editor-add-class

Add a class to the element when it is rendered in the Component Editor Popup. The class will not be added in the Page Preview or on Publish.

<element cms-component-editor-add-class="class_name">
  ...
</element>

<!-- Example -->
<div cms-component-editor-add-class="preview">Default Content</div>

<!-- Example in Page Preview -->
<div>Default Content</div>

<!-- Example in Component Editor Popup -->
<div class="preview">Default Content</div>

Remove Class in Component Editor Popup :: cms-component-editor-remove-class

Remove a class from the element when it is rendered in the Component Editor Popup. The class will not be removed from the Page Preview or on Publish.

<element cms-component-editor-remove-class="class_name">
  ...
</element>

<!-- Example -->
<div class="flex flex-3" cms-component-editor-remove-class="flex-3">
  ...
</div>

<!-- Example in Page Preview -->
<div class="flex flex-3">
  ...
</div>

<!-- Example in Component Editor Popup -->
<div class="flex">
  ...
</div>

Image Dimensions :: cms-image-dimensions

Image width and height can be automatically added to IMG tags by adding the "cms-image-dimensions" attribute to the IMG tag.

The image used must be from the CMS Media library, and no other "width" or "height" attributes should be present on the IMG:

<img src="<%=item.thumbnail%>" cms-image-dimensions />

EJS Container Slurp Tag :: <%~...%>

The EJS templating language used in the Render Components provides standard tags for escaping HTML (<%= ... %>), and for rendering non-escaped HTML (<%-  ...  %>).

However, the language does not have an elegant way to "slurp", or remove, the containing attribute if it does not exist.

The jsHarmony CMS adds a container slurp tag, that removes the containing HTML attribute or HTML element, if the value is empty or does not exist.

The slurp tag must be the only text inside the attribute or element:

<!-- HTML Attribute Slurp -->
<div class="<%~item.class%>"></div>
==> If item.class is empty, this will render as: <div></div>

<!-- HTML Element Slurp -->
<div><span><%~item.class%></span></div>
==> If item.class is empty, this will render as: <div></div>

The slurp tag can be used together with the standard EJS templating tags:

<%~=value%>
<%~-value%>
<%~_value%>
<%~_value_%>
<%~value-%>
Loading
Loading