Context library
Contents
This API provides functions to access and use the current context.
Install
Add the library to your build.gradle file:
dependencies {
include xplibs.context
}
TypeScript types come from the @enonic-types/lib-context package, installed at the version of XP your project builds against — see TypeScript.
Functions
get
Returns the current context.
Parameters
get() takes no arguments.
Returns
object : (Context) The current context. The attributes field is always present (possibly empty); branch, repository, and authInfo are present when set on the calling context.
In TypeScript, get() takes an optional type argument naming the attributes you expect to read. Each is typed as optional, since nothing guarantees it was set. Any other attribute stays readable as a plain ContextAttributeValue.
Example
import {get} from '/lib/xp/context';
const context = get();
import {get} from '/lib/xp/context';
type MyData = {values: string[]};
const data = get<{'custom.my-data': MyData}>().attributes['custom.my-data']; // MyData | undefined
{
branch: "draft",
repository: "com.enonic.cms.default",
authInfo: {
user: { (1)
type: "user",
key: "user:system:abc",
displayName: "A.B.C.",
disabled: false,
email: "abc@enonic.com",
login: "abc",
idProvider: "system",
hasPassword: true
},
principals: [
"user:system:abc",
"role:system.admin",
"role:system.admin.login",
"role:system.authenticated",
"role:system.everyone"
]
},
attributes: {
optionalAttributes: "of any kind"
}
}
| 1 | The user field is only set when a user is logged in. |
run
Runs a function inside a custom context, for instance the one returned by the get() function call. Commonly used when accessing repositories, or to override the current user’s permissions.
Parameters
run() takes two positional arguments: a ContextParams object defining the context for the scope of the callback (any field omitted is inherited from the current context), and a callback function to execute. The callback’s return value is propagated as the return value of run().
Returns
any : Whatever the callback returns.
Example
import {run} from '/lib/xp/context';
const result = run({
repository: 'system-repo',
branch: 'master',
user: {
login: 'su',
idProvider: 'system'
},
principals: ['role:system.admin'],
attributes: {
ignorePublishTimes: true
}
}, () => 'Hello from context');
"Hello from context"
setCustomLocalAttribute
Stores a value as a custom attribute in the local scope of the current context, where any other code running in the same execution can read it back.
This is how unrelated pieces of code hand data to each other within one request without a shared module or a wrapping run() call. A page implementation can leave data for a response processor, a part can leave data for the filter that wrapped the request, and apps on the same site can do this across application boundaries — each reader gets its own copy of the value, so nothing is shared but the data itself.
All apps in a request write into one flat namespace. The custom. prefix separates your attributes from the platform’s, not one app’s from another’s, and there is no per-app scoping underneath it: two apps that both store settings are writing the same attribute, and the last write wins. Unless you mean to collaborate on a value, name it after your app — setCustomLocalAttribute('com.example.myapp.settings', …). |
The local scope is shared with nested run() calls, so a value stored inside a run() callback is still there after it returns. It lives for the duration of the execution: a new HTTP request starts with an empty scope, and tasks, event listeners and websocket callbacks run with their own — nothing written during a request reaches them.
Values are serialized on write, so the stored attribute is a snapshot: mutating the object you passed in afterwards does not change it, and each reader gets its own copy. Only JSON-like values are allowed — strings, numbers, booleans, arrays, and plain objects nesting those. Anything else, such as a function or a Date, is rejected.
Parameters
Takes two positional arguments: name (string) — the attribute name, stored with the custom. prefix — and value, the JSON-like value to store. Passing null, undefined, or omitting the value removes the attribute.
In TypeScript, a type argument names the type of the value: setCustomLocalAttribute<MyData>('my-data', value) accepts only a MyData whose fields are all JSON-like, so a function or Date anywhere in it is a compile error as well as a runtime one. The type argument itself is a compile-time aid: the runtime rejects non-JSON values as described above, but does not check the value against MyData. Use the same type on the read side with get().
Returns
void
Example
get()
import {get, setCustomLocalAttribute} from '/lib/xp/context';
type MyData = {values: string[]};
setCustomLocalAttribute<MyData>('my-data', {values: ['one', 'two']});
const data = get<{'custom.my-data': MyData}>().attributes['custom.my-data'];
// cms/pages/article/article.ts
import {setCustomLocalAttribute} from '/lib/xp/context';
import type {Tracking} from '/lib/tracking';
export function GET() {
setCustomLocalAttribute<Tracking>('com.example.myapp.tracking', {pageType: 'article', experiment: 'B'});
return {body: renderArticle(), contentType: 'text/html'};
}
// lib/tracking.ts
export type Tracking = {pageType: string; experiment: string};
// cms/processors/tracker.ts
import {get as getContext} from '/lib/xp/context';
import type {Tracking} from '/lib/tracking';
export function responseProcessor(req, res) {
const tracking = getContext<{'custom.com.example.myapp.tracking': Tracking}>().attributes['custom.com.example.myapp.tracking'];
if (tracking) {
res.pageContributions.bodyEnd = [
`<script>window.tracking = ${JSON.stringify(tracking)}</script>`
];
}
return res;
}
| A value stored during a request is not carried into a task submitted from it, and is not visible to another request. Direct component rendering is a separate request, so a value left by a page implementation is absent when a part is rendered on its own. |
Type Definitions
Context
The shape of the object returned by get(). In TypeScript it takes an optional type argument, Context<Attributes>, whose properties are added to attributes as optional, typed entries.
Properties
| Name | Type | Description |
|---|---|---|
|
attributes |
Custom attributes set on the context. Always present; may be empty. Attributes stored with |
|
|
branch |
string |
Optional. Branch context. |
|
repository |
string |
Optional. Repository context. |
|
authInfo |
Optional. Authentication information for the current context. |
ContextParams
The context object passed as the first argument to run(). Any field omitted is inherited from the calling context.
Properties
| Name | Type | Description |
|---|---|---|
|
repository |
string |
Optional. Repository to run the callback in. Defaults to the current repository. |
|
branch |
string |
Optional. Branch to run the callback in. Defaults to the current branch. |
|
user |
Optional. User to run the callback as. |
|
|
principals |
Optional. Additional principal keys (users, groups, and roles) to attach to the authentication info for the duration of the callback. |
|
|
attributes |
Optional. Additional context attributes. |
AuthInfo
Authentication information attached to a context.
Properties
| Name | Type | Description |
|---|---|---|
|
user |
Optional. The currently authenticated user. Omitted when no user is logged in. |
|
|
principals |
Optional. Principal keys (users, groups, and roles) attached to the authentication info. |
ContextUserParams
Identifies the user to run a callback as, passed in ContextParams.user.
Properties
| Name | Type | Description |
|---|---|---|
|
login |
string |
Login name of the user. |
|
idProvider |
string |
Optional. Key of the ID provider the user belongs to. Defaults to the system ID provider when omitted. |
ContextAttributes
Attributes are read and written through different value sets, so the two directions do not share a type.
Reading — Context.attributes — is a record of JSON-like values: strings, numbers, booleans, arrays, and objects nesting those. Everything stored with setCustomLocalAttribute() comes back in full, keyed as custom.<name>. In TypeScript the value type is ContextAttributeValue, or the type named in the type argument to get().
Storing — setCustomLocalAttribute() — takes a CustomAttributeValue<T>: the JSON-like shape of T, where functions and non-JSON objects such as Date become never, so they fail to compile just as they fail at runtime. Without a type argument it is the same as ContextAttributeValue.
Writing — ContextParams.attributes, passed to run() — takes number, string and boolean. An object value is accepted and is visible to Java code reading the context, but it is not part of what get() returns.
get() merges every store it reads from: attributes set on the context — by run() or by the platform — win over local-scope attributes with the same key, which in turn win over session attributes. Attributes the platform sets are documented where they apply; a task started by the scheduler, for instance, finds the previous run’s task id in schedule.lastTaskId, see What a scheduled task receives. And unlike attributes passed to run(), which are scoped to the callback, a local-scope attribute stays readable after the call that wrote it returns.