Условно показать / скрыть блоки в макете XML

32

Как условно добавить блок (в зависимости от конфигурации в админ-панели) в макет Magento XML?

Мы можем проверить, является ли config верным для действий. В приведенном ниже примере, если sample/config/show_toplinksconfig из панели администратора (в System-> Configuration) имеет значение true , тогда файл шаблона links.phtmlбудет использоваться для визуализации Top Links. Если sample/config/show_toplinksэто ложь , то будет использоваться шаблон по умолчанию.

<reference name="top.links">
    <action method="setTemplate" ifconfig="sample/config/show_toplinks">
        <template>page/template/links.phtml</template>
    </action>
</reference>

Я нашел этот обходной путь где-то в сети. Мы можем установить пустой шаблон в качестве шаблона по умолчанию для Top Links, например так:

<reference name="top.links">
    <action method="setTemplate" ifconfig="sample/config/show_toplinks">
        <template>page/template/links.phtml</template>
    </action>

    <!-- OR set completely empty template -->
    <action method="setTemplate">
        <template>page/template/empty_template_for_links.phtml</template>
    </action>
</reference>

В этом случае, если sample/config/show_toplinksэто правда , то шаблон links.phtmlбудет использоваться и будет отображаться Top Links. но если sample/config/show_toplinksэто ложь , то empty_template_for_links.phtmlшаблон будет использоваться , и этот шаблон полностью пуст, поэтому он не возвращает HTML и Top ссылка не будет видна.

  1. Есть ли другой способ условно показать или скрыть блоки в зависимости от конфигурации в админ-панели?
  2. Этот обходной путь безопасен?
  3. Может ли это привести к неожиданным ошибкам?

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

Исходя из всех ответов, я думаю, что решение Рика Койперса выглядит наиболее удобным для моего случая. Но у меня есть еще один связанный вопрос:

    <block type="core/template" name="my_block" template="my/block.phtml" />
    <!-- ...add more blocks here -->

    <reference name="footer">
        <action method="append" ifconfig="sample/config/show_toplinks">
            <block>my_block</block>
        </action>
        <!-- ...append more blocks here -->
    </reference>

Если мне нужно добавить много таких блоков (используя appendметод и ifconfig), скажем, 50, это влияет на производительность ? Только некоторые из блоков будут действительно отображаться (это зависит от настроек пользователя в System -> Config), но мне нужно добавить все эти блоки, прежде чем я добавлю их внутрь <reference name="footer">...</reference>.

Magento мгновенно обрабатывает все добавленные блоки, как это?

    <block type="core/template" name="my_block" template="my/block.phtml" />

Или блоки обрабатываются, только если они должны быть окончательно отображены в шаблоне? Так будет ли Magento обрабатывать все мои 50 блоков, несмотря на то, что нужно отображать только некоторые из этих блоков?

zitix
источник

Ответы:

28

Я хотел бы добавить свой вариант, а не ответ бенчмарков.

Мой подход заключается в использовании действия добавления:

    <block type="core/template" name="my_block" template="my/block.phtml" />
    <reference name="head">
        <action method="append" ifconfig="myblock/general/enabled"><block>my_block</block></action>
    </reference>
Рик Кейперс
источник
1
Это может применяться в определенных случаях (и это было моей первоначальной мыслью), однако в этом случае рассматриваемый блок ( top.links ) вызывается по умолчанию из ядра.
отметки
@марки ах ты имеешь ввиду ради модульности? Тогда ваш подход будет лучшим подходом в этом случае.
Рик Кейперс
1
@RickKuipers 1. Можете ли вы уточнить, как работает этот метод «добавления»? Будет ли он перемещаться my_blockвнутри «головы», или он добавит еще одну копию этого блока внутри «головы», и первая копия все равно будет отображаться где-то еще (как блок уже был добавлен ранее <reference name="head">)? 2. В каком файле PHP я могу найти все эти методы компоновки, такие как "append" или "unsetChild"?
Zitix
1
@zitix Если определение блока находится в <reference name="root">(или любом другом не core/text_listблоке), то оно не будет автоматически отображаться, если оно не вызывается getChildHtml(). Он не будет перемещать блок, он будет копией, поэтому вы можете добавить его несколько раз. <action>вызывает метод в блоке. Так что это зависит от того, о каком блоке мы говорим. Вы можете найти несколько стандартных в Mage_Core_Block_Abstract. Но любой метод, принадлежащий блоку, может быть вызван с помощью <action>.
Рик Кейперс
@RickKuipers А как этот метод влияет на производительность? (Я отредактировал свой вопрос) Блок необходимо добавить, <block type="core/template" name="my_block" template="my/block.phtml" />даже если он не будет окончательно отображен.
zitix
15

Использование _templateсвойства для скрытия вывода является новым подходом. Я бы предпочел обратить значения в опции config так, чтобы Yes = 0 (возможно, пользовательская исходная модель), и вызвать unsetChildродительский головной блок:

<reference name="head">
    <action method="unsetChild" ifconfig="sample/config/show_toplinks">
       <child>topLinks</child>
    </action>
</reference>
benmarks
источник
1
Спасибо, это очень хорошо, но требует инвертирования всех полей конфигурации в System -> Config. Мне нужно было бы измениться: Top Links: [enable/disable]на что-то подобное Hide Top Links: [Yes/No].
zitix
1
Исходные модели для конфигурации системы невероятно просты, и этот путь гораздо менее сложен, чем добавление пользовательского дескриптора обновления макета через обозреватель.
отметки
12

Что касается ваших вопросов:

  1. Мой метод только расширяет ваш

  2. Я не могу понять, почему это не будет

  3. Опять же, ваш код довольно безопасен для методов, которые не будут вызывать исключения (например getStoreConfig, просто будут возвращать ложные значения, поэтому ваш условный дескриптор не будет добавлен), но вы получите исключение, если пустой файл шаблона не существует. Используйте самозакрывающийся тег для передачи пустого значения (например <template />)

Если бы я разрабатывал это, я бы расширил ваше решение, включив в него наблюдателя, который проверяет конфигурацию и условно добавляет дескриптор в ваш макет. Затем в файле макета вы можете установить оба действия в разных дескрипторах defaultиshow_toplinks

<config>
  <global>
    <!-- stuff -->
    <events>
      <controller_action_layout_load_before>
        <observers>
          <my_module_add_handle>
            <class>my_module/Observer</class>
            <method>addHandle</method>
          </my_module_add_handle>
        </observers>
      </controller_action_layout_load_before>
    </events>
    <!-- other stuff -->
  </global>
</config>

И тогда в вашей Observerмодели ...

public function addHandle(Varien_Event_Observer $observer)
{
    if (Mage::getStoreConfig('sample/config/toplinks') {
        $observer->getEvent()->getLayout()->getUpdate()
            ->addHandle('show_toplinks');
    }
}

Аааа наконец в твоем макете

<default>
  <reference name="top.links">
     <!-- yup -->
  </reference>
</default>

<show_toplinks>
  <reference name="top.links">
     <!-- another yup -->
  </reference>
</show_toplinks>
теплый морской полярный воздух
источник
Спасибо, я этого не знал, я обязательно буду использовать этот метод в будущем. Но для того, что мне нужно сделать сейчас, требуется слишком много дополнительного кода.
zitix