Класс active к активной ссылке

#
Класс active к активной ссылке
Добрый день, есть XSL шаблон для вывода групп и подгрупп для выподающего меню

<?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:template match="/">
      <xsl:apply-templates select="/shop"/>
   </xsl:template>
   
   
   
   <!-- Шаблон для магазина -->
   <xsl:template match="/shop">
      <ul class="dropdown">
         <xsl:apply-templates select="shop_group"/>
      </ul>
   </xsl:template>
   
   
   <!-- Шаблон для групп товара -->
   <xsl:template match="shop_group">

      <xsl:variable name="nesting_level" select="count(ancestor::*)"/>
      <xsl:variable name="parent" select="@id"/>
      <xsl:variable name="parent_group_id">
         <xsl:choose>
            <xsl:when test="/shop/ТекущаяГруппа/node()"><xsl:value-of select="/shop/ТекущаяГруппа"/></xsl:when>
            <xsl:otherwise>-1</xsl:otherwise>
         </xsl:choose>
      </xsl:variable>
      
      <xsl:variable name="this_group_has_subgroups"    select="subgroups_count &gt; 0" />
      <xsl:variable name="this_group_is_current"    select="@id = $parent_group_id" />
      <xsl:variable name="has_subgroups"    select="(@id = $parent_group_id and count(shop_group) &gt; 0)
         or (@id != $parent_group_id and count(.//shop_group[@id = $parent_group_id]) &gt; 0)" />
      <xsl:variable name="item_nesting_level">
         level-<xsl:value-of disable-output-escaping="yes" select="$nesting_level+1"/>
      </xsl:variable>

      <!-- Готовим класс элемента -->
      <xsl:variable name="item_css_class">
         <xsl:if test="$this_group_has_subgroups = 1"> sub</xsl:if>
         <xsl:if test="$this_group_is_current = 1"> active</xsl:if>
      </xsl:variable>
            
      <li>
         <xsl:if test="normalize-space($item_css_class) != '' ">
            <xsl:attribute name="class">
               <xsl:value-of disable-output-escaping="yes" select="normalize-space($item_css_class)"/>
            </xsl:attribute>
         </xsl:if>
         <xsl:if test="$this_group_is_current = 1">
            <span title="{name}" hostcms:id="{@id}" hostcms:field="name" hostcms:entity="shop_group">
               <xsl:value-of disable-output-escaping="yes" select="name"/>
            </span>
         </xsl:if>
         <xsl:if test="@id != $parent_group_id">
            <a href="{url}" title="{name}" hostcms:id="{@id}" hostcms:field="name" hostcms:entity="shop_group">
               <xsl:value-of disable-output-escaping="yes" select="name"/>
            </a>
         </xsl:if>
         
         <!--<a href="{url}" hostcms:id="{@id}" hostcms:field="name" hostcms:entity="shop_group">
            <xsl:value-of disable-output-escaping="yes" select="name"/>
         </a>-->
         
         <!-- Если есть подгруппы -->
         <xsl:if test="shop_group">
            <!--<ul class="left_menu gray_link gray" id="{@id}" style="display: none;">-->
               <ul class="sub_menu"  id="{@id}">
                  <xsl:apply-templates select="shop_group"/>
               </ul>
            </xsl:if>
         </li>
      </xsl:template>
   </xsl:stylesheet>


Как исправить шаблон что бы на активной ссылке когда мы по ней перешли добавлялся класс например active?

БОЛЬШОЕ СПАСИБО!
#
Re: Класс active к активной ссылке
нужно сделать проверку если текущая группа ровна id группы в шаблоне, то добавить атрибут class active
www.morozovpimnev.ru - создание, поддержка и продвижение сайтов | Наш канал https://asmp.su/channel
#
Re: Re: Класс active к активной ссылке
а как добавить к class значение active, если уже есть одно значение там? Т.е. если я сделал
<xsl:if test="@id = 419">
            <xsl:attribute name="class">mac</xsl:attribute>
         </xsl:if>

То как добавить к этому классу еще active,чтобы было 'mac active'?
Если просто
<xsl:if test="$current_structure_id = @id
            or count(.//structure[@id=$current_structure_id]) = 1">
            <xsl:attribute name="class">active</xsl:attribute>
         </xsl:if>

то значение ведь просто перезаписывается.
#
Re: Класс active к активной ссылке
попробывать так
<xsl:attribute name="class">mac active</xsl:attribute>
www.morozovpimnev.ru - создание, поддержка и продвижение сайтов | Наш канал https://asmp.su/channel
#
Re: Re: Класс active к активной ссылке
Не, такой вариант не подходит. Слишком много придется делать if ну или when конструкций. Как можно получить значение атрибута сlass? Если бы можно было его получить и объединить с новым, то было бы супер.
Объединить можно через concat, наверное придется в переменную пихать класс первоначальный
#
Re: Класс active к активной ссылке
GoodRoot писал(а):
Не, такой вариант не подходит. Слишком много придется делать if ну или when конструкций.
Это нормально, большие развесистые конструкции условий это вообще одна из характерных особенностей XSLT.

Чтобы не морочится с лишней переменной, можно засунуть условие внутрь атрибута:
<li>
   <!--Вычисляем класс-->
   <xsl:attribute name="class">
      <!--Проверим активность пункта-->
      <xsl:if test="$current_structure_id = @id or .//structure[@id=$current_structure_id]">
         <xsl:text>active</xsl:text>
      </xsl:if>
      <!--Пробел между классами-->
      <xsl:text> </xsl:text>
      <!--Добавим дополнительный класс, если надо-->
      <xsl:choose>
         <xsl:when test="@id = 419">
            <xsl:text>mac</xsl:text>
         </xsl:when>
         <xsl:when test="@id = 999">
            <xsl:text>win</xsl:text>
         </xsl:when>
      </xsl:choose>
   </xsl:attribute>

   <a href="{url}">
      <xsl:value-of select="name"/>
   </a>
</li>

Для XSLT это очень элегантное решение
Заказов не беру. Консультирую редко.
#
Re: Класс active к активной ссылке
И кстати, count в проверке активности пункта не нужен. Во1х, потому что count это очень накладно, во2х, если среди потомков текущего узла есть узел с @id=$current_structure_id, то выражение .//structure[@id=$current_structure_id] само по себе даст истину, а если нет - то ложь.
Поэтому в моем примере уже использована упрощенная логика.
Заказов не беру. Консультирую редко.
#
Re: Re: Класс active к активной ссылке
Kotoff писал(а):
И кстати, count в проверке активности пункта не нужен.

Так это вообще стандартная конструкция. Разрабы что-то не так написали?!
#
Re: Класс active к активной ссылке
GoodRoot, чувствуете разницу между "стандартная" и "оптимальная"?
Разработчики системы написали все верно, но в их вариант заложена избыточная проверка количества, которая на самом деле ни к чему, потому что исходя из устройства системы, для любого значения @id у вас не может быть более одного узла structure, т.е. count нам вернет либо 0 либо 1, а чем это лучше чем false/true? Но операция count затратна, в то время как простая проверка по xpath - дешева.
Кроме того, допустим у нас что-то в системе сломалось и пусть у нас среди потомков текущего узла structure оказалось вдруг два узла с @id=$current_structure_id, т.е. count вернет нам двойку. Но это же не повод, не отмечать текущий пункт активным. Т.е. условие нужно трансформировать в count() > 0, а в таком виде оно вообще теряет какие-либо преимущества перед простой xpath-проверкой.

Почему в родных шаблонах применены неоптимальные конструкции, тоже в общем-то достаточно очевидно. Эти шаблоны - учебные, по их коду и комментариям любой желающий может постепенно вникнуть в XSLT. А оптимальные конструкции, конечно, работают быстрее но зачастую имеют довольно неочевидный синтаксис, затрудняющий понимание языка, и без того не самого легкого для неподготовленного человека.

GoodRoot писал(а):
Разрабы что-то не так написали?!
И давайте все-таки повежливее к разработчикам.
Заказов не беру. Консультирую редко.
#
Re: Re: Класс active к активной ссылке
Kotoff, спасибо за конструктивный ответ. Все отлично работает. Возможно, кому-то тоже пригодится такое решение.
Авторизация