暂时更改Sitecore项目的布局

使用此代码,我设法更改当前项目的渲染。 然而,这在Sitecore中永久性地改变了(变化可以在CMS中看到)而不是暂时的,正如我预期的那样。

void ReplaceLayout(Item item) { if (item == null) return; using (new SecurityDisabler()) { // New item LayoutField newLayoutField = new LayoutField(item.Fields[Sitecore.FieldIDs.LayoutField]); LayoutDefinition newLayoutDefinition = LayoutDefinition.Parse(newLayoutField.Value); DeviceDefinition newDeviceDefinition = newLayoutDefinition.GetDevice(Sitecore.Context.Device.ID.ToString()); // Current item LayoutField layoutField = new LayoutField(Sitecore.Context.Item.Fields[Sitecore.FieldIDs.LayoutField]); LayoutDefinition layoutDefinition = LayoutDefinition.Parse(layoutField.Value); DeviceDefinition deviceDefinition = layoutDefinition.GetDevice(Sitecore.Context.Device.ID.ToString()); deviceDefinition.Layout = newDeviceDefinition.Layout; deviceDefinition.Renderings = newDeviceDefinition.Renderings; Sitecore.Context.Item.Editing.BeginEdit(); layoutField.Value = layoutDefinition.ToXml(); Sitecore.Context.Item.Editing.EndEdit(); } } 

我不想对项目进行永久性更改,我只想在满足某些条件的情况下动态替换当前显示的项目渲染。 有谁知道如何以这种方式改变项目的布局?

您在评论中解释说,您希望在侧栏中显示某些子布局,具体取决于某些表单部分/步骤。 您可以通过添加适合子布局的PlaceHolder(例如在侧边栏中)并使用此代码动态渲染子布局来实现。

首先,您需要一个项目(我称之为片段项目),该项目在其演示设置上配置了子布局。 然后,您可以使用代码在占位符(phSideBarPlaceHolder)中呈现该项目。

 // Load snippet item Item snippet = Sitecore.Context.Database.GetItem("{id-or-path-of-snippet-item}"); // Get the first rendering from item's presentation definition RenderingReference rendering = snippet.Visualization.GetRenderings(Sitecore.Context.Device, false).FirstOrDefault(); // We assume that its a Sublayout, but you can also check for xslt and create an XslFile() object Sublayout sublayout = new Sublayout(); sublayout.DataSource = snippet.Paths.FullPath; // creates a reference to the snippet item, so you can pull data from that later on sublayout.Path = rendering.RenderingItem.InnerItem["Path"]; sublayout.Cacheable = rendering.RenderingItem.Caching.Cacheable; // Copy cache settings if (rendering.RenderingItem.Caching.Cacheable) { sublayout.VaryByData = rendering.RenderingItem.Caching.VaryByData; sublayout.VaryByDevice = rendering.RenderingItem.Caching.VaryByDevice; sublayout.VaryByLogin = rendering.RenderingItem.Caching.VaryByLogin; sublayout.VaryByParm = rendering.RenderingItem.Caching.VaryByParm; sublayout.VaryByQueryString = rendering.RenderingItem.Caching.VaryByQueryString; sublayout.VaryByUser = rendering.RenderingItem.Caching.VaryByUser; } // Now render the sublayout to the placeholder phSideBarPlaceHolder.Controls.Add(sublayout); 

如果您需要有关如何在子布局代码中读取DataSource属性的更多信息,Mark Ursino已经写了一篇文章: http ://firebreaksice.com/using-the-datasource-field-with-sitecore-sublayouts

Sitecore构建渲染控件,并在ASP.NET Webforms生命周期的早期将它们插入到页面中。 您不太可能在布局本身上轻松完成此操作。 但是,如果您可以评估页面外的条件(例如,通过检查项目本身),您可以在insertRenderings管道中执行此操作。

使用ILSpy或其他反编译器检查Sitecore.Pipelines.InsertRenderingsSitecore.Pipelines.InsertRenderings.Processors 。 与其他管道一样,这些处理器的执行顺序在Web.config中定义。 您将需要在AddRenderings之后添加一个新处理器来评估您的条件(可能检查args.ContextItem ),然后根据需要修改args.Renderings

在上一个问题中,您只是想删除子布局。 这应该相当容易。 添加不同的子布局更加困难,因为您需要构建RenderingReference 。 这可能要求您实际创建其构造函数所需的XML定义。 或者,如果您有另一个定义所需新布局的项目,请考虑在管道中更早地更改args.ContextItem

您是否可以将“表单”控件和侧边栏放在一个父控件容器中,而不是更改sitecore表示? 然后,您将拥有一个侧边栏容器的简单ID,用于从表单控件以编程方式有条件地填充控件。

或者,您是否可以将所有可能的控件添加到侧边栏并“激活”(或者可能只是使可见)所需的控件,可能是通过会话状态变量? (我不知道这是否会违反某些生命周期或时间限制)

或者,您可以简单地使用条件渲染规则,根据您可以想到的任何逻辑来显示所需的渲染/子布局。