среда, 5 мая 2010 г.

Модули к Drupal, ожидающие моего свободного времени

Появилась необходимость перечислить модули, которые я собираюсь доработать и опубликовать на drupal.org (благо, теперь у меня есть подтвержденный CVS-аккаунт). Здесь же будут перечислены и уже опубликованные модули. Сообщение будет изменяться, пополняться, следите за изменениями.
  • Taxonomy Menu Trails (опубликован) - если у ноды нет собственного пункта меню, но у термина, к которому привязана эта нода, есть пункт меню, то менюшка будет открыта так, чтобы показывать пункт меню с термином. Это сильно упрощает построение каталогов, где в меню только термины, а ноды представлены списками по терминам.
  • Dynarray (не опубликован, готов на 80%) - модуль, расширяющий Form API. Добавляет тип элемента dynarray - массивы элементов, которые можно добавлять/удалять динамически. Можно прямо в описании указывать то, каким будет один элемент, или указать функцию для генерации одного элемента (например, когда ранее сохраненные элементы должны отличаться от вновь добавленных). Позволяет полностью избавиться от этой головной боли при написании форм. (Пометка для себя: проект orion)
  • GT Select, GT Checkbox, GT Radio (не опубликованы) - модули для темизации таких традиционно тяжело стилизуемых элементов страницы как списки для выбора, радиокнопки, галки. Для GT Select в качестве бонуса можно будет включить поле для фильтрации списка элементов. Возможно, будут выпущены еще и как jQuery-модули.
  • Tiny Menu Editor (опубликован) - очень простой модуль, позволяющий сократить потребление памяти на сервере при открытии редактора меню. На сайте, для которого писался этот модуль, около 800 пунктов меню в редакторе приводили к превышению лимита памяти в 64Мб. После включения модуля потребление памяти сократилось примерно до 40Мб.
  • File Info Filter (не опубликован, готов на 80%) - фильтр, добавляющий к ссылкам на локальные файлы информацию о типе файла и размере, а так же мини-изображение. (Пометка для себя: проект au-edu, называется au)
  • IM Status (не опубликован, готов на 80%) - модуль для отображения собственных статус-картинок для различных систем мгновенного обмена сообщениями. Пока поддерживаются Skype и ICQ. Планируется поддержка Jabber (GTalk) и хотелось бы MSN, если это вообще возможно. Изображения кэшируются на настраиваемый интервал. Сделал поддержку нескольких номеров из одной и той же социальной сети. Теперь зависит от Dynarray. Еще хотелось бы сделать разграничение доступа для показа статус-картинок только определенным ролям (или по определенной привилегии, или еще более гибко). (Пометка для себя: проект orion).
  • Taxonomy Picture (не опубликован, готов на 30%) - изображение, на котором в админке можно отметить зоны для терминов таксономии. А в режиме просмотра эти зоны заливаются цветом или наоборот, всё кроме этих зон заливается цветом. Зоны являются ссылками на термин таксономии.

понедельник, 5 апреля 2010 г.

text-decoration: underline у элемента input type="submit" в Firefox

При попытке подделать внешний вид кнопки под ссылку возникает одна проблема: в Firefox не отображается подчеркнутый стиль, т.е. вообще не отображается. В поисках решения набрел на достаточно развенутую статью по этой теме. Суть фикса в том, что элементу input нужно задать одно из следующих свойств:
input#your-submit {
    display: block;
    /* ИЛИ */
    float: left;
    /* ИЛИ */
    float: right;
    /* Тогда следующий стиль будет работать: */
    text-decoration: underline;
}

среда, 31 марта 2010 г.

min-width, min-height, max-width и max-height в IE 6

Про это очень много написано. В Internet Explorer 6 и ниже нет поддержки CSS-атрибутов min-* и max-*. Но, например, атрибут height часто ведет себя как min-height, позволяя растягивать контейнер вслед за контентом. Однако для абсолютно позиционированных элементов это не так и тут придется искать другое решение. Придется воспользоваться расширением CSS от Microsoft под названием expression, позволяющим создавать вычисляемые CSS-атрибуты. Всё просто: определяем, какая высота у нашего элемента и если она больше лимита, ограничиваем ее фиксированным значением.

Итак, решение для min-height:
#div1 {
    /* IE 6 */
    height: expression(this.scrollHeight < 50 ? "50px" : "auto");
    /* Other browsers */
    min-height: 50px;
}
max-height:
#div1 {
    /* IE 6: */
    height: expression(this.scrollHeight > 50 ? "50px" : "auto");
    /* Other browsers: */
    max-height: 50px;
}
min-width:
#div1 {
    /* IE 6: */
    width: expression(this.scrollWidth < 50 ? "50px" : "auto");
    /* Other browsers: */
    min-width: 50px;
}
max-width:
#div1 {
    /* IE 6: */
    width: expression(this.scrollWidth > 50 ? "50px" : "auto");
    /* Other browsers: */
    max-width: 50px;
}
Смешанное решение для min-width и max-width:
#div1 {
    /* IE 6: */
    width: expression(this.scrollWidth < 50 ? "50px" : (this.scrollWidth > 100 : "100px" : "auto"));
    /* Other browsers: */
    min-width: 50px;
    max-width: 100px;
}

height 100% и несколько background-image

Есть сложное фоновое изображение (никак не реализовать через один background-image, непременно нужно 2 или больше), например, нужно нарисовать 2 полосы по краям страницы. При растягивании страницы, полоски должны оставаться по краям, растягивается только фон посередине. Вот так:


Как вы понимаете, полоски должны продолжать идти до самого низа страницы, какой длинной бы она ни была. Для этого сразу в тело документа вставляем 2 элемента DIV (один в другом, во внутреннем вся остальная страница). Первое, что приходит на ум, это просто добавить "height: 100%" к HTML, BODY, #DIV1 и #DIV2. Это решает проблему, но только пока контент страницы меньше высоты окна. Как только появляется прокрутка, мы видим, что фоновое изображение не продолжается до конца страницы, только так, чтобы закрыть первый "экран":


А это совсем не то, что мы хотим. Только IE 6 на данном этапе отображает всё как нам нужно из-за его неверной интерпретации атрибута height. Почему же браузеры, уважающие стандарты, портят картину? Дело вот в чем: они четко воспринимают атрибут height равный 100%, задают элементам высоту окна, а весь контент, который выходит за пределы этой высоты, показывают просто "торчащим", т.е. контейнеры в данном случае не растягиваеются вслед за контентом.

Для исправления ситуации можно сделать вот что. Добавим еще 2 элемента DIV (#DIV3 и #DIV4) внутрь уже имеющихся, зададим для них такой же фон, как у двух первых, но вот высоту в 100% им задавать не будем. В итоге эти внутренние DIV'ы будут растягиваться за контентом и когда высота документа больше высоты окна, мы даже не увидим #DIV1 и #DIV2, но если контента недостаточно для заполнения всей высоты окна, эти DIV'ы будут видны. В итоге, фон будет всегда на полную страницу, что нам и требовалось.

Вот разметка:
<body>
  <div id="div1"><div id="div2"><div id="div3"><div id="div4">
    <!-- Здесь содержимое страницы -->
  </div></div></div></div>
</body>
И стили:
body, html {margin: 0; padding: 0; height: 100%;}
#div1,
#div2
   {height: 100%;}
#div1,
#div3
  {background: url('page-left.png') top left repeat-y;}
#div2,
#div4
  {background: url('page-right.png') top right repeat-y;}

среда, 2 декабря 2009 г.

Стилизация пунктов меню в Drupal 6

Есть проблема: нужно добавить к пунктам меню уникальные стили или идентификаторы, причем не к ссылкам, как это происходит по-умолчанию, а именно к обертке этих ссылок (в шаблоне по-умолчанию это LI). Параллельно решим еще и проблему добавления к этим же элементам-оберткам класса в зависимости от меню, к которому они принадлежат.

Сложность заключается в том, что функция theme_menu_item(...) не получает в качестве аргумента массив с данными, из которого можно извлечь идентификатор пункта меню, она получает уже сгенерированный HTML для ссылки этого пункта. Нужные данные поступают только в функцию theme_menu_item_link(...), нас интересует массив $link. Чтобы этот массив был доступен и в функции генерации элемента-обертки, можно воспользоваться следующим фокусом. Нам нужно переписать в теме обе эти функции. Например, создадим файл template.php со следующим содержанием:


<?php

function phptemplate_menu_item_link($link) {
  if (empty($link['localized_options'])) {
    $link['localized_options'] = array();
  }

  return array(
    'html' => l($link['title'], $link['href'], $link['localized_options']),
    'data' => $link,
  );

}

function phptemplate_menu_item($link, $has_children, $menu = '', $in_active_trail = FALSE, $extra_class = NULL) {
  $class = ($menu ? 'expanded' : ($has_children ? 'collapsed' : 'leaf'));
  if (!empty($extra_class)) {
    $class .= ' '. $extra_class;
  }
  if ($in_active_trail) {
    $class .= ' active-trail';
  }
  $class .= ' menu-item-' . $link['data']['mlid'];
  return '<li class="'. $class .'">'. $link['html'] . $menu ."</li>\n";
}

?>

Как видите, вместо того, чтобы просто возвращать HTML в первой функции, мы возвращаем массив, содержащий в добавок к HTML все данные о пункте меню. И уже во второй функции мы просто используем полученные данные для генерации класса, содержащего идентификатор этого пункта меню. Здесь можно использовать любые данные, например добавить название меню к классу, добавить идентификатор к элементу-обертке и др.

Первая запись

В блоге буду рассказывать (по возможности) обо всех найденных особенностях в верстке, клиентских скриптах на языке JavaScript, а также о модулях и разработке в целом под Drupal 6. Браузеры, на которые я ориентируюсь в разработке:
  • IE 6,7,8
  • Firefox 3+ (хотя и про 2-ю версию стараюсь не забывать)
  • Opera 9.5+
  • Safari 4+
Как только будет готов мой персональный сайт на Drupal, этот блог переедет туда.