Skip to content

@apostrophecms/util

Alias: apos.util

Extends: @apostrophecms/module ℹ️

The @apostrophecms/util module contains utility methods and tools that do not clearly belong in any other module.

Options

PropertyTypeDescription
loggerFunctionDeprecated in favor of the new option exposed in the @apostrophecms/logging module. A function that accepts the Apostrophe instance object (self.apos) and returns an object with at least info, debug, warn, and error methods for logging messages. Similarly named util module methods use these functions. See the default logger function for an example. Overrides should be written with support for substitution strings. See the console.log documentation.
stackLimitIntegerDefaults to 50. This is the maximum size of the asynchronous stack, tracking active widget loaders, async components, and relationship loaders.

The following methods belong to this module and may be useful in project-level code. See the source code for all methods that belong to this module.

Because this module has an alias, you can call these from another module from the alias path. For example, self.apos.util.log().

Logging utilities

The descriptions for log, info, debug, warn, and error below reflect default behavior. See the logger option description above for information about custom behavior. The info, debug, warn, and error methods have been deprecated going forward in favor of the structured logging methods logInfo, logDebug, logWarn, and logError, respectively, available on every module.

log(msg)

Logs a message or input, msg. The default implementation wraps console.log and passes on all arguments, so substitution strings may be used.

If a logger option function does not include a log function, the info method will be used. This allows an instance of bole or similar loggers to be passed to the logger option.

info(msg)

Logs a informational message. The default implementation wraps console.info and passes on all arguments, so substitution strings may be used.

debug(msg)

Logs a debugging message. The default implementation wraps console.debug (or console.log if that's unavailable) and passes on all arguments, so substitution strings may be used.

warn(msg)

Logs a warning message. The default implementation wraps console.warn and passes on all arguments, so substitution strings may be used.

warnDev(msg)

Identical behavior to apos.util.warn except that the warning is not displayed if process.env.NODE_ENV is production. It will log the message every time it is called. See warnDevOnce() for a quieter version when messages may become repetitive.

warnDevOnce(name, msg)

Identical to apos.util.warnDev, except that the warning is only displayed once for each registered name. name should be a string not already used in an unrelated warnDevOnce call.

Example:

javascript
apos.util.warnDevOnce('github-connection-error', 'There was an error connecting to your Github account.')

The warnings will be allowed in production mode if the command line option --all-[name] is present when running the app (or CLI task): node app --all-github-connection-error.

All warnings for a particular name will be muted if the option --ignore-[name] is used: node app --ignore-github-connection-error.

error(msg)

Logs an error message. The default implementation wraps console.error and passes on all arguments, so substitution strings may be used.

String manipulation methods

globalReplace(source, target, replacement)

Globally replaces a target string within a source string. This allows global string replacement without using regular expressions. It replaces the original source string and does not return a value.

Arguments are:

  • source: A string that will be replaced after updating target string segments.
  • target: A string that should be replaced every time it appears in source.
  • replacement: A string used to replace target wherever it appears in source.

truncatePlaintext(string, length, pruneString)

Truncate a string at the specified number of characters (length) without breaking words if possible. pruneString will be used at the end of the result as long as it does not force the end result to be longer than length. '...' will be used if pruneString is omitted.

See the Underscore.String.js prune function, of which this is a copy (replacing RegExp with XRegExp for better UTF-8 support).

escapeHtml(string, options)

Escape a plaintext string correctly for use in HTML. options is an object of options, but may be omitted.

If { pretty: true } is in the options object, new lines become br tags, and URLs become links to those URLs. Otherwise this does basic escaping. For backwards compatibility, if the second argument is truthy and not an object, { pretty: true } is assumed.

If { single: true } is in the options object, single-quotes are escaped, otherwise double-quotes are escaped.

htmlToPlaintext(htmlString)

A method to convert a string of HTML to simple plain text (no rich text indicators). This is meant for basic HTML conversion, such as converting the contents of a piece's rich text widget teaser into unformatted text to be displayed on the index page. It returns a string of plain text.

capitalizeFirst(string)

capitalizeFirst accepts a string argument and returns the string with the first letter capitalized.

cssName(camelString)

This method is used to convert "camel case" strings (spiderMan) into CSS-friendly "kebab case" (spider-man). It returns the converted string.

camelName(string)

This method converts a string to camel case and returns the converted string. Any characters that are not alphanumeric will be removed and the following character (if alphanumeric) will be capitalized.

addSlashIfNeeded(path)

addSlashIfNeeded() accepts a string and returns it with a slash at the end only if there is not one already. It is useful for ensuring uniform URL paths in code.

slugify(string, options)

This is a wrapper for the sluggo utility. It accepts a string and options object. It returns the string lower cased and with spaces and non-alphanumeric characters replaced with a dash (by default). See the sluggo documentation for other options.

sortify(string)

sortify does the same thing as slugify, but whitespace and non-alphanumeric characters are replaced with a single space instead of a dash. This is used to make strings uniform for sorting, including for populating document properties such as titleSortified that store the uniform version.

Other utility methods

generateId()

Returns a unique identifier (ID) for a new page or other object. IDs are generated with the cuid module which prevents collisions and ensures a certain level of complexity. This should not be used for passwords, however.

md5(string)

Perform an md5 checksum on a string. Returns a hex string.

async md5File(filepath)

Perform an md5 checksum on a file at a given path. Async. Returns a Promise that resolves to a hex string.

async fileLength(filepath)

Accepts a file path and returns a Promise that resolves to the file size in bytes.

clonePermanent(object, keepScalars)

Clone the given object recursively, discarding all properties whose names begin with underscores (_) except for _id. Returns the cloned object.

This removes the output of relationships and other dynamic loaders, so that dynamically available content is not stored redundantly in MongoDB. Object values that are Date objects are cloned as such. All other non-JSON objects are cloned as plain JSON objects.

If keepScalars is true, properties beginning with underscores are kept as long as they are not objects. This is useful when using clonePermanent to limit JSON inserted into browser attributes, rather than filtering for the database. Preserving simple string properties like _url is usually a good thing in the former case.

If the object argument is an array, the clone is also an array. Arrays are cloned as such only if they are true arrays (Array.isArray() returns true).

orderById(ids, items, idProperty)

ids should be an array of identifiers (_id properties, by default). The elements of the items array, which should be the result of a mongodb query, are returned in the order specified by the ids array.

This is useful after performing an $in query with MongoDB ($in does not sort its results in the order given). Any IDs that do not actually exist for an item in the items array are not returned, and vice versa. You should not assume the result will have the same length as either array.

Optionally you may specify a property name other than _id as the third argument (idProperty). You may use dot notation in this argument.

isAjaxRequest(req)

Returns true if the req request object is an AJAX request (req.xhr is set, or req.query.xhr is set to emulate it) and Apostrophe's main content area refresh mechanism is not in play (req.query.aposRefresh is not '1').

insensitiveSort(strings)

Sort an array of strings (strings) in place, comparing strings in a case-insensitive way. It does not return a value.

insensitiveSortByProperty(objects, property)

Sort an array of objects (objects) in place, based on the value of the given property of each object, in a case-insensitive way. It does not return a value.

findNestedObjectById(object, _id, options)

Within an object (typically a full content document or widget object), find and return a nested object with the given _id property. This works regardless of the target object's nesting depth. Useful to locate a specific widget within a document.

Pass { ignoreDynamicProperties: true } as the options argument to skip objects set on dynamic properties (those starting with _) during this check. This is useful to ignore documents loaded via relationships.

findNestedObjectAndDotPathById(object, _id, options)

Similar to findNestedObjectById. Within an object (typically a full content document or widget object), find a nested object with the given _id property. This works regardless of the target object's nesting depth. Useful to locate a specific widget within a document.

Unlike findNestedObjectById, this returns an object with two properties:

  • object: The target object as returned by the other method.
  • dotPath: The dot notation path to the target object.

Pass { ignoreDynamicProperties: true } as the options argument to skip objects set on dynamic properties (those starting with _) during this check.

getManagerOf(object)

Given a widget or document object, this returns the appropriate manager module.

get(obj, path)

Returns the value at the given path from the object or array obj.

path supports dot notation like MongoDB. If the first dot notation segment of path begins with @xyz (or @ followed by any alphanumeric value) the nested object within obj with an _id property equal to xyz is found and returned, no matter how deeply nested it is.

set(obj, path, val)

Set a value (val) at the provided path within the object or array obj, mutating obj.

path supports dot notation like MongoDB. If the first dot notation segment of path begins with @xyz (or @ followed by any alphanumeric value) the nested object within obj with an _id property equal to xyz is located, no matter how deeply nested it is. If @xyz is the full path argument, the nested object is replaced with val. If there are further components via dot notation, they are used to locate the final location for val.

The @ syntax works only for locating nested objects. You may not pass @abc where abc is the _id of obj itself.

cloneReq(req, properties)

Returns a new req object with the properties of the original plus any in the optional properties parameter. Used when a request object with one change is desired, such as mode: 'published'. Avoids the need to push and pop properties of the original req. Also available as req.clone(properties).

runPlayers(el)

Runs all the widget players that have not been run in the whole document. Passing an optional DOM element to the el parameter will restrict the search for unplayed players to that element only. This function is useful when dynamic content has been added after apos.util.onReady has fired.

Template helpers

Template helpers are methods available for use in template files. Because this module has an alias, you can call these in templates using the alias path. For example, apos.util.log().

Some of these utility helpers replicate JavaScript APIs that are not available in Nunjucks templates natively.

slugify(string, options)

A wrapper of the slugify() method described above.

log(msg)

A wrapper of the log() method described above.

generateId()

A wrapper of the generateId() method described above.

isCurrentYear(d)

Returns true if the Date object (d) refers to a date in the current year.

isUndefined(val)

Returns true if the value val is strictly equal to undefined.

isFalse(val)

Returns true if the value val is strictly equal to false.

isFunction(val)

Returns true if the value val is a function (typeof val === 'function').

startCase(str)

Returns a string str to start case (first letter of each word is capitalized).Used to make default labels out of camel case property names.

eqStrict(a, b)

Returns true if values a and b are strictly equal. The Nunjucks template syntax does not recognize === to test this.

contains(list, val)

Returns true if the list list contains the specified value, val. list may be an array, object, or string (to look for a substring). This uses the lodash includes method.

If val is an array, this returns true if the list contains any of the specified values.

containsProperty(list, prop)

Returns true if the list contains at least one object with the named property, prop. list may be an array, object, or string (to look for a substring). This uses the lodash has method.

If list is a single object, this function returns true if that object has a property prop.

Object and array helpers

inspect(obj)

Logs the properties of an object, obj, in detail. Invokes the Node.js util.inspect() method on the object, to a depth of 10.

reverse(arr)

Returns the array, arr, in reverse order.

beginsWith(list, val)

If the list argument is a string, returns true if it starts with the value val. If the list argument is an array, returns true if at least one of its items begins with val.

find(arr, prop, val)

Finds and returns the first array (arr) item, if any, that has the specified value (val) for the specified property (prop).

filter(arr, prop, val)

Finds and returns all array (arr) items, if any, that have the specified value (val) for the specified property (prop).

reject(arr, prop, val)

Returns the array (arr), filtering out any items, if any, that have the specified value (val) for the specified property (prop).

filterNonempty(arr, prop)

Finds and returns all array (arr) items, if any, that have truthy values for the specified property (prop).

filterEmpty()

Finds and returns all array (arr) items, if any, that have falsy values for the specified property (prop).

isEmpty(obj)

Returns true if the specified array or object (obj) is considered empty Objects are empty if they have no own enumerable properties. Arrays are considered empty if they have a length of 0.

pluck(arr, prop)

Given an array of objects (arr) with the given property (prop), return an array with the value of that property for each object.

omit(obj, paths)

Given an object (obj), returns an object without the named path or property paths (paths). paths may be a string or array of strings.

difference(arr1, arr2, prop)

Given the arrays arr1 and arr2, this returns a subset of elements in arr1 that do not appear in arr2. If arr2 is not an array it is treated as an empty array.

If prop is present, then that property of each object in arr1 is compared to arr2 items. This is useful when arr1 contains field choice objects (e.g., in select fields) with a value property, while arr2 just contains actual values.

A deep comparison is performed with the lodash isEqual method.

concat(arr1, arr2, /* arr3, arr4... */)

Concatenate all of the array and/or value arguments into a single array. If an argument is an array, all of its elements are individually added to the resulting array. If an argument is a non-array value, it is added directly to the array.

groupBy(items, key)

Returns an object that groups items in a collection (items) by the property named by key on each of the values.

If the first item in items has an array on the property named by key, this returns an object that groups each item by their shared array values.

object(/* key1, value1, key2, value2... */)

Given a series of alternating keys and values, this function returns an object with the keys set to the following values. For instance, apos.util.object('name', 'bob') returns { name: 'bob' }. This is useful since Nunjucks does not allow you to create an object with a property whose name is unknown at the time the template is written.

merge(/* obj1, obj2, obj3... */)

This helper accepts any number of object arguments. It then merges them into a new object and the returns resulting object. If several objects have a property, the last object passed in wins.

If any argument is null, it is skipped gracefully. This allows you to pass in an unexamined variable without checking if it is null.