Using Macros in Oracle Content and Experience

OCE blogger
Oracle Developers
Published in
8 min readAug 21, 2019

Overview

This blog demonstrates how to use macros in Oracle Content and Experience to provide dynamic content for components. The macros can be defined in JavaScript and used in rich-text components, a context list query, and other components. This use case will browse a list of blogs and drill down using a slug on the URL to a particular blog for details; the part of the URL that defines what the page is about is called a slug. A macro will be used to grab the slug from the URL for use in the content list query.

Blog Sample Setup

This use case uses content assets and a theme for a sample blog. Everything needed is available in a template package called BlogTemplate.zip from the Oracle Content and Experience Toolkit.

Go to https://github.com/oracle/content-and-experience-toolkit and click Clone or download. Choose Download ZIP, and content-and-experience-toolkit-master.zip will be downloaded. Unzip the file content-and-experience-toolkit-master.zip into the user home directory, ~/.

Enter cd ~/content-and-experience-toolkit-master/sites/cec-components/data/templates to go to the directory. Upload BlogTemplate.zip from that directory to Oracle Content and Experience.

In the Developer > Templates section, click Create and choose Import a template package.

Select the template package and import it.

Create a Blog Site

We will now create an enterprise site. Before we create the site, a repository must be created. In Assets > Repositories, click Create. Create a repository named Blog-Repository. In the Content Type field, select Starter-Blog-Author and Starter-Blog-Post.

Save and close the Create Repository screen.

Now we will create the localization policy. In Assets > Localization Policies, click Create.

Enter Blog-Localization-Policy for the name. Select English (United State) (en-US) for the required language and select English (United State) (en-US) for the default language. Save and close the Create Localization Policy screen.

Finally, create a site using BlogTemplate. Enter Blog-Site for Name. Choose Blog-Repository for Asset Repository and Blog-Localization-Policy for Localization Policy. Click Create to create the site.

After the site is created, select the site and click View. The site will render a summary of the blogs.

In the browser, hover over the links that show the blog title, and you will see URLs such as:

http://<host>:<port>/sites/preview/Blog-Site/post-detail/Starter-Blog-Post/CORE234835CB5D594A6FB39662DF2376874B/blog-site-1481786063051-developing-content-layout-for-content-and-experience-cloud

The URL ends with the post-detail page follow by “/<ContentType>/<AssetGUID>/<SiteName>-<GUID>-<Slug>”. The part of the URL that defines what the page is about is called a slug. In the example URL, the slug would be “developing-content-layout-for-content-and-experience-cloud”.

In this blog, we are going to modify the content-layout generated URL to be much simpler by changing the URL suffix to:

“…/post-detail.html#<Slug>”

This will make the URL more readable. We will create a custom macro that uses JavaScript to read the slug in the URL. With the slug that points to the detail blog to display, we will be able drive the content query that will fetch the detail blog.

Modify the Content Layout and Specify the Friendly URL

First, let’s modify the Starter-Blog-Post-Summary content layout so that the slug is passed through the URL after “post-detail.html#”. Go to Develop > View All Components and select Starter-Blog-Post-Summary content layout. Choose Open and navigate to the assets folder. Download layout.html and open it in an editor. Change href=“{{scsData.detailPageLink}}” to href=“post-detail.html#{{slug}}” on the anchor tag.

<!--
Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl.
-->
<div class="post-preview">
<a href="post-detail.html#{{slug}}">
<h2 class="post-title">
{{blogTitle}}
</h2>
<h3 class="post-subtitle">
{{blogSummary}}
</h3>
</a>
<p class="post-meta">Posted by {{blogAuthor}} on {{blogFormattedDate}}</p>
</div>
<hr>

For the JSON returned by the REST call, to get a list of blogs, each blog will look as follows, with a slug value:


},
"slug": "blog-site-1481786063051-developing-content-layout-for-content-and-experience-cloud",
"status": “draft"
}

The slug value is returned by the {{slug}} expression. Save the modification and upload the new version of layout.html to Oracle Content and Experience.

Select render.js in the same Oracle Content and Experience directory and download the file locally. Open it in an editor. Add the following line, “content = $.extend(content, this.contentItemData);”, to the render function. This additional line is needed in render.js so that the “{{slug}}” expression in layout.html can be correctly substituted by Mustache.js.


ContentLayout.prototype = {
contentVersion: '>=1.0.0 <2.0.0',
render: function (parentObj) {
var template,
contentClient = this.contentClient,
fields = this.contentItemData.fields,
content = {
blogImageRenditionURL: contentClient.getRenditionURL({
'id': fields['starter-blog-post_header_image'].id
}),
blogSummary: fields['starter-blog-post_summary'],
blogTitle: fields['starter-blog-post_title'],
blogContent: fields['starter-blog-post_content'],
blogFormattedDate: dateToMDY(this.contentItemData.updatedDate.value)
},
contentType,
secureContent = false;
content = $.extend(content, this.contentItemData); if (this.scsData) {
content = $.extend(content, {
'scsData': this.scsData
});
contentType = content.scsData.showPublishedContent === true ? 'published' : 'draft';
secureContent = content.scsData.secureContent;
}

Save the modification and upload the new version of the render.js file to Oracle Content and Experience.

Now we will tell Oracle Content and Experience to use a friendly URL for the content type Starter-Blog-Post. Go to Asset > Content Type. Select Starter-Blog-Post and choose Edit. Select Friendly URL. Check Enable friendly item name for URL. Select No default prefix for the field below it. Save and close the asset editor.

After specifying that the friendly URL is used by the content type Starter-Blog-Post, we can specify the friendly URL in the content items in assets. Go to Assets and limit the number of assets shown by Documents in Digital Assets and Starter-Blog-Post in Content Items.

For all the blog content items shown, select and edit the content item. Change the value in Friendly Item Name for URL to remove the site name and GUID. For example, blog-site-1481786063051-developing-content-layout-for-content-and-experience-cloud will be changed to developing-content-layout-for-content-and-experience-cloud. Save and close the asset editor. Repeat for all the blog post content items.

Finally, go to Sites > Blog-Site and choose View to run the site. In the browser, hover over the links that show the blog title. You will see the simpler, friendly URL, such as:

http://<host>:<port>/sites/preview/Blog-Site/post-detail.html#developing-content-layout-for-content-and-experience-cloud

Define the Custom Macro and Use It in a Content Query

Now that the content layout is rendering “post-detail.html#<slug>” for each content item, we will define the custom macro that uses JavaScript to read the slug in the URL. With the slug that points to a detail blog to display, we will be able drive the content query that will fetch the detail blog.

First, let’s define the macro. The macro is defined in the theme’s layout. Go to Developer > View All Themes. Navigate under BlogStarterTheme > layouts. Since the Post Detail page uses the page layout post-detail.html, we will select and download locally post-detail.html. Open the downloaded post-detail.html in an editor.

In the end of header section, add the following snippet, which defines {{getSlugMacro}}. It will fetch the string after “#” in the URL and return it via the expression {{getSlugMacro}}. The string will be the slug of the detail blog. Save the modification and upload the new version to post-detail.html.

<!--
Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl.
-->
<!DOCTYPE html>
<html lang="en">
<head>

<!--$SCS_RENDER_INFO-->
<!--$SCS_SITE_HEADER-->
<!--$SCS_PAGE_HEADER-->
<!-- {{getSlugMacro}} -->
<script type="text/javascript">
window.SCSMacros = window.SCSMacros || {};
window.SCSMacros.getSlugMacro = window.location.hash.substring(1);
</script>
</head>

We are going to add a Content List component for blogs to the Post Detail page. Let’s open the Post Detail page in Site Builder. Go to edit mode and create an update. Edit the Post Detail page. Add the seeded component Content List above Content Placeholder in row one.

Edit the settings of Content List. For the Content Type field, select Starter-Blog-Post. Enter the text slug eq “{{getSlugMacro}}” in the Additional Query String field. Choose Header for the Item View field.

The condition of Additional Query String will be applied to the query of Starter-Blog-Post Content List. The JSON returned by the REST call to get a list of blogs now looks as follows, with a slug value for each blog:


},
"slug": "developing-content-layout-for-content-and-experience-cloud",
"status": “draft"
}

The Additional Query String condition will match slug value against the value we get from {{getSlugMacro}} and return the blog that matches.

Close Content List Setting. Scroll down the Post Detail page and delete all three content placeholders.

Save and commit the Site Builder changes. Close Site Builder.

Select Sites > Blog-Sites and click View. The site will render a summary of the blogs. Hover over the blog title to see the URL with “#” follow by the slug.

Click the blog title, and the Post Detail page will render with the selected blog.

Note: This use case of blog drill down does not work in Site Builder. For it to work involves calling Renderer, and that is beyond the scope of the blog.

Summary

This is an example of using macros in Oracle Content and Experience. It involves defining the custom macro in the theme using JavaScript. The macro is used in the Additional Query String field of Content List to select the detail blog. In summary, you can extend Oracle Content and Experience in many ways through the custom macros.

--

--