2012-03-12 15 views
1

このコードを使用して、現在のアイテムのレンダリングを変更することができました。しかし、これはSitecoreで永久に変更されました(変更はCMSで見ることができました)。私は項目にpermenant変更を加えたくない一時的にSitecoreアイテムのレイアウトを変更する

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(); 
    } 
} 

は、私はいくつかの条件が満たされた場合、その場で、現在表示されている項目のレンダリングを交換したいです。この方法でアイテムのレイアウトを変更する方法を知っている人はいますか?

答えて

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); 

あなたはsublayoutコード内のデータにDataSourceプロパティを読み取る方法についての詳細情報が必要な場合は、マークウルシーノはそのことについて記事を書いた:むしろ変更サイトコアのプレゼンテーションよりhttp://firebreaksice.com/using-the-datasource-field-with-sitecore-sublayouts

+0

これはきちんと動作しますが、スニペット項目の必要性を取り除く方法はありますか?または、PlaceHolderコントロールでダミーのサブアイテムを必要とせずに、プレースホルダを含むアイテムからすべてのレンダリングを取得する方法があります。本質的に大丈夫と言うと、このパート/ステップの親レイアウトを使用したくないので、代わりにその子レイアウトを使用したいと思います。または、私たちは@ techphoria414が上で話していることの領域に入っていますか? – Jon

+0

Sublayoutアイテム(Database.GetItem)をロードして、そのアイテムに基づいてRenderingItemオブジェクトを作成するといいでしょう。 var renderingItem = new Sitecore.Data.Items.RenderingItem(sublayoutItem); 私はこれをテストしていません。 希望に役立ちます。 –

+0

レンダリングパラメータを取得するために 'sublayout.Parameters = rendering.Settings.Parameters; 'を追加しました。それ以外は、これは私が最後に行った解決策でした。 – Jon

2

Sitecoreはレンダリングコントロールを作成し、ASP.NET Webformsライフサイクルの早い段階でページに挿入します。これは、レイアウト自体で簡単に行うことはできません。ただし、ページ外で(アイテム自体を調べるなど)条件を評価できる場合は、おそらくinsertRenderingsパイプラインで行うことができます。

Sitecore.Pipelines.InsertRenderingsおよびSitecore.Pipelines.InsertRenderings.Processorsをチェックアウトするには、ILSpyまたは別のデコンパイラーを使用してください。他のパイプラインと同様に、これらのプロセッサの実行順序はWeb.configで定義されています。 AddRenderingsの後に新しいプロセッサを追加して、条件を評価し(おそらくargs.ContextItemを調べる)、必要に応じてargs.Renderingsを変更します。

previous questionでは、あなたはサブレイアウトを削除しようとしていました。それはここでかなり簡単になるはずです。 RenderingReferenceを作成する必要があるため、異なるサブレイアウトを追加することはより困難です。これには、コンストラクタに必要なXML定義を実際に作成する必要があります。または、新しいレイアウトを定義する別のアイテムがある場合は、パイプラインの早い方でargs.ContextItemを変更するだけです。

+0

悲しいことに、私は自分の状況をずっと後で評価することはできません。それはデータベース呼び出しに依存しています。私はその時点でサブレイアウトを追加できると思っていましたが、正しく答えを読んでいればこれは不可能ですか? – Jon

+0

そのロジックとデータベース呼び出しについてさらに詳しく説明できますか?可能かもしれない。それ以外の場合は、ASPを変更する必要があります。おそらくPage OnInitでは、Sitecoreのレンダリングに依存するのではなく、自分自身で、おそらくPage OnInitでコントロールします。 – techphoria414

+0

私たちはそれとは異なる部分を持つ形をしており、それぞれの部分は異なるステップを持っています。データベース呼び出しは、サブレイアウトのInit中に行われます。これにより、フォームのどの部分がロードされるかが決まります。これらは、フォームアイテムの子アイテムによって表されます。私たちがやりたいことは、特定の部分/ステップでサイドバーに特定のサブレイアウトを表示することです。これは、フォームが必ずしも順番に実行されるわけではないため、データベース呼び出しを必要とします。私たちはどのパート/ステップを試して、その時点でサブレイアウトをドロップするかを考えていました。希望は何らかの意味を作った! – Jon

0

を、あなたが配置することはできません親コントロールのコンテナ内に「フォーム」コントロールとサイドバーがありますか?その後、フォームコントロールからプログラマチックにコントロールを条件付きで取り込むためのサイドバーコンテナのIDが簡単になります。

また、可能なすべてのコントロールをサイドバーに追加して、必要なコントロールをセッション状態変数を介して「アクティブ化」する(または見えるようにする)ことはできますか? (これがライフサイクルやタイミングの限界に惑わされているかどうかは分かりません)

+0

悲しいことに、私が必要とするレンダリングパラメータをレンダリングしたいサブレイアウトとして、Sitecoreシステムを実行する必要があります。また、このシステムの外でサイト上の他の場所で使用される可能性があるので、スタンドアロンにする必要があるという警告もあります。 – Jon

+0

Hmmm ...これらのオプションはどちらも、標準的なsitecoreプレゼンテーション設定と組み合わせて使用​​できます。 ? –

0

または、条件付きレンダリングルールを使用して、夢を見ることができるロジックに基づいてレンダリング/サブレイアウトを表示できます。

関連する問題