1

これが私がやろうとしていることです:

「カルーセル プレゼンター」というコンテンツ アイテムがあります。基本的に、これはその子アイテムをカルーセル内に表示します。任意の数の子アイテムを持つ柔軟性が必要です。また、各子アイテムのプレゼンテーションを指定できる柔軟性も必要です。それらは同じでも異なっていてもかまいません。Sitecore 6.5 を使用しています。

カルーセルは jcarousel です。一般的に次のようなマークアップを生成する必要があります (項目「Carousel Presenter」から):

<div class="jcarousel">
    <ul>
        <li> ... MARKUP FROM ITEM 1 ... </li>
        <li> ... MARKUP FROM ITEM 2 ... </li>
        ... and so on
    </ul>
</div>

これが私が試したことです:

  • サブレイアウト「carousel presenter.ascx」を作成、マークアップ:

コードビハインド:

  protected void Page_Load(object sender, EventArgs e)
    {
        // Get all children and render them inside the <ul>
        var kids = Sitecore.Context.Item.GetChildren();
        foreach (Item snippet in kids)
        {
            // RENDER THE ITEMS HERE INTO THE PLACEHOLDER...
            // 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
            carouselItemsPh.Controls.Add(sublayout);
        }
    }

このコードの大部分はここから盗んだことに注意してください: Sitecore アイテムのレイアウトを一時的に変更する

  • コンテンツ ツリーで、コンテンツ アイテム「カルーセル プレゼンター」の下に子アイテムを作成しました。これは「カルーセル アイテム」であり、サブレイアウト コントロールがそれぞれに割り当てられています (構成/レイアウトの標準値を介して)。

すべて公開されています。

テスト ページのマークアップをヒットすると、子アイテム (「カルーセル アイテム」) ごとに生成され、カルーセルは機能しますが、データソースが適切に割り当てられていないようです - すべての子アイテムのデータソース/コンテキストが親です子コントロールを作成するときにデータソースを明示的に設定したにもかかわらず、項目。これを修正するにはどうすればよいですか?

Sitecore 6.5 で達成しようとしていることに対して、より良いアプローチはありますか?

ありがとう

4

2 に答える 2

2

子項目のユーザー コントロール/サブレイアウトは、プログラムでデータ ソースを読み取る必要があります。この仕事のために、ユーザーコントロールのデータソースの問題を処理する独自の「ベース」サブレイアウトクラスを常に持っています。基本クラスでは、データソースが設定されていない場合、デフォルトで Sitecore.Context.Item を使用します。コードは次のとおりです。

public class SublayoutBase : UserControl
{
    private Item _dataSource;

    public Item DataSource
    {
        get
        {
            if (_dataSource == null)
            {
                if (Parent is Sublayout)
                {
                    _dataSource =
                        Sitecore.Context.Database.GetItem(((Sublayout)Parent).DataSource);
                }
                if (_dataSource == null)
                {
                    _dataSource = Sitecore.Context.Item;
                }
            }
            return _dataSource;
        }
    }

    protected override void OnLoad(EventArgs e)
    {
        foreach (Control c in Controls)
        {
            SetFieldRenderers(DataSource, c);
        }
        base.OnLoad(e);
    }

    private void SetFieldRenderers(Item item, Control control)
    {
        if (item != null)
        {
            var ctrl = control as Sitecore.Web.UI.WebControl;
            if (ctrl != null && !string.IsNullOrEmpty(ctrl.DataSource))
            {
                //don't set the source item if the DataSource has already been set. 
                return;
            }
            if (control is FieldRenderer)
            {
                var fr = (FieldRenderer)control;
                fr.Item = item;
            }
            else if (control is Image)
            {
                var img = (Image)control;
                img.Item = item;
            }
            else if (control is Link)
            {
                var link = (Link)control;
                link.Item = item;
            }
            else if (control is Text)
            {
                var text = (Text)control;
                text.Item = item;
            }
            else
            {
                foreach (Control childControl in control.Controls)
                {
                    SetFieldRenderers(item, childControl);
                }
            }
        }
    }
}
于 2013-07-24T14:26:41.210 に答える