PHP

Облако тегов на PHP

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

Некоторые теги повторяются у различных статей, такие теги становятся популярными. На этом сайте, допустим, были бы популярны теги PHP и HTML.

Облако тегов — это блок с определенным количеством самых популярных тегов сайта. При чем, чем популярнее тег, тем больше визуально он выглядит в облаке.

Хранение тегов в базе данных

Для начала определимся, каким образом можно хранить теги для статей в базе данных. Просто хранить теги через запятую в текстовом поле для каждой статьи — плохое решение, так как реализация построения облака и поиска по тегам будет очень сложной и медленной. Самый оптимальный способ, я считаю — это связь "многие ко многим" между таблицами статей и тегов при помощи промежуточной таблицы.



В простейшем случае мы имеем таблицу со статьями articles следующей структуры:

id | alias | title | text


Таблица с тегами tags может выглядеть так:

id | alias | title


Поля alias нужны для создания читаемых URL с участием этих элементов (например /articles/hello, вместо использования числового идентификатора /articles/13).

Для установления связи между статьями и тегами создается промежуточная таблица articles_tags:

id | article_id | tag_id


В ней каждая запись описывает связь какого-то тега с какой-то статьей. Таким образом, любой из тегов может быть присвоен нескольким статьям. Нужно продумать алгоритм заполнения таблиц при добавлении новой публикации, но это уже выходит за пределы темы данной статьи.

Реализация облака тегов

Итак, предположим, что мы имеем вышеописанные три таблицы с заполненными данными. Нам нужно определить самые популярные теги и построить по ним облако. При помощи переменной зададим количество тегов, которое будет отображено в облаке:

$tags_count = 30; //--Кол-во тегов в облаке


Далее необходимо составить SQL-запрос для получения самых популярных тегов. Выглядеть он может следующим образом:

SELECT tags.title              AS title, 
       tags.alias              AS alias, 
       COUNT(tags_articles.id) AS cnt 
FROM   tags 
       INNER JOIN articles_tags
         ON ( articles_tags.tag_id = tags.id ) 
GROUP  BY tags.id 
ORDER  BY cnt DESC 
LIMIT  %tags_count%


В результате запрос возвратит таблицу с %tags_count% самых популярных тегов следующей структуры:

заголовок тега | алиас тега | количество упоминаний


Теги в ней будут отсортированы по популярности. В таком порядке построенное облако будет выглядеть не очень красиво, поэтому рекомендую отсортировать теги по заголовкам. Это можно сделать как на PHP, так и в момент запроса, доработав немного SQL-запрос:

SELECT * 
FROM   (SELECT tags.title              AS title, 
               tags.alias              AS alias, 
               COUNT(tags_articles.id) AS cnt 
        FROM   tags 
               INNER JOIN articles_tags
                 ON ( articles_tags.tag_id = tags.id ) 
        GROUP  BY tags.id 
        ORDER  BY cnt DESC 
        LIMIT  %tags_count%) AS subq
ORDER  BY title


Итак, у нас имеется список самых популярных тегов. Теперь необходимо отобразить их с разной величиной (размером шрифта) в зависимости от популярности. Критерием популярности служит параметр cnt (количество упоминаний). Но использовать этот параметр как размер шрифта нельзя. Во-первых, в большой базе он будет иметь большие значения. Во-вторых, у тегов эти параметры могут сильно отличаться, нарисовать один тег в тысячу раз больше другого — плохая идея.

Объявим две переменные, задающие минимальный и максимальный размер шрифта в облаке тегов:

$min_real = 8;  //--Минимальный размер тега (8pt)
$max_real = 22; //--Максимальный размер тега (22pt)


Предположим, что результат выполненного SQL-запроса хранится в переменной ret. Далее необходимо определить минимальное и максимальное значение параметра cnt:

$min_db = 999999;
$max_db = 0;
 
foreach ($ret as $tag)
{
    $min_db = min($min_db, $tag['cnt']);
    $max_db = max($max_db, $tag['cnt']);
}


Для чего все это нужно? Допустим, в результате выполнения запроса мы получили пять самых популярных тегов с параметрами cnt (значениями популярности) соответственно: 500, 170, 40, 111, 22. Нам необходимо отобразить эти теги шрифтом размером от 8 (min_real) до 22 (max_real). Мы определили максимальное (max_db = 500) и минимальное (min_db = 22) значения популярности. Для определения размера шрифта, которым необходимо отобразить тег со значением популярности cnt воспользуемся формулой:

(cnt - min_db) / (max_db - min_db) * (max_real - min_real) + min_real


В общем, сплошная математика. Даже она иногда пригождается в сайтостроении.

Код построения облака тегов, в итоге, может выглядеть примерно так:

$tagsarr = array();
foreach ($ret as $tag)
{
    $tagsarr[] = sprintf('<a style="font-size: %dpt;" title="%d" href="/articles/?tag=%s">%s</a>',
                         $min_db == $max_db ? $min_real : ( ($tag['cnt'] - $min_db) / ($max_db - $min_db) * ($max_real - $min_real) + $min_real ),
                         $tag['cnt'],
                         $tag['alias'],
                         $tag['title']
                 );
}
echo implode(', ', $tagsarr);


Участок

$min_db == $max_db ? $min_real : ...


описывает частный случай, когда максимальное и минимальное значение популярности равны, то есть все теги имеют одинаковую популярность. В этом случае отображаем их минимальным размером шрифта. Удачного кодинга!
Теги:
Облако тегов
Добавлено: 27 Февраля 2015 19:36:06 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...