5

ページタイトルの上にある、ページごとに異なるメイン画像が必要だとします。また、左側のバーにページ固有の画像を配置し、右側のバーにページ固有のテキストを配置する必要があります。左右のバーには、レイヤー固有のコンテンツも必要です。

サイト内のすべてのページにレイヤーを作成せずにこれを実現する方法はわかりませんが、1ページしか提供しないレイヤーが多すぎて、複雑すぎるように見えます。

私は何が欠けていますか?

コンテンツパーツを使用してこれを行う方法がある場合は、チュートリアル、ブログ、ビデオを紹介して、問題を解決するのに役立てていただければ幸いです。

ノート:

Sitefinityはこの種のことをうまくやってくれますが、Orchardはモジュールを作成するのがはるかに簡単であり、MVCであるという事実もはるかに簡単です。

果樹園は無料です、私はそれを理解しています(そして感謝しています)。製品が進化するにつれて、この種のことがより簡単になることを願っていますか?

言い換えれば、私はすべての世界の最高のものを望んでいます...

4

2 に答える 2

5

1.5の作業にはそれを簡単にする機能がありますが、それまでの間、ほんの少しのコードでこれを非常に簡単に機能させることができます。まず、必要なフィールドをコンテンツタイプに追加する必要があります。次に、配置を使用してそれらをトップレベルのレイアウトゾーンに送信します。箱から出して、配置はローカルコンテンツゾーンのみを対象としていますが、これは、Pete Hurst、別名randompeteによる少しのコードで回避できるものです。コードは次のとおりです。

ZoneProxyBehavior.cs:
=====================

using System;
using System.Collections.Generic;
using System.Linq;
using ClaySharp;
using ClaySharp.Behaviors;
using Orchard.Environment.Extensions;

namespace Downplay.Origami.ZoneProxy.Shapes {
    [OrchardFeature("Downplay.Origami.ZoneProxy")]
    public class ZoneProxyBehavior : ClayBehavior {

        public IDictionary<string, Func<dynamic>> Proxies { get; set; }

        public ZoneProxyBehavior(IDictionary<string, Func<dynamic>> proxies) {
            Proxies = proxies;
        }

        public override object GetMember(Func<object> proceed, object self, string name) {

            if (name == "Zones") {
                return ClayActivator.CreateInstance(new IClayBehavior[] {                
                    new InterfaceProxyBehavior(),
                    new ZonesProxyBehavior(()=>proceed(), Proxies, self)
                });
            }

            // Otherwise proceed to other behaviours, including the original ZoneHoldingBehavior
            return proceed();
        }

        public class ZonesProxyBehavior : ClayBehavior {
            private readonly Func<dynamic> _zonesActivator;
            private readonly IDictionary<string, Func<dynamic>> _proxies;
            private object _parent;

            public ZonesProxyBehavior(Func<dynamic> zonesActivator, IDictionary<string, Func<dynamic>> proxies, object self) {
                _zonesActivator = zonesActivator;
                _proxies = proxies;
                _parent = self;
            }

            public override object GetIndex(Func<object> proceed, object self, IEnumerable<object> keys) {
                var keyList = keys.ToList();
                var count = keyList.Count();
                if (count == 1) {

                    // Here's the new bit
                    var key = System.Convert.ToString(keyList.Single());

                    // Check for the proxy symbol
                    if (key.Contains("@")) {
                        // Find the proxy!
                        var split = key.Split('@');
                        // Access the proxy shape
                        return _proxies[split[0]]()
                            // Find the right zone on it
                            .Zones[split[1]];
                    }
                    // Otherwise, defer to the ZonesBehavior activator, which we made available
                    // This will always return a ZoneOnDemandBehavior for the local shape
                    return _zonesActivator()[key];
                }
                return proceed();
            }

            public override object GetMember(Func<object> proceed, object self, string name) {
                // This is rarely called (shape.Zones.ZoneName - normally you'd just use shape.ZoneName)
                // But we can handle it easily also by deference to the ZonesBehavior activator
                return _zonesActivator()[name];
            }
        }
    }
}

と:

ZoneShapes.cs:
==============


using System;
using System.Collections.Generic;
using Orchard.DisplayManagement.Descriptors;
using Orchard;
using Orchard.Environment.Extensions;

namespace Downplay.Origami.ZoneProxy.Shapes {
    [OrchardFeature("Downplay.Origami.ZoneProxy")]
    public class ZoneShapes : IShapeTableProvider {
        private readonly IWorkContextAccessor _workContextAccessor;
        public ZoneShapes(IWorkContextAccessor workContextAccessor) {
            _workContextAccessor = workContextAccessor;
        }

        public void Discover(ShapeTableBuilder builder) {

            builder.Describe("Content")
                .OnCreating(creating => creating.Behaviors.Add(
                    new ZoneProxyBehavior(
                        new Dictionary<string, Func<dynamic>> { { "Layout", () => _workContextAccessor.GetContext().Layout } })));
        }
    }

}

Layout@これにより、たとえば、アドレス指定するゾーン名の前を使用して、最上位のレイアウトゾーンをアドレス指定できるようになりますLayout@BeforeContent:1

于 2012-05-28T19:41:59.723 に答える
4

補遺:

Bertrand Le Royのコード(Pete Hurstのコードを作成)を使用してモジュールを作成し、Core/Commonのボディパーツのすべてのコピーである3つのコンテンツパーツを追加しました。

同じモジュールで、ContentTypeを作成し、それに3つのカスタムContentPartを追加し、さらにautoroute、bodypart、tagsなどを追加して、Orchard Pages ContentTypeと同じようにしましたが、それぞれ独自の形状のパーツを追加しました。

ContentTypeをビューと呼びました。

これで、ビューを使用してサイトのページを作成できます。次に、ZoneProxyを使用して、カスタムContentPartシェイプ(Parts_MainImage、Parts_RightContent、Parts_LeftContent)を、必要なゾーンにシャントします。これで作業は完了です。

Sitefinityとは言えませんが、Billが言うように、十分です。

TextFieldを使用するのではなく、BodyPartをコピーする独自のContentPartを作成する必要がある理由は、すべてのTextFieldが同じShapeを持っているため、ZoneProxyを使用して配置すると、すべて同じゾーンに配置されるためです。つまり、Shapesを取得するために、カスタムContentPartsをビルドするだけです。これは、ZoneProxyコードを使用して配置する形状です。

これをテストしたら、モジュールとしてオーチャードギャラリーにアップロードします。これはWingspan.Viewsと呼ばれます。

私は2012年6月12日まで休暇を取っているので、月末までは期待しないでください。

しかし、本質的には、Pete Hurstのコードを使用して、それが私の問題を解決した方法です。

編集:

3つのコンテンツ部分(LeftContent、RightContent、MainImageなど)または必要なコンテンツ部分を作成し、それらをPageコンテンツタイプに追加するだけで、同じ結果を得ることができます。

そうすれば、必要なものだけを追加できます。

ただし、そのまま使用できる標準のContentTypeを使用することにはいくつかの利点があります。

配置(Placement.infoファイル)を使用すると、たとえば、フッターにMainImageコンテンツ部分を使用できます。つまり、名前はおそらくパート1、パート2などである必要があります。

TextFieldによって生成された形状にカスタム名を付ける方法があれば、これは必要ありません。そうすれば、TextFieldsを好きなように追加して、ZoneProxyコードを使用して配置できます。これが可能かどうかはわかりません。

于 2012-06-02T16:23:00.193 に答える