Table of Contents
Introduction
EPiServer has support for context-sensitive client components.
Context could for instance be the current page that the user is working with. Since
components are losely coupled the context service object is responsible for handling
the current context. To get hold of the current context you could simply do this:
CopyJavaScript
var contextService = epi.dependency.resolve("epi.shell.ContextService");
var currentContext = contextService.currentContext;
The context service on the client interacts with the server to resolve context for the
selected page/block/entity. The actual properties on the context object depends on the
type of context being displayed but a few properties are available for all context:
uri | The key uniquely identifying the entity in context. |
previewUrl | The URL on which the entity can be displayed in the editing UI. |
data | The values of the entity in context. |
type | The type of data for this context. This information is derived from the uri. |
id | The id of the data for this context. This information is derived from the uri. |
Context on the server implements the IClientContext
interface and is serialized to the client.
Example: epi.cms.contentdata Context
One context implemented in CMS is the content data context. This is an example of such a context:
CopyJavaScript
{
"parentLink":"4",
"customViewType":"",
"language":"en",
"publicUrl":"/MaintAlloy/Alloy-Track/",
"capabilities":
{
"languageSettings":true,
"securable":true,
"dynamicProperties":true,
"isFolder":false,
"isPage":true,
"contentResources":true,
"language":true,
"isBlock":false
},
"languageContext":
{
"isTranslationNeeded":false,
"language":"en",
"isPreferredLanguageAvailable":true,
"preferredLanguage":"en",
"reason":1,
"warning":null,
"hasTranslationAccess":true
},
"hasSiteChanged":false,
"fullHomeUrl":"http://localhost/MaintAlloy/EPiServer/CMS/Home",
"versionedUrl":"",
"dataType":"epi.cms.page",
"uri":"epi.cms.contentdata:///8_8",
"previewUrl":"/MaintAlloy/EPiServer/CMS/Alloy-Track,,8_8/?id=8_8&epieditmode=true",
"data":null,
"name":"Alloy Track",
"requestedUri":"epi.cms.contentdata:///8",
"versionAgnosticUri":"epi.cms.contentdata:///8"
}
The class serialized to produce this client context is ContentDataContext.
Using _ContextMixin to Access Context in Components
To simplify interaction with the context it
is possible implement a mix-in that provides
access to the context from a component.
CopyJavaScript
define("epi/cms/component/PageVersions", [
"epi/shell/_ContextMixin"
], function (_ContextMixin) {
return dojo.declare("epi.cms.component.PageVersions", [_ContextMixin], {
constructor: function(){
dojo.when(this.getCurrentContext(), function(context){
console.log("we have context: ", context);
});
}
}
});
The _ContextMixin extends the class with a few methods:
getCurrentContext() | Returns any available context or a deferred object that will resolve to the context as soon as it becomes available. |
currentContext | The currently loaded context. This may be null. |
contextChanged(context, callerData) | Overridable method called when the context changes. Components should check that the context is not null and may look at context.type to determine whether they can work with a given context. |
contextChangeFailed(previousContext, callerData) | Overridable method called when loading the context fails for any reason. |
Changing the Current Context
If you need to change the current context this is done by publishing a message
to the "/epi/shell/context/request" channel with parameters for the new
context as the data. An URI parameter property is required to determine which
type of context to load. Here is an example to change the current context to an
EPiServer CMS ContentData object:
CopyJavaScript
var pageLink = "5_135";
var contextParameters = { uri: 'epi.cms.contentdata:///' + pageLink };
dojo.publish("/epi/shell/context/request", [contextParameters]);
Listening to Changes to the Current Context Using Subscription
Without using the _ContextMixin it is possible to subscribe to context changes using
the dojo pub/sub infrastructure. If you want to react to a context change simply subscribe
to the "/epi/shell/context/changed" message:
CopyJavaScript
startup: function () {
this.subscribe("/epi/shell/context/changed", this._contextChanged);
},
_contextChanged: function (newContext) {
if (!newContext) {
return;
}
}
Implementing a Context Resolver on the Server
To provide context for a certain type of entities you can implement context resolver interfaces.
There are two ways of providing context; resolving a known reference using URI, and querying context on a specific
URL.
This is an example of a context resolver that performs both these tasks:
CopyC#
[ServiceConfiguration(typeof(IUrlContextResolver))]
[ServiceConfiguration(typeof(IUriContextResolver))]
public class CmsFileContextResolver : IUriContextResolver, IUrlContextResolver
{
private VirtualPathProvider _vpp;
public CmsFileContextResolver(VirtualPathProvider vpp)
{
SortOrder = 123;
_vpp = vpp;
}
public string Name
{
get { return "epi.cms.unifiedfile"; }
}
public bool TryResolveUri(Uri uri, out IClientContext instance)
{
instance = ResolvePath("~" + uri.LocalPath);
return instance != null;
}
public bool TryResolveUrl(Uri url, out IClientContext instance)
{
instance = ResolvePath(url.LocalPath);
return instance != null;
}
private IClientContext ResolvePath(string path)
{
var file = _vpp.GetFile(path) as UnifiedFile;
if (file == null)
{
return null;
}
return new Models.UnifiedFileContext
{
Uri = new Uri("epi.file.unifiedfile://" + VirtualPathUtilityEx.ToAppRelative(file.VirtualPath).TrimStart('~')),
Data = new
{
file.VirtualPath,
},
PreviewUrl = file.VirtualPath
};
}
public int SortOrder { get; set; }
}
Querying for a New Context by URL
Context resolvers implementing the IUrlContextResolver
interface are queryed when an URL is loaded in the preview frame. To programmatically change the
context to the context associated with an URL publish a message. This is an example of this:
CopyJavaScript
var contextParameters = { url: someUnknownUrl.toString() };
dojo.publish("/epi/shell/context/request", [contextParameters, { sender: this }]);
Do you find this information helpful? Please log in to provide feedback.