Content library

Contents

Functions to find and manipulate content.

Usage

Add the following to your build.gradle file:

dependencies {
  include xplibs.content
}

Add the import statement to your code:

import contentLib from '/lib/xp/content';

You are now ready to use the API.

Constants

CONTENT_ROOT_PATH

String constant with the root path of content nodes (/content).

Usage

import {CONTENT_ROOT_PATH} from '/lib/xp/content';

const myRoot = CONTENT_ROOT_PATH; // "/content"

ARCHIVE_ROOT_PATH

String constant with the root path of archived nodes (/archive).

Usage

import {ARCHIVE_ROOT_PATH} from '/lib/xp/content';

const myRoot = ARCHIVE_ROOT_PATH; // "/archive"

Functions

addAttachment

Adds an attachment to an existing content.

Parameters:

addAttachment() takes a single AddAttachmentParam object with these properties:

Name Type Description

key

string

Path or id to the content.

name

string

Attachment name (unique within the content).

mimeType

string

Attachment content type.

label

string

Optional. Attachment label.

data

ByteSource

Stream with the binary data for the attachment.

Examples

import {addAttachment} from '/lib/xp/content';

// Adds an attachment.
addAttachment({
    key: '/mySite/mycontent',
    name: 'image',
    mimeType: 'image/png',
    label: 'photo',
    data: dataStream
});

archive

Archives a content

Parameters:

archive() takes a single ArchiveContentParams object with these properties:

Name Type Description

content

string

Path or id of the content to be archived

Returns

string[] : List with ids of the contents that were archived

Examples

import {archive} from '/lib/xp/content';

// Archive content by path.
const result1 = archive({
    content: '/path/to/mycontent',
});

log.info('Archived content ids: %s', result1.join(','));

// Archive content by id.
const result2 = archive({
    content: 'my-content-id'
});

log.info('Archived content ids: %s', result2.join(','));

create

Creates a content.

Either name or displayName (or both) must be specified. When name is not set, the system will auto-generate a name based on the displayName, by lower-casing and replacing certain characters. If there is already a content with the auto-generated name, a suffix will be added to name in order to make it unique.

To create a content where name is not important and there could be multiple instances under the same parent content, skip the name parameter and specify a displayName instead.

Parameters:

create() takes a single CreateContentParams object with these properties:

Name Type Description

name

string

Optional. Name of content.

parentPath

string

Path to place content under.

displayName

string

Optional. Display name. Defaults to the same as name.

requireValid

boolean

Optional. The content has to be valid, according to the content type, to be created. If true and the content is not strictly valid, an error will be thrown. Defaults to true.

refresh

boolean

Optional. If true, the created content will be searchable through queries immediately, otherwise within 1 second. Since there is a performance penalty doing this refresh, set to false for bulk operations. Defaults to true.

contentType

string

Content type to use.

language

string

Optional. The language tag representing the content’s locale.

childOrder

string

Optional. Default ordering of children when doing getChildren if no order is given in query.

data

object

Actual content data.

page

object

Optional. Content page.

x

object

Optional. eXtra data to use.

idGenerator

function

Optional. Function used to generate the id-suffix appended to the content name. Only called when name is auto-generated from displayName and the generated name is already taken.

workflow

Workflow

Optional. Workflow information to use. Defaults to { state: "READY" }.

Returns

object : (Content) The content that was created

Examples

import {create} from '/lib/xp/content';

// Creates a content.
const result1 = create({
    name: 'mycontent',
    parentPath: '/a/b',
    displayName: 'My Content',
    contentType: 'test:myContentType',
    language: 'es',
    data: {
        a: 1,
        b: 2,
        c: ['1', '2'],
        d: {
            e: {
                f: 3.6,
                g: true
            }
        }
    },
    x: {
        "com-enonic-myapplication": {
            myschema: {
                a: 1
            }
        }
    },
    workflow: {
        state: 'PENDING_APPROVAL'
    },
});

log.info('Content created with id %s', result1._id);
import {create} from '/lib/xp/content';

// Check if content already exists.
try {
    const result2 = create({
        name: 'mycontent',
        parentPath: '/a/b',
        displayName: 'My Content',
        contentType: 'test:myContentType',
        data: {}
    });

    log.info('Content created with id %s', result2._id);

} catch (e) {
    if (e.code == 'contentAlreadyExists') {
        log.error('There is already a content with that name');
    } else {
        log.error('Unexpected error: %s', e.message);
    }
}
// Content created.
const expected = {
    _id: "123456",
    _name: "mycontent",
    _path: "/a/b/mycontent",
    creator: "user:system:anonymous",
    createdTime: "1975-01-08T00:00:00Z",
    type: "test:myContentType",
    displayName: "My Content",
    hasChildren: false,
    language: "es",
    valid: false,
    data: {
        a: 1,
        b: 2,
        c: [
            "1",
            "2"
        ],
        d: {
            e: {
                f: 3.6,
                g: true
            }
        }
    },
    x: {
        "com-enonic-myapplication": {
            myschema: {
                a: 1
            }
        }
    },
    page: {},
    attachments: {},
    publish: {}
};

createMedia

Creates a media content

Parameters:

createMedia() takes a single CreateMediaParams object with these properties:

Name Type Description

name

string

Name of content.

parentPath

string

Optional. Path to place content under. Defaults to /.

focalX

number

Optional. Focal point for X axis (if it’s an image).

focalY

number

Optional. Focal point for Y axis (if it’s an image).

artist

string | string[]

Optional. Artist of the media.

tags

string | string[]

Optional. Tags of the media.

caption

string

Optional. Caption of the media.

altText

string

Optional. Alt text of the media.

copyright

string

Optional. Copyright of the media.

data

object

Data (as stream) to use.

idGenerator

function

Optional. Function used to generate the id-suffix appended to the content name.

Returns

object : (Content) The media content that was created

Examples

import {createMedia} from '/lib/xp/content';

// Creates a media.
const result = createMedia({
    name: 'mycontent',
    parentPath: '/a/b',
    data: stream
});
// Media created.
const expected = {
    _id: "123456",
    _name: "mycontent",
    _path: "/a/b/mycontent",
    creator: "user:system:anonymous",
    createdTime: "1975-01-08T00:00:00Z",
    type: "base:unstructured",
    hasChildren: false,
    valid: false,
    data: {},
    x: {},
    page: {},
    attachments: {},
    publish: {}
};

updateMedia

Updates a media content

modifyMedia is the deprecated predecessor of updateMedia, still exported for backward compatibility. Use updateMedia in new code.

Parameters:

updateMedia() takes a single UpdateMediaParams object with these properties:

Name Type Description

key

string

Path or id of the media content.

name

string

Name of the media content.

data

object

Media data (as a stream).

focalX

number

Optional. Focal point for X axis (if content is an image).

focalY

number

Optional. Focal point for Y axis (if content is an image).

caption

string

Optional. Caption.

artist

string | string[]

Optional. Artist.

copyright

string

Optional. Copyright.

tags

string | string[]

Optional. Tags.

Returns

object : (Content) The media content that was updated, or null if it was not found

Examples

import {updateMedia} from '/lib/xp/content';

// Updates a media.
const result = updateMedia({
    key: '/a/b/mycontent',
    name: 'mycontent',
    data: stream,
    artist: ['Artist 1', 'Artist 2'],
    caption: 'Caption',
    copyright: 'Copyright',
    tags: ['tag1', 'tag2']
});
// Modified media.
const expected = {
    _id: "123456",
    _name: "myMedia",
    _path: "/a/b/myMedia",
    creator: "user:system:anonymous",
    createdTime: "1975-01-08T00:00:00Z",
    type: "base:unstructured",
    hasChildren: false,
    valid: false,
    data: {
        caption: "Caption",
        artist: [
            "Artist 1",
            "Artist 2"
        ],
        copyright: "Copyright",
        tags: [
            "tag1",
            "tag2"
        ]
    },
    x: {},
    page: {},
    attachments: {},
    publish: {}
};

deleteContent

Deletes a content. A published content will be unpublished before deletion.

Renamed from delete to avoid the JavaScript reserved word. The old delete export is still available for backward compatibility.

Parameters:

deleteContent() takes a single DeleteContentParams object with these properties:

Name Type Description

key

string

Path or id to the content

Returns

boolean : true if deleted, false otherwise

Examples

import {deleteContent} from '/lib/xp/content';

// Deletes a content by path.
const result = deleteContent({
    key: '/features/js-libraries/mycontent'
});

if (result) {
    log.info('Content deleted');
} else {
    log.info('Content was not found');
}

duplicate

Duplicates a content.

Parameters:

duplicate() takes a single DuplicateContentParams object with these properties:

Name Type Description

contentId

string

Id of the content.

workflow

Workflow

Optional. Workflow information to use. Defaults to { state: "READY" }.

includeChildren

boolean

Optional. Indicates that children contents must be duplicated, too. Ignored if variant=true. Defaults to true.

variant

boolean

Optional. Indicates that duplicated content is a variant. Defaults to false.

parent

string

Optional. Destination parent path. By default, a duplicated content will be added as a sibling of the source content.

name

string

Optional. New content name.

Returns

object : (DuplicateContentsResult) Summary of the content duplicate

Examples

Duplicate a content

import {duplicate} from '/lib/xp/content';

// Duplicate content by id
const result = duplicate({
    contentId: '79e21db0-5b43-45ce-b58c-6e1c420b22bd',
    includeChildren: false,
});

// Summary of the duplicated content.
const expected = {
    contentName: "sourcecontentname-copy",
    sourceContentPath: "/path/to/duplicated-content",
    duplicatedContents: [
        "duplicated-content-id"
    ]
};

Create a variant

import {duplicate} from '/lib/xp/content';

// Create a variant of the content
const result = duplicate({
    contentId: '79e21db0-5b43-45ce-b58c-6e1c420b22bd',
    variant: true,
    name: 'variant-name'
});

const expected = {
    contentName: "variant-name",
    sourceContentPath: "/path/to/variant-name",
    duplicatedContents: [
        "variant-content-id"
    ]
}

exists

Checks if a content exists in the current context.

Parameters:

exists() takes a single ContentExistsParams object with these properties:

Name Type Description

key

string

Path or id to the content

Returns

boolean : true if exists, false otherwise

Examples

import {exists} from '/lib/xp/content';

// Checking if a content exists
const result = exists({
    key: '/path/to/mycontent'
});

if (result) {
    log.info('Content exists');
} else {
    log.info('Content does not exist');
}

get

Returns a content

Parameters:

get() takes a single GetContentParams object with these properties:

Name Type Description

key

string

Path or id to the parent content.

versionId

string

Optional. Content version id.

Returns

object : (Content) The content fetched from the repository, or null if it was not found

Examples

import {get as getContentByKey} from '/lib/xp/content';

// Gets a single content by path.
const result = getContentByKey({
    key: '/path/to/mycontent'
});

if (result) {
    log.info('Display Name = %s', result.displayName);
} else {
    log.info('Content was not found');
}
// Content as it is returned.
const expected = {
    _id: "123456",
    _name: "mycontent",
    _path: "/path/to/mycontent",
    creator: "user:system:admin",
    modifier: "user:system:admin",
    createdTime: "1970-01-01T00:00:00Z",
    modifiedTime: "1970-01-01T00:00:00Z",
    type: "base:unstructured",
    displayName: "My Content",
    hasChildren: false,
    language: "en",
    valid: true,
    childOrder: "_ts DESC, _name ASC",
    data: {
        myfield: "Hello World"
    },
    x: {},
    page: {},
    attachments: {
        "logo.png": {
            name: "logo.png",
            label: "small",
            size: 6789,
            mimeType: "image/png"
        },
        "document.pdf": {
            name: "document.pdf",
            size: 12345,
            mimeType: "application/pdf"
        }
    },
    publish: {}
};

getActiveVersions

Returns the active content version for each specified branch.

Parameters:

getActiveVersions() takes a single GetActiveVersionsParams object with these properties:

Name Type Description

key

string

Path or id of the content

branches

string[]

Array of branch names to get active versions for

Returns

object : (ActiveContentVersions) Object with branch names as keys and content versions as values

Examples

import {getActiveVersions} from '/lib/xp/content';

// Fetch active versions for draft and master branches
const result = getActiveVersions({
    key: 'contentid',
    branches: ['draft', 'master']
});

log.info('Draft version: %s', result.draft.versionId);
log.info('Master version: %s', result.master.versionId);

getAttachments

This function returns a content attachments

Parameters:

getAttachments() takes the content’s path or id as a single string argument.

Returns

object : A map of Attachment objects keyed by attachment name, or null if the content was not found

Examples

// Attachments returned.
const expected = {
    "logo.png": {
        name: "logo.png",
        label: "small",
        size: 6789,
        mimeType: "image/png"
    },
    "document.pdf": {
        name: "document.pdf",
        size: 12345,
        mimeType: "application/pdf"
    }
};

getAttachmentStream

This function returns a data-stream for the specified content attachment

Parameters:

getAttachmentStream() takes a single GetAttachmentStreamParams object with these properties:

Name Type Description

key

string

Path or id to the content

name

string

Attachment name

Returns

object : (ByteSource) Stream of the attachment data, or null if the content or attachment was not found

Examples

import {getAttachmentStream} from '/lib/xp/content';

// Get stream for attachment.
const stream = getAttachmentStream({
    key: '/a/b/mycontent',
    name: 'document.pdf'
});

getChildren

Fetches children of a content

Parameters:

getChildren() takes a single GetChildContentParams object with these properties:

Name Type Description

key

string

Path or id to the parent content.

start

number

Optional. Start index (used for paging). Defaults to 0.

count

number

Optional. Number of contents to fetch. Defaults to 10.

sort

string

Optional. Sorting expression.

Returns

object : (ContentsResult) The children fetched from the repository

Examples

import {getChildren} from '/lib/xp/content';

// Returns the children of specified path.
const result = getChildren({
    key: '/path/to',
    start: 0,
    count: 2,
    sort: '_modifiedTime ASC'
});

log.info('Found %s number of contents', result.total);

result.hits.forEach((content) => {
  log.info('Content %s loaded', content._name);
});
// Result set returned.
const expected = {
    total: 20,
    count: 2,
    hits: [
        {
            _id: "id1",
            _name: "name1",
            _path: "/a/b/name1",
            creator: "user:system:admin",
            modifier: "user:system:admin",
            createdTime: "1970-01-01T00:00:00Z",
            modifiedTime: "1970-01-01T00:00:00Z",
            type: "base:unstructured",
            displayName: "My Content 1",
            hasChildren: false,
            valid: false,
            data: {},
            x: {},
            page: {},
            attachments: {},
            publish: {}
        },
        {
            _id: "id2",
            _name: "name2",
            _path: "/a/b/name2",
            creator: "user:system:admin",
            modifier: "user:system:admin",
            createdTime: "1970-01-01T00:00:00Z",
            modifiedTime: "1970-01-01T00:00:00Z",
            type: "base:unstructured",
            displayName: "My Content 2",
            hasChildren: false,
            valid: false,
            data: {},
            x: {},
            page: {},
            attachments: {},
            publish: {}
        }
    ]
};

getOutboundDependencies

Returns the list of content items that are outbound dependencies of specified content.

Parameters:

getOutboundDependencies() takes a single GetOutboundDependenciesParams object with these properties:

Name Type Description

key

string

Path or id to the content

Returns

string[] : List with ids of dependent content items

Examples

import {getOutboundDependencies} from '/lib/xp/content';

// Gets outbound dependencies of content by its Id.
const result = getOutboundDependencies({
    key: '/features/js-libraries/mycontent'
});

if (result) {
    log.info('Outbound dependencies: %s', JSON.stringify(result, null, 4));
} else {
    log.info('Outbound dependencies were not found');
}

getPermissions

Returns content permissions

Parameters:

getPermissions() takes a single GetPermissionsParams object with these properties:

Name Type Description

key

string

Path or id to the content

Returns

object : (Permissions) Content permissions, or null if the content was not found

Examples

import {getPermissions} from '/lib/xp/content';

// Return permissions for content by path.
const result = getPermissions({
    key: '/features/js-libraries/mycontent'
});

if (result) {
    result.permissions.forEach((entry) => {
        log.info('%s is allowed: %s', entry.principal, entry.allow.join(','));
    });
} else {
    log.info('Content not found');
}
// Permissions returned.
const expected = {
    permissions: [
        {
            principal: "user:system:anonymous",
            allow: [
                "READ"
            ],
            deny: []
        }
    ]
};

getSite

Returns the parent site of a content

Parameters:

getSite() takes a single GetSiteParams object with these properties:

Name Type Description

key

string

Path or id to the content

Returns

object : (Content) The parent site, or null if the content has none

Examples

import {getSite} from '/lib/xp/content';

// Returns content's parent site
const result = getSite({
    key: '/path/to/mycontent'
});
log.info('Site name = %s', result._name);
// Site data returned.
const expected = {
    _id: "100123",
    _name: "my-content",
    _path: "/my-content",
    type: "base:unstructured",
    hasChildren: false,
    valid: false,
    data: {
        siteConfig: {
            applicationKey: "myapplication",
            config: {
                Field: 42
            }
        }
    },
    x: {},
    page: {},
    attachments: {},
    publish: {}
};

getSiteConfig

Returns configuration of a specified application assigned to the site of a content

Parameters:

getSiteConfig() takes a single GetSiteConfigParams object with these properties:

Name Type Description

key

string

Path or id to the content

applicationKey

string

Application key

Returns

object : App config (as JSON)

Examples

import {getSiteConfig} from '/lib/xp/content';

// Returns config of the content's parent site
const result = getSiteConfig({
    key: '/path/to/mycontent',
    applicationKey: app.name
});
log.info('Field value for the site config = %s', result.Field);
// Site config returned.
const expected = {
    Field: 42
};

getType

Returns properties and icon of the specified content type

Parameters:

getType() takes the content type name as a single string argument, formatted as <app>:<name> (for example, com.enonic.myapp:article).

Returns

object : (ContentType) The content type if found, or null otherwise

Examples

import {getType} from '/lib/xp/content';

// Get a content type by name
const contentType = getType('com.enonic.myapp:person');
// Content type returned:
const expected = {
    name: "com.enonic.myapp:person",
    title: "Person",
    description: "Person content type",
    superType: "base:structured",
    abstract: false,
    final: true,
    allowChildContent: true,
    modifiedTime: "2016-01-01T12:00:00Z",
    icon: {
        mimeType: "image/png",
        modifiedTime: "2016-01-01T12:00:00Z"
    },
    form: [
        {
            formItemType: "Input",
            name: "name",
            label: "Full name",
            maximize: true,
            inputType: "TextLine",
            occurrences: {
                maximum: 1,
                minimum: 1
            },
            config: {}
        },
        {
            formItemType: "Input",
            name: "title",
            label: "Photo",
            helpText: "Person photo",
            maximize: true,
            inputType: "ImageSelector",
            occurrences: {
                maximum: 1,
                minimum: 1
            },
            config: {}
        },
        {
            formItemType: "Input",
            name: "bio",
            label: "Bio",
            maximize: true,
            inputType: "HtmlArea",
            occurrences: {
                maximum: 1,
                minimum: 1
            },
            config: {}
        },
        {
            formItemType: "Input",
            name: "birthdate",
            label: "Birth date",
            maximize: true,
            inputType: "Date",
            occurrences: {
                maximum: 1,
                minimum: 0
            },
            config: {}
        },
        {
            formItemType: "Input",
            name: "email",
            label: "Email",
            helpText: "Email address",
            maximize: true,
            inputType: "TextLine",
            occurrences: {
                maximum: 1,
                minimum: 1
            },
            config: {
                regexp: [
                    {
                        value: "^[^@]+@[^@]+\\.[^@]+$"
                    }
                ]
            }
        },
        {
            formItemType: "Input",
            name: "nationality",
            label: "Nationality",
            maximize: true,
            inputType: "ContentSelector",
            occurrences: {
                maximum: 1,
                minimum: 0
            },
            config: {
                allowContentType: [
                    {
                        value: "com.enonic.myapp:country"
                    }
                ]
            }
        }
    ]
};
import {getType} from '/lib/xp/content';

// Get a content type icon
const ct = getType('com.enonic.myapp:person');
const icon = ct.icon;
return {
    body: icon.data,
    contentType: icon.mimeType
};

getTypes

Returns the list of all the content types currently registered in the system

Returns

array : (ContentType[]) All the content types found

Examples

import {getTypes} from '/lib/xp/content';

// Gets the list of all content types in the system
const contentTypes = getTypes();

log.info('%s content types found:', contentTypes.length);
contentTypes.forEach(({title, name, superType}) => {
    if (superType === 'base:structured') {
        log.info('%s - %s', name, title);
    }
});

getVersions

Returns content versions, with cursor-based pagination.

Parameters:

getVersions() takes a single GetVersionsParams object with these properties:

Name Type Description

key

string

Path or id of the content.

count

number

Optional. Number of content versions to fetch. Defaults to 10.

cursor

string

Optional. Cursor for pagination.

Returns

object : (ContentVersionsResult) The content versions

Examples

import {getVersions} from '/lib/xp/content';

// Fetch first page
const result = getVersions({
    key: 'contentid',
    count: 2
});

log.info('Total versions: %s', result.total);

// Fetch next page using cursor
if (result.cursor) {
    const nextPage = getVersions({
        key: 'contentid',
        count: 2,
        cursor: result.cursor
    });
}

update

Update a content

Properties starting with _ may not be modified using this function. To rename or move a content (ie to change the _name property), use the move function instead.
modify is the deprecated predecessor of update. It is still exported for backward compatibility and is backed by the same implementation, so everything on this page — including the editable-field restrictions below — applies to it unchanged. Use update in new code.

Parameters:

update() takes a single UpdateContentParams object with these properties:

Name Type Description

key

string

Path or id to the content.

editor

function

Editor callback function.

requireValid

boolean

Optional. The content has to be valid (according to the content type) to be updated. If true and the content is not strictly valid, an error will be thrown. Defaults to true.

The editor callback receives the current content and must return it with the desired modifications.

Editable Fields:

Only these properties are read back from the object the editor returns:

Name Type Description

displayName

string

The display name of the content.

language

string

The language tag representing the content’s locale.

data

object

The main data (properties) of the content, according to its content type.

x

object

Extra data (x-data) associated with the content.

page

object

The page configuration, including regions and components.

Any other property assigned inside the editor is silently ignored — no error is thrown, and the returned content reflects the unchanged value. Notably, setting workflow or publish in the editor worked in XP 7 but has no effect in XP 8. Use the dedicated functions instead:

A genuine update resets workflow state to IN_PROGRESS. Whenever the editor actually changes the content, the update also re-validates it and stamps workflow.state: IN_PROGRESS, modifier and modifiedTime. An editor that returns the content unchanged is a no-op: no new version is written and no transition happens.

Since publish() refuses content that is not READY, any create → update sequence ends unpublishable — for example create a content, create its image, update the content to reference the image id necessarily leaves the content IN_PROGRESS. Mark it ready with updateWorkflow() before publishing.

The same transition applies to every function built on the same underlying update operation: modify, updateMedia(), addAttachment() and removeAttachment().

Returns

object : (Content) The updated content, or null if it was not found

Examples

import {update} from '/lib/xp/content';

// Editor to call for content.
function editor(c) {
    c.displayName = 'Modified';
    c.language = 'en';
    c.data.myCheckbox = false;
    c.data["myTime"] = "11:00";
    return c;
}

// Update content by path
const result = update({
    key: '/a/b/mycontent',
    editor: editor
});

if (result) {
    log.info('Content modified. New title is %s', result.displayName);
} else {
    log.info('Content not found');
}
// Content modified.
const expected = {
    _id: "123456",
    _name: "mycontent",
    _path: "/path/to/mycontent",
    creator: "user:system:admin",
    modifier: "user:system:admin",
    createdTime: "1970-01-01T00:00:00Z",
    modifiedTime: "1970-01-01T00:00:00Z",
    type: "base:unstructured",
    displayName: "Modified",
    hasChildren: false,
    language: "en",
    valid: true,
    childOrder: "_ts DESC, _name ASC",
    data: {
        myfield: "Hello World",
        myCheckbox: "false",
        myTime: "11:00"
    },
    x: {},
    page: {},
    attachments: {
        "logo.png": {
            name: "logo.png",
            label: "small",
            size: 6789,
            mimeType: "image/png"
        },
        "document.pdf": {
            name: "document.pdf",
            size: 12345,
            mimeType: "application/pdf"
        }
    },
    publish: {}
};

updateMetadata

Updates metadata (owner and variantOf) for a content. The update is applied to both the master and draft branches.

Parameters:

updateMetadata() takes a single UpdateMetadataParams object with these properties:

Name Type Description

key

string

Path or id to the content

editor

function

Editor callback function to modify metadata

The editor callback receives an object with the current source content, owner and variantOf, and must return the same object with the desired modifications.

Returns

object : (UpdateMetadataResult) The updated content, wrapped in a content property

Examples

import {updateMetadata} from '/lib/xp/content';

// Update content metadata by path
const result = updateMetadata({
    key: '/a/b/mycontent',
    editor: (c) => {
        c.owner = 'user:system:new-owner';
        return c;
    }
});

if (result) {
    log.info('Content metadata updated');
} else {
    log.info('Content not found');
}

updateWorkflow

Updates the workflow state of a content. The update is applied to the draft branch only.

Parameters:

updateWorkflow() takes a single UpdateWorkflowParams object with these properties:

Name Type Description

key

string

Path or id to the content

editor

function

Editor callback function to modify workflow

The editor callback receives an object with the current source content and a writable state property, and must return the same object with the desired modifications. state must be set — returning the object without it throws.

Returns

object : (UpdateWorkflowResult) The updated content, wrapped in a content property

Examples

import {updateWorkflow} from '/lib/xp/content';

// Mark content workflow as READY
const result = updateWorkflow({
    key: '/a/b/mycontent',
    editor: (w) => {
        w.state = 'READY';
        return w;
    }
});

patch

Patches a content

This is a low-level and potentially dangerous operation.

It should be used with caution. Access is restricted to users with admin or cms.admin roles.

Parameters:

patch() takes a single PatchContentParams object with these properties:

Name Type Description

key

string

Path or id to the content.

patcher

function

Patcher callback function.

branches

string[]

Optional. A list of branches to patch. Defaults to [].
* If not provided or empty, the content in the current branch will be patched.
* If one branch is listed, the patch occurs in that specific branch.
* If multiple branches are listed:
1. The patch is applied to the first branch in the list.
2. For each subsequent branch in the list:
* If its content version is identical to the original (pre-patch) version from any processed branch, it is simply switched to point to the new, patched version.
* If its content version is different, the patch is applied to it separately.

skipSync

boolean

Optional. If true, skip synchronization of the content in children projects after patching. Defaults to false.

attachments

object

Optional. Object for managing content attachments. Contains optional arrays: `createAttachments` (add new), `modifyAttachments` (update existing) and `removeAttachments` (a string array with attachment names to remove).

patcher is a function that receives the current content as parameter and must return the modified content. A list of supported fields that can be patched is provided below.

Unlike update(), patch does no bookkeeping of its own: workflow state, valid, modifier and modifiedTime are left untouched unless the patcher sets them explicitly.

Patchable Fields:

Name Type Description

displayName

string

The display name of the content.

language

string

The language tag representing the content’s locale.

childOrder

string

String defining the sort order of children.

manualOrderValue

number

Numeric value used for manual sorting across siblings (when parent’s childOrder is manual).

valid

boolean

Sets the content’s validity status.

data

object

A JSON object containing the main data (properties) of the content, according to its content type.

page

object

A JSON object describing the page configuration including regions and components.

x

object

A JSON object containing extra data (x-data) associated with the content.

owner

string

The owner of the content. Must be a PrincipalKey string.

creator

string

The creator of the content. Must be a PrincipalKey string.

createdTime

string

The creation timestamp. Must be an ISO 8601 formatted string.

modifier

string

The principal who last modified the content. Must be a PrincipalKey string.

modifiedTime

string

The last modified timestamp. Must be an ISO 8601 formatted string.

archivedBy

string

The principal who archived the content. Must be a PrincipalKey string.

archivedTime

string

The archival timestamp. Must be an ISO 8601 formatted string.

publish

object

A JSON object containing publishing information.

workflow

object

A JSON object containing workflow state information.

inherit

string[]

An array of strings specifying which properties to inherit from the parent (e.g., ["owner", "language"]).

variantOf

string

The ContentId (as a string) of the content this item is a variant of (used for localization).

processedReferences

string[]

An array of ContentId strings that this content references.

validationErrors

ValidationError[]

An array of objects describing validation errors.

originProject

string

The name of the project this content was inherited from.

originalParentPath

string

The original parent path in the parent project.

originalName

string

The original name in the parent project.

attachments

object

An object listing the content’s existing attachments, keyed by attachment name. Use the attachments patch parameter (with createAttachments / modifyAttachments / removeAttachments) to manage the attachment binaries themselves.

createAttachments: Each entry is an object with these properties:

Name Type Description

name

string

Name of the attachment to create.

mimeType

string

Optional. Mime-type of the data.

label

string

Optional. Label of the attachment.

data

ByteSource | string

Optional. Data to use. A string is stored as its UTF-8 bytes.

These are the only keys accepted. Any other key throws Unknown CreateAttachment key: <name>.

modifyAttachments: Each entry is an object with these properties:

Name Type Description

name

string

Name of the attachment to modify.

mimeType

string

Optional. Mime-type of the data.

label

string

Optional. Label of the attachment.

sha512

string

Optional. SHA-512 hash of the data.

size

number

Optional. Size of the data in bytes.

These are the only keys accepted. Any other key throws Unknown attachment key: <name>. modifyAttachments cannot introduce a new attachment either — naming one that does not already exist throws Attachments can only be added using createAttachments.

Returns

object : (PatchContentResult) The content id and one result entry per patched branch

Examples

Patching archival info.
import {patch} from '/lib/xp/content';
function patcher(c) {
    c.archivedBy = 'user:system:admin';
    c.archivedTime = new Date().toISOString();
    return c;
}

const result = patch({
    key: '/a/b/mycontent',
    patcher: patcher
});
Patching content’s attachments.
import {patch} from '/lib/xp/content';
import {newStream} from '/lib/xp/io';

// Patcher function to modify content.
function patcher(c) {
    c.displayName = 'Patched Content';
    c.data.myField = 'New Value';
    return c;
}
// Patch content by path
const result = patch({
    key: '/a/b/mycontent',
    patcher: patcher,
    branches: ['draft', 'master'],
    attachments: {
        createAttachments: [
            {
                name: 'new-attachment.txt',
                mimeType: 'text/plain',
                data: newStream('Hello World')
            }
        ],
        modifyAttachments: [
            {
                name: 'existing-attachment.txt',
                mimeType: 'text/plain',
                label: 'updated-label'
            }
        ],
        removeAttachments: [
            'old-attachment.txt'
        ]
    }
});
// Result returned.
const expected = {
    contentId: "123456",
    results: [
        {
            branch: "draft",
            content: {/* the patched content */}
        },
        {
            branch: "master",
            content: {/* the patched content */}
        }
    ]
};

move

Renames a content or moves it to a new path

Parameters:

move() takes a single MoveContentParams object with these properties:

Name Type Description

source

string

Path or id of the content to be moved or renamed

target

string

New path or name for the content. If the target ends in slash '/', it specifies the parent path where to be moved. Otherwise it means the new desired path or name for the content

Returns

object : (Content) The content that was moved or renamed

Examples

import {move} from '/lib/xp/content';

// Rename content by path. Keeps same parent.
const content1 = move({
    source: '/my-site/my-content-name',
    target: 'new-name'
});

log.info('New path: %s', content1._path); // '/my-site/new-name'
import {move} from '/lib/xp/content';

// Move content by path. New parent path, keeps same name.
const content2 = move({
    source: '/my-site/my-content-name',
    target: '/my-site/folder/'
});

log.info('New path: %s', content2._path); // '/my-site/folder/my-content-name'
import {move} from '/lib/xp/content';

// Move content by id to new path. New parent path, keeps same name.
const content3 = move({
    source: '8d933461-ede7-4dd5-80da-cb7de0cd7bba',
    target: '/my-site/folder/'
});

log.info('New path: %s', content3._path); // '/my-site/folder/my-content-name'
import {move} from '/lib/xp/content';

// Move and rename content.
const content4 = move({
    source: '/my-site/my-content-name',
    target: '/my-site/folder/new-name'
});

log.info('New path: %s', content4._path); // '/my-site/folder/new-name'
import {move} from '/lib/xp/content';

// Handle error if target already exists.
try {
    const content5 = move({
        source: '/my-site/my-content-name',
        target: '/my-site/folder/existing-content'
    });

} catch (e) {
    if (e.code == 'contentAlreadyExists') {
        log.error('There is already a content in the target specified');
    } else {
        log.error('Unexpected error: %s', e.message);
    }
}

publish

Publishes content to the master branch

Parameters:

publish() takes a single PublishContentParams object with these properties:

Name Type Description

keys

string[]

List of all content keys (path or id) that should be published.

schedule

Schedule

Optional. Schedule publishing.

excludeDescendantsOf

string[]

Optional. List of content keys whose descendants should be excluded from publishing.

excludeChildrenIds

string[]

Optional. Deprecated, use excludeDescendantsOf instead.

includeDependencies

boolean

Optional. Whether all related content should be included when publishing content. Defaults to true.

message

string

Optional. Publish message.

Returns

object : (PublishContentResult) Status of the publish operation

failedContents holds content ids for items that failed to publish, and content paths for keys that could not be resolved to an existing content.

Publishing is all-or-nothing. XP validates the entire resolved set before pushing anything. If a single item is ineligible, the whole publish is abandoned: pushedContents comes back empty, every id lands in failedContents, and nothing is written to the server log. The call itself succeeds — there is no exception to catch.

Two conditions abort the batch:

  • valid is false — the content does not satisfy its content type.

  • workflow.state is set to anything other than READY — that is, IN_PROGRESS, PENDING_APPROVAL or REJECTED.

Note that any update() that genuinely changes a content resets its state to IN_PROGRESS, so a create → update → publish sequence blocks unless the content is marked ready in between.

The check runs on the resolved set, not just the keys you passed. With includeDependencies left at its default true, a single invalid dependency you never named is enough to block everything.

Content Studio enforces the same rule, but interactively: its publishing wizard flags in-progress items and lets the user mark them as ready — one at a time, or all at once via the Mark as ready option in the wizard — before publishing. publish() has no such affordance and never promotes workflow state; to publish in-progress content, first set it ready with updateWorkflow().

Internally XP records a reason per failed item (INVALID, NOT_READY, ALREADY_EXIST, PARENT_NOT_FOUND, ACCESS_DENIED), but the library discards it: failedContents is a flat list of ids. To identify the blockers, query for them before publishing — see the example below.

Examples

import {publish} from '/lib/xp/content';

// Publish content by path or key
const result = publish({
    keys: ['/mysite/somepage', '79e21db0-5b43-45ce-b58c-6e1c420b22bd'],
    schedule: {
        from: new Date().toISOString(),
        to: '2018-01-01T13:37:00.000Z'
    },
    includeDependencies: false
});

if (result) {
    log.info('Pushed %s content.', result.pushedContents.length);
    log.info('Content that failed operation: %s', result.failedContents.length);
} else {
    log.info('Operation failed.');
}
// Content published.
const expected = {
    pushedContents: [
        "d7ad428b-eae2-4ff1-9427-e8e8a8a3ab23",
        "9f5b0db0-38f9-4e81-b92e-116f25476b1c",
        "e1f57280-d672-4cd8-b674-98e26e5b69ae"
    ],
    failedContents: [
        "79e21db0-5b43-45ce-b58c-6e1c420b22bd"
    ]
};

Because a failed publish reports no reason, find the blockers up front. This query applies the same two conditions XP checks internally, scoped to the subtree you are about to publish:

import {query, publish} from '/lib/xp/content';

const blockers = query({
    count: -1,
    query: {
        boolean: {
            must: {
                pathMatch: {
                    field: '_path',
                    path: '/content/mysite'
                }
            },
            should: [
                {
                    term: {field: 'valid', value: false}
                },
                {
                    boolean: {
                        must: {exists: {field: 'workflow.state'}},
                        mustNot: {term: {field: 'workflow.state', value: 'READY'}}
                    }
                }
            ]
        }
    }
});

if (blockers.total > 0) {
    blockers.hits.forEach((content) => {
        log.warning('Blocks publishing: %s (valid=%s, workflow=%s)',
            content._path, content.valid, content.workflow && content.workflow.state);
    });
} else {
    publish({keys: ['/mysite']});
}

query

Retrieves content using a query

Parameters:

query() takes a single QueryContentParams object with these properties:

Name Type Description

start

number

Optional. Start index (used for paging). Defaults to 0.

count

number

Optional. Number of contents to fetch. Defaults to 10.

query

string | object

Optional. Query string or DSL expression.

filters

object | object[]

Optional. Filters to apply to query result.

sort

string | object | object[]

Optional. Sorting string or DSL expression.

aggregations

object

Optional. Aggregations expression.

contentTypes

string[]

Optional. Content types to filter on.

highlight

object

Optional. Highlight expression.

Returns

object : (ContentsResult) Result of the query

If sort was specified, results will contain system meta properties _sort and _score: null, otherwise _score will have a relevant value.

Examples

import {query} from '/lib/xp/content';

// Query content using aggregations.
const result = query({
    start: 0,
    count: 2,
    sort: "modifiedTime DESC, geoDistance('data.location', '59.91,10.75', 'km')",
    query: "data.city = 'Oslo' AND fulltext('data.description', 'garden', 'AND') ",
    filters: {
        boolean: {
            must: [
                {
                    exists: {
                        field: "modifiedTime"
                    }
                },
                {
                    exists: {
                        field: "another"
                    }
                }
            ],
            mustNot: {
                hasValue: {
                    field: "myField",
                    values: [
                        "cheese",
                        "fish",
                        "onion"
                    ]
                }
            }
        },
        notExists: {
            field: "unwantedField"
        },
        ids: {
            values: ["id1", "id2"]
        }
    },
    contentTypes: [
        app.name + ":house",
        app.name + ":apartment"
    ],
    aggregations: {
        floors: {
            terms: {
                field: "data.number_floor",
                order: "_count asc"
            },
            aggregations: {
                prices: {
                    histogram: {
                        field: "data.price",
                        interval: 1000000,
                        extendedBoundMin: 1000000,
                        extendedBoundMax: 3000000,
                        minDocCount: 0,
                        order: "_key desc"
                    }
                }
            }
        },
        by_month: {
            dateHistogram: {
                field: "data.publish_date",
                interval: "1M",
                minDocCount: 0,
                format: "MM-yyyy"
            }
        },
        price_ranges: {
            range: {
                field: "data.price",
                ranges: [
                    {to: 2000000},
                    {from: 2000000, to: 3000000},
                    {from: 3000000}
                ]
            }
        },
        my_date_range: {
            dateRange: {
                field: "data.publish_date",
                format: "MM-yyyy",
                ranges: [
                    {to: "now-10M/M"},
                    {from: "now-10M/M"}
                ]
            }
        },
        price_stats: {
            stats: {
                field: "data.price"
            }
        }
    }
});

log.info('Found %s number of contents', result.total);

result.hits.forEach((content) => {
  log.info('Content %s found', content._name);
});
// Result set returned.
const expected = {
    total: 20,
    count: 2,
    hits: [
        {
            _id: "id1",
            _name: "name1",
            _path: "/a/b/name1",
            _sort: ["1970-01-01T00:00:00Z", 9279.647306690395],
            _score: null,
            creator: "user:system:admin",
            modifier: "user:system:admin",
            createdTime: "1970-01-01T00:00:00Z",
            modifiedTime: "1970-01-01T00:00:00Z",
            type: "base:unstructured",
            displayName: "My Content 1",
            hasChildren: false,
            valid: false,
            data: {},
            x: {},
            page: {},
            attachments: {},
            publish: {}
        },
        {
            _id: "id2",
            _name: "name2",
            _path: "/a/b/name2",
            _sort: [ "1970-01-01T00:00:00Z", 15964.050071707446],
            _score: null,
            creator: "user:system:admin",
            modifier: "user:system:admin",
            createdTime: "1970-01-01T00:00:00Z",
            modifiedTime: "1970-01-01T00:00:00Z",
            type: "base:unstructured",
            displayName: "My Content 2",
            hasChildren: false,
            valid: false,
            data: {},
            x: {},
            page: {},
            attachments: {},
            publish: {}
        }
    ],
    aggregations: {
        genders: {
            buckets: [
                {
                    key: "male",
                    docCount: 10
                },
                {
                    key: "female",
                    docCount: 12
                }
            ]
        },
        by_month: {
            buckets: [
                {
                    key: "2014-01",
                    docCount: 8
                },
                {
                    key: "2014-02",
                    docCount: 10
                },
                {
                    key: "2014-03",
                    docCount: 12
                }
            ]
        },
        price_ranges: {
            buckets: [
                {
                    key: "a",
                    docCount: 2,
                    to: 50
                },
                {
                    key: "b",
                    docCount: 4,
                    from: 50,
                    to: 100
                },
                {
                    key: "c",
                    docCount: 4,
                    from: 100
                }
            ]
        },
        my_date_range: {
            buckets: [
                {
                    key: "date range bucket key",
                    docCount: 2,
                    from: "2014-09-01T00:00:00Z"
                },
                {
                    docCount: 5,
                    from: "2014-10-01T00:00:00Z",
                    to: "2014-09-01T00:00:00Z"
                },
                {
                    docCount: 7,
                    to: "2014-11-01T00:00:00Z"
                }
            ]
        },
        item_count: {
            count: 5,
            min: 1,
            max: 5,
            avg: 3,
            sum: 15
        }
    }
};

removeAttachment

Removes an attachment from an existing content

Parameters:

removeAttachment() takes a single RemoveAttachmentParams object with these properties:

Name Type Description

key

string

Path or id to the content

name

string | string[]

Attachment name, or array of names

Examples

import {removeAttachment} from '/lib/xp/content';

// Removes an attachment, by content path.
removeAttachment({key: '/mySite/mycontent', name: 'document'});
import {removeAttachment} from '/lib/xp/content';

// Removes multiple attachments, by content id.
removeAttachment({key: '3381d720-993e-4576-b089-aaf67280a74c', name: ['document', 'image']});

resetInheritance

Resets custom inheritance flags of a content item. For an item that was inherited from a parent content project/layer this action will reset specified changes made inside a specified layer.

Parameters:

resetInheritance() takes a single ResetInheritanceParams object with these properties:

Name Type Description

key

string

Path or id to the content

projectName

string

A unique id of a Content Layer in which the inherited content item should be reset

inherit

string[]

Array of inheritance flags (case-sensitive, all upper-case). Supported values are: CONTENT (resets any customized content data), PARENT (resets item moved under a different parent), NAME (resets renamed item), SORT (resets custom sorting).

Examples

import {resetInheritance} from '/lib/xp/content';

// Resets all custom changes made to inherited item '/mySite/mycontent' in the layer 'layer-no'
resetInheritance({key: '/mySite/mycontent', projectName: 'layer-no', inherit: ['CONTENT', 'PARENT', 'NAME', 'SORT']});
import {resetInheritance} from '/lib/xp/content';

// Resets custom sorting of inherited item '/mySite/mycontent' in the layer 'layer-no', but preserves any other changes
resetInheritance({key: '/mySite/mycontent', projectName: 'layer-no', inherit: ['SORT']});

restore

Restores a content from the archive

Parameters:

restore() takes a single RestoreContentParams object with these properties:

Name Type Description

content

string

Path or id of the content to be restored

path

string

Optional. Path of parent for restored content

Returns

string[] : List with ids of the contents that were restored

Examples

import {restore} from '/lib/xp/content';

// Restore content by path.
const result1 = restore({
    content: '/path/to/mycontent',
});

log.info('Restored content ids: %s', result1.join(','));

// Restore content by id.
const result2 = restore({
    content: 'my-content-id'
});

log.info('Restored content ids: %s', result2.join(','));

// Restore content by id to custom path.
const result3 = restore({
    content: 'my-content-id',
    path: '/custom-parent'
});

log.info('Restored content ids: %s', result3.join(','));

applyPermissions

Applies permissions on a content.

If the content is published, the permissions will be applied to the published content as well without a need to republish it.

Parameters:

applyPermissions() takes a single ApplyPermissionsParams object with these properties:

Name Type Description

key

string

Path or id of the content.

permissions

AccessControlEntry[]

Optional. Array of permissions to overwrite current permissions. Cannot be used with addPermissions or removePermissions.

addPermissions

AccessControlEntry[]

Optional. Array of permissions to add. Cannot be used simultaneously with permissions.

removePermissions

AccessControlEntry[]

Optional. Array of permissions to remove. Cannot be used simultaneously with permissions.

scope

string (SINGLE | TREE | SUBTREE)

Optional. Scope of applying permissions. SINGLE applies permissions only to the content itself. TREE applies permissions to the content and its descendants. SUBTREE applies permissions only to the content’s descendants. Defaults to SINGLE.

Returns

object : (ApplyPermissionsResult) A map keyed by content id, indicating for each affected content which permissions were applied

Examples

1) Applying permissions to a content by overwriting the current permissions.
import {applyPermissions} from '/lib/xp/content';

applyPermissions({
    key: '/my-content',
    permissions: [
        {
            principal: 'role:system.everyone',
            allow: ['READ']
        },
        {
            principal: 'user:system:my-user',
            allow: ['READ', 'CREATE', 'MODIFY', 'DELETE']
        }
    ]
});
2) Adding permissions to a content.
import {applyPermissions} from '/lib/xp/content';

applyPermissions({
    key: '/my-content',
    addPermissions: [
        {
            principal: 'role:system.everyone',
            allow: ['CREATE', 'MODIFY']  // 'READ' permission is already set and will be kept.
        },
        {
            principal: 'user:system:my-new-user',
            allow: ['READ', 'CREATE', 'MODIFY', 'DELETE'] // New user will have all permissions.
        }
    ]
});
3) Removing permissions from a content.
import {applyPermissions} from '/lib/xp/content';

applyPermissions({
    key: '/my-content',
    removePermissions: [
        {
            principal: 'role:system.everyone',
            allow: ['CREATE', 'MODIFY']  // 'READ' permission will be kept.
        },
        {
            principal: 'user:system:my-user',
            allow: ['DELETE'] // 'DELETE' permission will be removed. All other permissions will be kept.
        },
        {
            principal: 'user:system:my-new-user' // All permissions for this principal will be removed.
        }
    ]
});
Applying permissions to a content and its descendants.
import {applyPermissions} from '/lib/xp/content';

applyPermissions({
    key: '/my-content',
    permissions: [
        {
            principal: 'role:system.everyone',
            allow: ['READ']
        }
    ],
    scope: 'TREE'
});
Applying permissions to a content’s descendants only.
import {applyPermissions} from '/lib/xp/content';

applyPermissions({
    key: '/my-content',
    permissions: [
        {
            principal: 'role:system.everyone',
            allow: ['READ']
        }
    ],
    scope: 'SUBTREE'
});

unpublish

Unpublishes content that had been published to the master branch

Parameters:

unpublish() takes a single UnpublishContentParams object with these properties:

Name Type Description

keys

string[]

List of all content keys(path or id) that should be unpublished

Returns

string[] : List with ids of the content that were unpublished

Examples

import {unpublish} from '/lib/xp/content';

// Unpublish content by path or key
const result = unpublish({
    keys: ['/mysite/somepage', '79e21db0-5b43-45ce-b58c-6e1c420b22bd']
});

log.info('Unpublished content ids: %s', result.join(','));
// Content unpublished.
const expected = [
    "d7ad428b-eae2-4ff1-9427-e8e8a8a3ab23",
    "9f5b0db0-38f9-4e81-b92e-116f25476b1c",
    "e1f57280-d672-4cd8-b674-98e26e5b69ae"
];

Type Definitions

ContentType

Properties

Name Type Description

name

string

Name of the content type.

title

string

Title of the content type.

description

string

Description of the content type.

superType

string

Name of the super type, or null if it has no super type.

abstract

boolean

Whether or not content of this type may be instantiated.

final

boolean

Whether or not it may be used as super type of other content types.

allowChildContent

boolean

Whether or not to allow creating child items on content of this type.

modifiedTime

string

Modified time of the content type.

icon

Icon

Optional. Icon of the content type.

form

FormItem[]

Form schema — an array of form items.

config

object

Custom schema configuration for the descriptor.

Icon

Properties

Name Type Description

data

ByteSource

Stream with the binary data for the icon. Read it with lib-io.

mimeType

string

Mime type of the icon image.

modifiedTime

string

Modified time of the icon. May be used for caching.

Schedule

A publish schedule. Same shape as PublishInfo without the first field.

Properties

Name Type Description

from

string

Optional. Time from which the content is considered published, as an ISO-8601 instant. Defaults to the time of publishing.

to

string

Optional. Time until which the content is considered published. ISO-8601 instant.

AccessControlEntry

A permission entry for a single principal.

Properties

Name Type Description

principal

PrincipalKey

Principal the entry applies to (for example, role:system.admin, user:system:su).

allow

string[]

Optional. Permissions to grant. Each value is one of READ, CREATE, MODIFY, DELETE, PUBLISH, READ_PERMISSIONS, WRITE_PERMISSIONS.

deny

string[]

Optional. Permissions to deny. Same set of values as allow.

Permissions

The permission set on a single content. Returned by getPermissions().

Properties

Name Type Description

permissions

AccessControlEntry[]

One entry per principal with permissions on the content.

ApplyPermissionsResult

Returned by applyPermissions(). An object keyed by content id — one key per content the operation touched, which for TREE and SUBTREE scope includes descendants. Each value is a Permissions object holding the permissions that ended up on that content.

// Result returned.
const expected = {
    "d7ad428b-eae2-4ff1-9427-e8e8a8a3ab23": {
        permissions: [
            {
                principal: "role:system.everyone",
                allow: ["READ"],
                deny: []
            }
        ]
    }
};

ContentsResult

A page of content hits. Returned by query() and getChildren().

Properties

Name Type Description

total

number

Total number of contents matching the request, ignoring start and count.

count

number

Number of contents in hits.

hits

Content[]

The contents on this page.

aggregations

object

Optional. Aggregation results, keyed by the names used in the aggregations request. Present only when the request asked for aggregations.

highlight

object

Optional. Highlight results, keyed by content id. Present only when the request asked for highlighting.

ContentVersionsResult

A page of content versions. Returned by getVersions().

Properties

Name Type Description

total

number

Total number of versions for the content.

count

number

Number of versions in hits.

cursor

string

Cursor to pass to the next getVersions() call, or null when there are no more pages.

hits

ContentVersion[]

The versions on this page, newest first.

ContentVersion

A single version of a content.

Properties

Name Type Description

versionId

string

Id of this version.

contentId

string

Id of the content the version belongs to.

path

string

Path the content had at this version.

timestamp

string

Time the version was created, as an ISO-8601 instant.

comment

string

Optional. Version comment.

actions

ContentVersionAction[]

Optional. The operations recorded on this version.

ContentVersionAction

One operation recorded on a content version.

Properties

Name Type Description

operation

string

The operation performed, for example create, update, publish or unpublish.

user

PrincipalKey

Principal that performed the operation.

opTime

string

Time the operation was performed, as an ISO-8601 instant.

origin

string

Optional. Branch the operation was performed in.

editorial

string

Optional. Id of the version this one’s editorial content traces back to. Lets you tell versions that changed content substance (displayName, data, language, x, page components, attachments, ordering) apart from ones that only changed bookkeeping.

ActiveContentVersions

Returned by getActiveVersions(). An object keyed by branch name — one key per branch given in branches — where each value is the ContentVersion currently active in that branch.

// Result returned.
const expected = {
    draft: {
        versionId: "eb5f5b2e-fd0e-4b6a-b1a8-af7e0d0f0f3a",
        contentId: "123456",
        path: "/a/b/mycontent",
        timestamp: "1970-01-01T00:00:00Z"
    },
    master: {
        versionId: "0c1b3f1d-3ba1-4cbb-9a0f-2c2f31f0b7c9",
        contentId: "123456",
        path: "/a/b/mycontent",
        timestamp: "1970-01-01T00:00:00Z"
    }
};

DuplicateContentsResult

Returned by duplicate().

Properties

Name Type Description

contentName

string

Name given to the duplicated content.

sourceContentPath

string

Path of the content that was duplicated.

duplicatedContents

string[]

Ids of every content created by the operation, including children when includeChildren was set.

PatchContentResult

Returned by patch().

Properties

Name Type Description

contentId

string

Id of the content that was patched.

results

BranchPatchResult[]

One entry per branch the patch was applied to.

BranchPatchResult

The outcome of a patch in one branch.

Properties

Name Type Description

branch

string

Name of the branch.

content

Content

The patched content in that branch, or null if the content does not exist there.

PublishContentResult

Returned by publish().

Properties

Name Type Description

pushedContents

string[]

Ids of the contents that were published. Empty if the batch was aborted by an ineligible item.

failedContents

string[]

Ids of the contents that failed to publish, plus the paths of any keys that could not be resolved to an existing content. No failure reason is included — see the warning under publish().

UpdateMetadataResult

Returned by updateMetadata().

Properties

Name Type Description

content

Content

The content with its updated metadata.

UpdateWorkflowResult

Returned by updateWorkflow().

Properties

Name Type Description

content

Content

The content with its updated workflow state.


Contents

Contents