Content presentation
There are several places in the gui, besides the main content editor, where content is presented and it is possible to control how the content is displayed at those places. For example:

To construct a data model for the presentation, the content developer components first
fetches the content in the aceUISearch variant and then extracts a context from
the fetched data, the context is in turn comprised of one or more other, possibly named,
contexts. For example the Content Activity component constructs its data model from the
contexts 'LIST' and 'CONTENT-ACTIVITY'.
It is possible to customize the appearance of content of a specific type in the
aceUISearch variant composer, gui components will look for the property contentCard
in the resulting data and use it as the foundation when constructing its data model.
Example:
function compose (content) {
// This is a composer for a content representing an image
var image = content.aspects.image;
var contentCard = {
// 'label' is a context property, it is typically placed
// in a prime position in the view. Since it is here defined
// in the root level of the object it is considered to
// belong to the root context and will always be present.
label: image.title,
// 'thumbnail' is a context property that references an
// image that can be used to make a thumbnail image of
// content.
thumbnail: {
alias: content.system.id
},
// 'configurations' can only be defined in the root of
// this object and contains a list of contextual configurations.
// The contexts CARD and LIST will add the 'abstract' field to
// the result data.
contexts: [{
contexts: ['CARD', 'LIST'],
fields: {
// 'abstract' is a context property that implies some
// sort of summary of the content.
abstract: {
value: image.description,
// Fields may have properties, the 'rows' property
// of 'abstract' suggests that no more than two rows
// of text is sufficient to display this field.
rows: 2
}
}
}, {
// Contexts may target specific components of the gui.
// The Content Activity component of Content Developer
// will always get data from the context CONTENT-ACTIVITY.
contexts: ['CONTENT-ACTIVITY'],
fields: {
datetime: content.system.modificationTime
}
}]
};
return {
cacheControl: CacheControl,
aspects: {
aceUISearchEntry: {
contentCard: contentCard
}
}
};
}
The format of context data
Gui components can fetch data and extract a contextual data model from it using zero or more contexts. The contexts are merged together into a compiled context, consisting of some predefined fields. If a field is not set it wont be displayed in the gui, however, gui components have the ability to override contexts if they please.
A complete context data model with all fields set would look something like:
{
alias: '<string:alias>',
contentType: {
value: '<string:contentType>',
label: '<string>'
},
thumbnail: {
alias: '<string:alias>',
url: '<string:url>'
},
label: {
value: '<string>'
},
abstract: {
value: '<string>'
},
datetime: {
ISOstring: '<string>',
value: '<Date>'
},
classifiers: [
{
className: '<string>',
value: ['<string>']
}
],
tags: {
value: ['<string>']
}
}
Most fields follow the pattern { <key>: { value: 'grit value' } } and it is often possible
when configuring contexts to use a short-hand syntax like { <key>: 'grit value' } to set values:
{
alias: '<string:alias>',
contentType: '<string>', // ! -> contentType: { label: '<string>' }
thumbnail: '<string:alias>', // ! -> thumbnail: { alias: '<string>' }
label: '<string>',
abstract: '<string>',
datetime: '<string | Date>',
classifiers: '<Array>', // ! no short-hand for classifiers
tags: '<Array>'
}
Field by field reference
Most fields follow the pattern of an object with a 'value' property that is the displayed value in the gui.
alias: string
: The alias field exists in the compiled end context, it is an alias as a string for the content represented. Specifying this field in any other context has no effect.
abstract: { value: string, rows: Number }
: Comprises some essential parts of the content in a brief manner. The rows property suggests it is ok to display a truncated part of the value.
classifiers: [ { className: string, value: [ string... ] } ]
: Create named groups of data to be displayed in the gui. This is the way to inject custom fields to the view, each class is treated as a cohesive unit of information, and each item in value is considered to belong to its class.
contentType: { value: string, label: string }
: Conveys the contentType of the content represented, setting the value wont have any effect in the end context. The label property represents the display value of the contentType, setting the label suggests that it should be displayed in the gui.
datetime: { value: Date, ISOstring: string, shortDateFormat: boolean }
: Associate an important date and time to the entry. The emphasis of this field is highly context dependent. Only one of the properties needs to be set. If both are specified the value will be overwritten by the date that ISOstring represents. Setting the shortDateFormat to true communicates that the datetime may displayed in a shorter format.
label: { value: string, rows: Number }
: The display name of the content. It is the significant field of an entry and will be displayed in a highlighted position of the entry in the gui. The rows property suggests that the value can be truncated to a certain degree before displaying it.
tags: [ string... ]
: A list of tags to be displayed in conjuction with the content.
thumbnail: { alias: string, url: string, aspectRatio: string, height: Number, width: Number, alt: string }
: A thumbnail is a small image representation of the content. 'alias' is used to fetch the image from the Ace Image Service and 'url' uses the url value to get the image. The 'url' property takes precedence over the 'alias' property. The properties 'aspectRatio', 'width' and 'height' can be provided to suggest the appearance of the thumbnail in the gui. The value of 'alt' is the alternative text displayed if the image cannot be displayed for some reason.
Contexs used by Content Developer components
List of components and the contexts they use to get the view model.
Contexts are merged from right to left with the most specific context to the right.
| GUI component | Contexts | |
|---|---|---|
| Content Activity | LIST | CONTENT-ACTIVITY |
| Content Workflow | LIST | CONTENT-WORKFLOW |
| Search Dropdown | LIST | SEARCH-DROPDOWN |
| Full Search | CARD | SEARCH-VIEW |
| Recent Content | LIST | RECENT-CONTENT |
Customize the appearance of context fields in Content Developer
Although the gui components are in full control of the placement of different fields when displaying them in the gui, it is possible to control the appearance of the individual fields by context.
| data addition | html structured | custom field with styles |
|---|---|---|
![]() |
![]() |
![]() |
Add to the data
The most basic form of customization is to add information to the data model. For example to display the content type as a tag in the Content Activity component:
// This example is utilizing the article content type of Ace Starter Kit
// Example of adding a 'tag'
function compose (content) {
var typeLabel = 'articleContent';
var label = content.aspects.article.title;
var thumbnail = content.aspects.article.imageRef;
var abstract = content.aspects.article.lead;
var datetime = content.system.modificationDate;
return {
contentCard: {
label: {
value: label
},
thumbnail: {
alias: thumbnail
},
configurations: [{
contexts: ['CONTENT-ACTIVITY'],
fields: {
abstract: {
value: abstract,
rows: 1
},
datetime: {
ISOstring: datetime
},
// Here we add the content type as a tag
tags: [typeLabel]
}
}]
}
};
}
Customizing existing field appearance
Almost all fields allows for basic html formatting in its values, making it possible to customize the appearance of fields being displayed in the gui. For example:
// This example is utilizing the article content type of Ace Starter Kit
// Example of adding a 'type badge' in front of the label. The Content
// Developer comes with bootstrap styles by default so we take advantage
// of that
function compose (content) {
var typeLabel = 'Article';
var label = content.aspects.article.title;
var thumbnail = content.aspects.article.imageRef;
var abstract = content.aspects.article.lead;
var datetime = content.system.modificationDate;
return {
contentCard: {
label: {
value: label
},
thumbnail: {
alias: thumbnail
},
configurations: [{
contexts: ['CONTENT-ACTIVITY'],
fields: {
// This label overwrites the label in the root context...
label: {
value: '<span class="badge badge-primary">' + typeLabel + '</span> ' + label,
rows: 1
},
abstract: {
value: abstract,
rows: 1
},
datetime: {
ISOstring: datetime
}
}
}]
}
};
}
Adding custom fields with styles
It is even possible to provide css to further control the display of the context in the gui:
// This example is utilizing the article content type of Ace Starter Kit
var categorizationUtil = require ('categorization');
function compose (content) {
var typeLabel = 'Article',
label = content.aspects.article.title,
thumbnail = content.aspects.article.imageRef,
abstract = content.aspects.article.lead,
datetime = content.system.modificationDate,
categories = categorizationUtil.getEntityNames (content.aspects.aceCategorization || { categorization: {} });
articleTypes = categories.filter (function (category) {
return (category === 'news report' || category === 'editorial' || category === 'column');
});
return {
contentCard: {
label: {
value: label
},
thumbnail: {
alias: thumbnail
}
configurations: [{
cotexts: ['CONTENT-ACTIVITY'],
fields: {
// Note that css is added 'globally' so care must be taken
// not to overwrite existing rules
style: {
'.article-type': {
'background-color': 'green',
color: 'white',
'font-weight': 'bolder'
},
'.favorite-tag': {
'background-color': 'lightblue',
'border': '1px dotted black',
'border-radius': '5px'
},
'.favorite-tag .heart': {
'color': 'red',
'font-size': '18px'
}
},
classifiers: [{
// the field will have the className automagically added as a class
// attribute to the outputted html element for this field
className: 'article-type',
value: articleTypes
}, {
className: 'favorite-tag',
value: ['I <i class="material-icons heart">favorite</i> Ace']
}],
label: {
rows: 1
},
abstract: {
value: abstract,
rows: 1
},
datetime: {
ISOstring: datetime
}
}
}]
}
};
}


