Инструкции. Настройка визуализации поля в представлении списка

Дата последнего изменения: 29 марта 2011 г.

Применимо к: SharePoint Foundation 2010

В этой статье
Общие сведения о визуализации настраиваемых полей в представлениях списков
Определение пользовательской визуализации для настраиваемого поля
Пример: настройка поля Currency

В этом разделе описывается определение способа визуализации настраиваемых полей в представлении списка.

Общие сведения о визуализации настраиваемых полей в представлениях списков

Microsoft SharePoint Foundation использует таблицы стилей XSLT для визуализации представлений списков. (Дополнительные сведения см. в статье Обзор систем отображения представлений списков с помощью XSLT-преобразований.) Список отрисовывается как HTML-таблица, а значение поля отрисовывается в соответствующей ячейке таблицы с помощью простого шаблона XSLT из файла fldtypes.xsl, расположенного в папке %ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\TEMPLATE\LAYOUTS\XSL. Этот файл содержит множество шаблонов для визуализации значений поля. Выбор шаблона зависит от нескольких факторов, самый важный из которых — тип поля, который определяется перечислением SPFieldType. Например, имеется шаблон FieldRef_Number_body для полей Number и шаблон FieldRef_Text_body для полей Text.

ПримечаниеПримечание

Между типами полей и шаблонами не существует прямого соответствия. Например, для вычисляемых полей существуют разные шаблоны: шаблон FieldRef_Number_body используется для полей Currrency() и Number.

Ниже приведен пример шаблона FieldRef_Text_body.

<xsl:template name="FieldRef_Text_body" ddwrt:dvt_mode="body" match ="FieldRef" mode="Text_body">
  <xsl:param name="thisNode" select="."/>
  <xsl:choose>
    <xsl:when test="@AutoHyperLink='TRUE'">
      <xsl:value-of select="$thisNode/@*[name()=current()/@Name]" disable-output-escaping ="yes"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$thisNode/@*[name()=current()/@Name]"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

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

Учтите, что в шаблоне используется ветвление, которое зависит от того, выполняется ли в поле автоматическое форматирование строк, похожих на URL-адреса, в виде HTML-ссылок <a>. Если это так, то когда процессор XSLT отрисовывает HTML для поля, он не заменяет значимые символы, такие как "<" и "&", на их эквиваленты (&lt и &amp;), что обычно процессор XSLT делает по умолчанию. Помимо этого усложнения шаблон формирует значение с помощью следующей строки.

<xsl:value-of select="$thisNode/@*[name()=current()/@Name]"/>

Так как эта строка есть практически во всех шаблонах XSLT с визуализацией полей, ее следует рассмотреть более детально. Первое действие XPath, определяющее узел, значение которого отрисовывается, заключается в указании ссылки на параметр thisNode, поэтому оставшиеся действия выполняются относительно корня разметки в этом параметре. Следующий шаг перед применением предикатов — использование /@*. Этот параметр ссылается на все атрибуты корня и его потомков, поэтому в этом случае он ссылается на все атрибуты всех элементов в thisNode. Строка [name()=current()/@Name] еще больше сужает выбор. Слева от символа "=" размещена функция XSLT name(). Она представляет имя узла в последовательности, сформированное частью "$thisNode/@*". Другими словами, она представляет имя атрибута в каком-то элементе thisNode. Если применить это к примеру thisNode из раздела Примеры входного дерева узлов и результирующего дерева узлов в XSLT-преобразованиях, можно увидеть, что некоторые атрибуты именуются в соответствии с внутренними именами полей элемента списка; например, Attachments, Title и настраиваемое поле ISBN. Справа от символа "=" размещена ссылка на атрибут Name текущего узла в исходном дереве узлов: current()/@Name. Так как этот шаблон объявлен с параметром match ="FieldRef", он применяется только к элементам FieldRef, поэтому функция current() ссылается на элемент FieldlRef. Таким образом, весь элемент xsl:value-of сообщает: "сформировать значение атрибута из thisNode, имя которого совпадает с именем текущего узла FieldRef в исходном дереве узлов".

При обработке элемента Title FieldRef исходного дерева узлов из примера процессор XSLT формирует для него значение атрибута Title текущего элемента Row в разметке thisNode. (Для первой строки это "Theories of Truth"). Аналогично он отрисовывает значение атрибута ISBN той же строки Row при обработке элемента ISBN FieldRef исходного дерева узлов ("0-262-61107-4").

В большинстве случаев здесь требуется визуализация поля по умолчанию, получаемая для настраиваемого поля и определяемая в первую очередь по его базовому типу. В случае с полем Text, например, значение отрисовывается с использованием обычного текста в соответствующей ячейке таблицы HTML. Если настраиваемое поле должно визуализироваться по-особенному, требуется использовать таблицу стилей XSLT для определения его отрисовки. В следующем разделе показывается, как это можно сделать.

Определение пользовательской визуализации для настраиваемого поля

В следующей процедуре показано, как создать пользовательскую таблицу стилей XSLT для визуализации настраиваемого поля.

Создание пользовательской таблицы стилей XSLT для визуализации поля

  1. Создайте текстовый файл с расширением "xsl". Формат имени этого файла — fldtypes_*.xsl, где "*" — любая строка из разрешенных символов для имени файла. Можно использовать имя настраиваемого поля, например fldtypes_ISBN.xsl. При применении нескольких пользовательских таблиц стилей XSLT можно использовать имя организации, например fldtypes_Contoso.xsl, и включить их все в один файл. Следует избегать строк, которые могут применяться другим поставщиком решений.

  2. Добавьте в файл следующее объявление таблицы стилей.

    <xsl:stylesheet xmlns:x="http://www.w3.org/2001/XMLSchema"
                    xmlns:d="https://schemas.microsoft.com/sharepoint/dsp"
                    version="1.0"
                    exclude-result-prefixes="xsl msxsl ddwrt"
                    xmlns:ddwrt="https://schemas.microsoft.com/WebParts/v2/DataView/runtime"
                    xmlns:asp="https://schemas.microsoft.com/ASPNET/20"
                    xmlns:__designer="https://schemas.microsoft.com/WebParts/v2/DataView/designer" 
                    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                    xmlns:msxsl="urn:schemas-microsoft-com:xslt"
                    xmlns:SharePoint="Microsoft.SharePoint.WebControls"
                    xmlns:ddwrt2="urn:frontpage:internal">
    
    
    </xsl:stylesheet>
    
  3. Откройте файл с именем fldtypes.xsl, расположенный в папке %ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\TEMPLATE\LAYOUTS\XSL, и найдите шаблон, который отрисовывает поле по умолчанию. Если, например, базовый тип поля — Currency, шаблон для этого типа — FieldRef_Number_body. Скопируйте шаблон как потомок элемента xsl:stylesheet. Далее представлен пример использования шаблона FieldRef_Number_body.

    <xsl:stylesheet > <!-- stylesheet attributes omitted for brevity -->
    
      <xsl:template name="FieldRef_Number_body" ddwrt:dvt_mode="body" match="FieldRef" mode="Number_body">
        <xsl:param name="thisNode" select="."/>
        <xsl:choose>
          <xsl:when test="$FreeForm">
            <xsl:call-template name="FieldRef_ValueOf_DisableEscape">
              <xsl:with-param name="thisNode" select="$thisNode"/>
            </xsl:call-template>
          </xsl:when>
          <xsl:otherwise>
            <div align="right">
              <xsl:call-template name="FieldRef_ValueOf_DisableEscape">
                <xsl:with-param name="thisNode" select="$thisNode"/>
              </xsl:call-template>
            </div>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:template>
    
    </xsl:stylesheet>
    
  4. Удалите атрибут name из элемента xsl:template (в этом случае — name="FieldRef_Number_body"). Кроме того, удалите атрибут ddwrt:dvt_mode, если такой есть.

  5. Измените атрибут match, чтобы шаблон выделял только поля с точным внутренним именем настраиваемого поля. Это можно сделать с помощью предиката XSLT, который определяет необходимое значение атрибута Name элемента FieldRef. Например, предположим, существует поле Net Profit/Loss с внутренним именем "Net_x0020_Profit_x002f_Loss", тогда начальный тег шаблона должен выглядеть следующим образом.

    <xsl:template match="FieldRef[@Name='Net_x0020_Profit_x002f_Loss']" mode="Number_body">
    

    Таким образом можно убедиться, что настраивается визуализация только требуемого типа настраиваемого поля, а не всех полей с базовым типом Currency или Number.

  6. Измените или добавьте код в разметку шаблона для получения необходимого эффекта визуализации. Пример см. в следующем разделе.

  7. Сохраните и скопируйте файл fldtypes_*.xsl в папку %ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\TEMPLATE\LAYOUTS\XSL на всех серверах.

  8. Сбросьте параметры веб-приложения, чтобы загрузить файлы из папки %ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\TEMPLATE\LAYOUTS\XSL. Пользовательский файл переопределяет все встроенные файлы.

Пример: настройка поля Currency

В соответствии со сведениями, приводящимися на этапа 6, в этом разделе показано, как отрисовать значение поля Net Profit/Loss красным цветом, если оно меньше нуля. После этапа 5 шаблон должен выглядеть следующим образом.

<xsl:stylesheet > <!-- stylesheet attributes omitted for brevity -->

  <xsl:template match="FieldRef[@Name='Net_x0020_Profit_x002f_Loss']" mode="Number_body">
    <xsl:param name="thisNode" select="."/>
    <xsl:choose>
      <xsl:when test="$FreeForm">
        <xsl:call-template name="FieldRef_ValueOf_DisableEscape">
          <xsl:with-param name="thisNode" select="$thisNode"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <div align="right">
          <xsl:call-template name="FieldRef_ValueOf_DisableEscape">
            <xsl:with-param name="thisNode" select="$thisNode"/>
          </xsl:call-template>
        </div>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

</xsl:stylesheet>

Обратите внимание, что ветвление отрисовки по умолчанию зависит от тестирования параметра FreeForm. Этот тест возвращает значение "true", если атрибут Type элемента Toolbar в исходном дереве узлов имеет значение "FreeForm". Если значение атрибута равно "Standard" или атрибут просто не существует, шаблон добавляет разметку HTML в соответствии со значением поля в ячейке. (См. в статье Примеры входного дерева узлов и результирующего дерева узлов в XSLT-преобразованиях пример исходного дерева узлов и его элемента Toolbar. Дополнительные сведения также см. в статье Toolbar Element (View).) Так как отрицательные значения должны обозначаться красным цветом независимо от типа панели инструментов, изменения в разметке необходимо сделать в обеих ветвях.

Учтите также, что шаблон вызывает другой шаблон с именем FieldRef_ValueOf_DisableEscape, чтобы практически отрисовать значение. Последний шаблон также представлен в файле fldtypes.xsl и определяется следующим образом.

<xsl:template name="FieldRef_ValueOf_DisableEscape" ddwrt:dvt_mode="body">
  <xsl:param name="thisNode" select="."/>
  <xsl:value-of disable-output-escaping="yes" select="$thisNode/@*[name()=current()/@Name]" />
</xsl:template>

Как видно, этот шаблон отличается от стандартного шаблона визуализации поля, в котором для отрисовки значения поля используется строка <xsl:value-of select="$thisNode/@*[name()=current()/@Name]" />, только тем, что в нем добавляется атрибут disable-output-escaping="yes", который описывался ранее в этом разделе.

В элементе <xsl:when test="$FreeForm"> добавьте структуру choose-when-otherwise и переместите существующий вызов шаблона FieldRef_ValueOf_DisableEscape в элемент <xsl:otherwise>, как показано в примере ниже.

<xsl:when test="$FreeForm">
  <xsl:choose> 
    <when test=""> 

    </when> 
    <otherwise>
        <xsl:call-template name="FieldRef_ValueOf_DisableEscape">
          <xsl:with-param name="thisNode" select="$thisNode"/>
        </xsl:call-template>
    </otherwise> 
  </choose>
</xsl:when>

Значение test должно быть равно "true", если текущее поле Net_x0020_Profit_x002f_Loss имеет отрицательное значение, т. е. если оно меньше нуля. Как было показано выше, $thisNode/@*[name()=current()/@Name] оценивает текущее поле. Однако поля с валютой в SharePoint Foundation форматируются на низком уровне перед применением форматирования XSLT. В частности, отрицательное значение валюты выражается скобками, а не символом минуса. Например, потеря 497 882,87 долларов США выражается как (497882,87), а не -497882,87. Это создает проблему, так как процессор XSLT обрабатывает все выражения в скобках как положительные, поэтому нельзя напрямую сравнивать значение $thisNode/@*[name()=current()/@Name] с нулем. К счастью, для типов полей Currency SharePoint Foundation добавляет к разметке в параметре thisNode вторую версию значения поля как простой тип double, который при отрицательном значении выражается с символом минус. В частности, эта версия — значение атрибута элемента Row с тем же именем, что и у атрибута Net_x0020_Profit_x002f_Loss, только с символом ".", добавленным к концу имени атрибута. Сравните, например, атрибуты "Retail_x0020_Price" и "Retail_x0020_Price." элемента Row в примере "thisNode", приведенном в статье Примеры входного дерева узлов и результирующего дерева узлов в XSLT-преобразованиях.

Используйте этот атрибут с именем, заканчивающимся на точку, для тестирования на наличие отрицательного значения. Выражение test должно выглядеть следующим образом.

<xsl:when test="$thisNode/@*[name()=concat(current()/@Name, '.')] &lt; 0">
СоветСовет

"&lt;" следует использовать вместо "<", так как последнее для процессора XSLT будет отображаться в начале элемента. Если необходимо, можно поменять операнды местами, что позволит использовать простой знак ">": "0 > $thisNode/@*[name()=concat(current()/@Name, '.')]".

Теперь во внутренней структуре when скопируйте вызов шаблона FieldRef_ValueOf_DisableEscape, но "оберните" его в литералы HTML, которые окрашивают значение в красный цвет. Далее показано, как будет выглядеть внешняя структура when.

<xsl:when test="$FreeForm">
  <xsl:choose> 
    <xsl:when test="$thisNode/@*[name()=concat(current()/@Name, '.')] &lt; 0"> 
      <span style="color:red">
        <xsl:call-template name="FieldRef_ValueOf_DisableEscape">
          <xsl:with-param name="thisNode" select="$thisNode"/>
        </xsl:call-template>
      </span>
    </xsl:when> 
    <xsl:otherwise>
      <xsl:call-template name="FieldRef_ValueOf_DisableEscape">
        <xsl:with-param name="thisNode" select="$thisNode"/>
      </xsl:call-template>
    </xsl:otherwise> 
  </xsl:choose>
</xsl:when>

Как указано ранее, поле должно отрисовывать тот же цвет независимо от типа панели инструментов, поэтому вся внутренняя структура choose должна стать содержимым элемента div внутри части otherwise внешней структуры choose. При этом получается следующее определение шаблона.

<xsl:template match="FieldRef[@Name='Net_x0020_Profit_x002f_Loss']" mode="Number_body">
    <xsl:param name="thisNode" select="."/>

  <xsl:choose>
    <xsl:when test="$FreeForm">
      <xsl:choose> 
        <xsl:when test="$thisNode/@*[name()=concat(current()/@Name, '.')] &lt; 0"> 
          <span style="color:red">
            <xsl:call-template name="FieldRef_ValueOf_DisableEscape">
              <xsl:with-param name="thisNode" select="$thisNode"/>
          </xsl:call-template>
          </span>
        </xsl:when> 
        <xsl:otherwise>
          <xsl:call-template name="FieldRef_ValueOf_DisableEscape">
            <xsl:with-param name="thisNode" select="$thisNode"/>
          </xsl:call-template>
        </xsl:otherwise> 
      </xsl:choose>
    </xsl:when>
    <xsl:otherwise>    
      <div align="right">
        <xsl:choose> 
          <xsl:when test="$thisNode/@*[name()=concat(current()/@Name, '.')] &lt; 0"> 
            <span style="color:red">
              <xsl:call-template name="FieldRef_ValueOf_DisableEscape">
                <xsl:with-param name="thisNode" select="$thisNode"/>
            </xsl:call-template>
            </span>
          </xsl:when> 
          <xsl:otherwise>
            <xsl:call-template name="FieldRef_ValueOf_DisableEscape">
              <xsl:with-param name="thisNode" select="$thisNode"/>
            </xsl:call-template>
          </xsl:otherwise> 
        </xsl:choose>
      </div>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template

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

<xsl:stylesheet xmlns:x="http://www.w3.org/2001/XMLSchema"
                xmlns:d="https://schemas.microsoft.com/sharepoint/dsp"
                version="1.0"
                exclude-result-prefixes="xsl msxsl ddwrt"
                xmlns:ddwrt="https://schemas.microsoft.com/WebParts/v2/DataView/runtime"
                xmlns:asp="https://schemas.microsoft.com/ASPNET/20"
                xmlns:__designer="https://schemas.microsoft.com/WebParts/v2/DataView/designer" 
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:msxsl="urn:schemas-microsoft-com:xslt"
                xmlns:SharePoint="Microsoft.SharePoint.WebControls"
                xmlns:ddwrt2="urn:frontpage:internal">

  <xsl:template match="FieldRef[@Name='Net_x0020_Profit_x002f_Loss']" mode="Number_body">
    <xsl:param name="thisNode" select="."/>
    
    <xsl:variable name="FieldValue">   
      <xsl:call-template name="FieldRef_ValueOf_DisableEscape">
        <xsl:with-param name="thisNode" select="$thisNode" />
      </xsl:call-template>
    </xsl:variable>
           
    <xsl:variable name="ValueIsNegative">
      <xsl:value-of select="$thisNode/@*[name()=concat(current()/@Name, '.')]  &lt; 0" />
    </xsl:variable>
    
    <xsl:choose>
      <xsl:when test="$FreeForm">
        <xsl:call-template name="RedWhenNegative_ElseBlack" >  
             <xsl:with-param name="thisNode" select="$thisNode" />
             <xsl:with-param name="ValueIsNegative" select="$ValueIsNegative" />
               <xsl:with-param name="FieldValue" select="$FieldValue" />
          </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>    
        <div align="right">
          <xsl:call-template name="RedWhenNegative_ElseBlack" >  
        <xsl:with-param name="thisNode" select="$thisNode" />
        <xsl:with-param name="ValueIsNegative" select="$ValueIsNegative" />
        <xsl:with-param name="FieldValue" select="$FieldValue" />
              </xsl:call-template>
        </div>
      </xsl:otherwise>
    </xsl:choose>
    
  </xsl:template>
  
  <xsl:template name="FieldValueInRed">
    <xsl:param name="thisNode" select="." />
    <xsl:param name="FieldValue" select="." />
    
    <span style="color:red">
      <xsl:value-of select="$FieldValue" />
    </span>
    
  </xsl:template>
  
  <xsl:template name="RedWhenNegative_ElseBlack">
    <xsl:param name="thisNode" select="." />
    <xsl:param name="ValueIsNegative" select="." />
    <xsl:param name="FieldValue" select="." />
    
    <xsl:choose> 
      <xsl:when test="$ValueIsNegative='true'">
          <xsl:call-template name="FieldValueInRed">
            <xsl:with-param name="thisNode" select="$thisNode" />
                <xsl:with-param name="FieldValue" select="$FieldValue" />
          </xsl:call-template>      
      </xsl:when> 
      <xsl:otherwise>
        <xsl:value-of select="$FieldValue" />
      </xsl:otherwise> 
    </xsl:choose>

  </xsl:template>
  
</xsl:stylesheet>

На рисунке 1 показано, как поле отображается в списке.

Рис. 1. Поле валюты с отрицательными значениями, выделенными красным цветом

Колонка валюты, в которой отрицательные значения отмечены красным цветом.

См. также

Задачи

Пример: создание типа настраиваемого поля

Концепции

Типы настраиваемых полей