Спрятать колонку

Drupal. баг с pager

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

 
if (!isset($count_query)) {
    $count_query = preg_replace(array('/SELECT.*?FROM /As', '/ORDER BY .*/'), array('SELECT COUNT(*) FROM ', ''), $query);
}

вне всяких сомнений круты следующие вещи:
- использование звездочки;
- и дописывание селекта перед скобками запроса, что чревато во вложенных запросах;
- необходимость писать ключевые слова с большой буквы.

после замены на простое:

if (!isset($count_query)) {
    $count_query = "SELECT COUNT(1) FROM (" . $query . ") v";
}

все заработало как часы.

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

Drupal. Облако тегов

Большого смысла огород городить в этом посте нет. Приведу код.

<?php
	$fsMax = 180;
	$fsMin = 80;
	$dicts = array(1, 2, 3);
	$output = '';
	foreach($dicts as $dict){
		if ($output <> '') $output .= '<br/><br/><hr><br/>';
 
		$sql = "select max(v.term_count) max_count, min(v.term_count) min_count, t.name from (select td.tid, count(tn.tid) term_count from {term_data} td left join {term_node} tn on td.tid = tn.tid where td.vid = $dict group by td.tid) v, (select name from {vocabulary} where vid = $dict) t group by t.name";
		$res = db_query($sql);
		$vals = db_fetch_object($res);
		$max = $vals->max_count;
		$min = $vals->min_count;
		$name = $vals->name;
		$factor = ($min == $max ? 0 : ($fsMax - $fsMin) / ($max - $min));
 
		$orderBy = 't_data.name';
		$orderBy = 't_count desc';		
		$sql = "select t_data.name, t_data.tid, count(t_node.tid) t_count from {term_data} t_data left join {term_node} t_node on t_data.tid = t_node.tid where t_data.vid = %d group by t_data.name, t_data.tid order by %s";
		$res = db_query($sql, $dict, $orderBy);
		$tags = '';
		$has_terms = false;
		while ($term = db_fetch_object($res)){
			$size = $fsMin + ($term->t_count - $min) * $factor;
			$style = "font-size:$size%";
			$tags .= l($term->name, 'taxonomy/term/' . $term->tid, array('attributes' => array('style' => $style))) . " ";
			$has_terms = true;
		}
		$output .= "<h1>$name</h1> <br/>$tags";
 	}
 	if (!empty($output)) return $output;
?>

Комментировать тоже особенно нечего. Вывожу термины, с использованием l(), только потому, что нигде не темизировал у себя вывод терминов, а тратить при этом время на лишние вызовы не хочется. Этот кусок можно переделать по собственно желанию.

Все просто и легко.

>> Читать далее

Drupal. Просмотр присоединенных изображений.

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

Во многих форумах, как IPB, vB, phpBB, есть предпросмотр изображений, которые были приаттачены к посту. По умолчанию drupal не предоставляет такой возможности, однако, как всегда, можно дописать пару функций к template.php или же создать модуль. Модуль я не писал, предпочел обойтись изменениями в template.php, но, имея этот код, можно запросто переделать его в модуль.

В чем смысл функций.
Вся информация о загруженных файлах хранится в таблице {files}. Оттуда можно взять тип файла, путь и размер (если это изображение). В эту таблицу мы можем добавить еще одно поле, в котором будет хранится путь к изображению, используемому для предпросмотра. При просмотре нода мы сначала будем проверять, заполнено ли это поле, и если нет, то будем создавать файл с заранее заданными размерами.

Поехали по пунктам:
Создаем поле, будьте внимательны с префиксом для таблицы (в данном случае я сторонник править core table):

ALTER TABLE files
ADD COLUMN (thumbnail varchar(255) DEFAULT NULL);

В функцию phptemplate_preprocess_comment добавляем кусок кода:

 $cid = $vars['comment']->cid;
    $files = db_query("select f.* from {files} f, {comment_upload} up where up.cid = '$cid' and f.fid = up.fid");
    $contentFiles = getFilesPreview($files);
    if ($contentFiles <> ''){
    	$contentFiles = "<table>$contentFiles</tr></table>";
      $vars['content'] = str_replace('<table class="comment-upload-attachments">', $contentFiles . '<table class="comment-upload-attachments">', $vars['content']);
    }

аналогичный код можно добавить и в phptemplate_preporoccess_node

Функция getFilesPreview:

function getFilesPreview($files){
  $imagesPerRow = 5; -- количество изображений в строке
  $imageWidth = 150;  -- ширина превью

>> Читать далее

Drupal. Views vs Snippet

Есть в drupal такой модуль - Views
Модуль бесспорно хорош, но есть ли в нем такой уж большой смысл для людей, которые немного знают drupal api и sql. На примере я покажу, насколько просто и легко, в большинстве случаев, заменяется этот модуль обычным сниппетом. Зачем это стоит делать? Чем меньше модулей, тем быстрее работает сайт. Также вы можете написать любой запрос и не ограничивать себя возможностями, предоставляемыми конструктором, встроенным в модуль Views.

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

Неужели для ее решения нам нужен громоздкий модуль? Нет, смотрите сами.

Для начала напишем запрос, который позволит вычитать нам эти данные из бд:

SELECT n.* FROM {node} n WHERE n.uid = 1

Важное замечание по данному примеру: нельзя писать ключевые слова SELECT и FROM в нижнем регистре (а вот WHERE можно писать), потому что pager при этом будет некорректно работать.

Теперь напишем сам сниппет:

<?php
  // инициализация данных
  $output = '';
  $postsPerPage = 20;
  $uid = 1;
  $sql = "SELECT n.nid, n.sticky, n.created FROM {node} n WHERE n.uid = $uid";
  $has_posts = false;
 
  // выполняется запрос и с разбиением по страницам, когда мы получаем информацию кусками и такими порциями выдает пользователю
  $result = pager_query(db_rewrite_sql($sql), $postsPerPage, 0, NULL);
 
  // чтение данных
  while ($node = db_fetch_object($result)) {
    $output .= node_view(node_load($node->nid), 1);
    $has_posts = true;
  }
 
  // добавляем pager
  if ($has_posts) {
    $output .= theme('pager', NULL, $postsPerPage);
  }
  return $output;
?>

Сниппет готов.

>> Читать далее

Drupal. Добавление мета тегов

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

решение:
откроем файл node.tpl.php и добавим следующий код:

<?php if ($terms) and (!$is_front): ?>
         <?php 
                 $text = strip_tags($terms);
                 $text = check_plain($text);
                 $text = eregi_replace("\n",", ",$text);
                 $text = substr($text, 0, strlen($text) - 2);
 
                 drupal_set_html_head('<meta name="keywords" content="' . $text .'" />'); 
        ?>
<?php endif; ?>

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

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

Drupal. Создание шаблона страницы

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

решение тоже архипростое:
1. включаем модуль path
2. создаем ноду и задаем ей пусть, пускай будет contacts
3. в папке с темой создаем файл page-contacts.tpl.php
4. в файле template.php ищем (или создаем) функцию phptemplate_preprocess_page и добавляем в нее строчки:

 if(request_uri() == '/contacts'){
   unset($vars['template_files']);
   $vars['template_files'][] = 'page-contacts';
 }

5. чистим кеш
6. любуемся результатом

Drupal. модуль simple_gmap

нашел небольшой баг в модуле simple_gmap 1.6
при перетаскивании маркера не происходит нормальное обновление координат маркера.
пришлось доработать напильником и заменить функцию

   function updateMarker(marker) {
     var latlng = marker.getPoint();    
     $('#' + marker.content + " .x").val(latlng.y);
     $('#' + marker.content + " .y").val(latlng.x);
 
     upd_gmap_data();
   }

на

   function updateMarker(marker) {
     var latlng = marker.getPoint();    
     $('#marker_'+ marker.content).find('.x').val(latlng.y);
     $('#marker_'+ marker.content).find('.y').val(latlng.x);
 
     upd_gmap_data();
   }

в аттаче файлик прилагаю simple_gmap.js

RSS-материал

Наверх