HOSTCMS v.6
XSL
РАЗНЫЕ МЕЛОЧИ В XSL
Разное
<img src="{dir}{image_large}" alt="{name}" width="{image_large_width}" height="{image_large_height}" />
<xsl:variable name="var_compare_id" select="."/>
<xsl:text disable-output-escaping="yes" select="."> </xsl:text>
<xsl:text> </xsl:text>
<xsl:value-of disable-output-escaping="yes" select="property_value[tag_name='short_name']/value" />
<xsl:if test="description !=''">
<xsl:value-of disable-output-escaping="yes" select="description" />
</xsl:if>
<xsl:if test="position() mod 3 = 0 and position() != last()">
<xsl:text disable-output-escaping="yes">
</tr>
<tr valign="top">
</xsl:text>
</xsl:if>
<xsl:if test="property_value[tag_name='link']/value !=''">
<xsl:value-of disable-output-escaping="yes" select="property_value[tag_name='link']/value" />
</xsl:if>
Дополнительное свойство - ссылка
property_value[tag_name='link']/value !=''
<xsl:if test="property_value[tag_name='link']/value !=''">
<xsl:value-of disable-output-escaping="yes" select="property_value[tag_name='link']/value" />
</xsl:if>
<xsl:if test="property_value[tag_name='link']/value !=''">
<a href="{property_value[tag_name='link']/value}" target="_parent" >
<img src="{dir}{image_small}" alt="{name}"/>
</a>
</xsl:if>
<xsl:if test="property_value[tag_name='short_name']/value !=''">
<xsl:value-of disable-output-escaping="yes" select="property_value[tag_name='short_name']/value" />
</xsl:if>
Дополнительное свойство - изображение
<xsl:if test="property_value[tag_name='img']/file !=''">
<a href="{property_value[tag_name='img']/file}">
<img src="{dir}{property_value[tag_name='img']/file}" alt="{name}"
width="{property_value[tag_name='img']/file_width}" height="{property_value[tag_name='img']/file_height}"/>
</a>
</xsl:if>
Ограничение количества групп в выпадающем меню
<!-- Если есть подгруппы -->
<xsl:if test="count(shop_group) > 0 and 1 > count(ancestor::shop_group)">
<ul class="left_menu gray_link gray" id="{@id}" style="display: none;">
<xsl:apply-templates select="shop_group"/>
</ul>
</xsl:if>
Выбираем последний элемент списка и назначаем ему класс last
<xsl:if test="position() mod 4 = 0 and position() > 3">
<xsl:attribute name="class">last</xsl:attribute>
</xsl:if>
Выбираем первый элемент списка и назначаем ему класс first
<xsl:if test="position() mod 1 = 0 and position() < 2">
<xsl:attribute name="class">first</xsl:attribute>
</xsl:if>
Ссылка на все товары производителя в карточке товара
<xsl:if test="shop_producer/node()">
<xsl:variable name="shop_produser_id" select="shop_producer/@id" />
<a href="{/shop/url}producer-{$shop_produser_id}" class="button">Другие товары этого производителя</a>
</xsl:if>
Ограничиваем текст по количеству знаков
<xsl:variable name="myConcatString" select="description"/>
<xsl:value-of disable-output-escaping="yes" select="substring($myConcatString, 1, 800)" /><xsl:text>...</xsl:text>
Вставляем код JAVASCRIPT в XSL
<SCRIPT>
<xsl:comment>
<xsl:text disable-output-escaping="yes">
<![CDATA[
.........код скрипта......................
]]>
</xsl:text>
</xsl:comment>
</SCRIPT>
Шаблон для условия
<xsl:choose>
<xsl:when test="">
...
</xsl:when>
<xsl:otherwise>
...
</xsl:otherwise>
</xsl:choose>
Если нет изображения, то скрываем блок на boostrap 5
<div class="d-none">
<xsl:if test="image_small != ''">
<xsl:attribute name="class">col-xs-3 col-sm-3 col-md-3 col-lg-3</xsl:attribute>
</xsl:if>
<xsl:if test="image_small != ''">
<div>
<a href="{url}">
<img src="{dir}{image_small}" alt="{name}"/>
</a>
</div>
</xsl:if>
Меняем адрес ссылки, если есть Дополнительное свойство - Ссылка на материал
<xsl:variable name="link">
<xsl:choose>
<xsl:when test="property_value[tag_name='link']/value !=''">
<xsl:value-of disable-output-escaping="yes" select="property_value[tag_name='link']/value" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of disable-output-escaping="yes" select="url" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:choose>
<xsl:when test="property_value[tag_name='link']/value !=''">
<a href="{property_value[tag_name='link']/value}" >
<img src="{dir}{image_small}" class="news_img" alt="" />
</a>
</xsl:when>
<xsl:otherwise>
<img src="{dir}{image_small}" class="news_img" alt="" />
</xsl:otherwise>
</xsl:choose>
Определяем позицию
Добавляем атрибут
<xsl:attribute name="class">
<xsl:choose>
<xsl:when test="position() mod 2 = 0">right</xsl:when>
<xsl:otherwise>left</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
Последний элемент строки
<xsl:if test="position() = last()">
<xsl:attribute name="style">background-image: none</xsl:attribute>
</xsl:if>
<xsl:if test="position() = last()">
<xsl:attribute name="class">last</xsl:attribute>
</xsl:if>
Для меню
<xsl:variable name="position">
<xsl:choose>
<xsl:when test="$count div position() <= 1">4</xsl:when>
<xsl:otherwise>3</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:if test="position() mod $floor = 0 and position() != last()">
<xsl:text disable-output-escaping="yes">
</ul>
<ul>
</xsl:text>
</xsl:if>
Перевод строки после n-элемента
<xsl:if test="position() mod 4 = 0 and position() != last()">
<xsl:text disable-output-escaping="yes">
</ul>
<ul class="shop_table">
</xsl:text>
</xsl:if>
<xsl:if test="position() mod 3 = 0 and position() != last()">
<span class="table_row"></span>
</xsl:if>
<xsl:if test="position() mod 3 = 0 and position() != last()">
<xsl:attribute name="style">background-image: none</xsl:attribute>
</xsl:if>
В списках
<!-- Перевод строки после каждого 2-го элемента -->
<xsl:if test="((position() - 2) mod 2 = 0) and position() != last()">
<xsl:text disable-output-escaping="yes">
</div>
<div class="wrapper">
</xsl:text>
</xsl:if>
В таблице
<xsl:template match="shop_item">
<td>
.............
</td>
<xsl:if test="position() mod 3 = 0">
<xsl:text disable-output-escaping="yes"></tr><tr></xsl:text>
</xsl:if>
</xsl:template>
<div id="gallery" class="board" style="max-width: {$image_width + 50}px">
Вывод сообщение "В данном разделе магазина товаров нет", если раздел пустой
<xsl:if test="count(shop_item) = 0 and .//shop_group[@id=$group]/items_total_count = 0" >В данном разделе
товаров нет</xsl:if>
Вставляем значение дополнительного свойства в ссылку для изображения
<!-- Изображение для информационного элемента (если есть) -->
<xsl:choose>
<xsl:when test="property_value[tag_name='url']/value != ''">
<a href="{property_value[tag_name = 'url']/value}" target="_parent">
<img src="{dir}{image_small}" align="left"/>
</a>
</xsl:when>
<xsl:otherwise>
<img src="{dir}{image_small}" align="left"/>
</xsl:otherwise>
</xsl:choose>
Выводим массив дополнительных свойств - изображения (file)
<xsl:if test="property_value[tag_name='img']/file != ''">
<ul>
<xsl:for-each select="property_value[tag_name='img']">
<li><a href="{../dir}{file}" ><img src="{../dir}{file_small}" alt="{name}" /></a></li>
</xsl:for-each>
</ul>
</xsl:if>
<xsl:for-each select="property_value[tag_name='dopfoto']">
<a href="{../dir}{file}" target="_blank"><img src="{../dir}{file_small}" /></a>
</xsl:for-each>
Вставляем дату и время в XSL шаблон
<dt>
<xsl:value-of select="substring-before(date, '.')"/>
<xsl:variable name="month_year" select="substring-after(date, '.')"/>
<xsl:variable name="month" select="substring-before($month_year, '.')"/>
<xsl:choose>
<xsl:when test="$month = 1"> января </xsl:when>
<xsl:when test="$month = 2"> февраля </xsl:when>
<xsl:when test="$month = 3"> марта </xsl:when>
<xsl:when test="$month = 4"> апреля </xsl:when>
<xsl:when test="$month = 5"> мая </xsl:when>
<xsl:when test="$month = 6"> июня </xsl:when>
<xsl:when test="$month = 7"> июля </xsl:when>
<xsl:when test="$month = 8"> августа </xsl:when>
<xsl:when test="$month = 9"> сентября </xsl:when>
<xsl:when test="$month = 10"> октября </xsl:when>
<xsl:when test="$month = 11"> ноября </xsl:when>
<xsl:otherwise> декабря </xsl:otherwise>
</xsl:choose>
<xsl:value-of select="substring-after($month_year, '.')"/><xsl:text> г.</xsl:text>
</dt>
Заменяем запятую на точку в цене (каталог товаров)
В самом начале шаблона вывода товаров определяем формат вывода
имеется
<xsl:decimal-format name="my" decimal-separator="," grouping-separator=" "/>
добавляем
<xsl:decimal-format name="my1" decimal-separator="." grouping-separator=" "/>
в выводе цены вставляем код
<xsl:value-of select="format-number(price, '### ##0.00', 'my1')"/>
Откладываем в корзину минимальное количество товара по умолчанию
1. Создаем Допсвойство "Минимальное количество" min_quantity, тип строка.
В карточке товара в Допсвойстве "Минимальное количество" указываем минимальное количество для заказа, например, 10шт.
2. В XSL-шаблоне "ИнтернетМагазинКаталогТоваров" или "ИнтернетМагазинТовар" создаем переменную quantum, которая из Допсвойства min_quantity выделяет только числа
3. Вставляем значение переменной $quantum в скрипт кнопки "В корзину"
ПРИМЕР
<div class="actions">
<xsl:variable name="string" select="property_value[tag_name='min_quantity']/value"/>
<!-- Выделяем из строки числа -->
<xsl:variable name="quantum" select="translate($string, translate($string,'0123456789,',''),'')" />
<a data-animation="fadeAndPop" data-reveal-id="modalCart" id="add_to_cart_{@id}" href="#">
<button class="button btn-cart" onclick="return $.bootstrapAddIntoCart('{/shop/url}cart/', {@id}, {$quantum}); yaCounter31644173.reachGoal('addtocart'); return true;" title="В корзину" type="button">
<i class="fa fa-shopping-cart bg-color5">
<b></b>
</i>
<span class="bg-color3"><span>В корзину</span></span>
</button>
</a>
</div>
Обработка даты - приведение к числу для последующего сравнения с другой датой
<xsl:variable name="datetime" select="datetime" />
<xsl:value-of select="concat(substring($datetime, 7, 4), substring($datetime, 4, 2), substring($datetime, 1, 2), substring($datetime, 12, 2), substring($datetime, 15, 2), substring($datetime, 18, 2) )" disable-output-escaping="yes" />
Пересобираем URL (удаление первых трех символов)
<xsl:variable name="url">
<xsl:for-each select="url">
<xsl:variable name="link">
<xsl:value-of select="."/>
</xsl:variable>
<xsl:value-of select='substring($link, 4, string-length($link) - 1)'/>
</xsl:for-each>
</xsl:variable>
<a href="/en{$url}">... </a>
Меняем формат вывода даты
<div class="date">
<xsl:variable name="month_year" select="substring-after(date, '.')"/>
<xsl:variable name="month" select="substring-before($month_year, '.')"/>
<xsl:variable name="time1" select="substring-after(datetime, ' ')"/>
<xsl:variable name="time2" select="substring-after($time1, ':')"/>
<xsl:variable name="hour" select="substring-before($time1, ':')"/>
<xsl:variable name="minutes" select="substring-before($time2, ':')"/>
<span><xsl:value-of select="substring-before(date, '.')"/>.<xsl:value-of select="$month"/> / <xsl:value-of select="$hour"/>:<xsl:value-of select="$minutes"/></span>
</div>
СОРТИРОВКА ТОВАРОВ ОТ МИНИМАЛЬНОЙ ЦЕНЫ ПО УМОЛЧАНИЮ
В XSL-шаблоне МагазинКаталогТоваров заменяем код
<!--===== Выводим товары магазина =====-->
<div class="row products-grid">
<xsl:apply-templates select="shop_item"/>
</div>
на этот
<!--===== Выводим товары магазина =====-->
<div class="row products-grid">
<xsl:apply-templates select="shop_item">
<xsl:sort select="price" order="ascending" data-type="number"/>
</xsl:apply-templates>
</div>
Для сортировки товаров по умолчанию от максимальной цены заменить ascending на descending
Сортировка Допсвойств по id
<xsl:apply-templates select="property_value[not(file/node())]">
<xsl:sort select="property_id" order="ascending" data-type="number"/>
</xsl:apply-templates>
Случайный вывод элементов
<xsl:template match="/">
<xsl:for-each select="shop_item">
<xsl:value-of select="generate-id()"/> <br/>
</xsl:for-each>
</xsl:template>
Выводим надпись "НОВИНКА" для товаров, загруженных за последние 30 дней
<xsl:variable name="сurrent_date" select="/shop/сurrent_date"/>
<xsl:variable name="date" select="translate(date, translate(date, '0123456789', ''), '')"/>
<xsl:variable name="difference_date" select="$сurrent_date - $date" />
<xsl:if test="number($difference_date) < 30">
<div class="ribbon-wrapper-new">НОВИНКА</div>
</xsl:if>
Предварительно добавляем в ТДС Интернет-магазина вывод текущей даты
Текущая дата в Каталоге товаров
Меняем высоту блока, в зависимости от размера файла изображения из Допсвойства
<div id="sub-menu" class="dropdown-menu">
<xsl:if test="property_value[tag_name='img']/file !=''">
<xsl:attribute name="style">height:<xsl:value-of disable-output-escaping="yes" select="20+(property_value[tag_name='img']/file/@height)" />px</xsl:attribute>
// добавляем к высоте картинки 20px, если нужно, изменить параметр
</xsl:if>
.........
</div>
Вывод брендов с разбивкой по алфавиту
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xsl:stylesheet>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:hostcms="http://www.hostcms.ru/"
exclude-result-prefixes="hostcms">
<xsl:output xmlns="http://www.w3.org/TR/xhtml1/strict" doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" encoding="utf-8" indent="yes" method="html" omit-xml-declaration="no" version="1.0" media-type="text/xml"/>
<xsl:key name="a" match="shop_producer" use="substring(name, 1, 1)" />
<!-- МагазинСписокПроизводителей -->
<xsl:template match="/">
<section id="produsers">
<xsl:apply-templates select="shop"/>
</section>
</xsl:template>
<xsl:template match="shop">
<div class="top">
<h1>Бренды</h1>
</div>
<xsl:if test="count(shop_producer) = 0">
<div id="error">Производители не найдены!</div>
</xsl:if>
<div class="block3" style="padding: 5px 0 12px 5px;">
<div class="row">
<ul>
<xsl:apply-templates select="shop_producer" mode="alphabet">
<xsl:sort select="name" order="ascending"/>
</xsl:apply-templates>
</ul>
</div>
<!--xsl:apply-templates select="shop_producer">
<xsl:sort select="name" order="ascending"/>
</xsl:apply-templates-->
</div>
</xsl:template>
<xsl:template match="shop_producer" mode="alphabet">
<xsl:variable name="a" select="substring(name,1,1)"/>
<xsl:if test="not(preceding-sibling::shop_producer[starts-with(name, $a)][1])">
<li class="col-xs-12">
<h4><xsl:value-of select="$a"/></h4>
<div class="row">
<ul>
<xsl:for-each select="/shop/shop_producer">
<xsl:variable name="name" select="substring(name,1,1)"/>
<xsl:if test="$a = $name">
<li class="col-xs-6 col-sm-4 col-md-3 match-height"><a class="producer" href="{/shop/url}producer-{@id}/"><xsl:value-of disable-output-escaping="no" select="name"/></a></li>
</xsl:if>
</xsl:for-each>
</ul>
</div>
</li>
</xsl:if>
</xsl:template>
<xsl:template match="shop_producer">
<a class="producer" href="{/shop/url}producers/{path}/"><xsl:value-of disable-output-escaping="no" select="name"/></a>
</xsl:template>
</xsl:stylesheet>
Интернационализация в XSL-шаблонах
<!DOCTYPE xsl:stylesheet><!DOCTYPE xsl:stylesheet SYSTEM "lang://21"><!DOCTYPE xsl:stylesheet SYSTEM "lang://Search">
<!ENTITY labelSearch "Поиск"><h1>&labelSearch;</h1><img src="/images/my-image.png" alt="&labelSearch;" title="&labelSearch;" />Core::setLng('en');
<?php
return array (
'lngs' => array('en', 'de', 'ru'),
);
Наиболее часто используемые XSLT и XPath функции
Функции XSLT
-
node-set current() — возвращает текущий узел преобразования;
-
node-set document(object, node-set) — позволяет обращаться к внешним документам по заданным URI. Первый узел необязательного параметра node-set принимается за точку отсчета для относительных URI;
-
boolean element-available(string) — проверяет доступность элемента или множества, указанного в параметре. В качестве параметра принимает строку - имя искомого элемента;
-
string format-number(number, format, name?) — возвращает число number в виде строки, отформатированной в соответствии с параметром format. Необязательный параметр name - это имя QName, задающее формат в соответствии правилами элемента <xsl:decimal-format>;
-
boolean function-available(string) — проверяет доступность функции указанной в параметре. В качестве параметра принимает строку - имя функции;
-
string generate-id(node-set) — присваивает уникальный строковый идентификатор первому узлу переданного множества node-set или контекстного узла, если аргумент опущен;
-
node-set key(name, value) — по данному имени name и значению ключа value возвращает множество узлов, которые им обладают. Ключи создаются при помощи элемента <xsl:key>;
-
string system-property(string)— возвращает значения системных свойств, имя которых передается как аргумент;
-
xsl:version — возвращает версию XSLT процессора;
-
xsl:vendor — возвращает производителя XSLT процессора;
-
xsl:vendor-url — возвращает URL, идентифицирующий производителя.
-
string unparsed-entity-uri(string) — предоставляет доступ к не разбираемым сущностям, возвращая URI сущности по ее имени.
Функции XPath
Логические функции
-
boolean boolean(object)— функция возвращает логическое значение переданного ей объекта;
-
number — если число равно нулю возвращает ложь, иначе — истину. NaN всегда возвращает ложь;
-
string — если строка не пуста возвращает истину, иначе — ложь;
-
boolean — значение не изменяется;
-
node-set — пустой набор узлов дает ложь, иначе — истину.
-
boolean false() — функция возвращает ложь;
-
boolean lang(string) — функция проверяет соответствие языка контекстного узла(определенного параметром xml:lang) переданному ей языку в виде строки string;
-
boolean not(boolean) — выполняет логическое отрицание;
-
boolean true() — функция возвращает истину.
Числовые функции
-
number ceiling(number) — округляет аргумент до ближайшего целого, не меньшего переданного функции числа;
-
number floor(number) — округляет аргумент до ближайшего целого, не большего переданного функции числа;
-
number number(object?) — явным образом приводит переданный функции объект в числовой тип. Если аргумент опущен, то применяется к множеству контекстного узла;
-
number round(number) — округляет аргумент до ближайшего целого значения;
-
number sum(node-set) — суммирует значения узлов переданного ей множества.
Строковые функции
-
string concat(string, string, …) — возвращает конкатенацию аргументов;
-
boolean contains(string, string) — принимает на вход два строковых аргумента и возвращает true, если первая строка содержит вторую и false в противном случае;
-
string normalize-space(string?) — удаляет начальные и завершающие разделительные символы, нормализует все внутренние идущие подряд разделители в один пробел. Если аргумент опущен, выполняется со строковым значением контекстного узла;
-
boolean starts-with(string, string) — принимает на вход два строковых аргумента и проверяет начинается ли первая строка со второй;
-
string string(object?) — приводит объект к строковому типу явным образом. Если аргумент опущен, то применяется к множеству контекстного узла;
-
number string-length(string?) — возвращает длину переданного ей строкового аргумента. Если аргумент опущен, то применяется к контекстному узлу;
-
string substring(string, number, number?) — возвращает подстроку переданного ей строкового аргумента, начинающуюся с позиции определенной вторым аргументом и длиной, указанной третьим аргументом. Если третий аргумент не передан, то подстрока продолжается до конца строки;
-
string substring-after(string, string) — принимает на вход два строковых аргумента, находит в первой строке вторую и возвращает подстроку, которая за ней следует;
-
string substring-before(string, string) — принимает на вход два строковых аргумента, находит в первой строке вторую и возвращает подстроку, которая ей предшествует;
-
string translate(string, string, string) — производит замену символов первого своего строкового аргумента, которые присутствуют во втором аргументе на соответствующие символы третьего аргумента.
Функции для работы с наборами узлов
-
number count(node-set) — возвращает число узлов в наборе node-set, переданного ей в качестве аргумента;
-
node-set id(id-value) — возвращает множество узлов по уникальным идентификаторам;
-
number last() — возвращает позицию последнего узла в наборе узлов;
-
string local-name(node-set?) — возвращает локальное (неполное) имя узла, или имя первого узла множества. Если node-set не передан, функция вернет имя контекстного узла;
-
string name(node-set?) — возвращает полное имя узла, или имя первого узла множества. Если node-set не передан, функция вернет локальную часть имени контекстного узла;
-
string namespace-uri(node-set?) — возвращает URI пространства имен а расширенном имени узла;
-
number position() — возвращает позицию контекстного узла в наборе узлов.xsl
Сортировка значений дополнительных свойств
Значения дополнительных свойств выбираются из нескольких таблиц и не имеют порядка сортировки, в отличии от самих дополнительных свойств. Если Вам необходимо выводить значения дополнительных свойств в порядке сортировки свойств, то в XSL-шаблоне необходимо вместо прямого применения шаблона к property_value применять шаблон к property, а из шаблона property применять шаблон к property_value с ограничением по property_id.
Вариант 1
<xsl:template match="shop_item">
...
<xsl:apply-templates select="/shop/shop_item_properties//property">
<xsl:sort
select = "sorting"
data-type = "number"
order = "ascending"
/>
</xsl:apply-templates>
...
</xsl:template>
<xsl:template match="property">
<xsl:variable name="property_id" select="@id" />
<xsl:if test="/shop/shop_item/property_value[property_id = $property_id]/value/node() and /shop/shop_item/property_value[property_id = $property_id]/value != '' or /shop/shop_item/property_value[property_id = $property_id]/type != 2">
<tr>
<td><xsl:value-of disable-output-escaping="yes" select="name"/></td>
<xsl:apply-templates select="/shop/shop_item/property_value[property_id = $property_id]" />
</tr>
</xsl:if>
</xsl:template>
<xsl:template match="/shop/shop_item/property_value">
<xsl:variable name="property_id" select="property_id" />
<xsl:variable name="property" select="/shop/shop_item_properties//property[@id=$property_id]" />
<td style="padding: 5px" bgcolor="#F5F5F5">
<xsl:choose>
<xsl:when test="$property/type = 7">
<input type="checkbox" disabled="disabled">
<xsl:if test="value = 1">
<xsl:attribute name="checked">checked</xsl:attribute>
</xsl:if>
</input>
</xsl:when>
<xsl:otherwise>
<xsl:value-of disable-output-escaping="yes" select="value"/>
</xsl:otherwise>
</xsl:choose>
</td>
</xsl:template>
Рабочий вариант с сайта (вывод свойств разбит по директориям)
<xsl:if test="count(property_value[property_dir_id=14])">
<div class="property_list_title">Габариты и вес</div>
<div class="propertys-property_list">
<xsl:apply-templates select="/shop/shop_item_properties//property[property_dir_id=14]">
<xsl:sort
select = "sorting"
data-type = "number"
order = "ascending"
/>
</xsl:apply-templates>
</div>
</xsl:if>
<xsl:template match="property">
<xsl:variable name="property_id" select="@id" />
<xsl:if test="/shop/shop_item/property_value[property_id = $property_id]/value/node() and /shop/shop_item/property_value[property_id = $property_id]/value != '' or /shop/shop_item/property_value[property_id = $property_id]/type != 2">
<xsl:apply-templates select="/shop/shop_item/property_value[property_id = $property_id]" mode="property_list"/>
</xsl:if>
</xsl:template>
<!-- Вывод строки со значением свойства -->
<xsl:template match="property_value" mode="property_list">
<xsl:f test="value/node() and value != '' or file/node() and file != ''">
<div class="shop_property">
<xsl:variable name="property_id" select="property_id" />
<xsl:variable name="property" select="/shop/shop_item_properties//property[@id=$property_id]" />
<span class="property-name">
<xsl:value-of select="$property/name"/>
</span>
<span class="property-value"><xsl:choose>
<xsl:when test="$property/type = 2">
<a href="{../dir}{file}" target="_blank"><xsl:value-of select="file_name"/></a>
</xsl:when>
<xsl:when test="$property/type = 5">
<a href="{informationsystem_item/url}"><xsl:value-of select="informationsystem_item/name"/></a>
</xsl:when>
<xsl:when test="$property/type = 7">
<input type="checkbox" disabled="disabled">
<xsl:if test="value = 1">
<xsl:attribute name="checked">checked</xsl:attribute>
</xsl:if>
</input>
</xsl:when>
<xsl:when test="$property/type = 12">
<a href="{shop_item/url}"><xsl:value-of select="shop_item/name"/></a>
</xsl:when>
<xsl:otherwise>
<xsl:value-of disable-output-escaping="yes" select="value"/>
<!-- Единица измерения свойства -->
<xsl:if test="$property/shop_measure/node()">
<xsl:text> </xsl:text><xsl:value-of select="$property/shop_measure/name"/>
</xsl:if>
</xsl:otherwise>
</xsl:choose></span>
</div>
</xsl:if>
</xsl:template>
Вариант 2
<!-- Шаблон для товара -->
<xsl:template match="shop_item">
...
<xsl:variable name="myItem" select="." />
<xsl:for-each select="/shop/shop_item_properties//property">
<xsl:variable name="propertyId" select="@id" />
<xsl:choose>
<xsl:when test="count($myItem/property_value[property_id = $propertyId])">
<xsl:apply-templates select="$myItem/property_value[property_id = $propertyId]"/>
</xsl:when>
<xsl:otherwise><td></td></xsl:otherwise>
</xsl:choose>
</xsl:for-each>
...
</xsl:template>
Вариант 3
Используется при сортировке значений дополнительных свойств при выводе списка товаров. Хук вносится в код типовых динамических страниц и добавляет тег sort для значений доп. свойств (в примере для значений свойств целого и строчного типа).
if (!$Shop_Controller_Show->item)
{
class Property_Value_Observer
{
static public function onBeforeGetXml($object, $args)
{
$object->addXmlTag('sort', $object->Property->sorting);
}
}
Core_Event::attach('property_value_string.onBeforeGetXml', array('Property_Value_Observer', 'onBeforeGetXml'));
Core_Event::attach('property_value_int.onBeforeGetXml', array('Property_Value_Observer', 'onBeforeGetXml'));
}
Вариант 4
Сортировка значений одного свойства в порядке добавления достигается указанием <xsl:sort select="@id" />, например:
<xsl:for-each select="property_value[tag_name='img'][file !='']">
<xsl:sort select="@id" />
<div class="item">
<a href="{../dir}{file}" class="elevatezoom-gallery" data-image="{../dir}{file}" data-zoom-image="{../dir}{file}">
<img class="img-responsive" height="150" width="100" src="{../dir}{file}"/>
</a>
</div>
</xsl:for-each>
ШАБЛОН "МагазинСамыеПопулярныеТовары"
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xsl:stylesheet>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:hostcms="http://www.hostcms.ru/" exclude-result-prefixes="hostcms">
<xsl:output xmlns="http://www.w3.org/TR/xhtml1/strict" doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" encoding="UTF-8" indent="yes" method="html" omit-xml-declaration="no" version="1.0" media-type="text/xml"/>
<!-- Шаблон показа популярных товаров.
Основан на шаблоне "МагазинКаталогТоваровНаГлавнойСпецПред" -->
<!-- Кол-во товаров в строку
Если указано 0 то не разбивать, выводить все в одну строку -->
<xsl:param name="items_per_line" select="'3'"/>
<!--Формат вывода чисел-->
<xsl:decimal-format name="my" decimal-separator="," grouping-separator=" "/>
<!--Создадим ключ по идентификатору товара, чтобы оптимизировать выборку товаров при показе в предопределенном порядке -->
<xsl:key name="items_id" match="/shop/shop_item" use="@id"/>
<!--Признак того, что нужно показывать товары в порядке убывания популярности-->
<xsl:variable name="is_ordered_show" select="/shop/popular/method = 'orders' and /shop/popular/item"/>
<xsl:template match="/shop">
<!-- Есть товары -->
<xsl:if test="shop_item">
<h1>Популярные товары</h1>
<!-- Выводим товары магазина -->
<xsl:choose>
<!--Если в XML существуют узлы, описывающие порядок показа товаров-->
<xsl:when test="$is_ordered_show">
<!--то запустим цикл по этим узлам-->
<xsl:for-each select="popular/item">
<xsl:sort select="@order" data-type="number" order="ascending"/>
<!--и для каждого id товара будем вызывать темплейт item, передавая в него узел соответствующего товара, выбранный с помощью ключа-->
<xsl:apply-templates select="key('items_id', .)">
<xsl:with-param name="ordered_count" select="current()/@count"/>
</xsl:apply-templates>
<!--Если показываем товары в порядке убывания популярности,
то добавляем разбивку по N товаров в строке
ЗДЕСЬ.-->
<xsl:if test="$items_per_line > 3 and position() mod $items_per_line = 3 and position() != last()">
<div style="margin-top:20px;" class="clear"/>
</xsl:if>
</xsl:for-each>
</xsl:when>
<!--а в случае рандомного показа просто вызовем темплейт item для всех товаров описанных в XML-->
<xsl:otherwise>
<xsl:apply-templates select="shop_item"/>
</xsl:otherwise>
</xsl:choose>
<div class="clear"></div>
</xsl:if>
</xsl:template>
<!-- Шаблон для товара -->
<xsl:template match="shop_item">
<div class="shop-item">
<div class="inner">
<a href="{url}" title="Подробная информация // {name} // {shop_producer/name}" class="item-images-inner">
<!-- Изображение для товара, если есть -->
<xsl:choose>
<xsl:when test="image_small!=''" >
<img src="{dir}{image_small}" alt="{name}" class="item-image" />
</xsl:when>
<xsl:otherwise>
<img src="/images/no_img.jpg" alt="{name}" />
</xsl:otherwise>
</xsl:choose>
<img src="/images/bg-item.png" alt="{name}" class="item-image-back" />
</a>
<xsl:if test="property_value[tag_name = 'hit'] != ''">
<span class="hit"></span>
</xsl:if>
<!-- Название товара -->
<span class="price">
<xsl:value-of select="shop_producer/name" />
<!--<xsl:value-of disable-output-escaping="yes" select="name"/>--><xsl:text> / </xsl:text>
<xsl:if test="marking != ''">
<span><xsl:value-of disable-output-escaping="yes" select="marking"/></span><xsl:text> / </xsl:text>
</xsl:if>
<!-- Цена товара -->
<xsl:choose>
<xsl:when test="price != 0">
<span>
<xsl:variable name="price" select="price"/>
<xsl:value-of select="format-number($price, '### ##0', 'my')"/> 
<!-- Валюта товара -->
<xsl:value-of disable-output-escaping="yes" select="currency"/>
</span>
</xsl:when>
<xsl:otherwise>
<span class="shop_price">под заказ</span>
</xsl:otherwise>
</xsl:choose>
<!-- Если цена со скидкой - выводим ее -->
<xsl:if test="price_tax != price">
<span style="color: gray; text-decoration: line-through;">
<xsl:variable name="price_tax" select="price_tax"/>
<span style="font-size: 11pt">
<xsl:value-of select="format-number($price_tax, '### ##0', 'my')"/> <xsl:value-of disable-output-escaping="yes" select="currency"/>
</span>
</span>
</xsl:if>
</span>
</div>
<div class="clear"></div>
</div>
<!-- Перевод строки после каждого 3-го элемента -->
<xsl:if test="((position() - 3) mod 3 = 0) and position() != last()">
<xsl:text disable-output-escaping="yes">
</div>
<div class="wrapper">
</xsl:text>
</xsl:if>
</xsl:template>
<!-- Склонение после числительных -->
<xsl:template name="declension">
<xsl:param name="number" select="number"/>
<!-- Именительный падеж -->
<xsl:param name="nominative" select="nominative"/>
<!-- Родительный падеж, единственное число -->
<xsl:param name="genitive_singular" select="genitive_singular"/>
<!-- Родительный падеж, множественное число -->
<xsl:param name="genitive_plural" select="genitive_plural"/>
<xsl:variable name="last_digit">
<xsl:value-of select="$number mod 10"/>
</xsl:variable>
<xsl:variable name="last_two_digits">
<xsl:value-of select="$number mod 100"/>
</xsl:variable>
<xsl:choose>
<xsl:when test="$last_digit = 1 and $last_two_digits != 11">
<xsl:value-of select="$nominative"/>
</xsl:when>
<xsl:when test="$last_digit = 2 and $last_two_digits != 12 or $last_digit = 3 and $last_two_digits != 13 or $last_digit = 4 and $last_two_digits != 14">
<xsl:value-of select="$genitive_singular"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$genitive_plural"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
