понедельник, 17 сентября 2012 г.

Sharepoint и XSLT? Не, не слышал.

Доброе время суток, друзья. Сегодня темой моего повествования будет Sharepoint 2010. В частности, мы изменим представление готового списка, используя XSLT. Скажу сразу, я не эксперт ни в шарепоинте, ни в XSLT, потому если вы обнаружите ошибки в тексте, прошу мне об этом сообщить. Для опытов я использую Sharepoint Foundation 2010 и Windows Web Server 2008 SP2. (Различия между разными версиями шарепоинта)
За подробностями прошу под кат.


Итак, допустим, мы создали простой список с набором полей. Пусть это будут название, ссылка, картинка, какой то контент и выбор из нескольких вариантов.
Как известно, при получении данных для списка, шарепоинт получает XML, который впоследствии при помощи XSLT преобраования, образует HTML для вывода на страницу. Весь этот XSLT лежит в папке C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\XSL . Там несколько файлов, но, как нетрудно догадаться, начинается все с main.xsl. Для того, чтобы что то изменить в представлении списка, нам нужно будет написать свой XSLT файл и (что необязательно), указать ссылку на этот main.xsl. Приступим к написанию своего файла.

1. Создадим файл C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\XSL\custom.xsl.
2. Укажем начальное его содержимое (я его просто скопировал из main.xsl)

  1. <xsl:stylesheet xmlns:x="http://www.w3.org/2001/XMLSchema"
  2.                 xmlns:d="http://schemas.microsoft.com/sharepoint/dsp"
  3.                 version="1.0"
  4.                 exclude-result-prefixes="xsl msxsl ddwrt"
  5.                 xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime"
  6.                 xmlns:asp="http://schemas.microsoft.com/ASPNET/20"
  7.                 xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer"
  8.                 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  9.                 xmlns:msxsl="urn:schemas-microsoft-com:xslt"
  10.                 xmlns:SharePoint="Microsoft.SharePoint.WebControls"
  11.                 xmlns:ddwrt2="urn:frontpage:internal">
  12. </xsl:stylesheet>
3. Далее, открываем страницу со списком, нажимаем "Действия сайта-Изменить страницу" и открываем редактор веб части. Нас интересует параметр "Ссылка на XSL".
4. Укажем значение этого параметра как /_layouts/xsl/custom/custom.xsl . После этого отображаемое содержимое списка пропадет. Это и неудивительно, ведь пока наш XSLT чист и не генерирует никакой разметки.

Теперь обратим внимание на файл main.xsl. Вот его содержимое:

  1. <xsl:stylesheet xmlns:x="http://www.w3.org/2001/XMLSchema" xmlns:d="http://schemas.microsoft.com/sharepoint/dsp" version="1.0" exclude-result-prefixes="xsl msxsl ddwrt" xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" xmlns:asp="http://schemas.microsoft.com/ASPNET/20" xmlns:__designer="http://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">
  2.   <xsl:import href="/_layouts/xsl/fldtypes.xsl"/>
  3.   <xsl:import href="/_layouts/xsl/vwstyles.xsl"/>
  4.   <xsl:output method="html" indent="no"/>
  5.   <xsl:decimal-format NaN=""/>
  6.   <xsl:param name="NavigateForFormsPages" />
  7.   <xsl:param name="MasterVersion" select="3"/>
  8.   <xsl:param name="TabularView"/>
  9.   <xsl:param name="NoAJAX"/>
  10.   <xsl:param name="WPQ"/>
  11.   <xsl:param name="RowLimit" select="5"/>
  12.   <xsl:param name="dvt_sortdir" select="'ascending'"/>
  13.   <xsl:param name="dvt_sortfield" />
  14.   <xsl:param name="WebPartClientID"/>
  15.   <xsl:param name="dvt_filterfields" />
  16.   <xsl:param name="dvt_partguid" />
  17.   <xsl:param name="dvt_firstrow" select="1"/>
  18.   <xsl:param name="dvt_nextpagedata" />
  19.   <xsl:param name="dvt_prevpagedata" />
  20.   <xsl:param name="XmlDefinition" select="."/>
  21.   <xsl:param name="ViewCounter" select="'1'"/>
  22.   <xsl:param name="View" />
  23.   <xsl:param name="ListUrlDir"/>
  24.   <xsl:param name="List" />
  25.   <xsl:param name="Project"/>
  26.   <xsl:param name="WebTitle"/>
  27.   <xsl:param name="ListTitle"/>
  28.   <xsl:param name="FORM_DISPLAY"/>
  29.   <xsl:param name="FORM_DISPLAY_HTMLURLATTRIBUTEENCODED"/>
  30.   <xsl:param name="FORM_EDIT"/>
  31.   <xsl:param name="FORM_NEW"/>
  32.   <xsl:param name="ENCODED_FORM_NEW"/>
  33.   <xsl:param name="Userid" select="-1"/>
  34.   <xsl:param name="PagePath"/>
  35.   <xsl:param name="PagePathFinal" select="concat($PagePath,'?')"/>
  36.   <xsl:param name="HttpVDir"/>
  37.   <xsl:param name="HttpVDirUniEncoded"/>
  38.   <xsl:param name="HttpPath"/>
  39.   <xsl:param name="HttpHost"/>
  40.   <xsl:param name="PresenceEnabled"/>
  41.   <xsl:param name="FilterLink"/>
  42.   <xsl:param name="FilterLinkNoHost"/>
  43.   <xsl:param name="RecursiveView"/>
  44.   <xsl:param name="WebEditorPreview"/>
  45.   <xsl:param name="NoAnnouncements"/>
  46.   <xsl:param name="NoAnnouncementsHowTo"/>
  47.   <xsl:param name="MoreAnnouncements"/>
  48.   <xsl:param name="AddNewAnnouncement"/>
  49.   <xsl:param name="FreeForm" select="0"/>
  50.   <xsl:param name="OpenMenuKeyAccessible"/>
  51.   <xsl:param name="open_menu"/>
  52.   <xsl:param name="select_deselect_all"/>
  53.   <xsl:param name="IsGhosted" select="'0'"/>
  54.   <xsl:param name="Filter" select="'0'"/>
  55.   <xsl:param name="IsDocLib"/>
  56.   <xsl:param name="WorkspaceAltString"/>
  57.   <xsl:param name="NewGifAltString"/>
  58.   <xsl:param name="LCID"/>
  59.   <xsl:param name="ByText"/>
  60.   <xsl:param name="Modified"/>
  61.   <xsl:param name="Modified_By"/>
  62.   <xsl:param name="SelectedID"/>
  63.   <xsl:param name="idPresEnabled"/>
  64.   <xsl:param name="dvt_RowCount" select="0" />
  65.   <xsl:param name="HasTitleField" select="$XmlDefinition/ViewFields/FieldRef[@Name='Title']"/>
  66.   <xsl:param name="IsHomePageView" select="0" />
  67.   <xsl:param name="ManualRefresh" />
  68.   <xsl:param name="ListRight_AddListItems"/>
  69.   <xsl:param name="GroupingRender"/>
  70.   <xsl:param name="dvt_form_key"/>
  71.   <!-- -1 means insert-->
  72.   <xsl:param name="InlineEdit"/>
  73.   <xsl:param name="ServerRelativeUrl"/>
  74.   <xsl:param name="OverrideSelectCommand"/>
  75.   <xsl:param name="OverrideFilterQstring"/>
  76.   <xsl:param name="OverrideScope"/>
  77.   <xsl:param name="EcbMode"/>
  78.   <xsl:param name="FieldSortParam"/>
  79.   <xsl:param name="RootFolderParam"/>
  80.   <xsl:param name="AddServerFilterOperationHash"/>
  81.   <xsl:param name="IsPostBack"/>
  82.   <xsl:param name="ShowWebPart"/>
  83.   <xsl:param name="SortQueryString"/>
  84.   <xsl:param name="NoCTX"/>
  85.   <xsl:param name="ShowAlways"/>
  86.   <xsl:param name="EnableAlert"/>
  87.   <xsl:param name="RootSiteUrl"/>
  88.   <xsl:param name="RenderCTXOnly"/>
  89.   <!-- For Relationships-->
  90.   <xsl:param name="HasRelatedCascadeLists" select="0" />
  91.   <xsl:param name="CascadeDeleteWarningMessage"/>
  92.   <!-- For External Lists-->
  93.   <xsl:param name="EntityName" />
  94.   <xsl:param name="EntityNamespace" />
  95.   <xsl:param name="SpecificFinderName" />
  96.   <xsl:param name="LobSystemInstanceName" />
  97.   <xsl:param name="ExternalDataListPermissions" />
  98.   <xsl:param name="RowTotalCount" select="0"/>
  99. </xsl:stylesheet>

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

  1. <xsl:stylesheet xmlns:x="http://www.w3.org/2001/XMLSchema" xmlns:d="http://schemas.microsoft.com/sharepoint/dsp"
  2.     version="1.0" exclude-result-prefixes="xsl msxsl ddwrt" xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime"
  3.     xmlns:asp="http://schemas.microsoft.com/ASPNET/20" xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer"
  4.     xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt"
  5.     xmlns:sharepoint="Microsoft.SharePoint.WebControls" xmlns:ddwrt2="urn:frontpage:internal">
  6.   <xsl:output method="html" indent="no" />
  7.   <xsl:decimal-format nan="" />
  8.   <xsl:param name="NavigateForFormsPages" />
  9.   <xsl:param name="MasterVersion" select="3" />
  10.   <xsl:param name="TabularView" />
  11.   <xsl:param name="NoAJAX" />
  12.   <xsl:param name="WPQ" />
  13.   <xsl:param name="RowLimit" select="5" />
  14.   <xsl:param name="dvt_sortdir" select="'ascending'" />
  15.   <xsl:param name="dvt_sortfield" />
  16.   <xsl:param name="WebPartClientID" />
  17.   <xsl:param name="dvt_filterfields" />
  18.   <xsl:param name="dvt_partguid" />
  19.   <xsl:param name="dvt_firstrow" select="1" />
  20.   <xsl:param name="dvt_nextpagedata" />
  21.   <xsl:param name="dvt_prevpagedata" />
  22.   <xsl:param name="XmlDefinition" select="." />
  23.   <xsl:param name="ViewCounter" select="'1'" />
  24.   <xsl:param name="View" />
  25.   <xsl:param name="ListUrlDir" />
  26.   <xsl:param name="List" />
  27.   <xsl:param name="Project" />
  28.   <xsl:param name="WebTitle" />
  29.   <xsl:param name="ListTitle" />
  30.   <xsl:param name="FORM_DISPLAY" />
  31.   <xsl:param name="FORM_DISPLAY_HTMLURLATTRIBUTEENCODED" />
  32.   <xsl:param name="FORM_EDIT" />
  33.   <xsl:param name="FORM_NEW" />
  34.   <xsl:param name="ENCODED_FORM_NEW" />
  35.   <xsl:param name="Userid" select="-1" />
  36.   <xsl:param name="PagePath" />
  37.   <xsl:param name="PagePathFinal" select="concat($PagePath,'?')" />
  38.   <xsl:param name="HttpVDir" />
  39.   <xsl:param name="HttpVDirUniEncoded" />
  40.   <xsl:param name="HttpPath" />
  41.   <xsl:param name="HttpHost" />
  42.   <xsl:param name="PresenceEnabled" />
  43.   <xsl:param name="FilterLink" />
  44.   <xsl:param name="FilterLinkNoHost" />
  45.   <xsl:param name="RecursiveView" />
  46.   <xsl:param name="WebEditorPreview" />
  47.   <xsl:param name="NoAnnouncements" />
  48.   <xsl:param name="NoAnnouncementsHowTo" />
  49.   <xsl:param name="MoreAnnouncements" />
  50.   <xsl:param name="AddNewAnnouncement" />
  51.   <xsl:param name="FreeForm" select="0" />
  52.   <xsl:param name="OpenMenuKeyAccessible" />
  53.   <xsl:param name="open_menu" />
  54.   <xsl:param name="select_deselect_all" />
  55.   <xsl:param name="IsGhosted" select="'0'" />
  56.   <xsl:param name="Filter" select="'0'" />
  57.   <xsl:param name="IsDocLib" />
  58.   <xsl:param name="WorkspaceAltString" />
  59.   <xsl:param name="NewGifAltString" />
  60.   <xsl:param name="LCID" />
  61.   <xsl:param name="ByText" />
  62.   <xsl:param name="Modified" />
  63.   <xsl:param name="Modified_By" />
  64.   <xsl:param name="SelectedID" />
  65.   <xsl:param name="idPresEnabled" />
  66.   <xsl:param name="dvt_RowCount" select="0" />
  67.   <xsl:param name="HasTitleField" select="$XmlDefinition/ViewFields/FieldRef[@Name='Title']" />
  68.   <xsl:param name="IsHomePageView" select="0" />
  69.   <xsl:param name="ManualRefresh" />
  70.   <xsl:param name="ListRight_AddListItems" />
  71.   <xsl:param name="GroupingRender" />
  72.   <xsl:param name="dvt_form_key" />
  73.   <!-- -1 means insert-->
  74.   <xsl:param name="InlineEdit" />
  75.   <xsl:param name="ServerRelativeUrl" />
  76.   <xsl:param name="OverrideSelectCommand" />
  77.   <xsl:param name="OverrideFilterQstring" />
  78.   <xsl:param name="OverrideScope" />
  79.   <xsl:param name="EcbMode" />
  80.   <xsl:param name="FieldSortParam" />
  81.   <xsl:param name="RootFolderParam" />
  82.   <xsl:param name="AddServerFilterOperationHash" />
  83.   <xsl:param name="IsPostBack" />
  84.   <xsl:param name="ShowWebPart" />
  85.   <xsl:param name="SortQueryString" />
  86.   <xsl:param name="NoCTX" />
  87.   <xsl:param name="ShowAlways" />
  88.   <xsl:param name="EnableAlert" />
  89.   <xsl:param name="RootSiteUrl" />
  90.   <xsl:param name="RenderCTXOnly" />
  91.   <!-- For Relationships-->
  92.   <xsl:param name="HasRelatedCascadeLists" select="0" />
  93.   <xsl:param name="CascadeDeleteWarningMessage" />
  94.   <!-- For External Lists-->
  95.   <xsl:param name="EntityName" />
  96.   <xsl:param name="EntityNamespace" />
  97.   <xsl:param name="SpecificFinderName" />
  98.   <xsl:param name="LobSystemInstanceName" />
  99.   <xsl:param name="ExternalDataListPermissions" />
  100.   <xsl:param name="RowTotalCount" select="0" />
  101.   <xsl:template match="/">
  102.     <table>
  103.       <tr><td>NavigateForFormsPages</td><td><xsl:value-of select="$NavigateForFormsPages" /></td></tr>
  104.       <tr><td>MasterVersion</td><td><xsl:value-of select="$MasterVersion" /></td></tr>
  105.       <tr><td>TabularView</td><td><xsl:value-of select="$TabularView" /></td></tr>
  106.       <tr><td>NoAJAX</td><td><xsl:value-of select="$NoAJAX" /></td></tr>
  107.       <tr><td>WPQ</td><td><xsl:value-of select="$WPQ" /></td></tr>
  108.       <tr><td>RowLimit</td><td><xsl:value-of select="$RowLimit" /></td></tr>
  109.       <tr><td>dvt_sortdir</td><td><xsl:value-of select="$dvt_sortdir" /></td></tr>
  110.       <tr><td>dvt_sortfield</td><td><xsl:value-of select="$dvt_sortfield" /></td></tr>
  111.       <tr><td>WebPartClientID</td><td><xsl:value-of select="$WebPartClientID" /></td></tr>
  112.       <tr><td>dvt_filterfields</td><td><xsl:value-of select="$dvt_filterfields" /></td></tr>
  113.       <tr><td>dvt_partguid</td><td><xsl:value-of select="$dvt_partguid" /></td></tr>
  114.       <tr><td>dvt_firstrow</td><td><xsl:value-of select="$dvt_firstrow" /></td></tr>
  115.       <tr><td>dvt_nextpagedata</td><td><xsl:value-of select="$dvt_nextpagedata" /></td></tr>
  116.       <tr><td>dvt_prevpagedata</td><td><xsl:value-of select="$dvt_prevpagedata" /></td></tr>
  117.       <tr><td>XmlDefinition</td><td><xsl:value-of select="$XmlDefinition" /></td></tr>
  118.       <tr><td>ViewCounter</td><td><xsl:value-of select="$ViewCounter" /></td></tr>
  119.       <tr><td>View</td><td><xsl:value-of select="$View" /></td></tr>
  120.       <tr><td>ListUrlDir</td><td><xsl:value-of select="$ListUrlDir" /></td></tr>
  121.       <tr><td>List</td><td><xsl:value-of select="$List" /></td></tr>
  122.       <tr><td>Project</td><td><xsl:value-of select="$Project" /></td></tr>
  123.       <tr><td>WebTitle</td><td><xsl:value-of select="$WebTitle" /></td></tr>
  124.       <tr><td>ListTitle</td><td><xsl:value-of select="$ListTitle" /></td></tr>
  125.       <tr><td>FORM_DISPLAY</td><td><xsl:value-of select="$FORM_DISPLAY" /></td></tr>
  126.       <tr><td>FORM_DISPLAY_HTMLURLATTRIBUTEENCODED</td><td><xsl:value-of select="$FORM_DISPLAY_HTMLURLATTRIBUTEENCODED" /></td></tr>
  127.       <tr><td>FORM_EDIT</td><td><xsl:value-of select="$FORM_EDIT" /></td></tr>
  128.       <tr><td>FORM_NEW</td><td><xsl:value-of select="$FORM_NEW" /></td></tr>
  129.       <tr><td>ENCODED_FORM_NEW</td><td><xsl:value-of select="$ENCODED_FORM_NEW" /></td></tr>
  130.       <tr><td>Userid</td><td><xsl:value-of select="$Userid" /></td></tr>
  131.       <tr><td>PagePath</td><td><xsl:value-of select="$PagePath" /></td></tr>
  132.       <tr><td>PagePathFinal</td><td><xsl:value-of select="$PagePathFinal" /></td></tr>
  133.       <tr><td>HttpVDir</td><td><xsl:value-of select="$HttpVDir" /></td></tr>
  134.       <tr><td>HttpVDirUniEncoded</td><td><xsl:value-of select="$HttpVDirUniEncoded" /></td></tr>
  135.       <tr><td>HttpPath</td><td><xsl:value-of select="$HttpPath" /></td></tr>
  136.       <tr><td>HttpHost</td><td><xsl:value-of select="$HttpHost" /></td></tr>
  137.       <tr><td>PresenceEnabled</td><td><xsl:value-of select="$PresenceEnabled" /></td></tr>
  138.       <tr><td>FilterLink</td><td><xsl:value-of select="$FilterLink" /></td></tr>
  139.       <tr><td>FilterLinkNoHost</td><td><xsl:value-of select="$FilterLinkNoHost" /></td></tr>
  140.       <tr><td>RecursiveView</td><td><xsl:value-of select="$RecursiveView" /></td></tr>
  141.       <tr><td>WebEditorPreview</td><td><xsl:value-of select="$WebEditorPreview" /></td></tr>
  142.       <tr><td>NoAnnouncements</td><td><xsl:value-of select="$NoAnnouncements" /></td></tr>
  143.       <tr><td>NoAnnouncementsHowTo</td><td><xsl:value-of select="$NoAnnouncementsHowTo" /></td></tr>
  144.       <tr><td>MoreAnnouncements</td><td><xsl:value-of select="$MoreAnnouncements" /></td></tr>
  145.       <tr><td>AddNewAnnouncement</td><td><xsl:value-of select="$AddNewAnnouncement" /></td></tr>
  146.       <tr><td>FreeForm</td><td><xsl:value-of select="$FreeForm" /></td></tr>
  147.       <tr><td>OpenMenuKeyAccessible</td><td><xsl:value-of select="$OpenMenuKeyAccessible" /></td></tr>
  148.       <tr><td>open_menu</td><td><xsl:value-of select="$open_menu" /></td></tr>
  149.       <tr><td>select_deselect_all</td><td><xsl:value-of select="$select_deselect_all" /></td></tr>
  150.       <tr><td>IsGhosted</td><td><xsl:value-of select="$IsGhosted" /></td></tr>
  151.       <tr><td>Filter</td><td><xsl:value-of select="$Filter" /></td></tr>
  152.       <tr><td>IsDocLib</td><td><xsl:value-of select="$IsDocLib" /></td></tr>
  153.       <tr><td>WorkspaceAltString</td><td><xsl:value-of select="$WorkspaceAltString" /></td></tr>
  154.       <tr><td>NewGifAltString</td><td><xsl:value-of select="$NewGifAltString" /></td></tr>
  155.       <tr><td>LCID</td><td><xsl:value-of select="$LCID" /></td></tr>
  156.       <tr><td>ByText</td><td><xsl:value-of select="$ByText" /></td></tr>
  157.       <tr><td>Modified</td><td><xsl:value-of select="$Modified" /></td></tr>
  158.       <tr><td>Modified_By</td><td><xsl:value-of select="$Modified_By" /></td></tr>
  159.       <tr><td>SelectedID</td><td><xsl:value-of select="$SelectedID" /></td></tr>
  160.       <tr><td>idPresEnabled</td><td><xsl:value-of select="$idPresEnabled" /></td></tr>
  161.       <tr><td>dvt_RowCount</td><td><xsl:value-of select="$dvt_RowCount" /></td></tr>
  162.       <tr><td>HasTitleField</td><td><xsl:value-of select="$HasTitleField" /></td></tr>
  163.       <tr><td>IsHomePageView</td><td><xsl:value-of select="$IsHomePageView" /></td></tr>
  164.       <tr><td>ManualRefresh</td><td><xsl:value-of select="$ManualRefresh" /></td></tr>
  165.       <tr><td>ListRight_AddListItems</td><td><xsl:value-of select="$ListRight_AddListItems" /></td></tr>
  166.       <tr><td>GroupingRender</td><td><xsl:value-of select="$GroupingRender" /></td></tr>
  167.       <tr><td>dvt_form_key</td><td><xsl:value-of select="$dvt_form_key" /></td></tr>
  168.       <tr>
  169.         <td>
  170.           raw xml
  171.         </td>
  172.         <td style='word-wrap: break-word;'>
  173.           <span style="font-size: 10pt; width: 100%; word-wrap: break-word;" align="justify">
  174.             <xmp>
  175.               <xsl:copy-of select="."></xsl:copy-of>
  176.             </xmp>
  177.           </span>
  178.         </td>
  179.       </tr>
  180.     </table>
  181.   </xsl:template>
  182. </xsl:stylesheet>

Вот, что покажет этот стиль:


И в самом низу будет наш XML. Выглядит он так (я его скопировал в текстовый редактор и отформатировал):

Как вы можете заметить, в пришедшем XML есть все необходимые нам поля.

Теперь мы знаем, с чем имеем дело, и какие параметры нам доступны. Дальнейшая работа будет выглядеть следующим образом:
1. Мы модифицируем наш XSLT так, чтобы вернулось стандартное представление списка.
2. Мы постепенно будем добавлять элементы в наш XSLT, чем и будем менять визуальное представление списка.

Ну, начнем по порядку. Чтобы наш XSLT отображал стандартное представление, необходимо просто в пустом XSLT импортировать main.xsl, а далее всё само заработает. Выглядеть это будет так:


  1. <xsl:stylesheet xmlns:x="http://www.w3.org/2001/XMLSchema" xmlns:d="http://schemas.microsoft.com/sharepoint/dsp" version="1.0" exclude-result-prefixes="xsl msxsl ddwrt" xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" xmlns:asp="http://schemas.microsoft.com/ASPNET/20" xmlns:__designer="http://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">
  2.   <xsl:import href="/_layouts/xsl/main.xsl"/>
  3. </xsl:stylesheet>

Теперь что я хочу получить на выходе. Я хочу, чтобы название было сверху крупными буквами. А ещё картинка должна быть внутри ссылки, которая будет указывать туда, куда указывает наше поле УРЛ. А надпись с выбранным вариантом мы вообще уберем, но столбец с названием оставим. А ещё ссылку "Добавить элемент" мы переименуем в "Добавить новость". Пока вроде все.

Как я уже говорил, вначале файла main.xsl происходит импорт двух других файлов.

  1. <xsl:import href="/_layouts/xsl/fldtypes.xsl"/>
  2. <xsl:import href="/_layouts/xsl/vwstyles.xsl"/>

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

  1. <xsl:template match="/">
  2.   <xsl:choose>
  3.     <xsl:when test="$RenderCTXOnly='True'">
  4.       <xsl:call-template name="CTXGeneration"/>
  5.     </xsl:when>
  6.     <xsl:when test="($ManualRefresh = 'True')">
  7.       <xsl:call-template name="AjaxWrapper" />
  8.     </xsl:when>
  9.     <xsl:otherwise>
  10.       <xsl:apply-templates mode="RootTemplate" select="$XmlDefinition"/>
  11.     </xsl:otherwise>
  12.   </xsl:choose>
  13. </xsl:template>

Далее у нас возможны различные варианты ветвления, но если у вас параметры все были выставлены по умолчанию, скорее всего будет применен шаблон на строке 603

  1. <xsl:template match="View" mode="full">
  2.   <xsl:param name="ShowSelectAllCheckbox" select="'True'"/>
  3.   <xsl:variable name="ViewStyleID">
  4.     <xsl:value-of select="ViewStyle/@ID"/>
  5.   </xsl:variable>
  6.   <xsl:variable name="dirClass">
  7.     <xsl:choose>
  8.       <xsl:when test="$XmlDefinition/List/@Direction='rtl'"> ms-vhrtl</xsl:when>
  9.       <xsl:otherwise> ms-vhltr</xsl:otherwise>
  10.     </xsl:choose>
  11.   </xsl:variable>
  12.   <tr valign="top" class="{concat('ms-viewheadertr',$dirClass)}">
  13.     <xsl:if test="$MasterVersion=4 and $TabularView='1'">
  14.       <!-- ViewStyleID ''=Default / ViewStyleID 17=Shaded -->
  15.       <xsl:if test="($ViewStyleID = '' or $ViewStyleID = '17') and $ShowSelectAllCheckbox = 'True'">
  16.         <th class="ms-vh-icon" scope="col">
  17.           <input type="checkbox" title="{$select_deselect_all}" onclick="ToggleAllItems(event,this,{$ViewCounter})" onfocus="EnsureSelectionHandlerOnFocus(event,this,{$ViewCounter})" />
  18.         </th>
  19.       </xsl:if>
  20.     </xsl:if>
  21.     <xsl:if test="$InlineEdit">
  22.       <th class="ms-vh2 ms-vh-inlineedit"/>
  23.     </xsl:if>
  24.     <xsl:if test="not($GroupingRender)">
  25.       <xsl:apply-templates mode="header" select="ViewFields/FieldRef[not(@Explicit='TRUE')]"/>
  26.     </xsl:if>
  27.   </tr>
  28.   <xsl:apply-templates select="." mode="RenderView" />
  29.   <xsl:apply-templates mode="footer" select="." />
  30. </xsl:template>

Затем будет вызван темплейт со строки 1823


  1. <xsl:template match="View" mode="RenderView">
  2.   
  3.   <xsl:variable name="ViewStyleID">
  4.     <xsl:value-of select="ViewStyle/@ID"/>
  5.   </xsl:variable>
  6.   <xsl:variable name="HasExtraColumn" select="$TabularView='1' and $MasterVersion=4 and ($ViewStyleID = '' or $ViewStyleID = '17')"/>
  7.   <!-- total first -->
  8.   <xsl:if test="Aggregations[not(@Value='Off')]/FieldRef">
  9.     <tr>
  10.       <xsl:if test="$HasExtraColumn">
  11.         <td/>
  12.       </xsl:if>
  13.       <xsl:if test="$InlineEdit">
  14.         <td width="1%"/>
  15.       </xsl:if >
  16.       <xsl:apply-templates mode="aggregate" select="ViewFields/FieldRef[not(@Explicit='TRUE')]">
  17.         <xsl:with-param name="Rows" select="$AllRows"/>
  18.         <xsl:with-param name="GroupLevel" select="0"/>
  19.       </xsl:apply-templates>
  20.     </tr>
  21.   </xsl:if>
  22.   <xsl:variable name="Fields" select="ViewFields/FieldRef[not(@Explicit='TRUE')]"/>
  23.   <xsl:variable name="Groups" select="Query/GroupBy/FieldRef"/>
  24.   <xsl:variable name="Collapse" select="Query/GroupBy[@Collapse='TRUE']"/>
  25.   <xsl:variable name="GroupCount" select="count($Groups)"/>
  26.   <xsl:for-each select="$AllRows">
  27.     <xsl:variable name="thisNode" select="."/>
  28.     <xsl:if test="$GroupCount &gt; 0">
  29.       <xsl:call-template name="GroupTemplate">
  30.         <xsl:with-param name="Groups" select="$Groups"/>
  31.         <xsl:with-param name="Collapse" select="$Collapse"/>
  32.         <xsl:with-param name="HasExtraColumn" select="$HasExtraColumn"/>
  33.       </xsl:call-template>
  34.     </xsl:if>
  35.     <xsl:if test="not(not($NoAJAX) and not($InlineEdit) and $Collapse and $GroupCount &gt; 0)">
  36.       <xsl:apply-templates mode="Item" select=".">
  37.         <xsl:with-param name="Fields" select="$Fields"/>
  38.         <xsl:with-param name="Collapse" select="$Collapse"/>
  39.         <xsl:with-param name="Position" select="position()"/>
  40.         <xsl:with-param name="Last" select="last()"/>
  41.       </xsl:apply-templates>
  42.     </xsl:if>
  43.   </xsl:for-each>
  44.   <xsl:if test="$InlineEdit and not($IsDocLib) and $ListRight_AddListItems = '1'">
  45.     <xsl:call-template name="rowinsert">
  46.       <xsl:with-param name="Fields" select="$Fields"/>
  47.     </xsl:call-template>
  48.   </xsl:if>
  49. </xsl:template>

Как видите, тут есть большой foreach, который будет рендерить каждую строку. Осталось найти шаблон для этой строки. Так как я ничего в представлениях не менял, то найти шаблон для строки очень просто - это первый среди шаблонов строк (строка 1086).


  1. <xsl:template mode="Item" match="Row">
  2.   <xsl:param name="Fields" select="."/>
  3.   <xsl:param name="Collapse" select="."/>
  4.   <xsl:param name="Position" select="1" />
  5.   <xsl:param name="Last" select="1" />
  6.   <xsl:variable name="thisNode" select="."/>
  7.   <xsl:variable name="ID">
  8.     <xsl:call-template name="ResolveId">
  9.       <xsl:with-param name="thisNode" select ="."/>
  10.     </xsl:call-template>
  11.   </xsl:variable>
  12.   <xsl:variable name="FSObjType">
  13.     <xsl:choose>
  14.       <xsl:when test="$EntityName != ''">0</xsl:when>
  15.       <xsl:otherwise>
  16.         <xsl:value-of select="./@FSObjType"/>
  17.       </xsl:otherwise>
  18.     </xsl:choose>
  19.   </xsl:variable>
  20.   <xsl:variable name="altClass">
  21.     <xsl:choose>
  22.       <xsl:when test="$Position mod 2 = 0">ms-alternating</xsl:when>
  23.       <xsl:otherwise></xsl:otherwise>
  24.     </xsl:choose>
  25.   </xsl:variable>
  26.   <xsl:variable name="hoverClass">
  27.     <xsl:choose>
  28.       <xsl:when test="($TabularView='1' and $MasterVersion=4) or $InlineEdit">ms-itmhover</xsl:when>
  29.       <xsl:otherwise></xsl:otherwise>
  30.     </xsl:choose>
  31.   </xsl:variable>
  32.   <xsl:variable name="EditMode" select="$dvt_form_key = @ID or $dvt_form_key = @BdcIdentity"/>
  33.   <tr>
  34.     <xsl:if test="$Collapse">
  35.       <xsl:attribute name="style">display:none</xsl:attribute>
  36.     </xsl:if>
  37.     <xsl:attribute name="class">
  38.       <xsl:value-of select="normalize-space(concat($altClass, ' ', $hoverClass))"/>
  39.     </xsl:attribute>
  40.     <xsl:if test="($TabularView='1' and $MasterVersion=4) or $InlineEdit">
  41.       <xsl:attribute name="iid">
  42.         <xsl:value-of select="$ViewCounter"/>,<xsl:value-of select="$ID"/>,<xsl:value-of select="$FSObjType"/>
  43.       </xsl:attribute>
  44.     </xsl:if>
  45.     <xsl:if test="$EditMode">
  46.       <xsl:attribute name="automode">
  47.         <xsl:value-of select ="$ViewCounter"/>
  48.       </xsl:attribute>
  49.     </xsl:if>
  50.     <xsl:if test="$TabularView='1' and $MasterVersion=4">
  51.       <td class="ms-vb-itmcbx ms-vb-firstCell">
  52.         <input type="checkbox" class="s4-itm-cbx"/>
  53.       </td>
  54.     </xsl:if>
  55.     <xsl:if test="$InlineEdit">
  56.       <xsl:call-template name="AutoModeHeader"/>
  57.     </xsl:if>
  58.     <xsl:for-each select="$Fields">
  59.       <xsl:choose>
  60.         <xsl:when test="$EditMode and not(@ReadOnly='TRUE') and not(@FieldType='Recurrence') and not(@FieldType='CrossProjectLink')">
  61.           <xsl:call-template name="AutoModeForm">
  62.             <xsl:with-param name="thisNode" select="$thisNode" />
  63.             <xsl:with-param name="Position" select="$Position"/>
  64.             <xsl:with-param name="Fields" select="$Fields"/>
  65.           </xsl:call-template>
  66.         </xsl:when>
  67.         <xsl:otherwise>
  68.           <xsl:apply-templates select="." mode="printTableCellEcbAllowed">
  69.             <xsl:with-param name="thisNode" select="$thisNode"/>
  70.           </xsl:apply-templates>
  71.         </xsl:otherwise>
  72.       </xsl:choose>
  73.     </xsl:for-each>
  74.   </tr>
  75. </xsl:template>

Если вы взглянете повнимательнее на этот шаблон, то заметите, что тут рендерится конкретная строка для таблицы. Теперь скопируем этот шаблон в свой файл custom.xsl и начнем веселиться!

(Небольшое отступление. В зависимости от Вашей задумки, тут возможно использование другого стиля для вашего представления. Соответственно, при выборе другого стиля представления, для рендеринга возможно будут использоваться другие шаблоны из этого же файла. Статья получается итак довольно объемная, поэтому рендеринг в других стилях я сегодня рассматривать не буду).

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


  1. <xsl:stylesheet xmlns:x="http://www.w3.org/2001/XMLSchema" xmlns:d="http://schemas.microsoft.com/sharepoint/dsp"
  2.     version="1.0" exclude-result-prefixes="xsl msxsl ddwrt" xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime"
  3.     xmlns:asp="http://schemas.microsoft.com/ASPNET/20" xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer"
  4.     xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt"
  5.     xmlns:sharepoint="Microsoft.SharePoint.WebControls" xmlns:ddwrt2="urn:frontpage:internal">
  6.     <xsl:import href="/_layouts/xsl/main.xsl" />
  7.     <xsl:template mode="Item" match="Row">
  8.         <xsl:param name="Fields" select="." />
  9.         <xsl:param name="Collapse" select="." />
  10.         <xsl:param name="Position" select="1" />
  11.         <xsl:param name="Last" select="1" />
  12.         <xsl:variable name="thisNode" select="." />
  13.         <xsl:variable name="ID">
  14.             <xsl:call-template name="ResolveId">
  15.                 <xsl:with-param name="thisNode" select="." />
  16.             </xsl:call-template>
  17.         </xsl:variable>
  18.         <xsl:variable name="FSObjType">
  19.             <xsl:choose>
  20.                 <xsl:when test="$EntityName != ''">0</xsl:when>
  21.                 <xsl:otherwise>
  22.                     <xsl:value-of select="./@FSObjType" />
  23.                 </xsl:otherwise>
  24.             </xsl:choose>
  25.         </xsl:variable>
  26.         <xsl:variable name="altClass">
  27.             <xsl:choose>
  28.                 <xsl:when test="$Position mod 2 = 0">ms-alternating</xsl:when>
  29.                 <xsl:otherwise>
  30.                 </xsl:otherwise>
  31.             </xsl:choose>
  32.         </xsl:variable>
  33.         <xsl:variable name="hoverClass">
  34.             <xsl:choose>
  35.                 <xsl:when test="($TabularView='1' and $MasterVersion=4) or $InlineEdit">ms-itmhover</xsl:when>
  36.                 <xsl:otherwise>
  37.                 </xsl:otherwise>
  38.             </xsl:choose>
  39.         </xsl:variable>
  40.         <xsl:variable name="EditMode" select="$dvt_form_key = @ID or $dvt_form_key = @BdcIdentity" />
  41.         <tr>
  42.             <xsl:if test="$Collapse">
  43.                 <xsl:attribute name="style">display:none</xsl:attribute>
  44.             </xsl:if>
  45.             <xsl:attribute name="class">
  46.                 <xsl:value-of select="normalize-space(concat($altClass, ' ', $hoverClass))" />
  47.             </xsl:attribute>
  48.             <xsl:if test="($TabularView='1' and $MasterVersion=4) or $InlineEdit">
  49.                 <xsl:attribute name="iid">
  50.           <xsl:value-of select="$ViewCounter" />,
  51. <xsl:value-of select="$ID" />,
  52. <xsl:value-of select="$FSObjType" />
  53.         </xsl:attribute>
  54.             </xsl:if>
  55.             <xsl:if test="$EditMode">
  56.                 <xsl:attribute name="automode">
  57.                     <xsl:value-of select="$ViewCounter" />
  58.                 </xsl:attribute>
  59.             </xsl:if>
  60.             <xsl:if test="$TabularView='1' and $MasterVersion=4">
  61.                 <td class="ms-vb-itmcbx ms-vb-firstCell">
  62.                     <input type="checkbox" class="s4-itm-cbx" />
  63.                 </td>
  64.             </xsl:if>
  65.             <xsl:if test="$InlineEdit">
  66.                 <xsl:call-template name="AutoModeHeader" />
  67.             </xsl:if>
  68.             <td colspan='1000' class="ms-stylebody" style="padding: 10px;" width="100%">
  69.                 <div style='display: none;'>
  70.                     <table>
  71.                         <tr>
  72.                             <xsl:apply-templates select="$Fields[@Name='LinkTitle']" mode="printTableCellEcbAllowed">
  73.                                 <xsl:with-param name="thisNode" select="$thisNode" />
  74.                             </xsl:apply-templates>
  75.                         </tr>
  76.                     </table>
  77.                 </div>
  78.                 <xsl:if test="./@Image != ''">
  79.                     <a target="_blank">
  80.                         <xsl:attribute name="href">
  81.                             <xsl:value-of select="./@Url" />
  82.                         </xsl:attribute>
  83.                         <img align="left" width="100px" style="margin: 10px; margin-bottom: 2px; border: none;">
  84.                             <xsl:attribute name="src">
  85.                                 <xsl:value-of select="./@Image" />
  86.                             </xsl:attribute>
  87.                         </img>
  88.                     </a>
  89.                 </xsl:if>
  90.                 <h4 style="margin-bottom: 3px; margin-top: 10px; font-size: 12pt;">
  91.                     <a target="_blank">
  92.                         <xsl:attribute name="href">
  93.                             <xsl:value-of select="./@Url" />
  94.                         </xsl:attribute>
  95.                         <xsl:value-of select="./@Title" />
  96.                     </a>
  97.                 </h4>
  98.                 <span style="font-size: 10pt;" align="justify">
  99.                     <xsl:value-of select="./@Content" disable-output-escaping="yes" />
  100.                 </span>
  101.             </td>
  102.             <!--<xsl:for-each select="$Fields">
  103.         <xsl:choose>
  104.           <xsl:when test="$EditMode and not(@ReadOnly='TRUE') and not(@FieldType='Recurrence') and not(@FieldType='CrossProjectLink')">
  105.             <xsl:call-template name="AutoModeForm">
  106.               <xsl:with-param name="thisNode" select="$thisNode" />
  107.               <xsl:with-param name="Position" select="$Position"/>
  108.               <xsl:with-param name="Fields" select="$Fields"/>
  109.             </xsl:call-template>
  110.           </xsl:when>
  111.           <xsl:otherwise>
  112.             <xsl:apply-templates select="." mode="printTableCellEcbAllowed">
  113.               <xsl:with-param name="thisNode" select="$thisNode"/>
  114.             </xsl:apply-templates>
  115.           </xsl:otherwise>
  116.         </xsl:choose>
  117.       </xsl:for-each>-->
  118.         </tr>
  119.     </xsl:template>
  120. </xsl:stylesheet>

В принципе, тут все понятно, разве что я поясню назначение вот этого:


  1. <div style='display: none;'>
  2.     <table>
  3.         <tr>
  4.             <xsl:apply-templates select="$Fields[@Name='LinkTitle']" mode="printTableCellEcbAllowed">
  5.                 <xsl:with-param name="thisNode" select="$thisNode" />
  6.             </xsl:apply-templates>
  7.         </tr>
  8.     </table>
  9. </div>

Без этого при клике на всю строку, кнопки в риббоне для редактирования/удаления не становились активными. Если заглянуть в разметку, там для этого есть какой то javascript. Я не стал разбираться, как он работает, просто добавил в скрытый див одно корректно отрендеренное поле. С ним все работает нормально.


Отлично. остался последний штрих - это переименовать кнопку "Добавить элемент" на кнопку "Добавить новость".
Само формирование этой кнопки происходит в строке 1986, Нам достаточно скопировать тот темплейт и поправить его под себя:


  1. <xsl:template name="Freeform">
  2.     <xsl:param name="AddNewText" />
  3.     <xsl:param name="ID"/>
  4.     <xsl:variable name="Url">
  5.       <xsl:choose>
  6.         <xsl:when test="List/@TemplateType='119'"><xsl:value-of select="$HttpVDir"/>/_layouts/CreateWebPage.aspx?List=<xsl:value-of select="$List"/>&amp;RootFolder=<xsl:value-of select="$XmlDefinition/List/@RootFolder"/></xsl:when>
  7.         <xsl:when test="$IsDocLib"><xsl:value-of select="$HttpVDir"/>/_layouts/Upload.aspx?List=<xsl:value-of select="$List"/>&amp;RootFolder=<xsl:value-of select="$XmlDefinition/List/@RootFolder"/></xsl:when>
  8.         <xsl:otherwise><xsl:value-of select="$ENCODED_FORM_NEW"/></xsl:otherwise>
  9.       </xsl:choose>
  10.     </xsl:variable>
  11.     <xsl:variable name="HeroStyle">
  12.       <xsl:choose>
  13.         <xsl:when test="Toolbar[@Type='Standard']">display:none</xsl:when>
  14.         <xsl:otherwise></xsl:otherwise>
  15.       </xsl:choose>
  16.     </xsl:variable>
  17.     <xsl:if test="$ListRight_AddListItems = '1' and (not($InlineEdit) or $IsDocLib)">
  18.       <table id="Hero-{$WPQ}" width="100%" cellpadding="0" cellspacing="0" border="0" style="{$HeroStyle}">
  19.         <tr>
  20.           <td colspan="2" class="ms-partline">
  21.             <img src="/_layouts/images/blank.gif" width="1" height="1" alt="" />
  22.           </td>          
  23.         </tr>
  24.         <tr>
  25.           <td class="ms-addnew" style="padding-bottom: 3px">
  26.           <span style="height:10px;width:10px;position:relative;display:inline-block;overflow:hidden;" class="s4-clust"><img src="/_layouts/images/fgimg.png" alt="" style="left:-0px !important;top:-128px !important;position:absolute;"  /></span>
  27.           <xsl:text disable-output-escaping="yes" ddwrt:nbsp-preserve="yes">&amp;nbsp;</xsl:text>
  28.           <xsl:choose>
  29.             <xsl:when test="List/@TemplateType = '115'">
  30.               <a class="ms-addnew" id="{$ID}-{$WPQ}"
  31.                  href="{$Url}"
  32.                  onclick="javascript:NewItem2(event, &quot;{$Url}&quot;);javascript:return false;"
  33.                  target="_self">
  34.                 Добавить новость
  35.               </a>
  36.             </xsl:when>
  37.             <xsl:otherwise>
  38.               <a class="ms-addnew" id="{$ID}"
  39.                  href="{$Url}"
  40.                  onclick="javascript:NewItem2(event, &quot;{$Url}&quot;);javascript:return false;"
  41.                  target="_self">
  42.                 Добавить новость
  43.               </a>
  44.             </xsl:otherwise>
  45.           </xsl:choose>
  46.           </td>
  47.         </tr>
  48.         <tr>
  49.           <td>
  50.             <img src="/_layouts/images/blank.gif" width="1" height="5" alt="" />
  51.           </td>
  52.         </tr>
  53.       </table>
  54.       <xsl:choose>
  55.         <xsl:when test="Toolbar[@Type='Standard']">
  56.           <script type='text/javascript'>
  57.             if (typeof(heroButtonWebPart<xsl:value-of select="$WPQ"/>) != "undefined")
  58.             {
  59.                 <xsl:value-of select="concat('  var eleHero = document.getElementById(&quot;Hero-', $WPQ, '&quot;);')"/>
  60.                 if (eleHero != null)
  61.                     eleHero.style.display = "";
  62.             }
  63.           </script>
  64.         </xsl:when>
  65.         <xsl:otherwise>
  66.         </xsl:otherwise>
  67.       </xsl:choose>
  68.       <xsl:if test="List/@TemplateType = '115'">
  69.           <script type='text/javascript'>
  70.             if (typeof(DefaultNewButtonWebPart<xsl:value-of select="$WPQ"/>) != "undefined")
  71.             {
  72.                 <xsl:value-of select="concat('  var eleLink = document.getElementById(&quot;', $ID, '-', $WPQ, '&quot;);')"/>
  73.                 if (eleLink != null)
  74.                 {
  75.                     DefaultNewButtonWebPart<xsl:value-of select="$WPQ"/>(eleLink);
  76.                 }
  77.             }
  78.           </script>
  79.       </xsl:if>
  80.     </xsl:if>
  81.   </xsl:template>

И вуаля, мы получаем наше кастомное представление списка.


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

На этом все, всем спасибо.

Ссылки по теме:

Глобальные параметры XSLT
Обзор систем отображения представлений списков с помощью XSLT-преобразований
SharePoint и XSLT: область ссылок «быстрого доступа»
SharePoint и XSLT: Почему XSLT - это важно?
SharePoint и XSLT: Hello world!
SharePoint Developer Roadmap

Интересные блоги

GANDJUSTAS' BLOG
SharePoint для профессионалов
Блог Виталия Жукова
Русский блог SharePoint 2010

В качестве подопытных данных были использованы материалы статьи Torrent Stream для Ubuntu ресурса Хабрахабр

10 комментариев:

  1. Спасибо за пост. Будем теперь знать, что за значения в параметрах.

    ОтветитьУдалить
  2. "Добавить новость" отображается ромбиками с вопросом...

    ОтветитьУдалить
    Ответы
    1. Сохраните файл стиля в кодировке utf-8 и в начало файла добавьте <?xml version="1.0" encoding="utf-8"?>. Должно починиться.

      Удалить

  3. tr
    У меня вот после этой строки пишет variable ждет закрытия тега, когда добавляю закрывающийся тег, то пишет ошибку ожидается закрытие тега tr, в чем может быть ошибка?

    ОтветитьУдалить
    Ответы
    1. xsl:variable name="EditMode" select="$dvt_form_key = @ID or $dvt_form_key = @BdcIdentity"/
      tr
      /xsl:variable
      вот этих строк

      Удалить
    2. Добрый день. Пришлите скриншот или сам текст мне на почту tym32167[собака]gmail.com, попробуем разобраться

      Удалить
    3. Отправила, буду очень благодарна, если вы поможете, а то я уже голову сломала, синтаксис скорее всего хромает

      Удалить
    4. Похоже, что тег переменной EditMode закрывается сразу и для него не нужно закрывающего тега xsl:variable. Попробуйте его удалить ( как то так https://lh3.googleusercontent.com/-dUdxhjxj47s/UkGWl1_k6sI/AAAAAAAAE20/NZLqG7Arv2k/w718-h151-no/%25D0%25A1%25D0%25BD%25D0%25B8%25D0%25BC%25D0%25BE%25D0%25BA.PNG).

      Удалить
    5. не помогло, появились другие ошибки(

      Удалить
    6. Вы же правите стандартный шаблон. Верните его к исходному состоянию и вносите изменения понемногу - так узнаете, где скорее всего закралась ошибка.

      Удалить