Orchard CMS:当每个页面的特定内容分布在不同的列中时,是否必须为每个页面添加新图层?

awr*_*ley 5 orchardcms

假设我想为页面标题上方的每个页面添加不同的主图像.此外,我需要在左侧栏中放置页面特定的图像,并在右侧栏中放置页面特定的文本.在左右栏中,我还想要特定于图层的内容.

我不知道如何在不为网站中的每个页面创建一个图层的情况下实现这一目标,但最终我得到了大量的图层,这些图层只能提供一个看起来过于复杂的页面.

我错过了什么?

如果有一种方法可以使用内容部分进行此操作,那么如果您可以指导我阅读教程,博客,视频以帮助我解决问题,那就太棒了.

注意:

Sitefinity做得很好,但是我发现Orchard更容易创建模块,而且事实上它是MVC,我发现它更容易.

果园是免费的,我理解(并欣赏).只是希望随着产品的发展这种事情会更容易吗?

换句话说,我希望世界上最好的......

Ber*_*Roy 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];
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

和:

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

}
Run Code Online (Sandbox Code Playgroud)

有了这个,您将能够使用Layout@您要寻址的区域名称前面的顶级布局区域Layout@BeforeContent:1.