Небольшой сниппет, показывающее облако тэгов по заданному (через код vid) словарю ...
Конечно он не покрывает все возможности и настройки модуля tagadelic, но в некоторых случаях может оказаться полезным
Для темизации всего блока можно использовать стилизацию tags.voc-номер-словоря,
для темизации терминов a.tags-voc-номер-словоря ...
PS.Данный код выводит только «реальные» термины словоря, т.е. термины которые «привязаны» к нодам (просто мне показалось не логичным выводить «пустые» тэги, не связанные с материалом)
Обновление:
Добавил сортировку терминов в сниппет, переменная $order может принимать следующие значения
0 - сортировка по ид термина
1 - сортировка по весу по убыванию (с наибольшим весом выше)
2 - сортировка по весу по возрастанию (с наибольшим весом ниже)
другое значение - сортировка по имени термина
<?php
$max_fontsize = 150; // Размер шрифта для тэга с максимальным весом
$min_fontsize = 90; // Размер шрифта для тэга с минимальным весом
$metrics = '%'; // в чем измеряется размер px,pt,em,%
$voc = 3; // vid словаря
$order = 1; // сортировка терминов
// 0 - сортировка по ид термина
// 1 - сортировка по весу по убыванию (с наибольшим весом выше)
// 2 - сортировка по весу по возрастанию (с наибольшим весом ниже)
// другое значение - сортировка по имени термина
// получим максимальны и минимальный вес терминов в словаре
$result = db_query(db_rewrite_sql("SELECT max(cnt) AS maxcnt,min(cnt) AS mincnt
FROM {term_data} td INNER JOIN
(SELECT tn.tid,COUNT(tn.nid) as cnt FROM {term_node} tn
INNER JOIN {node} n ON n.nid=tn.nid GROUP BY tn.tid) n
ON n.tid=td.tid AND td.vid=%d"),$voc);
$term = db_fetch_object($result);
$min_weight = $term->mincnt;
$max_weight = $term->maxcnt;
// вычислим коэффициент для размера шрифта
if ($min_weight == $max_weight ) {
$font_metric_koof = 0;
}
else {
$font_metric_koof = ($max_fontsize - $min_fontsize) / ($max_weight - $min_weight);
}
$ord = '';
switch($order){
case 0:
$ord = 'ORDER BY td.tid';
break;
case 1:
$ord = 'ORDER BY n.cnt DESC';
break;
case 2:
$ord = 'ORDER BY n.cnt';
break;
default:
$ord = 'ORDER BY td.name';
}
$result = db_query(db_rewrite_sql("SELECT td.tid,td.name,n.cnt
FROM {term_data} td INNER JOIN
(SELECT tn.tid,COUNT(tn.nid) as cnt FROM {term_node} tn
INNER JOIN {node} n ON n.nid=tn.nid GROUP BY tn.tid) n
ON n.tid=td.tid AND td.vid=%d ".$ord),$voc);
$tags = '';
while($term = db_fetch_object($result)) {
$size = $min_fontsize + ($term->cnt - $min_weight) * $font_metric_koof;
$style = 'font-size: '.$size.$metrics.';';
$tags .= l($term->name,'taxonomy/term/'.$term->tid,
array('attributes' => array('style' => $style,'class' => 'tags-voc-'.$voc))).' ';
}
if (!empty($tags)) {
print '<tags class="voc-'.$voc.'">'.$tags.'</tags>';
}
?>
Комментарии
Отличная работа!
Уже не раз задумывался о такой штучке. Очень полезно, если нужно выводить блок с облаком в разных местах (регионах) на разных страницах сайта...
Спасибо.
Решение было сохранено на сайте DrupalCookBook.ru:
Вывести облако тегов в блоке.
Авторы, предложившие решения, также указаны в сохранённой статье.
user warning: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELECTG max(cnt) AS maxcnt,min(cnt) AS mincnt FROM term_data td INNER JOIN (S' at line 1 query: SELECTG max(cnt) AS maxcnt,min(cnt) AS mincnt FROM term_data td INNER JOIN (SELECT tn.tid,COUNT(tn.nid) as cnt FROM term_node tn INNER JOIN node n ON n.nid=tn.nid GROUP BY tn.tid) n ON n.tid=td.tid AND td.vid=3 in Z:\home\dru\www\includes\common.inc(1537) : eval()'d code on line 12
Не силен в этом, такая вот ошибка???
Синтаксическая ошибка. Должно быть:
Убрать "G"
Тоже синтаксическая ошибка...
Орфографическая
Да ладно - застыдили «Папа у Васи силен в математике» :),а не в русском языке , хотя я с этим борюсь
спасибо, пригодится
Если не трудно, подскажите пожалуйста, где в коде это условие записано.
SELECT tn.tid,COUNT(tn.nid) as cnt FROM {term_node} tn
INNER JOIN {node} n ON n.nid=tn.nid GROUP BY tn.tid
Данный вложенный запрос отбирает только те термины которые связаны с какой либо нодой, так как применен INNER JOIN (если убрать INNER JOIN {node} n ON n.nid=tn.nid , то будут отбираться все термины)
olk, спасибо большое
спасибо. поставил вместо тормознутого тагаделика. работает.
А как ограничить количество выводимых терминов (чтобы например выводилось 50 самых популярных)?
Данный сниппет будет выводить 20 (см. переменную $max_tags) наиболее популярных и «свежих» тэгов
<?php
$max_fontsize = 18; // Размер шрифта для тэга с максимальным весом
$min_fontsize = 9; // Размер шрифта для тэга с минимальным весом
$metrics = 'pt'; // в чем измеряется размер px,pt,em, (с установкой в процентном отношении Flash облоко глючит )
$voc = array(3); // массив (vid) словарей
$max_tags = 20; // максимальное количество показываемых тэгов
$vocs = implode(',',$voc);
$class_voc = implode('-',$voc);
$result = db_query(db_rewrite_sql("SELECT max(cnt) AS maxcnt,min(cnt) AS mincnt
FROM {term_data} td INNER JOIN
(SELECT tn.tid,COUNT(tn.nid) as cnt FROM {term_node} tn
INNER JOIN {node} n ON n.nid=tn.nid GROUP BY tn.tid) n
ON n.tid=td.tid AND td.vid IN (".$vocs.")"));
$term = db_fetch_object($result);
$min_weight = $term->mincnt;
$max_weight = $term->maxcnt;
// вычислим коэффициент для размера шрифт
if ($min_weight == $max_weight ) {
$font_metric_koof = 0;
}
else {
$font_metric_koof = ($max_fontsize - $min_fontsize) / ($max_weight - $min_weight);
}
$result = db_query_range(db_rewrite_sql("SELECT td.tid,td.name,n.cnt
FROM {term_data} td INNER JOIN
(SELECT tn.tid,COUNT(tn.nid) as cnt,MAX(n.created) as created FROM {term_node} tn
INNER JOIN {node} n ON n.nid=tn.nid GROUP BY tn.tid) n
ON n.tid=td.tid AND td.vid IN (".$vocs.") ORDER BY n.cnt DESC,n.created DESC"),0,$max_tags);
$tags = '';
while($term = db_fetch_object($result)) {
$size = $min_fontsize + ($term->cnt - $min_weight) * $font_metric_koof;
$style = 'font-size: '.$size.$metrics.';';
$tags .= l($term->name,'taxonomy/term/'.$term->tid,
array('attributes' => array('style' => $style,'class' => 'tags-voc-'.$class_voc))).' ';
}
if (!empty($tags)) {
$output = ''.$tags.'';
echo $output;
}
?>
спасибо, попробую на досуге заменить tagadelic сниппетом
спасибо, полезный код!
кстати чтобы получить случайную картинку по тегу можно воспользоваться функцией image_get_random
а чем отличается от этого снипета (я использую у себя, нашел где то тут)
$vocs = array(1, 2, 3); //номера словарей
$tags = tagadelic_get_weighted_tags($vocs, 6, 50);
$tags = tagadelic_sort_tags($tags);
$output = theme('tagadelic_weighted',$tags);
print $output;
?>
Как я понял, этот сниппет использует функции модуля tagadelic, а olk предложил сниппет БЕЗ использования модуля
я тож так подумал
а чем плох тагаделик?
Вопрос. А как надо изменить сниппет чтобы:
1. Выводились все термины словаря?
2. Термины словаря к которым не прикреплены ноды были другого цвета?
Зарание спасибо за помощь.
Да, чем плох, если учитывать, что у него есть API и он кэширует данные?
В чём выражается тормознутость? Может из-за кэша (см. tagadelic_get_weighted_tags)?
Действительно выводит.
Однако, если указать сортировку по имени тэга (ORDER BY td.name), тогда сортировка по алфавиту обрезает популярные тэги. У кого-нибудь есть готовое решение? Т.е. чтобы сортировка производилась после того, как сформирован массив популярных тегов, ограниченный переменной $max_tags.
Спустя год решение появилось
Собственно доработал данный сниппет.
--
Исправления и доработки:
<?php
$max_fontsize = 18; // Размер шрифта для тэга с максимальным весом
$min_fontsize = 8; // Размер шрифта для тэга с минимальным весом
$metrics = 'pt'; // в чем измеряется размер px,pt,em, (с установкой в процентном отношении Flash облоко глючит )
$voc = array(8); // массив (vid) словарей
$nodetype = array('vacancy'); //массив типов материала
$max_tags = 10; // максимальное количество показываемых тэгов
$order=3; // сортировка терминов
// 0 - сортировка по ид термина
// 1 - сортировка по весу по убыванию (с наибольшим весом выше)
// 2 - сортировка по весу по возрастанию (с наибольшим весом ниже)
// 3 - сортировка в случайном порядке
// другое значение - сортировка по имени термина $vocs = implode(',',$voc);
$class_voc = implode('-',$voc);
foreach(
$nodetype as &$value){$value="'".$value."'";
}
$nodetypes = implode(',',$nodetype); $result = db_query("SELECT td.tid,td.name,n.cnt
FROM {term_data} td INNER JOIN
(SELECT tn.tid,COUNT(tn.nid) as cnt,MAX(n.created) as created FROM {term_node} tn
INNER JOIN {node} n ON n.nid=tn.nid AND n.type in (".$nodetypes.") GROUP BY tn.tid) n
ON n.tid=td.tid AND td.vid IN (".$vocs.") ORDER BY n.cnt DESC LIMIT 0, %d",$max_tags); $mincnt=-1;
while($term = db_fetch_array($result)) {
//Определение максимального и минимального коэффициентов
$term['cnt']>$maxcnt?$maxcnt=$term['cnt']:FALSE;
$mincnt==-1?$mincnt=$maxcnt:FALSE;
$term['cnt']<$mincnt?$mincnt=$term['cnt']:FALSE;
//Для разных сортировок
$i++;
$termscnt[$term['cnt'].'-'.$i]=$term;
$termstid[$term['tid']]=$term;
$termsname[$term['name']]=$term;
} // вычислим коэффициент для размера шрифт
if ($mincnt == $maxcnt) {
$font_metric_koof = 0;
}
else {
$font_metric_koof = ($max_fontsize - $min_fontsize) / ($maxcnt - $mincnt);
}
switch(
$order){case 0:
ksort($termstid);
$terms=$termstid;
break;
case 1:
krsort($termscnt);
$terms=$termscnt;
break;
case 2:
ksort($termscnt);
$terms=$termscnt;
break;
case 3:
shuffle($termscnt);
$terms=$termscnt;
break;
default:
ksort($termsname);
$terms=$termsname;
} $tags = '';
foreach(
$terms as $term) {$size = $min_fontsize + ($term['cnt'] - $mincnt) * $font_metric_koof;
$style = 'font-size: '.$size.$metrics.';';
$tags .= l($term['name'],'taxonomy/term/'.$term['tid'],
array('attributes' => array('style' => $style,'class' => 'tags-voc-'.$class_voc))).' ';
}
if (!empty($tags)) {
$output = '<tags class="voc-'.$class_voc.'">'.$tags.'</tags>';
echo $output;
}
?>
Удачного использования.
1. Незнаю, мне кажется нет смысла выделять в модуль т.к. потеряется основная идея сниппета. Да и когда делал, основная цель была другой - позволить выводить термины для разных типом ватериалов:
на сайте есть 2 логических/тематических разделения, на которых вывожу 2 разных блока (1-популярные должности в резюме. 2-популярные должности в вакансиях).
2,3 - поправлю, выложу. Не подскажите, лучше запостить в эту тему или выделить в отдельную? (1й раз публикую наработки)
4. - не подскажите где почитать про риализацию?
-
Спасибо.
1. А какова идея сниппета? Я всегда считал, "зачем делать сниппеты, если можно сделать модуль". Модуль можно включить/выключить, он может хранить настройки, его легко передать другим, он чудно лежит в системе контроля версий, для него не надо включать PHP-фильтр (а на рабочем сайте этот фильтр должен быть отключен в обязательном порядке).
4. [ru-api=cache_set] и [ru-api=cache_get] - посмотрите использование в ядре, там всё просто. Таблицу для хранения советую использовать "cache_filter".
Плюсую. Всегда не любил делать эти сниппеты.
Ок, спасибо, займусь
всегда любил сниппеты
темизировать проще
Сниппеты не темизируемы. В принципе.
результаты работы сниппетов проще темизировать
А разница? Отредактировать код в файле сложнее, чем код в сниппете?
чтобы не быть голословным
есть вывод модулем тагаделик, есть такой же вывод - сниппетом
вывод сниппетом я легко оберну в див клас (какой надо)
вывод модулем - придется заморочится (привязываться к примеру к блоку или еще к чему ни будь)
Другой пример. Отображение 10 последних материалов определенного вида (пусть будет page)
сниппет легко, можно изменить ul на dd , или на p, div
Этот же вывод с помощью вьюс - да вот не получится, нет такой гибкости
(зато вьюсом можно вывести сеткой)
сделать ОДИН файлик шаблона блока и сделать это там.
а да.
с 23 февраляс 8 марта, пацаны!Во-первых, различай _свой_ модуль от чужого - свой ты так же легко можешь поменять как и сниппет. А если делать правильно, то и модуль менять не нужно - делай в шаблоне модуля.
Во-вторых, для правильно написанных модулей (тот же views), изменение шаблонов вывода - пятиминутное дело, просто копи-паст без включения мозгов.
А разве делая свои модули, вы не используете темизацию?
я не про свои модули
и сравните что проще, переопределять блок
или добавить один div
Да, и давно, переделка вывода вьюс стала простым делом?
можно ссылку?
всегда была)
http://mustardseedmedia.com/podcast/episode30
это пусть Толя смотрит касты
я только текст воспринимаю
и еще, вот вывод, сделаете мне это вьюсом? (также просто) . Вопрос же не в том, что "нельзя сделать". Вопрос в том, что проще.
http://www.hr-portal.ru/page/novosti-5
один вьюс, с группировкой по типу материала. здесь шаблон не нужен
да, только я могу каждый из блоков отобразить по разному
в строчку, dd-dt, li, p и тд. С вьюсами вы замучаетесь
Не замучаюсь. Если надо извратиться с выводом, можно вызвать views ручками и построить вывод самому. Такое нужно очень редко.
а разве вопрос сделать или нет, часто или редко
я утверждал что быстрее. И не более того.
Я более чем уверен, что Dan при необходимости напишет свой модуль свой. И не только он.
друзья, подскажите, как быть с мультиязычностью?
чтобы на русском выводились теги в облаке на русском, а на английском крутилось английское облачко?
заранее спасибо!
Подскажите как отключить линки на теги в облаке ?
строку
<?php
$tags .= l($term->name,'taxonomy/term/'.$term->tid,
array('attributes' => array('style' => $style,'class' => 'tags-voc-'.$voc))).' ';?>
меняешь на
<?php
$tags .= '<span style="' . $style . ">' . $term->name . '</span> ';?>
А возможно вывести в облако выборочные иерархии?
Как отдельно от других терминов вывести термины из иерархии --Термин1 ?
------ из иерархии --Термин1.1 ?
Словарь
-Термин1
--Термин1.1
---термин
---термин
---термин
--Термин1.2
-Термин2
--Термин2.1
--Термин2.2
-Термин3
--Термин3.1
--Термин3.2
Тогда нужно в коде явно указывать из каких иерархий нужно брать термины и будет вам счастье.