EPiServer CMS 6.0 / R2
Document last saved:
A Page Object in EPiServer CMS is basically a normal .NET object instance that is associated with a CMS page. The Page Object functionality can be utilized in a mulitude of ways, the scenario described in this document is just one way how Page Object can be used.
A Page Object can be associated to a page in 3 different ways. This is known as the Page Object’s Owner Option. These options are:
Each Page Object is given a name which must be unique per page.
In order to work with Page Objects you instantiate an instance of the EPiServer.Core.PageObjectManager class.
The public constructors available take parameters which tell the PageObjectManager which EPiServer CMS page version you want it to manage Page Objects for:
public PageObjectManager(PageData pageData)
public PageObjectManager(PageData pageData, IPageObjectRepository repository)
public PageObjectManager(Guid pageGuid, string pageLanguageBranch, int workPageId)
public PageObjectManager(Guid pageGuid, string pageLanguageBranch, int workPageId, IPageObjectRepository repository)
The PageObjectManager requires an IPageObjectRepository to work with. If one is not provided via the constructor then the EPiServer ClassFactory mechanism is queried to see if one has been registered with it. If one has not been registered with the ClassFactory then an instance of the default EPiServer.DataAccess. DdsPageObjectRepository is instantiated and used.
There are several methods for loading Page Objects
public virtual Object Load(string name)
public virtual TObject Load<TObject>(string name)
public virtual PageObject LoadMetaObject(string name)
public virtual IDictionary<string, Object> LoadAll()
public virtual IEnumerable<PageObject> LoadAllMetaObjects()
The PageObject instances returned by the LoadMetaObject and LoadAllMetaObjects methods are objects that are managed by the PageObjectManager and as their name suggests contain meta-data for the Page Object. These may be useful in debugging scenarios or if you are just curious.
The EPiServer.Core namespace also has a class which defines a generic extension method called ItemAs<> for the IDictionary<string, Object> type. This allows you to access your objects in a strongly typed way:
PageObjectManager pom = new PageObjectManager(……);
IDictionary<string, object> objects = pom.LoadAll();
MyClass myObject = objects.ItemAs<MyClass>("MyObject");
There are two public save methods:
public virtual void Save(string name, Object value, PageObject.OwnerOption ownerOption)
public virtual void Save(string name, Object value)
The first overload takes the Page Object name, the object to save and the OwnerOption. If you save an existing Page Object with a different OwnerOption to the one it already has then the existing one will be overwritten. It is very important to understand the consequence of this especially if Page Objects are used with Dynamic Content and the web editor it given the ability to set the OwnerOption via the Dynamic Content User Interface.
Consider the following scenario:
A Page Object which holds the rating (i.e. a score from 1 to 5) for a CMS page has been wrapped in a Dynamic Content object and is therefore optionally insertable on a page by the web editor. The developer of the Rating Dynamic Content has quite reasonably decided that the web editor should decide what the rating applies to:
These options you will notice map quite nicely to the OwnerOption that is set when saving the Page Object.
The problem potentially comes when the page exists in more than one language. This means that the Rating Dynamic Content needs to be added to each language branch of the page and there lies an opportunity for the editor to chose one owner type for one language and a different owner type for another. The system does not allow the same named Page Object to coexist on the same page with different owner types which means that they will constantly overwrite each other when saved.
The second overload of Save does not require an OwnerOption. When this is called for a new Page Object then the default OwnerOption of PageLanguageBranch will be assigned to it. When this is called for an existing Page Object then the OwnerOption remains unchanged. This allows for code that saves a Page Object without having to know what OwnerOption to specify.
There a two public delete methods:
public virtual void Delete(params string pageObjectsNames)
public virtual void DeleteAll()
Delete removes all the Page Objects for the names passed. This works in conjunction with the OwnerOption which means that only the Page Objects the CMS page the PageObjectManager is associated with will be deleted.
DeleteAll deletes all Page Objects for the CMS page associated with the PageObjectManager.
An EPiServer CMS Page Template is created to show news items. The template also has a text box and a submit button to allow logged in users to comment on the page’s content and renders the last 5 comments posted. The Page Template has code to load and retrieve the comments using a Page Object named “Comments”.
An EPiServer CMS page called “News” is created for the default language branch (English) using the Page Template above.
The first time the PageObjectManager.Load method is called for the “Comments” Page Object it will return null as one has not yet been saved. The code will create a new instance of the class developed for the comments and call the PageObjectManager.Save method with the name “Comments”, the object instance value and an OwnerOption of Page. The next time the Page Template is executed for the “News” page the PageObjectManager.Load method will return the “Comments” Page Object previously saved (note that it will not be the same physical object instance due to how the Dynamic Data Store caches objects. See http://world.episerver.com/Blogs/Johan-Bjornfot/Dates1/2010/1/Dynamic-Data-Store-caching--The-internals/ for more details).
Next a version of the “News” page is created in another language branch, say Swedish. When the Page Template executes for the Swedish version of the page it will get the same “Comments” Page Object returned as the English version as the Page Object was saved with Page OwnerOption. Only one instance of the Page Object will exist.
Later on the Swedish language branch is deleted for the “News” page. The “Comments” Page Object instance will remain as it is shared between all language branches / versions of the page.
If the “Comments” Page Object is saved with PageLanguageBranch OwnerOption then the PageObjectManager.Load method will return null when the Page Template is executed for the Swedish version of the “News” page. The Page Template will then save a new instance of the Page Object for that language branch. An instance of the Page Object will exist per language branch.
If the Swedish language branch for the page is deleted then the “Comments” Page Object owned by that language branch will be deleted but not those owned by other language branches.
If the “Comments” Page Object is saved with PageVersion OwnerOption then the PageObjectManager.Load method will return null when the Page Template is executed for every new version of the CMS Page regardless of language branch. The Page Template will then save a new instance of the Page Object for every page version. An instance of the Page Object will exist per CMS page version.
If a version of the page is deleted then the “Comments” Page Object owned by that version will be deleted but not those owned by other versions of the page.