Orchard CMS условно скрывает виджет и подавляет зону

Я пытаюсь условно отключить виджет от его драйвера. У меня в основном есть логика, что если встретил, должен отображать виджет, а если нет, должен его подавить. Виджет загружает свойства из текущего элемента содержимого страницы, и на основе некоторых свойств должен отображаться или скрываться. У меня вся логика работает, единственная оставшаяся часть - это подавление фактического вывода.

Я попытался вернуть ноль из драйвера, однако это просто выводит пустой виджет (с его оберткой). Как полностью удалить виджет из вида?

Наконец, зона, в которой находится этот виджет, должна подавляться, если ни один из условных виджетов не отображается.

Возможен ли этот тип гибкости в саду? Предпочтительно из моего пользовательского модуля, а не из моей темы, я пытаюсь отделить функциональность от стиля.

РЕДАКТИРОВАТЬ:

Вот контекст моей ситуации и то, что я пытаюсь достичь. Я уверен, что в Orchard есть гораздо более чистый способ сделать это, чем то, как я наивно спроектировал это в качестве первого шага: копирайтеры моего клиента помечают страницы так, как они считают нужным (используя модуль / часть Tags). Я создал 2 пользовательских типа контента, "Отзывы" и "Предложения", оба с самими тегами и другими свойствами [ими управляет другая команда копирайтеров].

На большинстве "внутренних страниц" веб-сайта (я использую слой для определения соответствующих страниц) боковая панель страницы получает виджет "Отзыв" и виджет "Предложение". Эти виджеты работают одинаково, но независимо друг от друга:

Они берут теги текущей страницы, а затем выбирают случайный [Отзыв | Предложение], который также имеет любые подходящие теги. На любой внутренней странице может произойти 4 случая: отображается отзыв, а предложение скрыто (тег совпадения совпал, тег предложения не был), отзыв скрыт, и отображается предложение, как отображение отзыва, так и предложения, и, наконец, ни один не отображает. Первые 3 варианта использования работают отлично, 4-й - это то, с чем я сталкиваюсь, так как боковая панель [зона] по-прежнему отображается, даже если оба виджета нет (возвращая ноль из соответствующих драйверов).

2 ответа

Решение

Немного контекста о виджетах: виджеты должны быть частями содержимого, которые видны на некоторых или всех страницах сайта, и которые предоставляют информацию, которая не имеет прямого отношения к основному элементу контента на странице (если есть такой вещь).

Как следствие, то, что вы описываете, не должно быть реализовано в виде виджетов (все, что вам нужно было сделать, чтобы это работало, свидетельствует об этом в дальнейшем), потому что они действительно являются частью элемента контента. Вместо этого вы должны были реализовать часть или поле. Затем вы можете просто поместить форму для этой части поля, используя размещение, указав зону верхнего уровня: <place the_shape_name="/the_zone_where_you_want_it:1"/>

К сожалению, мне пришлось немного взломать, чтобы я мог продолжить работу над проектом, поскольку у меня агрессивный крайний срок, но если есть лучший метод и / или решение, я протестирую, как только получу шанс и отметьте как ответ.

Чтобы заставить его работать, я переписал файл Widget.Wrapper.cshtml в своей теме. Там я назначил переменную для вызова Display(Model.Child), и, если результатом будет пустая строка, просто вернемся. Это удаляет все пустые теги обтекания виджетов. (Я лично считаю, что Орчард должен вести себя так по умолчанию):

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),

Это работает в настоящее время. Это довольно взломанное и хрупкое решение, но мне пришлось перейти к другим вещам.

Другие вопросы по тегам