暂时更改Sitecore项目的布局

时间:2012-03-12 12:14:22

标签: c# .net sitecore sitecore6

使用此代码我设法更改当前项目的渲染。然而,这在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();
    }
}

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

4 个答案:

答案 0 :(得分:5)

您在评论中说明了您希望在侧边栏中显示某些子布局,具体取决于某些表单部件/步骤。 您可以通过添加适合子布局的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

答案 1 :(得分:2)

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

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

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

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

或者你可以简单地使用条件渲染规则来根据你想象的逻辑来显示你想要的渲染/子布局。