Описание

Набор шаблонов создает блок постраничной навигации.

Пример вызова

<xsl:call-template name="list_navigation">
  <xsl:with-param name="total" select="@total" />
  <xsl:with-param name="per_page" select="@per_page" />
  <xsl:with-param name="page" select="@page" />
  <xsl:with-param name="type">query</xsl:with-param>
  <xsl:with-param name="separator">·</xsl:with-param>
  <xsl:with-param name="url_subquery" select="/node()/url/@query" />
  <xsl:with-param name="is_tiny">0</xsl:with-param>
  <xsl:with-param name="step">10</xsl:with-param>
  <xsl:with-param name="js_func" />
  <xsl:with-param name="lang" />
</xsl:call-template>
Параметр Описание
total Общее количество элементов в списке.
per_page Количество элементов на одной странице.
page Текущая страница.
type По какому принципу нужно формировать ссылки на страницы (url, если страницы списка называются, например, 6.html и query, если номер страницы передается через URL, например, ?p=6).
url_subquery Строка, которая будет дописана к адресу на страницы списка (если в адресной строке были переданы параметры методом GET и их нужно учитывать на других страницах).
separator Можно передать символ, который будет разделителем между элементами навигации.
is_tiny Возможность вывода более компактных обозначений элементов навигации (комбинации из < и > вместо «следующая», «предыдущая» и др.).
step Навигацию по какому количеству страниц нужно показывать.
js_func В ссылке вместо перехода по адресу можно вызывать функцию Java Script.

Листинг

<xsl:template name="list_navigation">
  <xsl:param name="total" />
  <xsl:param name="per_page" />
  <xsl:param name="page" />
  <xsl:param name="type" />
  <xsl:param name="url_subquery" />
  <xsl:param name="separator" />
  <xsl:param name="is_tiny" />
  <xsl:param name="step" />
  <xsl:param name="js_func" />
  <xsl:param name="lang" />

  <xsl:variable name="total_pages" select="ceiling($total div $per_page)" />
  <xsl:variable name="item_separator">
    <xsl:choose>
      <xsl:when test="$separator">
        <span class="list_navigation_spacer"><xsl:value-of select="$separator" /></span>
      </xsl:when>
      <xsl:otherwise> </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>
  <xsl:variable name="from" select="floor(($page - 1) div $step) * $step + 1" />

  <xsl:if test="$total_pages > 1">
    <div id="list_navigation">
      <xsl:if test="$page != 1 and $page > $step">
        <a>
          <xsl:attribute name="href">
            <xsl:call-template name="list_navigation_url">
              <xsl:with-param name="page" select="1" />
              <xsl:with-param name="url_subquery" select="$url_subquery" />
              <xsl:with-param name="type" select="$type" />
              <xsl:with-param name="js_func" select="$js_func" />
            </xsl:call-template>
          </xsl:attribute>
          <xsl:choose>
            <xsl:when test="$is_tiny = 1">|<</xsl:when>
            <xsl:when test="$lang = 'en'">First</xsl:when>
            <xsl:otherwise>В начало</xsl:otherwise>
          </xsl:choose>
        </a>
        <xsl:copy-of select="$item_separator" />
      </xsl:if>
      <xsl:if test="$page - $step >= 1">
        <a>
          <xsl:attribute name="href">
            <xsl:call-template name="list_navigation_url">
              <xsl:with-param name="page" select="$page - $step" />
              <xsl:with-param name="url_subquery" select="$url_subquery" />
              <xsl:with-param name="type" select="$type" />
              <xsl:with-param name="js_func" select="$js_func" />
            </xsl:call-template>
          </xsl:attribute>
          <xsl:choose>
            <xsl:when test="$is_tiny = 1"><<</xsl:when>
            <xsl:otherwise>−<xsl:value-of select="$step" /></xsl:otherwise>
          </xsl:choose>
        </a>
        <xsl:copy-of select="$item_separator" />
      </xsl:if>
      <xsl:if test="$page != 1">
        <a>
          <xsl:attribute name="href">
            <xsl:call-template name="list_navigation_url">
              <xsl:with-param name="page" select="$page - 1" />
              <xsl:with-param name="url_subquery" select="$url_subquery" />
              <xsl:with-param name="type" select="$type" />
              <xsl:with-param name="js_func" select="$js_func" />
            </xsl:call-template>
          </xsl:attribute>
          <xsl:choose>
            <xsl:when test="$is_tiny = 1"><</xsl:when>
            <xsl:when test="$lang = 'en'">Previous</xsl:when>
            <xsl:otherwise>Предыдущая</xsl:otherwise>
          </xsl:choose>
        </a>
        <xsl:copy-of select="$item_separator" />
      </xsl:if>
      <xsl:call-template name="list_navigation_item">
        <xsl:with-param name="total" select="$total_pages" />
        <xsl:with-param name="page" select="1" />
        <xsl:with-param name="selected" select="$page" />
        <xsl:with-param name="from">
          <xsl:choose>
            <xsl:when test="$total_pages - $page < $step and $from > $step">
              <xsl:value-of select="$total_pages - $step" />
            </xsl:when>
            <xsl:otherwise>
              <xsl:value-of select="$from - 1" />
            </xsl:otherwise>
          </xsl:choose>
        </xsl:with-param>
        <xsl:with-param name="type" select="$type" />
        <xsl:with-param name="url_subquery" select="$url_subquery" />
        <xsl:with-param name="separator" select="$separator" />
        <xsl:with-param name="step" select="$step" />
        <xsl:with-param name="js_func" select="$js_func" />
      </xsl:call-template>
      <xsl:if test="$page != $total_pages">
        <xsl:copy-of select="$item_separator" />
        <a>
          <xsl:attribute name="href">
            <xsl:call-template name="list_navigation_url">
              <xsl:with-param name="page" select="$page + 1" />
              <xsl:with-param name="url_subquery" select="$url_subquery" />
              <xsl:with-param name="type" select="$type" />
              <xsl:with-param name="js_func" select="$js_func" />
            </xsl:call-template>
          </xsl:attribute>
          <xsl:choose>
            <xsl:when test="$is_tiny = 1">></xsl:when>
            <xsl:when test="$lang = 'en'">Next</xsl:when>
            <xsl:otherwise>Следующая</xsl:otherwise>
          </xsl:choose>
        </a>
      </xsl:if>
      <xsl:if test="$total_pages - $page >= $step">
        <xsl:copy-of select="$item_separator" />
        <a>
          <xsl:attribute name="href">
            <xsl:call-template name="list_navigation_url">
              <xsl:with-param name="page" select="$page + $step" />
              <xsl:with-param name="url_subquery" select="$url_subquery" />
              <xsl:with-param name="type" select="$type" />
              <xsl:with-param name="js_func" select="$js_func" />
            </xsl:call-template>
          </xsl:attribute>
          <xsl:choose>
            <xsl:when test="$is_tiny = 1">>></xsl:when>
            <xsl:otherwise>+<xsl:value-of select="$step" /></xsl:otherwise>
          </xsl:choose>
        </a>
      </xsl:if>
      <xsl:if test="$total_pages != $page and $from + $step < $total_pages">
        <xsl:copy-of select="$item_separator" />
        <a>
          <xsl:attribute name="href">
            <xsl:call-template name="list_navigation_url">
              <xsl:with-param name="page" select="$total_pages" />
              <xsl:with-param name="url_subquery" select="$url_subquery" />
              <xsl:with-param name="type" select="$type" />
              <xsl:with-param name="js_func" select="$js_func" />
            </xsl:call-template>
          </xsl:attribute>
          <xsl:choose>
            <xsl:when test="$is_tiny = 1">>|</xsl:when>
            <xsl:when test="$lang = 'en'">Last</xsl:when>
            <xsl:otherwise>В конец</xsl:otherwise>
          </xsl:choose>
        </a>
      </xsl:if>
    </div>
    <br style="clear: left" />
  </xsl:if>
</xsl:template>

<xsl:template name="list_navigation_item">
  <xsl:param name="total" />
  <xsl:param name="page" />
  <xsl:param name="selected" />
  <xsl:param name="from" />
  <xsl:param name="type" />
  <xsl:param name="separator" />
  <xsl:param name="url_subquery" />
  <xsl:param name="step" />
  <xsl:param name="js_func" />

  <xsl:variable name="current" select="$page + $from" />

  <xsl:choose>
    <xsl:when test="$selected = $current">
      <span class="list_navigation_selected"><xsl:value-of select="$current" /></span>
    </xsl:when>
    <xsl:otherwise>
      <a>
        <xsl:attribute name="href">
          <xsl:call-template name="list_navigation_url">
            <xsl:with-param name="page" select="$current" />
            <xsl:with-param name="type" select="$type" />
            <xsl:with-param name="url_subquery" select="$url_subquery" />
            <xsl:with-param name="js_func" select="$js_func" />
          </xsl:call-template>
        </xsl:attribute>
        <xsl:value-of select="$current" />
      </a>
    </xsl:otherwise>
  </xsl:choose>

  <xsl:if test="$page + $from < $total and $page < $step">
    <xsl:choose>
      <xsl:when test="$separator">
        <span class="list_navigation_spacer"><xsl:value-of select="$separator" /></span>
      </xsl:when>
      <xsl:otherwise> </xsl:otherwise>
    </xsl:choose>

    <xsl:call-template name="list_navigation_item">
      <xsl:with-param name="total" select="$total" />
      <xsl:with-param name="page" select="$page + 1" />
      <xsl:with-param name="selected" select="$selected" />
      <xsl:with-param name="from" select="$from" />
      <xsl:with-param name="type" select="$type" />
      <xsl:with-param name="separator" select="$separator" />
      <xsl:with-param name="url_subquery" select="$url_subquery" />
      <xsl:with-param name="step" select="$step" />
      <xsl:with-param name="js_func" select="$js_func" />
    </xsl:call-template>
  </xsl:if>
</xsl:template>

<xsl:template name="list_navigation_url">
  <xsl:param name="page" />
  <xsl:param name="url_subquery" />
  <xsl:param name="type" />
  <xsl:param name="js_func" />

  <xsl:choose>
    <xsl:when test="$js_func != ''">
      <xsl:choose>
        <xsl:when test="contains($js_func, '~')">
          <xsl:text>javascript:</xsl:text>
          <xsl:value-of select="translate($js_func, '~', $page)" />
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="concat('javascript:', $js_func, '(', $page, ')')" />
        </xsl:otherwise>
      </xsl:choose>
    </xsl:when>
    <xsl:otherwise>
      <xsl:choose>
        <xsl:when test="$type = 'query'">
          <xsl:value-of select="concat('?p=', $page)" />
        </xsl:when>
        <xsl:when test="$type = 'url'">
          <xsl:value-of select="concat($page, '.html')" />
        </xsl:when>
      </xsl:choose>

      <xsl:if test="$url_subquery != ''">
        <xsl:choose>
          <xsl:when test="$type = 'query'">
            <xsl:variable name="replaced">
              <xsl:if test="$url_subquery != 'p'">
                <xsl:choose>
                  <xsl:when test="contains($url_subquery, 'p=')">
                    <xsl:value-of select="substring-before($url_subquery, 'p=')" />
                    <xsl:variable name="tail" select="substring-after($url_subquery, 'p=')" />
                    <xsl:if test="contains($tail, '&')">
                      <xsl:value-of select="substring-after($tail, '&')" />
                    </xsl:if>
                  </xsl:when>
                  <xsl:when test="contains($url_subquery, 'p&')">
                    <xsl:value-of select="concat(substring-before($url_subquery, 'p&'),
                      substring-after($url_subquery, 'p&'))" />
                  </xsl:when>
                  <xsl:otherwise>
                    <xsl:value-of select="$url_subquery" />
                  </xsl:otherwise>
                </xsl:choose>
              </xsl:if>
            </xsl:variable>
            <xsl:if test="$replaced != ''">
              <xsl:value-of select="concat('&', $replaced)" />
            </xsl:if>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="concat('?', $url_subquery)" />
          </xsl:otherwise>
        </xsl:choose>
      </xsl:if>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

Стили

#list_navigation {
  float:left;
  border: 1px solid #dddddd;
  margin: 2em 0;
  padding: 0.5em;
  font-size: 0.84em;
  clear: both;
}

.list_navigation_selected {
  font-weight: bold;
}

.list_navigation_spacer {
  margin: 0 0.5em;
  color: grey;
}