Tutorial

Platform actions

Table of contents
  1. Finding users
  2. Writing Searches and filters
  3. Sorting pages
  4. Reading builtin attributes

Finding users

Often you will find yourself in a situation where you want to provide users or groups to some cplaceJS api but the script does not provide any direct way of accessing the desired principals (like e.g. via binding or the attribute of a page) and you cannot or don't want to search for the Uids. For this and all other occurrences cplaceJS provides a handy util api which you can use to easily acquire user- and group objects.

To get a specific user or group you have to know the name of the group or the login of the user. When e.g. sending a notification to a selected set of users you can use findUserByLogin(login) and findGroupByName(groupName) like

var userToNotify = cplace.utils().findUserByLogin('mustermann@test.tricia');
var groupToNotify = cplace.utils().findGroupByName('myUsersGroup');

cplace.actions().sendNotification({
  message: "You have been notified!",
  recipients: [userToNotify, groupToNotify]
});

You can also access the all users system group which contains all registered users and send a notification to everybody on the server using getAllUsersGroup():

cplace.actions().sendNotification({
  message: "You have been notified!",
  recipients: cplace.utils().getAllUsersGroup()
});

Bear in mind though that the all users group is a SystemGroup and no "regular" Group so you may not be able to use it like a normal group.

To reference the current user at execution time of the script there is getCurrentUser(). So if you e.g. create a page out of an attribute change and want the triggering user to be assigned to it in a way:

cplace.actions().createPage({
    space: 'space/iogef7klu9wjdj4l63ne4iyie',
    customType: 'my.custom.issue',
    customAttributes: {
        'cf.cplace.issue.assignee': cplace.utils().getCurrentUser()
    }
}, {
    setGeneratedName: true
});

Whoever then triggers the script will be set as the assignee of the created issue.

Writing searches and filters

Writing searches in cplaceJS is a little different in terms of api usage compared to other things. Before searching and retrieving pages we have to at first instantiate a search object via

var search = new Search();

(be sure that searches are actually enabled in the script - a good sign that they aren't is when you get errors from instantiating search objects) and then add filters to the search. This is of course optional; you could run a new Search().findAllPages() to retrieve all accessible pages, but usually that is way more than you actually want. You can add filters via the .add() method and retrieve matched pages by calling .findAllPages().

In the following we will have a look on different use cases and how we can define searches to fit our needs.

Note that our examples will mostly make use of the Search's builder pattern, but it's also possible to do operations step by step.

Pages of a type inside a space

A very simple but often required result is to find pages of a type inside a given (usually the embedding) space. We will quickly model an example using the type() and embeddingSpace() filters:

var search = new Search()
      .add(Filters.embeddingSpace())
      .add(Filters.type('cf.cplace.myType'));

Pages with a specific custom attribute value

Getting a set of pages with a specific custom attribute value is very common. As there is no filter for explicit custom attribute values yet we have to improvise a bit by filtering for the value by hand using the cplace.each util:

var pages = new Search()
    .add(Filters.type('cf.cplace.employee'))
    .findAllPages();

var result = [];
cplace.each(pages, function (page) {
    if (page.get('cf.cplace.surname') === 'Ekkehard') {
        result.push(page);
    }
});

Searches with pagination

Sometimes it is not useful to retrieve all pages from a search to result. For this case there is the possibility to add pagination to a search. The following script will return the first five elements of the search result:

var pages = new Search()
    .add(Filters.type('cf.cplace.employee'))
    .find(0, 5);

Term frequencies of searches

It is possible to retrieve a term frequency for a specific field. The fieldname can either be the name of a custom property or a builtin field name. We assume that there are four employees with the following surnames 'Smith', 'Smith', 'Baker' and 'Jones'. The term frequencies of the search would return a result with the following values:

surname Frequency
Smith 2
Baker 1
Jones 1
var surnameTermFrequency = new Search()
    .add(Filters.type('cf.cplace.employee'))
    .getTermFrequenciesForField('surname');

Sorting pages

Sorting results of a search is indispensable for consistency reasons. Sometimes it is also necessary in order to meet certain requirements, i.e. for an ordered aggregation. In cplaceJS you have the option to either sort alphabetically via the page name, or define a custom order with attributes.

Alphabetical sort

The alphabetical sorting by page name is the default for searches. The last sorting parameter of every search is always an ascending alphabetical sort. If you want to invert this you can do that by telling the search to use

var descending = true;
var search = search.addAlphabeticalSort(descending);

Custom sort

If the default sort does not fulfill your requirements you can sort by any attribute

var descending = false;
var search = search.addCustomFieldSort('cf.cplace.surname', descending)

Chaining sorts

It is also possible to apply sorting to multiple fields, defining secondary sorting criteria to sort by if the data does not happen to be distinctive. You can chain sorts by just adding them to the search subsequently. Like done in our example where we sort employees by their last name at first and then by their surname.

var search = new Search()
      .add(Filters.type('cf.cplace.employee'))
      .addCustomFieldSort('cf.cplace.lastName', false)
      .addCustomFieldSort('cf.cplace.surname', false);

Note that the alphabetical sort is always added afterwards if it isn't already there.

Reading builtin attributes

For reading builtin attributes you don't need more than the CustomEntity class' getBuiltinFeatureValue(featureName) method. This works with all builtin attributes of an entity.

var creator = page.getBuiltinFeatureValue('creator');
attribute feature name return type
Created at createdAt Date
Creator creator WrappedPerson
Data Exchange active isShared boolean
Description content string
Display Name localizedName LocalizedString
Editors writers ArrayLike<WrappedPerson>
Editors have default value writersAreDefault boolean
Has Datasource hasSource boolean
Last Editor modifier WrappedPerson
Last Modification modifiedAt Date
Layout layoutName string
Name name string
Readers readers ArrayLike<WrappedPerson>
Readers have default value readersAreDefault boolean
Subscription status entityMirrorStatus string
Type customType string