Share via


リスト ビューでのフィールドのレンダリングをカスタマイズする

最終更新日: 2011年3月29日

適用対象: SharePoint Foundation 2010

この記事の内容
リスト ビューでのカスタム フィールド レンダリングの概要
ユーザー設定フィールドのカスタム レンダリングを定義する
例: 通貨フィールドをカスタマイズする

このトピックでは、リスト ビューでユーザー設定フィールドをレンダリングする方法をどのように定義できるかについて説明します。

リスト ビューでのカスタム フィールド レンダリングの概要

Microsoft SharePoint Foundation は XSLT スタイル シートを使用してリスト ビューをレンダリングします (システムの詳細については、「XSLT リスト ビュー レンダリング システムの概要」を参照)。リストは HTML テーブルとしてレンダリングされます。フィールドの値は、%ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\TEMPLATE\LAYOUTS\XSL にある fldtypes.xsl ファイルからの簡単な XSLT テンプレートによってテーブルの適切なセルにレンダリングされます。このファイルには、フィールド値をレンダリングするための多くのテンプレートが含まれます。使用するテンプレートは、いくつかの要因によって決まります。最も重要な要因は、SPFieldType 列挙によって定義されたフィールドの型です。たとえば、Number フィールド用として FieldRef_Number_body テンプレートがあり、Text フィールド用として FieldRef_Text_body テンプレートがあります。

注意

フィールドの型とテンプレートの 1 対 1 対応はありません。たとえば、計算フィールド用としていくつかの異なるテンプレートがあります。また、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 の第 1 ステップは、thisNode パラメーターの参照のみです。したがって、残りのステップは、そのパラメーター内のマークアップのルートに対して相対的であると解釈されます。次のステップ (述語が適用される前) は、/@* です。これは、ルートとその子孫のすべての属性を参照します。したがって、この場合は、thisNode 内のすべての要素のすべての属性を参照します。述語 [name()=current()/@Name] は、選択をさらに絞り込みます。"=" の左側は XSLT name() 関数です。これは、"$thisNode/@*" 部分により生成された順序でノードの名前を表します。つまり、thisNode の何らかの要素で属性の名前を表します。これを、「XSLT 変換での入力と結果ノード ツリーの例」の例の thisNode に適用すると、その中のいくつかの属性は、リスト アイテムの各フィールドの内部名の後に名付けられていることを確認できます (例: Attachments、Title、およびユーザー設定フィールドの ISBN)。"=" の右側は、ソース ノード ツリー内の現在のノードの Name 属性への参照です (current()/@Name)。このテンプレートは match ="FieldRef" で宣言されているので、FieldRef 要素にのみ適用されます。したがって、current() 関数は FieldlRef 要素を参照します。つまり、xsl:value-of 要素全体の意味は、"ソース ノード ツリー内の現在の FieldRef の名前と同じ名前を持つ thisNode から属性の値を生成する" ことです。

したがって、例のソース ノード ツリーの Title FieldRef が処理されるときに、XSLT プロセッサは、thisNode マークアップ内で現在の Row 要素の Title 属性の値を自動で生成します (1 番目の行については、これが "真理の理論" になる)。同様に、XSLT プロセッサは、ソース ノード ツリーの ISBN FieldRef を処理するときに、同じ Row の ISBN 属性の値をレンダリングします ("0-262-61107-4")。

ほとんどの場合、ユーザー設定フィールドの既定のレンダリング方法 (ベース タイプによって基本的に決まる) は、自由に設定できます。たとえば、テキスト フィールドの場合、値は 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. %ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\TEMPLATE\LAYOUTS\XSL 内にある fldtypes.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 述語を使用して、FieldRef 要素の Name 属性の必要な値を指定します。たとえば、"Net_x0020_Profit_x002f_Loss" の内部名を持つ [Net Profit/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. Web アプリケーションをリセットして、%ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\TEMPLATE\LAYOUTS\XSL 内のファイルを再度読み込ます。カスタム ファイルによってすべての組み込みファイルが上書きされます。

例: 通貨フィールドをカスタマイズする

手順 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 パラメーターのテストによって分岐します。ソース ノード ツリー内の Toolbar 要素の Type 属性が "FreeForm" の場合、このテストは true を返します。属性値が "Standard" の場合、または属性が単に存在しない場合、テンプレートは、セル内でフィールド値を右揃えにする HTML マークアップを追加します (ソース ノード ツリーとその Toolbar 要素の例については、「XSLT 変換での入力と結果ノード ツリーの例」を参照。その他の詳細については、「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>

現在の Net_x0020_Profit_x002f_Loss フィールドの値が負の場合、つまり、値がゼロよりも小さい場合、test 値は true になります。$thisNode/@*[name()=current()/@Name] の評価の結果が現在のフィールドになることは既に確認しました。ただし、SharePoint Foundation の通貨フィールドは、何らかの XSLT 書式が適用される前であっても、低レベルの書式を取ります。特に、負の通貨値はマイナス記号ではなくかっこで表現されます。たとえば、$497,882.87 の損失は、-$497,882.87 ではなく ($497,882.87) で表現されます。これにより、問題が生じます。XSLT プロセッサはあらゆるかっこ表現をゼロより大きいとして処理するため、$thisNode/@*[name()=current()/@Name] の値をゼロと直接比較できません。ただし、Currency フィールド型の場合、SharePoint Foundation は、thisNode パラメーター内のマークアップに、第 2 バージョンのフィールド値を単純な倍精度型の値として追加します。この値は、負の場合、マイナス記号で表現されます。特に、このバージョンは、Net_x0020_Profit_x002f_Loss 属性と同じ名前の Row 要素の属性の値です。ただし、1 つの "." が属性名の末尾に付加されている場合を除きます。たとえば、「XSLT 変換での入力と結果ノード ツリーの例」の "thisNode" の例にある Row 要素の "Retail_x0020_Price" と "Retail_x0020_Price." 属性を比較してください。

この属性を、ドットで終了する名前と共に使用して、負値かどうかをテストします。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 構造全体が、外部 choose 構造の otherwise 部分の内側にある div 要素の内容になる必要があります。これにより、次のコードがテンプレート定義として生成されます。

<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: 負の値を持つ赤い通貨フィールド

負の数を赤い文字で表示した通貨の列。

関連項目

タスク

[ウォークスルー] ユーザー設定フィールド型を作成する

概念

ユーザー設定フィールド型