Help shape the future of CMS PaaS release notes! Take this quick survey and share your feedback.
Help shape the future of CMS PaaS release notes! Take this quick survey and share your feedback.
The basic idea is that when editing shared blocks you should have a page template (WebForm asxp or MVC page controller) registered as IRenderTemplate<BlockData> with tag "Preview". That template will then be used when editing the block. The reason you see PreviewContainerPage.aspx is that there is no page template registered that can show the block instance.
There is an implementation in the new Alloy templates that displays the block in several content areas. Another simple implementation can be:
[TemplateDescriptor(Inherited = true, Tags = new string[] { RenderingTags.Preview })]
public partial class PreviewBlock : PreviewPage, IRenderTemplate<BlockData>
{
/// <summary>
/// Raises the <see cref="E:System.Web.UI.Control.Load"/> event.
/// </summary>
/// <param name="e">The <see cref="T:System.EventArgs"/> object that contains the event data.</param>
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
((EPiServer.Templates.AlloyTech.MasterPages.MasterPage)this.Master).Body.Attributes["class"] = "PreviewBlock";
ContentArea.Controls.Add(new ContentRenderer()
{
CurrentData = CurrentData,
CurrentContent = CurrentData,
RenderType = PageEditing.PageIsInEditMode ? RenderType.OnPageEdit : RenderType.Default
});
}
}
and the markup can be something like:
<%@ Page Language="C#" AutoEventWireup="False" CodeBehind="PreviewBlock.aspx.cs"
MasterPageFile="~/Templates/AlloyTech/MasterPages/MasterPage.master" Inherits="EPiServer.Templates.AlloyTech.Pages.PreviewBlock" %>
<asp:Content ContentPlaceHolderID="BreadcrumbsRegion" runat="server" />
<asp:Content ContentPlaceHolderID="MenuRegion" runat="server" />
<asp:Content ContentPlaceHolderID="MainBodyRegion" runat="server">
<div id="MainBody">
<asp:Panel runat="server" ID="ContentArea" />
</div>
</asp:Content>
<asp:Content ContentPlaceHolderID="SecondaryBodyRegion" runat="server">
</asp:Content>
<asp:Content ContentPlaceHolderID="FooterRegion" runat="server" />
The same concept applies to MVC as well, that is you should have a controller that handles BlockData that is tagged with Preview, like:
[TemplateDescriptor(Inherited = true, Tags = new string[] { RenderingTags.Preview }, TemplateTypeCategory=TemplateTypeCategories.MvcController)]
[Authorize(Roles = "CmsEditors, CmsAdmins")]
public class PreviewBlockController : ActionControllerBase, IRenderTemplate<BlockData>
{
public ActionResult Index(BlockData currentContent)
{
return View(currentContent);
}
}
And then a corresponding view for PreviewBlock like (of course it could have been a Razor view instead):
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<EPiServer.Core.IContent>" %>
<%@ Import Namespace="EPiServer.Web.Mvc.Html" %>
<asp:Content ID="Content2" ContentPlaceHolderID="Content" runat="server">
<%Html.RenderContentData(Model, false);%>
</asp:Content>
Thanks a lot for the reply.
But I implemented a conroller to replace the aspx (same as your post) and the view, but still not working.
I think the problem is Html.RenderContentData(Model, false); in the view in this case I use razor. I get the error saying:
error CS1502: The best overloaded method match for 'System.Web.WebPages.WebPageExecutingBase.Write(System.Web.WebPages.HelperResult)' has some invalid arguments.
It looks like the arguments I'm sending is not valid. I'm wondering if this RenderContentData is doing the same thing as the ASPX equivalent one. If thats the case then what about the RenderType and CurrentContent parameters?
CurrentData = CurrentData,
CurrentContent = CurrentData,
RenderType = PageEditing.PageIsInEditMode ? RenderType.OnPageEdit : RenderType.Default
Thanks!
OK, I got it working on a web form (mvc) but, editing doesn't work for all the controls such as images.
If I remove this new controller I can edit every content block, but I then I will get that castle proxy exception again.
Have you implemented this in MVC which supports full editing of content blocks? I dont know why this should not come with EpiServer, while editing and previewing a content block is a usual task!
The reason that a page that allows onpageedit support for blocks is not included in EPiServer is that the preview page used is probably highly dependent on the templates/styles used in your soultion. As for example in the new Alloy web form templates where the preview of blocks uses the twitter bootstrap framework for styling.
The easiest way to get onpageedit support for properties is to render them through Html.PropertyFor extension method in your block views. PropertyFor will use standard Mvc DisplayFor but will also ensure nessecary html attributes are outputed to get onpageedit support.
Thanks Johan. I read your blog post about "Rendering of content". Thanks for the great job. So, I understand the rendering and tagging concept in Epi7.
So, when I create an image block (including model, controller, viewmodel, view etc.) the view is rendered when I browse the page which is hosting my image block, so I can see the image rendering on the page.
Now, when I edit the image block (as a shared block), I can see the exception happnes, so I create the controller with Preview tag to handle it and it does. Therefore, the exception doesnt happen again which is good.
All is fine. The only question here is that is this Preview tag used when I click small drop down on the right hand side corner of a shared block? because still I see that my normal partial view is still rendered instead of the BlockPreview page which I created.
Thanks
The idea with onpageediting is that the editing shold be done on the same template that is used in view mode. That is the editor should see how the content will appear on the site while editing.
So the idea with the PreviewBlock controller (or page in web forms) is that is just a host for a partial template (e.g. partial view in MVC or User control in web forms) which perhaps add some styling according to the styles used in the templates.
So in your case it is expected that you should get your "normal" partial view. If you use PropertyFor (or Property webcontrol in web forms) to render your property you can see that in onpage edit mode it adds some extra attributes but it is the same template used both on site and during editing.
Just for reference MVC razor view:
@model EPiServer.Core.BlockData @{ Html.RenderContentData(Model, false); }
I have class PreviewBlock like Johan described, editing/showing to users works without a problem. However when submiting XForms page (dont know exactly how it works yet), I get the same error as described. Of course only when there is instance of shared block on that particular page.
I have the same problem as krzysztofmorcinek Does anyone know a solution to this?
Everytime I edit a block, I can see an exception for about 1 second, then the page disapears and gets replaced by the edit-view in forms-mode. I've checked the logs and the exception occurs in [MYHOST]/EPiServer/CMS/edit/PreviewContainerPage.aspx?id=9_18&epiworkspaceactive=true
Message: "Content with id '9_18' is of type 'Castle.Proxies.SlideShowProxy' which does not inherit required type 'EPiServer.Core.PageData'"
Anyone who knows what that is? It's not a problem actually, just very annoying