Сайт-визитка

от 14 000 рублей

Каталог

от 19 000 рублей

Магазин

от 30 000 рублей

Про hook_library_alter на примере Яндекс.Карт

Есть в Drupal 7 такая замечательная возможность — упаковать набор CSS и JS в библиотеку, и подключать потом одним разом. Достигается эта радость объявлением библиотеки через hook_library() и подключением — через drupal_add_library().

И есть такой модуль — Yandex.Maps, тоже хороший во всех отношениях. Нет только в нём (по крайней мере, в текущей версии) очевидной возможности скрыть поле карты для той или ноды. Простым способом скрыть карту «в лоб» было бы добавление чекбокса «Показать карту» и вот такой примитивный JavaScript:

(function ($) {
  $(document).ready( function() {
    $('input#edit-field-ymap-show-und').click(hideShowYmap);
    //если галочки нет, карту надо по-умолчанию скрыть заранее
    if (!$('input#edit-field-ymap-show-und').is(':checked')) {
      $('#edit-field-ymap').hide();
    }
  });
 
  function hideShowYmap() {
    $('#edit-field-ymap').toggle(400);
  }

})(jQuery);

Поле чекбокса тут называется field_ymap_show, а поле Яндекс.Карты — field_ymap.

Добавив этот скрипт на страницах редактирования нод с полем Яндекс.Карты, мы сможем скрывать див с картой если галочка убрана, и экономить место в форме.

Однако тут есть одна неприятность: если карта по умолчанию скрыта, то при установке чекбокса «Показать карту» мы увидим, что в развернутом диве с картой — карты либо нет, либо от нее осталась лишь маленькая полоска. Так получается потому, что в момент вызова нашего обработчика $(document).ready() API Яндекс.Карт еще не готов и карта не инициализирована.

Руководство по API Яндекс.Карт подсказывает, что правильный способ дождаться готовности карты — использование объекта ymaps. Можно просто заменить $(document).ready() на ymaps.ready(). Но объекта ymaps нашему скрипту не видно.

Но зато его видно из скриптов библиотеки yamaps! Посмотрим на реализацию хука hook_library() в модуле и увидим там библиотеку:

function yamaps_library() {
  //...
  $libraries['yamaps.full'] = array(
    //...
    'js' => array(
      $api_url => array(
        'type' => 'external',
        'scope' => 'footer',
        'weight' => $w++,
      ),
      $path . 'yamaps.init.js' => array('scope' => 'footer', 'weight' => $w++),
      //...
      $path . 'yamaps.run.js' => array('scope' => 'footer', 'weight' => $w++),
    ),
  );
  return $libraries;
}

Просто возьмем и прицепим наш маленький скрипт к самой библиотеке — такая возможность у нас есть благодаря хуку hook_library_alter():

function mymodule_library_alter(&$libraries, $module) {
  if ($module == 'yamaps') {
    $js_addr = drupal_get_path('module', 'mymodule') . '/mymodule_hide_ymap.js';
    $libraries['yamaps.full']['js'][$js_addr] = array(
      'scope' => 'footer',
      'weight' => 100,
    );
  }
}

Теперь наш скрипт — неотъемлемая часть библиотеки, куда она — туда и он. И даже следить за подключением не надо.