One way that comes up to my mind is to have a baseclass called e.g. OnPageEditableBlock that inherits BlockData and then all blocks that should be on page editable would inherit that class. While your other blocks that should have forms editing would inherit directly from BlockData. Then in your BlockPreview you should set the generic argument to IRenderTemplate to OnPageEditableBlock.
Hmmm I'm getting an error though in PreviewContainerPage.aspx. The error just flashes and then the form view slides in.
The error
Content with id '24_363' is of type 'Castle.Proxies.SlideBlockProxy' which does not inherit required type 'EPiServer.Core.PageData'
[TypeMismatchException: Content with id '24_363' is of type 'Castle.Proxies.SlideBlockProxy' which does not inherit required type 'EPiServer.Core.PageData']
EPiServer.DataFactory.ThrowTypeMismatchException(ContentReference link, Type actual, Type required) +179
EPiServer.DataFactory.Get(ContentReference contentLink, ILanguageSelector languageSelector) +482
EPiServer.PageBase.GetPage(PageReference pageLink, ILanguageSelector selector) +233
EPiServer.Web.PageExtensions.LoadCurrentPage.get_CurrentPage() +133
EPiServer.PageBase.SetCachePolicy() +195
EPiServer.PageBase.OnInit(EventArgs e) +39
System.Web.UI.Control.InitRecursive(Control namingContainer) +186
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +2098
And this is what I find in the log
2013-06-12 19:04:05,660 ERROR [user] EPiServer.Global System.Web.HttpUnhandledException (0x80004005): Exception of type 'System.Web.HttpUnhandledException' was thrown. ---> EPiServer.Core.TypeMismatchException: Content with id '85_584' is of type 'Castle.Proxies.SlideBlockProxy' which does not inherit required type 'EPiServer.Core.PageData'
at EPiServer.DataFactory.ThrowTypeMismatchException(ContentReference link, Type actual, Type required)
at EPiServer.DataFactory.Get[T](ContentReference contentLink, ILanguageSelector languageSelector)
at EPiServer.PageBase.GetPage(PageReference pageLink, ILanguageSelector selector)
at EPiServer.Web.PageExtensions.LoadCurrentPage.get_CurrentPage()
at EPiServer.PageBase.SetCachePolicy()
at EPiServer.PageBase.OnInit(EventArgs e)
at System.Web.UI.Control.InitRecursive(Control namingContainer)
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
at System.Web.UI.Page.HandleError(Exception e)
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
at System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
at System.Web.UI.Page.ProcessRequest()
at System.Web.UI.Page.ProcessRequest(HttpContext context)
at ASP.episerver_cms_edit_previewcontainerpage_aspx.ProcessRequest(HttpContext context) in c:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\78f76313\91ca32c3\App_Web_vru0ko5h.19.cs:line 0
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
- 1.2.5 Unhandled exception in ASP.NET
The SlideBlock inherits from SiteFormsViewBlockDataBase which inherits from BlockData.
Make sure that you describe the templatedescriptor so your blockdata is not included.
You can look your block type settings and make sure the fields for Web Form Template and MVC Template are empty. Sometimes you need to Revert to default. Especially if you are a couple of developers sharing database since they will update the selected template on restart according to their "old" TemplateDescriptor
Sorry I misread your callstack.
This is what seems to be ordinary when editing a Block that does not have a Preview-Template. I also had this after my first couple of Blocks.
Yeah, and the thing is that we don't want a template. We just want the Forms Editing view.
This works great for pages though, so I guess there is some attribute we can render on the template to load up the Forms Editing view.
When I'm looking in the XML Http Requests for a Block (/EPiServer/shell/Stores/context/?uri=epi.cms.contentdata:///8664&dojo.preventCache=1371078678651) that have no Template I can see the following:
hasTemplate: false
previewUrl: "/secure/CMS/edit/PreviewContainerPage.aspx"
I can see the same in the XHR when I edit a Container Page (ordinary page that have no template)
Though when I'm editing a Block that have a template i can see the following:
hasTemplate: true
previewUrl: "/secure/CMS/Content/Ny-katalog/Ny-katalog1/,,8664_35819/?epieditmode=true"
My guess is that "hasTemplate" is what's triggering whether to automatically show the form editing and the call stack you see flash by must be the PreviewContainerPage.aspx throwing an exception since it tries to get a PageData object where CurrentContent in fact is a Block.
A spontanious search for "hasTemplate" brought me to C:\Program Files (x86)\EPiServer\CMS\7.0.586.1\Application\UI\EPiServer\CMS\ClientResources\EPi\Cms\contentediting\PageDataController.js which seems to confirm this:
_getDefaultView: function (viewModel) {
// summary:
// Get the default view based on user's access rights.
//
// tags:
// private
return viewModel.contentData.hasTemplate ?
(viewModel.canChangeContent() ? this._defaultEditViewName : "readonly") :
"formedit";
}
So the question is how you can return false on hasTemplate while also returning another previewUrl than PreviewContainerPage.aspx
I think this seems kinda tricky since EPiServer.Cms.Shell.UI.dll seems to be the assembly deciding what previewUrl should be sent in the XHR.
Here you can find IContentExtensions with a method PreviewUrl:
public static string PreviewUrl(this IContent content)
{
if (!content.HasTemplate())
{
return UriSupport.ResolveUrlFromUIBySettings("edit/PreviewContainerPage.aspx");
}
VirtualPathData virtualPathData = RouteTable.Routes.GetVirtualPath(content.ContentLink, content.LanguageBranch(), true, true);
if (virtualPathData == null)
{
return string.Empty;
}
UrlBuilder builder = new UrlBuilder(virtualPathData.GetUrl());
if (!(content is PageData))
{
builder.QueryCollection.Remove("id");
}
return builder.ToString();
}
content.HasTemplate() is an extension method in IContentExtensions:
internal static bool HasTemplate(this IContent content)
{
PageData data = content as PageData;
if ((data != null) && (data.LinkType == PageShortcutType.Inactive))
{
return false;
}
return ServiceLocator.Current.GetInstance<TemplateResolver>().HasTemplate(content, TemplateTypeCategories.Page, "Preview");
}
I would call this a bug or a request to let PreviewContainerPage not be dependent on having a PageData.
Either way, at the moment I think you'll have to live with the call stack flashing by, or create a plugin that does some Dojo magic displaying the forms edit.
Looking at sourcecode I see that this has changed (PreviewContainerPage handles other content than PageData) in development branch meaning it will be fixed in 7.5 release.
I have however also reported a bug on that it should be fixed in Maint branch meaning that it then (given that the bug will be fixed) will be available in next maintenanace drop.
I just want to add that we have added the posibility to define the default view for a content type in the next release. More info about this when we get closer to the release...
And for everyone that finds this thread through search; here's the answer http://world.episerver.com/Blogs/Linus-Ekstrom/Dates/2013/12/Customizing-the-look-and-behavior-in-the-UI-for-your-content-types/.
Note that UIDescriptor<T> with the DefaultView is only available in EPiServer 7.5
Some blocks doesn't make sense to edit on page. Maybe they have a lot of "hidden" properties that is not visible to the user and sometimes the design of the block makes it to hard for the edtior. Sometimes the block has different apperance depending on where it is rendered.
My scenario
I have a general previewing template...
...and then I add a content renderer to this page for the block.
But is there a way to force the user to the forms view straight away? I have tried with all attributes on the blocks, but they always gets rendered on my preview template with the message "Block A dosen't have a renderer for the tag Preview", which is true, because I don't want to render them there.