【问题标题】:Orchard CMS conditionally hide widget and suppress zoneOrchard CMS 有条件地隐藏小部件并抑制区域
【发布时间】:2014-03-05 20:54:40
【问题描述】:

我正在尝试有条件地从其驱动程序中抑制一个小部件。我基本上有逻辑,如果遇到,应该显示小部件,如果没有,应该抑制它。小部件从当前页面内容项加载属性,并根据某些属性显示或隐藏。我已经完成了所有的逻辑工作,剩下的唯一部分就是抑制实际输出。

我尝试从驱动程序返回 null,但这只是输出一个空的小部件(及其包装器)。如何从视图中完全删除小部件?

最后,如果没有显示任何条件小部件,则放置此小部件的区域应禁止显示。

这种灵活性在 Orchard 是否可行?最好从我的自定义模块而不是我的主题中,我试图将功能与样式分开。

编辑:

这是我的情况以及我想要完成的任务。我敢肯定,在 Orchard 中,有一种比我在第一次尝试时天真地设计它的方式更简洁的方法:我的客户的撰稿人在他们认为合适的时候标记页面(使用标签模块/部分)。我创建了 2 种自定义内容类型,“推荐”和“优惠”,它们本身都带有标签以及其他属性 [这些由不同的文案团队管理]。

在网站的大多数“内页”(我使用层来确定合适的页面)上,页面的侧边栏有一个“推荐”小部件和一个“报价”小部件。这些小部件的操作相同,但彼此独立:

他们抓取当前页面的标签,然后随机抽取一个包含任何匹配标签的 [Testimonial|Offer]。任何内页都可能发生 4 种情况:显示推荐并隐藏报价(推荐标签匹配,报价标签不匹配),隐藏推荐并显示报价,推荐和报价都显示,最后都没有显示。前 3 个用例运行良好,第 4 个用例是我遇到的困难,因为即使两个小部件都没有显示侧边栏 [zone](从各自的驱动程序返回 null)。

【问题讨论】:

  • 这正是图层正在做的事情。创建一个图层,将您的规则用于在其中显示或隐藏小部件,完成。
  • 我不能在图层中包含逻辑,显示的逻辑在小部件中(基于它所在的当前页面的属性)。这一切正常(意味着小部件正在针对逻辑正确执行,如果未满足,则正确“隐藏”(从驱动程序返回 null)。一个层可能有多个“条件”小部件。它仍应显示是否有 1 个小部件显示/活动,但如果所有小部件子项均未显示,则折叠。为了进一步说明,
  • 为什么不能在层规则中包含逻辑?这正是层的设计目的。
  • 当逻辑范围为 PAGE 宽时,层非常好。在我的情况下,逻辑的范围是小部件,而不是页面。我的“侧边栏”有 2 个小部件,它们彼此独立运行。 1 小部件查找显示页面的标签,并显示具有相同标签的随机“推荐”(自定义部分/类型)。同样,第二个小部件查找页面标签并显示具有相同标签的随机“报价”(另一个自定义部分/类型)。
  • 字符用完了...在某些页面上,可能只有一个匹配的“推荐”小部件,在其他页面上,可能只有一个匹配的“报价”小部件,在另一个页面子集上可能既有推荐小部件,也有报价小部件,最后在其他小部件上可能没有匹配的小部件[这是我的问题所涉及的边缘情况]。我不知道要在哪些页面上显示哪个组合,所以我无法创建图层来处理这个问题。一切正常,除了页面没有匹配的推荐或报价小部件时。我得到一个“空白”侧边栏区域,我该如何缓解?

标签: asp.net-mvc orchardcms orchardcms-1.7


【解决方案1】:

关于小部件的一些上下文:小部件应该是在网站的部分或所有页面上可见的内容片段,并且提供与页面上的主要内容项不直接相关的信息(如果有是这样的)。

因此,您所描述的内容不应被实现为小部件(您必须做的所有事情才能进一步证明这一点),因为它们实际上是内容项的一部分。相反,您应该已经实现了一个部分或一个字段。然后,您可以通过指定顶级区域来简单地放置这部分字段的形状,使用放置:<place the_shape_name="/the_zone_where_you_want_it:1"/>

【讨论】:

  • 嘿,Bertrand,我想了很多,还在学习:)。您能否详细说明实现这一点的正确方法?创建零件如何工作?我创建了一个部分(包括引用 [body]、作者 [text] 的推荐部分)以及一个推荐类型,以便他们可以创建他们的推荐。我无法将推荐部分添加到页面类型,某些页面共享相同的推荐“桶”(具有相同的标签),并且推荐不一定与页面耦合。小部件用于连接推荐和页面,但是,推荐可以在其他地方使用。
  • 为什么不能在页面类型中添加推荐部分?
  • 因为推荐书没有与页面耦合。这不会迫使内容管理者在不同的页面上创建许多重复的推荐吗?因此,对于有 5 个页面的网站“部分”,其中应该显示 1 个(假设)10 个池的随机推荐,这将迫使他们创建 50 个推荐,5 个重复的 10 组。同样的事情X 页面的不同部分和 Y 推荐池。
  • 没有。想想内容项选择器。
  • 感谢您对这个 Bertrand 的帮助!我不敢相信内容项目选择器没有出现在我的脑海中。我还没来得及试一试,但已经可以看出这是要走的路。我会把它标记为答案,再次感谢!
【解决方案2】:

不幸的是,我不得不使用一些技巧,以便我可以继续进行该项目,因为我的截止日期很紧迫,但如果有更好的方法和/或解决方案,我会测试我抓住机会并标记为答案。

为了让它工作,我在我的主题中覆盖了 Widget.Wrapper.cshtml 文件。在那里,我为 Display(Model.Child) 调用分配了一个变量,如果结果为空字符串,则简单地返回。这将删除任何空的小部件包装标签。 (我个人觉得 Orchard 默认应该是这样的):

var child = Display(Model.Child);

// -- NOTE: shape tracing breaks this logic!
if (string.IsNullOrWhiteSpace(child.ToString())) {
    return;
}

然后只需将页眉和页脚之间的@Display(Model.Child) 替换为@(child)

然后我将以下方法添加到我的 Layout.cshtml 文件中。

Func<dynamic, IHtmlString> CollapsableZone = x =>
{
    var display = Display(x);
    string zoneName = x.ZoneName;
    if (string.Equals(display.ToString(), string.Format("<div class=\"zone zone-{0}\"></div>", zoneName.HtmlClassify()), StringComparison.CurrentCultureIgnoreCase))
    {
        return new HtmlString(string.Empty);
    }
    return display;
};

将显示调用分配给变量的简单函数,检查它是否为空区域标记,然后返回。然后,我为分配给上述函数值的每个区域创建变量。我将所有@if (Model.ZoneName != null) 替换为@if (!string.IsNullOrWhiteSpace(zoneVariable)),并将对@Zone(Model.ZoneName) 的调用替换为@(zoneVariable)

这暂时有效。这是一个相当简单的解决方案,但我不得不继续做其他事情。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-18
    • 1970-01-01
    • 2020-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多