Подсветка синтаксиса (фильтры для кода)

Рано или поздно все в веб-разработке сталкиваются с подсветкой синтаксиса и красивой версткой (на автомате) используемого в материале исходника, будь это sql запросы или команды bash — не суть — важна читаемость, красота; как следствие конверсия и глубина просмотра, а значит качество и вклад в развитие рунета

Я решил посмотреть, что есть готового для седьмой версии друпала, уяснить +/- найденных решений и найти оптимальный для своего скромного сайта со справочной информацией, кейсами прекрасными леди и преферансом.

BUEditor
т.к. WYSIWYG я не перевариваю (мне он не нужен), для собственных проектов использую  bueditor в целях уменьшения ручного ввода разметки. из коробки есть батон CODE, обрамляет указанное в <pre><?php phpinfo(); ?></pre> Подсветки нет (на drupal.ru используется code, точнее это  geshifilter встроенный в редактор. BUEditor позволяет создавать собственные кнопки со сравнительно малыми трудозатратами (капитан очевидность у руля) и использовать библиотеки, например Syntax Highlighter для подсветки в back-end’e. В отличие от тега pre дополнительные пробелы внутри контейнера code не учитываются, так же, как и переносы текста. Но это другая опера.

BUEditor + GeSHi Filter
 geshifilter подключает библиотеку http://qbnz.com/highlighter/

Установка
$drush dl geshifilter
Project geshifilter (7.x-1.2) downloaded to sites/all/modules/geshifilter. [success]
Project geshifilter contains 2 modules: geshifield, geshifilter.
$ drush en geshifilter
The following projects have unmet dependencies: [ok]
geshifilter requires libraries
Would you like to download them? (y/n): y
Project libraries (7.x-2.2) downloaded to sites/all/modules/libraries. [success]
The following extensions will be enabled: geshifilter, libraries
Do you really want to continue? (y/n): y
geshifilter was enabled successfully. [ok]
libraries was enabled successfully. [ok]
GeSHi filter is installed. You should now configure the GeSHi filter and enable it in the [status]
desired text formats.
$ wget http://sourceforge.net/projects/geshi/files/geshi/GeSHi%201.0.8.11/GeSHi…
$ tar -xzf GeSHi-1.0.8.11.tar.gz

В админке переходим к настройке фильтров и включаем поддержку GeSHi. Готово, и танцев с бубном не потребовалось.

3. highlightjs (на клиенте)
 highlightjs

не использовал, если есть что сказать про этот вариант — предлагаю обсудить в комментариях

4.  codefilter
простой и деревянный, то что на d.org

2be continued
давайте перетрем))

Источник: http://www.drupal.ru/node/116500

Работа с Facet API и Apache Solr. Часть 1

Всем привет.

Так сложилось, что передо мной встала задача создать библиографическую систему для хранения научных публикаций в большом количестве. Ну и как в любой нормальной библиографической системе, мне нужен поиск. На момент начала работы я уже был знаком с модулями Apachesolr search integration и Facet API, работающими в связке, и у которых довольно много возможностей из коробки, а помимо них есть ведь и API. Так вот некоторые мои задачи из коробки не решались, пришлось пообщаться и с разработчиками, и поковыряться в коде, поэтому я таки решил написать о решении некоторых задачек здесь. Возможно, кому-то будет полезно, возможно кто-то предложит, как сделать лучше.

Итак, поехали. Расписывать модули и что они делают, я не буду, это неинтересно, можно почитать на drupal.org и в интернете, благо, такой информации достаточно. В этом посте я хочу рассказать о том, как можно создавать свои собственные фильтры (их еще называет фасетами).

Дело в том, что в моём проекте достаточно непростая структура. Так, например, у меня есть тип материала “Публикация”, у которого есть поле – ссылка на материал типа “Издание”. В свою очередь, у издания есть поле – ссылка на материал “Издательство”. Таким образом, когда я ищу публикации, в списке доступных фильтров я вижу “Издания”, но, что если я хочу фильтровать результаты поиска по издательствам, когда они привязаны к публикациям не напрямую?

Один из предложенных вариантов решения этой задачки было ручное индексирование публикаций. Добавив в индексированную публикацию поле издательства мы легко получим нужный фильтр. Добавить поле можно с помощью реализации хука hook_apachesolr_index_document_build() (если вы такого хука не нашли, значит у вас старая версия модуля apachesolr, где он называется hook_apachesolr_update_index()), описанного в файле apachesolr.api.php:

<?php
function mymodule_apachesolr_index_document_build($document, $node, $namespace) {
  if ($node->type == 'publication') {
    if (!empty($node->field_edition)) {

      // Примечание: $node->field_edition - это ассоциативный массив, в котором ключами являются языки, это важно понимать при индексировании. 
      // В данном случае у меня материалы не привязаны к языку, поэтому ключ массива я захардкодил.
      foreach ($node->field_edition['und'] as $edition) {
        if (!empty($edition['node']->field_publishing_house))    {
          foreach ($edition['node']->field_publishing_house['und'] as $pubhouse) {

            // Ну а таким образом я добавляю новое поле в наш документ. Здесь хочу добавить два примечания.
            // Первое: В качестве значения не надо пихать весь термин, или всю ноду, а достаточно проиндексировать идентификатор.
            // Второе: У Apachesolr есть правила именования поля. Название всегда должно быть формата xy_fieldname, где
            // x - тип поля (s - строка, t - текст, i - тип long, а f - float), а y - количество значений (s - одно, m - несколько).
            // В моем примере в поле хранится идентификатор, а издательство у издания может быть только одно.
            // fieldname может быть любым, но для себя я решил, что разделяю его на две части, где первая хранит информацию о том, чье это поле,
            // а вторая - о том, что это поле содержит. pub - публикация, pubhouse - издательство.
            $document->addField('is_pub_pubhouse', $pubhouse['nid']);          
          }
        }
      }
    }
  }
}
?>

Таким образом в самом друпале у нас публикация не хранит информацию о своём издательстве, а в индексе хранит. И помимо этого, может хранить любую другую информацию, какую разработчик пожелает туда “запихнуть”.
Но этого недостаточно. Теперь мы должны рассказать модулю Facet API, что мы хотим по этому полю получить фильтр. Это, в свою очередь, решается с помощью реализации хука hook_facetapi_facet_info(), описанного в файле facetapi.api.php:

<?php
function mymodule_facetapi_facet_info($searcher_info) {
  // Данная функция должна возвращать ассоциативный массив с описаниями полей, где
  // ключом является само название поля.
  $facets = array();
  $facets['is_pub_pubhouse'] = array(

    // Название фильтра на странице настройки.
    // Учитывая, что каждый фильтр отображается в блоке, а заголовок блока я всегда успею переопределить,
    // метку я тоже решил делать понятной
    'label' => t('Publication->Pubhouse'),
    'description' => t('Pubhouse facet for publications'),

    // Здесь я должен указать название коллбэка, который будет вместо идентификаторов подставлять нормальные 
    // значения. Для полей - ссылок на таксономию рекомендую использовать уже готовый коллбэк
    // facetapi_map_taxonomy_terms, для ссылок на ноды я создал свой коллбэк, для полей со списком значений
    // я создавал отдельные коллбэки, хотя возможно, можно это сделать изящнее.
    // Помимо этого, здесь можно указать параметры фильтра такие, как, например, древовидность (hierarchy_callback).
    // Подробнее можно посмотреть в вышеуказанном файле facetapi.api.php в коде описания хука.
    'map callback' => 'mymodule_map_node_references',
  );
}

function mymodule_map_node_references(array $values) {
  // Здесь все очень просто, коллбэк возвращает ассоциативный массив, где ключ массива - это значение, хранимое в поле,
  // а значение в массиве - это то, что должен увидеть пользователь.
  $map = array();
  if ($values) {
    $map = db_select('node', 'n')->fields('n', array('nid', 'title'))->condition('n.nid', $values, 'IN')->execute()->fetchAllKeyed();
  }
  return $map;
}
?>

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

Примечание: вышенаписанное актуально для текущих версий модулей apachesolr (7.x-1.0-beta16) и facetapi (7.x-1.0-rc4). Они активно развиваются, поэтому если у вас другая версия и что-то не работает, читайте release notes.

Ссылки:
Часть 2. О подмене коллбэка для индексации определенного полям и о том, как искать по дополнительным полям.
Часть 3. О том, как не индексировать, если не хочется.
Часть 4. Установка Solr 3.x и поиск с использованием *

Источник: http://www.drupal.ru/node/78426

© 2009 Обзор CMS