Xpoint
   [напомнить пароль]

Прошу помочь с версткой в 2 колонки, а заодно раскритиковать

Метки: [без меток]
2009-05-07 12:14:41 [обр] walek[досье]

Привет друзья.

Сделал макет для внутреннего использования газеты «Ведомости».
Макет доступен тут http://photofile.ru/users/zishnik/115366563/126732332/full_image/

Пару слов по макету:
— 2-х колоночный дизайн.
— Две полосы: А1 и Б1 (на макете они не обозначены намерено, в XML они присутствуют) разделяют статьи на 2-х колоночный дизайн.
— Первые заголовки статей полос А1 и Б1 отличаются цветом и размером шрифта. Это важно.
— Статьи группируются по категориям (пример, Власть / Деньги и Индустрия / Энергоресурсы, выделены зеленым) и соответственно отделяются друг от друга.
— В левой колонке должны находится статьи, сгруппированные по соответствующим категориям, до категории Б1, в правой соответственно, все статьи после категории Б1. Это очень важно.

XML газеты расположен тут http://www.vedomosti.ru/newspaper/out/rss.xml

Вот такой XSLT попытался написать.

<?xml version="1.0" encoding="WINDOWS-1251"?>
<xsl:stylesheet
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:msxsl="urn:schemas-microsoft-com:xslt"
  xmlns:ext="urn:extension-functions"
  exclude-result-prefixes="msxsl ext">
  
<xsl:output method="html" encoding="windows-1251" indent="yes" />
<xsl:param name="line" select="item[category='Полоса А1']" />
<xsl:key name="firstline" match="item[not(category='Полоса А1') and (following-sibling::item/category='Полоса Б1')]" use="category" />

<xsl:template match="channel">
   <div style="float: left; width: 50%;">
      <xsl:apply-templates select="item[category='Полоса А1'][1]" mode="A1" /><br /><br /><br />
      
      <xsl:for-each select="item[category='Полоса А'][not(position()=1)]">
         <p style="color: green; font-weight: bold;">
            <xsl:value-of select="title" disable-output-escaping="yes" />
         </p>
         <xsl:value-of select="description" disable-output-escaping="yes" />
      </xsl:for-each>
      
      <xsl:apply-templates mode="head" select="item[generate-id(.)=generate-id(key('firstline',category))]" />
   </div>
   
   <div style="width: 50%; display: inline;">
      <xsl:apply-templates select="item[category='Полоса Б1'][1]" mode="B1" /><br /><br /><br /><br />
      
      <xsl:for-each select="item[category='Полоса Б1'][not(position()=1)]">
         <p style="color: green; font-weight: bold;">
            <xsl:value-of select="title" disable-output-escaping="yes" />
         </p>
         <xsl:value-of select="description" disable-output-escaping="yes" />
      </xsl:for-each>
   </div>
   
   <div style="clear: both;"></div>
<!--Информация для статистики-->
   Количество категорий — <xsl:value-of select="count(item[not(category=preceding-sibling::item/category)])" /><br />
   Количество статей — <xsl:value-of select="count(item/title)" /><br />
   Количество статей исключая полосы А1 и Б1 — <xsl:value-of select="count(item[not(category='Полоса А1') and not(category='Полоса Б1')])" />
</xsl:template>

<xsl:template match="item" mode="A1">
      <strong><xsl:value-of select="title" disable-output-escaping="yes" /></strong><br />
      <xsl:value-of select="description" disable-output-escaping="yes" />
</xsl:template>

<xsl:template match="item" mode="B1">
      <strong><xsl:value-of select="title" disable-output-escaping="yes" /></strong><br />
      <xsl:value-of select="description" disable-output-escaping="yes" />
</xsl:template>

<xsl:template match="item" mode="head">
   <p style="color: red;">
      <xsl:value-of select="category" />
   </p>
   <xsl:apply-templates mode="item" select="key('firstline', category)" />
</xsl:template>

<xsl:template match="item" mode="item">
<xsl:variable name="issueNum" select="normalize-space(substring-before(substring-after(/rss/channel/description, '&#185;'),' ('))" />
            <xsl:choose>
             <xsl:when test="string-length($issueNum) = 1">
                  <a href="/Athenaeum/Vedomosti/{substring(/rss/channel/description, 20, 4)}/XML/V{substring(/rss/channel/description, 22, 2)}00{$issueNum}{substring(link, 59, 7)}.htm">
                     <xsl:value-of select="title" disable-output-escaping="yes" />
                  </a><br />
                  <xsl:value-of select="description" disable-output-escaping="yes" /><br /><br />
            </xsl:when>
            <xsl:when test="string-length($issueNum) = 2">
                  <a href="/Athenaeum/Vedomosti/{substring(/rss/channel/description, 20, 4)}/XML/V{substring(/rss/channel/description, 22, 2)}0{$issueNum}{substring(link, 59, 7)}.htm">
                     <xsl:value-of select="title" disable-output-escaping="yes" />
                  </a><br />
               <xsl:value-of select="description" disable-output-escaping="yes" /><br /><br />
            </xsl:when>
            <xsl:when test="string-length($issueNum) = 3">
                  <a href="/Athenaeum/Vedomosti/{substring(/rss/channel/description, 20, 4)}/XML/V{substring(/rss/channel/description, 22, 2)}{$issueNum}{substring(link, 59, 7)}.htm">
                     <xsl:value-of select="title" disable-output-escaping="yes" />
                  </a><br /><br />
               <xsl:value-of select="replacedescription" disable-output-escaping="yes" /><br />
            </xsl:when>
            </xsl:choose>
</xsl:template>
</xsl:stylesheet>

Сейчас это рабочий макет, поэтому прошу не обращать внимание на верстку.
Вышеприведенный текст реализует идею только в левом столбике.
В правом только статьи из категории Б1.

Как мне кажется я делаю совершенно неправильно.
Поясню. Мне кажется, что шаблон <xsl:template match="item" mode="item"> должен быть единым для обеих колонок, а в моей реализации для того, чтобы отобразить в правой колонке статьи после категории Б1, нужно дописать еще 2 шаблона, практически идентичных, только переименовать, что на мой вгляд в корне неправильно.

А как сделать по-другому не знаю.
Может у вас есть идеи элегантнее?

Спасибо!

спустя 1 час 28 минут [обр] walek[досье]
Сделал так, но прошу покритиковать.
<?xml version="1.0" encoding="WINDOWS-1251"?>
<xsl:stylesheet
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:msxsl="urn:schemas-microsoft-com:xslt"
  xmlns:ext="urn:extension-functions"
  exclude-result-prefixes="msxsl ext">
  
<xsl:output method="html" encoding="windows-1251" indent="yes" />
<!--<xsl:key name="firstline" match="item[not(category='Полоса А1') and (following-sibling::item/category='Полоса Б1')]" use="category" />-->
<xsl:key name="leftLine" match="item[not(category='Полоса А1') and (following-sibling::item/category='Полоса Б1') and not(category='Полоса Б1')]" use="category" />
<xsl:key name="rightLine" match="item[not(category='Полоса А1') and (preceding-sibling::item/category='Полоса Б1') and not(category='Полоса Б1')]" use="category" />

<xsl:template match="channel">
   <div style="float: left; width: 50%;">
      <xsl:apply-templates select="item[category='Полоса А1'][1]" mode="A1" /><br /><br /><br />
      <!--<xsl:apply-templates select="item[category='Полоса А1'][not(position()=1)]" mode="A1" /><br />-->
      
      <xsl:for-each select="item[category='Полоса А1'][not(position()=1)]">
         <p style="color: green; font-weight: bold;">
            <xsl:value-of select="title" disable-output-escaping="yes" />
         </p>
         <xsl:value-of select="description" disable-output-escaping="yes" />
      </xsl:for-each>
      
      <xsl:apply-templates mode="head" select="item[generate-id(.)=generate-id(key('leftLine',category))]" />
   </div>
   
   <div style="width: 50%; display: inline;">
      <xsl:apply-templates select="item[category='Полоса Б1'][1]" mode="B1" /><br /><br /><br /><br />
      
      <xsl:for-each select="item[category='Полоса Б1'][not(position()=1)]">
         <p style="color: green; font-weight: bold;">
            <xsl:value-of select="title" disable-output-escaping="yes" />
         </p>
         <xsl:value-of select="description" disable-output-escaping="yes" />
      </xsl:for-each>
      
      <xsl:apply-templates mode="head2" select="item[generate-id(.)=generate-id(key('rightLine',category))]" />
   </div>
   
   <div style="clear: both;"></div>
   Количество категорий — <xsl:value-of select="count(item[not(category=preceding-sibling::item/category)])" /><br />
   Количество статей — <xsl:value-of select="count(item/title)" /><br />
   Количество статей исключая полосы А1 и Б1 — <xsl:value-of select="count(item[not(category='Полоса А1') and not(category='Полоса Б1')])" />
</xsl:template>

<xsl:template match="item" mode="A1">
      <strong><xsl:value-of select="title" disable-output-escaping="yes" /></strong><br />
      <xsl:value-of select="description" disable-output-escaping="yes" />
</xsl:template>

<xsl:template match="item" mode="B1">
      <strong><xsl:value-of select="title" disable-output-escaping="yes" /></strong><br />
      <xsl:value-of select="description" disable-output-escaping="yes" />
</xsl:template>


<!--<xsl:template match="/">
   <xsl:apply-templates mode="head" select="rss/channel/item[generate-id(.)=generate-id(key('key-category',category))]" />
</xsl:template>-->

<xsl:template match="item" mode="head">
   <p style="color: red;">
      <xsl:value-of select="category" />
   </p>
   
   <xsl:apply-templates mode="item" select="key('leftLine', category)" />
</xsl:template>

<xsl:template match="item" mode="head2">
   <p style="color: red;">
      <xsl:value-of select="category" />
   </p>
   
   <xsl:apply-templates mode="item" select="key('rightLine', category)" />
</xsl:template>

<xsl:template match="item" mode="item">
   <xsl:variable name="issueNum" select="normalize-space(substring-before(substring-after(/rss/channel/description, '№'),' ('))" />
      <xsl:choose>
             <xsl:when test="string-length($issueNum) = 1">
                  <a href="/Athenaeum/Vedomosti/{substring(/rss/channel/description, 20, 4)}/XML/V{substring(/rss/channel/description, 22, 2)}00{$issueNum}{substring(link, 59, 7)}.htm">
                     <xsl:value-of select="title" disable-output-escaping="yes" />
                  </a><br />
                  <xsl:value-of select="description" disable-output-escaping="yes" /><br /><br />
            </xsl:when>
            <xsl:when test="string-length($issueNum) = 2">
                  <a href="/Athenaeum/Vedomosti/{substring(/rss/channel/description, 20, 4)}/XML/V{substring(/rss/channel/description, 22, 2)}0{$issueNum}{substring(link, 59, 7)}.htm">
                     <xsl:value-of select="title" disable-output-escaping="yes" />
                  </a><br />
               <xsl:value-of select="description" disable-output-escaping="yes" /><br /><br />
            </xsl:when>
            <xsl:when test="string-length($issueNum) = 3">
                  <a href="/Athenaeum/Vedomosti/{substring(/rss/channel/description, 20, 4)}/XML/V{substring(/rss/channel/description, 22, 2)}{$issueNum}{substring(link, 59, 7)}.htm">
                     <xsl:value-of select="title" disable-output-escaping="yes" />
                  </a><br /><br />
               <xsl:value-of select="replacedescription" disable-output-escaping="yes" /><br />
            </xsl:when>
            </xsl:choose>
</xsl:template>
</xsl:stylesheet>
спустя 1 час 8 минут [обр] GRAy(64/259)[досье]
Чем отличается шаблон match="item" mode="A1" и match="item" mode="B1"?
Чем отличаются ключи leftLine и rightLine? Смотрел, смотрел - так и не понял.
спустя 30 минут [обр] walek[досье]

GRAy[досье]
Спасибо.

Действительно, шаблон match="item" mode="B1" — лишний.
Удалил.

На счет ключей.

<xsl:key name="leftLine" match="item[not(category='Полоса А1') and (following-sibling::item/category='Полоса Б1') and not(category='Полоса Б1')]" use="category" />
Отвечает за вывод всех статей до полосы Б1 исключая саму категорию Б1.

<xsl:key name="rightLine" match="item[not(category='Полоса А1') and (preceding-sibling::item/category='Полоса Б1') and not(category='Полоса Б1')]" use="category" />
Отвечает за вывод всех статей после полосы Б1 исключая саму категорию Б1.

Вы считаете так неправильно делать?

спустя 16 минут [обр] GRAy(64/259)[досье]
walek[досье] Я не вижу между ними вообще никакой разницы ;) кроме названия.
спустя 23 минуты [обр] walek[досье]
GRAy[досье]
Хм ...
Простите, но я не могу сообразить, как в правый блок поместить все статьи после категории Б1 исключая А1 и Б1 :[ без того, что я нагородил.
спустя 21 час [обр] GRAy(64/259)[досье]
walek[досье] Я сначала не заметил preceding-sibling и following-sibling.
спустя 5 минут [обр] walek[досье]
GRAy[досье]
По вашему мнению так делать корректно?
Powered by POEM™ Engine Copyright © 2002-2005