In one of our projects we use News page type to show the latest Company news. The news page is an article with title, image, teaser, main content and “See also” section. The section is Content Area with links to other news pages. Editor manually selects few news that should be displayed as related with currently edited news page. Each section item is rendered using custom partial page template. When editor creates news page, he doesn’t know how the page will look like in See also version. That’s why I tried to prepare news page template preview. It will be a custom edit mode view available on News Page.
Introduction
In this article I used Alloy demo code. There is also News Page with template for a page and a custom renderer for a Content Area item. I prepared few news based on Wikipedia articles and photos.
The See also section is a standard Content Area property.
The custom view will show current page rendered inside Content Area. The item will be between two other fake items, to show how it will looks like with more items scenario. During the implementation I had to solve few issues both on client-side and server-side:
- the IFrame view doesn’t refresh the content when editing page – I need instant preview,
- adding current draft to Content Area – the iframe should show page in edit mode,
- adding fake items to Content Area – content area items use Content References, while fake items are not stored in the database.
In this article I will describe how to prepare iframe view with document refreshed on every page save. Working with fake Content Areas will be described in a separated articles.
Custom IFrame view
To prepare custom view I used class registered as ViewConfiguration service. ControllerType property defines client-side class view. For views with MVC or ASP.NET Forms content “epi-cms/widget/IFrameController” should be used.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
using System.Web; using EPiServer.ServiceLocation; using EPiServer.Shell; namespace AlloyDemo.Business { [ServiceConfiguration(typeof (ViewConfiguration))] public class NewsSeeAlsoView : ViewConfiguration<NewsPage> { public const string ViewKey = "news-page-view"; public NewsSeeAlsoView() { Key = ViewKey; Name = "News preview"; Description = "Preview of news page"; ControllerType = "epi-cms/widget/IFrameController"; ViewType = VirtualPathUtility.ToAbsolute("~/Plugin/NewsPageView.aspx"); IconClass = "epi-iconPreview"; } } } |
The ViewType set the location of iframe document. For now custom view will just display the MetaDescription property value.
1 2 3 4 |
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/MasterPages/Root.Master" AutoEventWireup="true" CodeBehind="NewsPageView.aspx.cs" Inherits="AlloyDemo.Plugin.NewsPageView" %> <asp:Content ContentPlaceHolderID="FullRegion" runat="server"> <EPiServer:Property runat="server" PropertyName="MetaDescription"></EPiServer:Property> </asp:Content> |
The IFrameControler use “epi/shell/widget/Iframe” dependency to display iframe content. Iframe has load method used to show document content based on URL property value. During reloading iframe, when one document is already assigned and new URL is the same as previous one, the load method has no effect and document will not be refreshed. For currently edited page, URL has two parameters: uri and id. For those values, the draft never changes, so the page won’t be refreshed until editor publish a page or refresh browser window.
To solve this problem I implemented extended version of IFrameController. I had to override _constructQuery method. Now the method has additional timestamp query parameter.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
define([ "dojo/_base/declare", "epi-cms/widget/IFrameController" ], function( declare, IFrameController ) { return declare([IFrameController], { _constructQuery: function (context) { var result = this.inherited(arguments); result.timeStamp = new Date().getTime(); return result; } }); }); |
Whenever new _constructQuery method is executed, timestamp parameter has new value assigned, the document URL change and iframe is reloaded.
We have to use “refreshableIframe/refreshablehIframeController” in NewsSeeAlsoView.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
using System.Web; using EPiServer.ServiceLocation; using EPiServer.Shell; namespace AlloyDemo.Business { [ServiceConfiguration(typeof (ViewConfiguration))] public class NewsSeeAlsoView : ViewConfiguration<NewsPage> { public const string ViewKey = "news-page-view"; public NewsSeeAlsoView() { Key = ViewKey; Name = "News preview"; Description = "Preview of news page"; ControllerType = "refreshableIframe/refreshablehIframeController"; ViewType = VirtualPathUtility.ToAbsolute("~/Plugin/NewsPageView.aspx"); IconClass = "epi-iconPreview"; } } } |
Now when editing MetaDescription, property iframe is automatically refreshed.
In next article I will describe how to render current page inside ContentArea.