четверг, 19 февраля 2015 г.
Облако тегов средствами XSLT
Облако тегов средствами XSLT
XSLT*
Не так давно столкнулся с необходимостью реализовать на одном из проектов то, что в народе называют «облаком тегов» — набор ссылок, в котором наиболее «весомые» элементы имеют бОльший размер. Для этого можно было бы, конечно, посчитать и получить все необходимые данные в PHP, на котором работает проект, но мне хотелось сделать конечный вариант отображения на XSLT и CSS, чтобы все необходимые величины для конфигурирования максимальных/минимальных размеров шрифта, например, были заданы в представлении, а не в логике приложения.
Возможно, кому-то мой опыт окажется полезным, поэтому публикую конечное решение здесь.
Итак, на входе у нас есть простейший XML с тегом и количеством его упоминаний:
теперь сделаем преобразование:
В переменные $minfont и $maxfont задаются значения размера шрифта тега в пикселях. Остальные вычисления необходимы для того, чтобы понять, какое количество пикселей нужно прибавить к $minfont в зависимости от величины «веса» того или иного тега. Можно перенести это из переменных в параметры шаблона, и тогда в разных местах сайта можно будет указывать разные значения максимального и минимального размеров шрифтов при вызове шаблона, для более гармоничного отображения.
В результате вычислений значения изменяются довольно плавно, и теги с небольшими различиями в весе при небольшом диапазоне от $minfont до $maxfont будут иметь одинаковый размер.
В результате представленного выше преобразования, получаем следующий HTML:
А выглядит это так:
Таким образом генерировать облако тегов можно и при помощи client-side XSLT-преобразований.
Конструктивная критика приветствуется. Буду рад, если пригодится не только мне. :)
Возможно, кому-то мой опыт окажется полезным, поэтому публикую конечное решение здесь.
Итак, на входе у нас есть простейший XML с тегом и количеством его упоминаний:
<?xml version="1.0" encoding="utf-8" ?>
<cloud>
<row id="1">
<name>биология</name>
<weight>2</weight>
</row>
<row id="2">
<name>русский язык</name>
<weight>20</weight>
</row>
<row id="3">
<name>алгебра</name>
<weight>13</weight>
</row>
<row id="4">
<name>география</name>
<weight>2</weight>
</row>
<row id="5">
<name>физкультура</name>
<weight>20</weight>
</row>
<row id="6">
<name>астрономия</name>
<weight>1</weight>
</row>
<row id="7">
<name>правоведение</name>
<weight>7</weight>
</row>
<row id="8">
<name>история</name>
<weight>14</weight>
</row>
</cloud>
* This source code was highlighted with Source Code Highlighter.
теперь сделаем преобразование:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<xsl:apply-templates />
</body>
</html>
</xsl:template>
<xsl:template match="cloud">
<xsl:variable name="theMax" select="row[not(weight < ../row/weight)]/weight" />
<xsl:variable name="theMin" select="row[not(weight > ../row/weight)]/weight" />
<xsl:variable name="perc100" select="$theMax - $theMin"/>
<xsl:variable name="perc1">
<xsl:choose>
<xsl:when test="$perc100 = 0">100</xsl:when>
<xsl:otherwise><xsl:value-of select="100 div $perc100"/></xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="maxfont">26</xsl:variable>
<xsl:variable name="minfont">11</xsl:variable>
<xsl:variable name="font" select="$maxfont - $minfont"/>
<div style="width:300px">
<xsl:for-each select="row">
<xsl:variable name="size" select="$minfont + ceiling($font div 100 * ((weight - $theMin) * $perc1))"/>
<a href="/tag/{name}" style="font-size: {$size}px">
<xsl:value-of select="name" />
</a>
<xsl:if test="position() != last()"><xsl:text> </xsl:text></xsl:if>
</xsl:for-each>
</div>
</xsl:template>
</xsl:stylesheet>
* This source code was highlighted with Source Code Highlighter.
В переменные $minfont и $maxfont задаются значения размера шрифта тега в пикселях. Остальные вычисления необходимы для того, чтобы понять, какое количество пикселей нужно прибавить к $minfont в зависимости от величины «веса» того или иного тега. Можно перенести это из переменных в параметры шаблона, и тогда в разных местах сайта можно будет указывать разные значения максимального и минимального размеров шрифтов при вызове шаблона, для более гармоничного отображения.
В результате вычислений значения изменяются довольно плавно, и теги с небольшими различиями в весе при небольшом диапазоне от $minfont до $maxfont будут иметь одинаковый размер.
В результате представленного выше преобразования, получаем следующий HTML:
<html>
<body>
<div style="width: 300px;">
<a href="/tag/биология" style="font-size: 12px;" title="weight: 2">биология</a>
<a href="/tag/русский язык" style="font-size: 26px;" title="weight: 20">русский язык</a>
<a href="/tag/алгебра" style="font-size: 21px;" title="weight: 13">алгебра</a>
<a href="/tag/география" style="font-size: 12px;" title="weight: 2">география</a>
<a href="/tag/физкультура" style="font-size: 26px;" title="weight: 20">физкультура</a>
<a href="/tag/астрономия" style="font-size: 11px;" title="weight: 1">астрономия</a>
<a href="/tag/правоведение" style="font-size: 16px;" title="weight: 7">правоведение</a>
<a href="/tag/история" style="font-size: 22px;" title="weight: 14">история</a>
</div>
</body>
</html>
* This source code was highlighted with Source Code Highlighter.
А выглядит это так:
Таким образом генерировать облако тегов можно и при помощи client-side XSLT-преобразований.
Конструктивная критика приветствуется. Буду рад, если пригодится не только мне. :)
Похожие публикации
Анимированное облако тегов на css3 31 октября 2012 в 18:21
Гос-cloud-контроль: главные по облакам? 13 февраля 2012 в 20:58
3D облако тегов на html 5 27 октября 2010 в 16:58
Древовидное облако тэгов 14 июня 2010 в 14:01
Разметка облака тегов 25 января 2009 в 19:55
Алгоритмы организации тэгов 19 сентября 2008 в 14:26
Вращающееся облако тегов на javascripte 27 августа 2008 в 18:46
Пользуетесь ли вы облаком тэгов для навигации по хабру? 5 августа 2008 в 13:19
Облако тегов: линейная зависимость vs логарифмическая 4 августа 2008 в 02:27
Когда Вы в последний раз кликали на тег в облаке тегов? (не на Хабре, а вообще) 20 июня 2007 в 13:18
Комментарии (31)