In this article I will continue implementing page preview in ContentArea. I already have custom view which renders current page in ContentArea. The item could look better when it’s surrounded by two fake items. It will give the feeling of how the page will look like together with other elements. That’s why I decided to prepare ContentArea with fake items.
ContentArea has generic collection of ContentAreaItem. Main item property is ContentLink. I didn’t wanted to create a custom content provider which returns fake content, so I tried to find other solution. ContentArea has also Fragments property which expose virtual GetContent method.
I’ve implemented FakeStringFragment which extend default ContentArea ContentFragment. The GetContent method is overriden and instead of returning Content using ContentReference the fake News Page is always created.
I also changed the GetSecurityDescriptor method implementation, because by default item would be filtered out in ContentArea.FilteredItems property.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
using System.Collections.Generic; using EPiServer; using EPiServer.Core; using EPiServer.Core.Html.StringParsing; using EPiServer.Security; using EPiServer.Web; namespace AlloyDemo.Plugin { public class FakeStringFragment : ContentFragment, ISecurable { private readonly PageData _page; private readonly IContentRepository _contentRepository; public ISecurable Securable { get; set; } public FakeStringFragment(PageData page, IContentRepository contentRepository, TemplateControlLoader templateControlLoader, ISecuredFragmentMarkupGenerator securedFragmentMarkupGenerator, IPublishedStateAssessor publishedStateAssessor, DisplayOptions displayOptions) : base( contentRepository, templateControlLoader, securedFragmentMarkupGenerator, displayOptions, publishedStateAssessor, new Dictionary<string, object>()) { _page = page; this._contentRepository = contentRepository; ContentLink = page.ContentLink; } public override IContent GetContent() { var newsPage = this._contentRepository.GetDefault<NewsPage>(ContentReference.StartPage); newsPage.Name = "Lorem ipsum dolor sit amet"; newsPage.TeaserText = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer vel volutpat mauris, quis convallis magna."; newsPage.PageImage = new ContentReference(233); return newsPage; } ISecurityDescriptor ISecurable.GetSecurityDescriptor() { return this._page.GetSecurityDescriptor(); } } } |
Now using newsPage.MainContentArea.Fragments.Add(CreateFakeFragment(contentAreaItem)) I created two fake items.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
using System; using System.Linq; using System.Web; using System.Web.UI; using EPiServer; using EPiServer.Core; using EPiServer.Core.Html.StringParsing; using EPiServer.ServiceLocation; using EPiServer.Shell.WebForms; using EPiServer.Web; namespace AlloyDemo.Plugin { public partial class NewsPageView : ContentWebFormsBase { protected void Page_Load(object sender, EventArgs e) { } protected override void OnInit(EventArgs e) { base.OnInit(e); Bundles.Controls.Add( new LiteralControl(System.Web.Optimization.Scripts.Render("~/bundles/js").ToHtmlString())); Bundles.Controls.Add( new LiteralControl(System.Web.Optimization.Styles.Render("~/bundles/css").ToHtmlString())); var contentRepository = ServiceLocator.Current.GetInstance<IContentRepository>(); var newsPage = contentRepository.GetDefault<NewsPage>(this.CurrentContent.ParentLink); newsPage.Name = "Preview"; newsPage.MainContentArea = new ContentArea(); var contentAreaItem = new ContentAreaItem {ContentLink = this.CurrentContent.ContentLink}; newsPage.MainContentArea.Fragments.Add(CreateFakeFragment(contentAreaItem)); newsPage.MainContentArea.Items.Add(contentAreaItem); newsPage.MainContentArea.Fragments.Add(CreateFakeFragment(contentAreaItem)); this.CurrentContent = newsPage; HttpContext.Current.Request.RequestContext.RouteData.DataTokens["contextmode"] = ContextMode.Edit; } private IStringFragment CreateFakeFragment(ContentAreaItem contentAreaItem) { var publishedStateAssessor = ServiceLocator.Current.GetInstance<IPublishedStateAssessor>(); var templateControlLoader = ServiceLocator.Current.GetInstance<TemplateControlLoader>(); var displayOptions = ServiceLocator.Current.GetInstance<DisplayOptions>(); var securedFragmentMarkupGeneratorFactory = ServiceLocator.Current.GetInstance<ISecuredFragmentMarkupGeneratorFactory>(); var fragmentMarkupGenerator = securedFragmentMarkupGeneratorFactory.CreateSecuredFragmentMarkupGenerator(); fragmentMarkupGenerator.ContentGroup = contentAreaItem.ContentGroup; if (contentAreaItem.AllowedRoles != null && Enumerable.Any<string>(contentAreaItem.AllowedRoles)) fragmentMarkupGenerator.RoleSecurityDescriptor.RoleIdentities = contentAreaItem.AllowedRoles; return new FakeStringFragment((PageData) this.CurrentContent, this.ContentRepository, templateControlLoader, fragmentMarkupGenerator, publishedStateAssessor, displayOptions ); } } } |
The fake items could be faded. It allows editor to focus on current page item. That’s why first and last elements have added opacity in styles.
1 2 3 4 5 6 7 8 9 10 11 |
<style type="text/css"> .row>div:first-child, .row>div:last-child { opacity: 0.3; } .row:hover>div:first-child, .row:hover>div:last-child { opacity: 1; } </style> |
The full source code for last three articles is available on Gist