Asp.net mvc Orchard CMS有条件地隐藏小部件和抑制区域

Asp.net mvc Orchard CMS有条件地隐藏小部件和抑制区域,asp.net-mvc,orchardcms,orchardcms-1.7,Asp.net Mvc,Orchardcms,Orchardcms 1.7,我试图有条件地从其驱动程序中抑制小部件。我基本上有这样的逻辑,如果满足,应该显示小部件,如果不满足,应该抑制它。小部件从当前页面内容项加载属性,并根据某些属性显示或隐藏。我已经完成了所有的逻辑工作,只剩下抑制实际输出的部分了 我已经尝试从驱动程序返回null,但是这只是输出一个空的小部件(及其包装器)。如何从视图中完全删除小部件 最后,如果没有任何条件小部件显示,则放置该小部件的区域应该被抑制 果园里有这种灵活性吗?最好是从我的自定义模块而不是我的主题,我正在尝试将功能与样式分离 编辑: 以下是

我试图有条件地从其驱动程序中抑制小部件。我基本上有这样的逻辑,如果满足,应该显示小部件,如果不满足,应该抑制它。小部件从当前页面内容项加载属性,并根据某些属性显示或隐藏。我已经完成了所有的逻辑工作,只剩下抑制实际输出的部分了

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

最后,如果没有任何条件小部件显示,则放置该小部件的区域应该被抑制

果园里有这种灵活性吗?最好是从我的自定义模块而不是我的主题,我正在尝试将功能与样式分离

编辑:

以下是我的处境和我正在努力实现的目标。我确信,在Orchard中有一种比我第一次天真地设计它更干净的方法:我的客户的文案撰写人在他们认为合适的时候标记页面(使用标记模块/部分)。我已经创建了两种自定义内容类型,“推荐”和“优惠”,这两种类型都带有标签和其他属性(由不同的文案撰写团队管理)

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


他们抓取当前页面的标签,然后随机抽取一个包含任何匹配标签的[推荐报价]。给定任何内部页面,可能会发生4种情况:显示推荐信息并隐藏报价(推荐标记匹配,报价标记未匹配),隐藏推荐信息并显示报价,同时显示推荐信息和报价,最后两者都不显示。前3个用例工作得很好,第4个是我遇到的困难,因为侧边栏[zone]仍然显示,即使两个小部件都不显示(从各自的驱动程序返回null)。

不幸的是,我不得不使用一些技巧,以便在紧迫的期限内继续进行项目,但如果有更好的方法和/或解决方案,我会在有机会时进行测试,并将分数作为答案

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

然后只需将页眉和页脚之间的
@显示(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;
};
Func CollapsableZone=x=>
{
var显示=显示(x);
字符串zoneName=x.zoneName;
if(string.Equals(display.ToString()、string.Format(“、zoneName.HtmlClassify())、StringComparison.CurrentCultureIgnoreCase))
{
返回新的HtmlString(string.Empty);
}
返回显示;
};
一个简单的函数,将display调用分配给变量,检查它是否为空区域标记,然后返回。然后,我为分配给上述函数值的每个区域创建变量。我将所有
@if(Model.ZoneName!=null)
替换为
@if(!string.IsNullOrWhiteSpace(zoneVariable))
,并将对
@Zone(Model.ZoneName)
的调用替换为
@(zoneVariable)


这是暂时有效的。这是一个非常简单和脆弱的解决方案,但我不得不转移到其他方面。

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


因此,您所描述的内容不应该实现为小部件(您为使其工作所做的一切进一步证明了这一点),因为它们实际上是内容项的一部分。相反,您应该实现一个部件或字段。然后,您可以使用placement,通过指定顶级区域,简单地为字段的这一部分放置形状:

,这正是层所做的。创建一个层,在其中抛出显示或隐藏小部件的规则,完成。我不能在层中包含逻辑,显示的逻辑在小部件中(基于它所在的当前页面的属性)。这一切都正常(意味着小部件正确地按照逻辑执行,如果不满足,则正确地“隐藏”(从驱动程序返回null)。一个层可能有多个“条件”窗口小部件。它应该仍然显示是否有1个窗口小部件被显示/激活,但如果所有窗口小部件子项都没有显示,它将崩溃。为了进一步澄清,为什么不能将逻辑包含在层规则中?这正是层的设计目的。当逻辑范围为页面范围时,层非常好。在我的情况下,逻辑范围为wid获取,而不是页面。我的“侧边栏”有两个小部件,它们彼此独立运行。一个小部件查找显示页面的标记,并显示具有相同标记的随机“推荐”(自定义部分/类型)。类似地,第二个小部件查找页面标记,并显示随机“报价”(另一个自定义部分/类型)使用相同的标签。字符用完…在某些页面上,可能只有一个匹配的“推荐”小部件,在其他页面上,可能只有一个匹配的“报价”小部件,在另一个页面子集上,可能有推荐和报价小部件,最后在其他页面上可能没有匹配的小部件[这是我的问题涉及的边缘案例].我不知道在哪些页面上显示哪个组合,所以我无法创建la
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;
};