Реализация выпадающего меню на базе структуры сайта с помощью xsl-шаблона

#
Реализация выпадающего меню на базе структуры сайта с помощью xsl-шаблона
Для отображения какого-либо меню сайта в виде выпадающего меню, основанного на узлах структуры сайта, нужно, во-первых, создать xsl-шаблон, например под названием "ВыпадающееМеню", и вставить в него следующий код:
<?xml version="1.0" encoding="windows-1251"?>
<!DOCTYPE xsl:stylesheet>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output xmlns="http://www.w3.org/TR/xhtml1/strict" doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
encoding="Windows-1251" indent="no" method="html" omit-xml-declaration="no" version="1.0" media-type="text/xml" />

<xsl:template match="/document">
<table border="0" cellpadding="0" cellspacing="0" width="100%" style="margin-top: 2px; margin-left: 0px;">
   <tr>
      <xsl:apply-templates select="structure[show=1]"/>
   </tr>
</table>
</xsl:template>

<xsl:template match="structure">

<xsl:param name="posit" select="1" />


<xsl:variable name="current_structure_id" select="/document/structure/current_structure_id"/>
<xsl:if test="show_link = 1">
    <!-- Определяем адрес ссылки -->
         <xsl:variable name="link"><xsl:choose>
            <!-- Если внешняя ссылка -->
            <xsl:when test="is_external_link=1"><xsl:value-of disable-output-escaping="yes" select="external_link"/></xsl:when>
            <!-- Иначе если внутренняя ссылка -->
            <xsl:otherwise><xsl:value-of disable-output-escaping="yes" select="link"/></xsl:otherwise>
         </xsl:choose></xsl:variable>
        
         <!-- Определяем стиль вывода ссылки -->
         <xsl:variable name="link_style"><xsl:choose>
            <!-- Выделяем текущую страницу жирным (если это текущая страница, либо у нее есть ребенок с ID, равным текущей) -->
            <xsl:when test="current_structure_id=@id or count(.//structure[@id=$current_structure_id])=1">font-weight: bold</xsl:when>
            <!-- Иначе обычный вывод с пустым стилем -->
            <xsl:otherwise></xsl:otherwise>
         </xsl:choose></xsl:variable>
        
   <xsl:choose>
      <xsl:when test="level=0">
         <xsl:choose>
            <xsl:when test="count(structure[show=1]) > 0">
              
              
               <td valign="top" OnMouseOver="JavaScript:SlideLayer('id_{@id}');" OnMouseOut="JavaScript:SlideLayerHide('id_{@id}');">

<div>                  
<a href="{$link}" class="menu_center"><xsl:value-of select="name"/></a>
</div>
                  
                  
                  <div style="display: none; z-index: 10; padding-right: 0; margin-top: 1px; margin-left: 0px; margin-right: 0px;" id="id_{@id}">
                    
                     <table border="0" cellpadding="0" cellspacing="0">
                  
                        <xsl:variable name="posit_var" select="position()"/>
                        
                        <xsl:apply-templates select="structure[show=1]">
                              
                           <xsl:with-param name="posit" select="$posit_var"/>
                          
                        </xsl:apply-templates>                  
                    
                     </table>
                  </div>                  
               </td>
              
                  
            </xsl:when>
            <xsl:otherwise>
               <td  valign="top" align="center">                  
                    
                        <a href="{$link}" class="menu_center"><xsl:value-of select="name"/></a>
                              
               </td>            
            </xsl:otherwise>            
         </xsl:choose>
      
      
      </xsl:when>
      <xsl:otherwise>
    
        
         <tr>
            
            <td><a href="{$link}" class="menu_link_no_bold"><xsl:value-of select="name"/></a>
</td>
            
         </tr>
    
      </xsl:otherwise>
   </xsl:choose>
  
</xsl:if>
</xsl:template>
</xsl:stylesheet>


Затем в html-код макета, на страницах котором планируется вывод нашего меню, нужно импортировать файл со скриптами, написанными на языке javascript. Это будет внешний файл, хранящийся на сервере. Если, например, этот самый файл хранится в директории images и имеет имя menu.js, то импортировать его можно так в секции <head>:
<script type="text/javascript" src="/images/menu.js"></script>
. Вот исходный код подобного файла menu.js:
function SlideLayer(Num)
   {
   var el = document.getElementById(Num);
   if (el.style.display=="none" )
      {
         el.style.display="block";
         el.style.position="absolute";
      }
   }
         
function SlideLayerHide(Num)
   {
   var el = document.getElementById(Num);
   if (el.style.display=="block" )
      {
         el.style.display="none";
         el.style.position="absolute";
      }
   }

Теперь только осталось в макете (для которого планируется отображение меню) дописать показ структуры на основе, например, меню №8:
<?php
$Structure = new Structure();
$Structure->ShowStructure(8,'ВыпадающееМеню');
?>
#
Re: Реализация выпадающего меню на базе структуры сайта с помощью xsl-шаблона
Вот еще один вариант горизонтального выпадающего меню для ИнфоСистемы.


<?xml version="1.0" encoding="windows-1251"?>
<!DOCTYPE xsl:stylesheet>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output xmlns="http://www.w3.org/TR/xhtml1/strict" doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
encoding="Windows-1251" indent="yes" method="html" omit-xml-declaration="no" version="1.0" media-type="text/xml" />

<!-- ############################################ -->
<!-- XSL Шаблон Для ИнфоСистемы "Выпадающее меню" -->
<!-- ############################################ -->

<xsl:template match="/">
    <xsl:apply-templates/>
</xsl:template>

<xsl:template match="/document">

      <xsl:comment>
         <xsl:text disable-output-escaping="yes">
         <![CDATA[
         function SlideLayer(Num)
         {
            var el = document.getElementById(Num);
            if (el.style.display=="none" )
            {
               el.style.display="block";
               el.style.position="absolute";            
            }   
         }
         
         function SlideLayerHide(Num)
         {
            var el = document.getElementById(Num);
            if (el.style.display=="block" )
            {
               el.style.display="none";
               el.style.position="absolute";            
            }   
         }
         ]]>
         </xsl:text>
      </xsl:comment>
   
   
   <!-- Получаем ID родительской группы и записываем в переменную $parent_group_id -->
   <xsl:variable name="parent_group_id" select="blocks/parent_group_id"/>   
   <!-- Если в находимся корне - выводим название информационной системы -->
   <xsl:if test="blocks/parent_group_id=0">
      <!--<h1><xsl:value-of disable-output-escaping="yes" select="blocks/name"/></h1>-->
      <xsl:value-of disable-output-escaping="yes" select="blocks/description"/>
   </xsl:if>
   <!-- Если в находимся в группе - выводим название группы -->
   <xsl:if test="blocks/parent_group_id!=0">
      <h1><xsl:value-of disable-output-escaping="yes" select=".//group[@id=$parent_group_id]/name"/></h1>      
   </xsl:if>
   <!-- Отображение подгрупп данной группы -->
   <div style="width: 185px; position: relative;">
      <xsl:apply-templates select=".//group[@parent_id=$parent_group_id]" mode="groups"/>
   </div>
</xsl:template>


<xsl:template match="group" mode="groups">   
   <!-- Если группа содержит описание, то выводим ссылку на страницу -->
      <xsl:choose>
         <xsl:when test="propertys/property/value!=''">
         <xsl:variable name="top" select="26*(position()-1)"/>
         <div OnMouseOver="JavaScript:SlideLayer('id_{@id}');" OnMouseOut="JavaScript:SlideLayerHide('id_{@id}');" class="menu_level_1"><a href="{/document/blocks/url}{fullpath}" style="text-decoration: none;"><b><xsl:value-of disable-output-escaping="yes" select="name"/></b></a>
            <!-- Если группа содержит вложенные группы, то вызываем шаблон для вложенных групп -->
            <xsl:if test="@id=group/@parent_id or @id=//item/@group_id">
               <div id="id_{@id}" style="position: aboslute; top: -1px; display: none; left: 190px;">
                  <!-- Если группа содержит вложенные группы, то вызываем шаблон для вложенных групп -->
                  <xsl:if test="@id=group/@parent_id">
                     <xsl:apply-templates select="group" mode="groups_level_2"/>
                  </xsl:if>
                  <xsl:variable name="id_parent_group" select="@id"/>                  
                  <xsl:if test="@id=//item/@group_id">
                     <xsl:apply-templates select="//item[@group_id=$id_parent_group]" mode="item_level_2"/>
                  </xsl:if>
               </div>
            </xsl:if>
         </div>               
         </xsl:when>
         <!-- Иначе выводим просто текст -->
         <xsl:otherwise>
         <xsl:variable name="top" select="26*(position()-1)"/>
         <div OnMouseOver="JavaScript:SlideLayer('id_{@id}');" OnMouseOut="JavaScript:SlideLayerHide('id_{@id}');" class="menu_level_1">
            <font color="#0089CE" style="cursor: default;"><b><xsl:value-of disable-output-escaping="yes" select="name"/></b></font>
            <xsl:if test="@id=group/@parent_id or @id=//item/@group_id">
            <div id="id_{@id}" style="position: aboslute; top: -1px; display: none; left: 190px;">
               <!-- Если группа содержит вложенные группы, то вызываем шаблон для вложенных групп -->
               <xsl:if test="@id=group/@parent_id">
                  <xsl:apply-templates select="group" mode="groups_level_2"/>
               </xsl:if>
               <xsl:variable name="id_parent_group" select="@id"/>                  
               <xsl:if test="@id=//item/@group_id">
                  <xsl:apply-templates select="//item[@group_id=$id_parent_group]" mode="item_level_2"/>
               </xsl:if>
            </div>            
            </xsl:if>            
         </div>         
         </xsl:otherwise>
      </xsl:choose>         
</xsl:template>

<!-- =========================================== -->
<!-- Шаблон для групп второго уровня вложенности -->
<!-- =========================================== -->
<xsl:template match="group" mode="groups_level_2">   
      <!-- Если группа содержит описание, то выводим ссылку на страницу -->
      <xsl:choose>
         <xsl:when test="propertys/property/value!=''">
            <div OnMouseOver="JavaScript:SlideLayer('id_{@id}');" OnMouseOut="JavaScript:SlideLayerHide('id_{@id}');" class="menu_level_2"><a href="{/document/blocks/url}{fullpath}" style="text-decoration: none;"><b><xsl:value-of disable-output-escaping="yes" select="name"/></b></a>
            <xsl:if test="@id=group/@parent_id or @id=//item/@group_id">
               <div id="id_{@id}" style="position: aboslute; top: -1px; display: none; left: 195px;">
                  <!-- Если группа содержит вложенные группы, то вызываем шаблон для вложенных групп -->
                  <xsl:if test="@id=group/@parent_id">
                     <xsl:apply-templates select="group" mode="groups_level_2"/>
                  </xsl:if>
                  <xsl:variable name="id_parent_group" select="@id"/>                  
                  <xsl:if test="@id=//item/@group_id">
                     <xsl:apply-templates select="//item[@group_id=$id_parent_group]" mode="item_level_2"/>
                  </xsl:if>
               </div>
            </xsl:if>
            </div>                  
         </xsl:when>
         <!-- Иначе выводим просто текст -->
         <xsl:otherwise>
            <div OnMouseOver="JavaScript:SlideLayer('id_{@id}');" OnMouseOut="JavaScript:SlideLayerHide('id_{@id}');" class="menu_level_2">
               <font color="#0089CE" style="cursor: default;"><b><xsl:value-of disable-output-escaping="yes" select="name"/></b></font>         
            <xsl:if test="@id=group/@parent_id or @id=//item/@group_id">
               <div id="id_{@id}" style="position: aboslute; top: -1px; display: none; left: 195px;">
                  <!-- Если группа содержит вложенные группы, то вызываем шаблон для вложенных групп -->
                  <xsl:if test="@id=group/@parent_id">
                     <xsl:apply-templates select="group" mode="groups_level_2"/>
                  </xsl:if>
                  <xsl:variable name="id_parent_group" select="@id"/>                  
                  <xsl:if test="@id=//item/@group_id">
                     <xsl:apply-templates select="//item[@group_id=$id_parent_group]" mode="item_level_2"/>
                  </xsl:if>
               </div>
            </xsl:if>
            </div>
         </xsl:otherwise>
      </xsl:choose>
</xsl:template>

<xsl:template match="item" mode="item_level_2">
   <!-- Если элемент содержит описание, то выводим ссылку на страницу -->
   <div class="item_menu"><a href="{item_path}" style="text-decoration: none;"><b><xsl:value-of disable-output-escaping="yes" select="item_name"/></b></a></div>
</xsl:template>
</xsl:stylesheet>
#
Re: Реализация выпадающего меню на базе структуры сайта с помощью xsl-шаблона
..а в CSS добавить 3 класса.

.menu_level_1
{
   margin-bottom: 1px;
   border: 1px solid #dddddd;
   padding: 5px;
   position: relative;
   width: 180px;
}
.menu_level_2
{
   border: 1px solid #dddddd;
   padding: 5px;
   position: relative;
   width: 185px;
   margin-bottom: 1px;
   background-color: #ffffff;
}

.item_menu
{
   border: 1px solid #dddddd;
   padding: 5px;
   position: relative;
   width: 170px;
   margin-bottom: 1px;
   background-color: #fafffa;
}
#
Re: Реализация выпадающего меню на базе структуры сайта с помощью xsl-шаблона
lozoffoy, почему то не работает ваш код.
Делаю сайты на HostCMS! Подробнее по почте anton.yurzanov@gmail.com
#
Re: Реализация выпадающего меню на базе структуры сайта с помощью xsl-шаблона
Он и не будт работать! ))
В XSL`е, код

<xsl:comment>
         <xsl:text disable-output-escaping="yes">
         <![CDATA[
         function SlideLayer(Num)
         {
            var el = document.getElementById(Num);
            if (el.style.display=="none" )
            {
               el.style.display="block";
               el.style.position="absolute";            
            }  
         }
        
         function SlideLayerHide(Num)
         {
            var el = document.getElementById(Num);
            if (el.style.display=="block" )
            {
               el.style.display="none";
               el.style.position="absolute";            
            }  
         }
         ]]>
         </xsl:text>
      </xsl:comment>


..заключите в тег <SСRIРТ>...<SСRIРТ> (пишу кириллицей).
А форум, их просто "обрезал".
#
Re: Реализация выпадающего меню на базе структуры сайта с помощью xsl-шаблона
lozoffoy, ваш код вообще не выводит ссылки! про выпадающее менюя и не мечтал (все равно бы делал по своему)
Делаю сайты на HostCMS! Подробнее по почте anton.yurzanov@gmail.com
#
Re: Re: Реализация выпадающего меню на базе структуры сайта с помощью xsl-шаблона
Ссылки в меню выводятся только на элементах IS и на группах имеющих описание (как собственно и должно быть).
Дабы удостовериться, код лично скопировал с форума и применил к ИнфоСистеме. Все сразу заработало.
#
Re: Реализация выпадающего меню на базе структуры сайта с помощью xsl-шаблона
Вопрос для Varkolak, - у вас в подписе написано: [Занимаюсь разработкой сайтов на HostCMS]
Сколько будет стоить сделать диз. и шаблон для www.climatservise.ru
Климатическая техника в Санкт Петербурге
#
Re: Реализация выпадающего меню на базе структуры сайта с помощью xsl-шаблона
lozoffoy  уточните пожалуйста про <SСRIРТ>
сделал меню по вашему варианту - не работает
дядя Федор®
#
Re: Реализация выпадающего меню на базе структуры сайта с помощью xsl-шаблона
установил script, но не работает... прост пустота вместо меню
дядя Федор®
Авторизация