我试图有条件地从其驱动程序中抑制一个小部件。我基本上有逻辑,如果遇到,应该显示小部件,如果没有,应该抑制它。窗口小部件从当前页面内容项加载属性,并基于应显示或隐藏的某些属性。我已经完成了所有逻辑工作,剩下的唯一部分就是抑制实际输出。
我已经尝试从驱动程序返回null,但是这只是输出一个空的小部件(带有它的包装器)。如何从视图中完全删除小部件?
最后,放置此窗口小部件的区域应禁止显示任何条件窗口小部件。
Orchard的这种灵活性是否可行?最好从我的自定义模块而不是我的主题,我试图将功能与样式分开。
编辑:
以下是我的情况以及我想要完成的事情。我确信在Orchard中有一个更清洁的方法,比我在第一次复飞时天真地设计它:我的客户的copywriters标记页面,他们认为合适(使用Tags模块/部分)。我创建了2种自定义内容类型,“推荐”和“优惠”,这些内容类型都有标签本身和其他属性[这些由不同的撰稿人团队管理]。
在网站的大多数“内部页面”上(我使用图层来确定适当的页面),页面的侧边栏会获得“推荐”窗口小部件和“优惠”窗口小部件。这些小部件的运行方式相同,但彼此独立:
他们抓取当前页面的标签,然后拉随机[Testimonial | Offer],它也有任何匹配的标签。在任何内页面上都会发生4种情况:显示推荐信并隐藏优惠(推荐标签匹配,商品标签没有),隐藏推荐书并显示优惠,显示推荐和优惠,最后都没有显示。前3个用例运行良好,第4个是我遇到的困难,因为侧边栏[区域]仍然显示,即使两个小部件都没有(从各自的驱动程序返回null)。
答案 0 :(得分:2)
关于小部件的一些上下文:小部件应该是在网站的某些或所有页面上可见的内容,并且提供与页面上的主要内容项不直接相关的信息(如果有的话)是这样的事情。)
因此,您所描述的内容不应该被实现为小部件(所有您必须做的才能使其工作证明更进一步),因为它们实际上是内容项的一部分。相反,您应该已经实现了部分或字段。然后,您可以通过指定顶级区域,使用展示位置简单地为此部分字段放置形状:<place the_shape_name="/the_zone_where_you_want_it:1"/>
答案 1 :(得分:0)
不幸的是,我不得不使用一些黑客,以便我可以继续使用该项目,因为我处于激进的最后期限,但如果有更好的方法和/或解决方案,我会测试我抓住机会并标记为答案。
为了让它工作,我在我的主题中覆盖了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)
。
这暂时有效。这是一个非常破旧和脆弱的解决方案,但我不得不转向其他事情。