次の方法で共有


SharePoint 開発

SharePoint 2010 で情報アーキテクチャを構築する

Shahram Khosravi Khosravi

コード サンプルのダウンロード

Microsoft SharePoint 2010 のリリースでは、このコラボレーション ソフトウェアにエンタープライズ コンテンツ管理 (ECM) の新機能が追加されました。今回の記事ではこの新機能を利用して、次の 2 種類のポータルに、柔軟で、拡張性が高く、管理しやすい情報アーキテクチャを構築する方法を紹介します。

  • インターネット/イントラネット/エクストラネットに接続する発行ポータル
  • ナレッジ マネージメント ポータル

ここでは、SharePoint のカスタム コンポーネントの設計と実装についてのチュートリアルを提供します。このカスタム コンポーネントは、上記のポータルに情報アーキテクチャを実装するのに利用可能です。

インターネット/イントラネット/エクストラネットに接続する発行ポータル向けに情報アーキテクチャを構築する

従来のインターネット/イントラネット/エクストラネットに接続する発行ポータルは、メニューなどの GUI 要素を使用し、厳密にガイドするナビゲーション モデルに従って、目的のコンテンツまでユーザーを案内していました。このようなポータルには、通常、画面の上と左にナビゲーション メニューがあります。

一般に、画面上部のナビゲーション メニューは、ポータル分類の第 1 層と第 2 層からユーザーが選択できる AspMenu です。画面左のナビゲーション メニューは、通常、ポータル分類の第 3 層と第 4 層 (第 5 層が含まれることもあります) からユーザーが選択できる AspMenu です。

ポータルの全コンテンツは、第 1 層を形成する一連のカテゴリに分割されます。今回はカテゴリに「Term "i"」という名前付け規則を使用します ("i" は整数値です)。たとえば、1 つ目のカテゴリは「Term1」、2 つ目のカテゴリは「Term2」となります。

各カテゴリのコンテンツは、次に第 2 層を形成する一連のサブカテゴリに分割されます。サブカテゴリには「Term "ij"」という名前付け規則を使用します ("i" と "j" は整数値です)。たとえば、1 つ目のカテゴリに属する 1 つ目のサブカテゴリは「Term11」になります。

このようにして、細分化の必要がなくなるまでコンテンツの分類を続けます。図 1 は、このポータル分類を示しています。

Portal Taxonomy
図 1 ポータル分類

こうしたポータル分類は、通常、適切なサイト構造を構築することで SharePoint 2007 に実装します。それにはまず、カテゴリごとに個別のサイトを作成します。次に、各カテゴリのサイトの下に、サブカテゴリごとに個別のサブサイトを作成します。その下位カテゴリについても、同様に個別のサイトを作成していきます。図 2 は、ポータルのサイト構造を示します。

The Site Structure of the Portal
図 2 ポータルのサイト構造

基本的には、各カテゴリ、サブカテゴリ、その下位カテゴリにはそれぞれ専用のサイトを用意します。この専用サイトには、そのサイト用のページを含む Pages ドキュメント ライブラリが存在します。ソーシャル ネットワーキングの用語を使うなら、サイトの Pages ドキュメント ライブラリの全ページに、サイトが表すカテゴリ、サブカテゴリ、またはその下位カテゴリのタグが暗黙のうちに付けられると言えます。ある意味では、カテゴリ、サブカテゴリ、またはその下位カテゴリを表すサイトにページを作成することで、それらたくさんのページに暗黙のうちに各カテゴリのタグを付けることになります。このようにして新しいサイトを作成することで、新たなタグ (または用語) を暗黙のうちに作成します。

画面上部のナビゲーション AspMenu には、カテゴリ (第 1 層) とそのサブカテゴリ (第 2 層) が表示されます。ユーザーはこの AspMenu からカテゴリやサブカテゴリを選択し、そのカテゴリまたはサブカテゴリのタグが暗黙のうちに付けられたページに移動します。

画面上部のナビゲーション メニューからサブカテゴリを選択すると、画面左のナビゲーション AspMenu (サイド リンク バー) に、そのサブカテゴリに関連付けられた下位カテゴリが表示されます。ユーザーは、画面左の AspMenu からサブカテゴリの下位カテゴリを選択し、そのカテゴリのタグが暗黙のうちに付けられたページに移動します。特定のサイトの Pages ドキュメント ライブラリには複数のページが含まれることがあります。その場合、この複数のページには暗黙のうちに同じカテゴリ、サブカテゴリ、またはその下位カテゴリのタグが付けられます。サイド リンク バーには、同じサブカテゴリの下位カテゴリのタグが暗黙のうちに付けられた全ページへのリンクが表示されます。

図 1図 2 を比較すると、ポータル分類または情報アーキテクチャが、ポータルのサイト構造をそのまま反映していることがよくわかります。この方法だと情報アーキテクチャは柔軟性に欠け、次のような問題が生じます。

  • 新たに暗黙のタグを作成する場合、サイトを新規作成するためにサイト管理者の許可が必要です。
  • ページにタグを付け直す場合、ページを現在のサイトから別のサイトへ物理的に移動する必要があります。
  • 情報アーキテクチャを再編成する場合、サイトとページを物理的に移動および削除する必要があります。
  • コンテンツの作成者は、複数のカテゴリ、サブカテゴリ、その下位カテゴリなどをまたいで同じページを使用することができません。カテゴリ、サブカテゴリなどはサイトが異なるため、コンテンツの作成者はページを個別に作成する必要があります。それぞれのサイトにページをコピーする以外に組み込み機能で可能な代替策はありませんが、この方法には 2 つの実用上の問題があります。第 1 に、コンテンツの作成者は多くの異なる場所にページをコピーしなければなりません。第 2 に、作成者がページのコンテンツに変更を加えるたびに、そのページをコピーした全サイトでページに同じ変更を加えるか、コピーし直す必要があります。これは間違いのもとになります。
  • 分類に変更を加える場合は、サイト構造を根本から構築し直す必要があり、時間と労力が膨大にかかるため、柔軟性がほとんどありません。分類は、サイト コレクションに実際に情報を格納する方法と密接に結び付いています。

そこで登場するのが SharePoint 2010 ECM です。SharePoint 2010 ECM を導入すると、ポータル分類を Managed Metadata Service アプリケーションに実装し、一元管理できるようになります。この実装はポータルのサイト構造に依存しないため、以下のことが可能です。

  • 新しく暗黙のタグを作成するだけのために、新規サイトを用意する必要はありません。用語ストアのポータル分類で、任意の場所に簡単に新しい用語を追加できます。SharePoint 2010 ではドキュメント ライブラリの拡張性の問題が解決されているため、この方法で同一サイトの同じ Pages ドキュメント ライブラリにすべてのページを保存できます。ここでは、すべてのページを 1 つのサイトの同じ Pages ドキュメント ライブラリで管理することを想定して話を進めます。
  • ページを物理的に移動しなくても、新たな用語でページのタグを付け直すことができます。
  • サイトやページを物理的に移動または削除しなくても、用語ストアで簡単に分類を再編成できます。
  • ページを異なるサイトに物理的にコピーしなくても、ページにカテゴリやサブカテゴリなどを表す複数の用語でタグを付けるだけで、複数のカテゴリをまたいで同じページを使用できます。

図 3 に示すように、ここではポータル分類を単一の用語セットとして実装します。

Implementation of Portal Taxonomy in the Managed Metadata Service Application
図 3 Managed Metadata Service アプリケーションにおけるポータル分類の実装

ただし、ポータル分類をポータルのサイト構造にではなく、単一の用語ストアに実装する方法には、2 つの課題があります。ここからは、この 2 つの課題について説明します。

TaxonomyDataSource コントロール

まず、v4.master のマスター ページには、画面上部のナビゲーション メニューを表示する AspMenu を置きます。AspMenu を、サイト マップ データ ソース コントロールにバインドし、プロバイダーを使用してポータルのサイト構造からサイト マップ データを取得します。ここではポータルの物理的なサイト構造からではなく、用語ストアからサイト マップ データを取得することを考えているため、上記のようにはいきません。

1 つの選択肢として、用語ストアから適切な用語を取得するカスタム サイト マップ プロバイダーを実装する方法があります。もう 1 つの方法として、カスタム データ ソース コントロールを実装することもできます。ASP.NET には XmlDataSource という強力なデータ ソース コントロールがあり、目的に応じて簡単に拡張できるため、ここでは後者の方法を採用します。カスタム データ ソース コントロールには、TaxonomyDataSource という名前を付けます。

TaxonomyDataSource は IsGlobal というブール型プロパティを公開します。マスター ページに TaxonomyDataSource のインスタンスを 2 つ含めます。1 つ目のインスタンスは、画面上部のナビゲーション メニューをレンダリングする AspMenu にバインドします。このインスタンスの IsGlobal プロパティには true を設定し、ポータル分類を格納した用語セットのすべての用語を取得します。これにより、画面上部のナビゲーション メニューに、すべてのカテゴリとそのサブカテゴリが表示されます。このカテゴリとそのサブカテゴリは、用語セットの子用語と孫用語にすぎないことに留意してください。

2 つ目のインスタンスは、画面左のナビゲーション メニュー (サイド リンク バー) をレンダリングする AspMenu にバインドします。このインスタンスの IsGlobal プロパティには false を設定し、現在の用語のサブ用語のみを取得します。ここで "現在の用語" とは何を意味しているのか説明が必要でしょう。

先ほど説明したように、画面上部のナビゲーション メニューからサブカテゴリを選択すると、画面左のナビゲーション メニューにそのサブカテゴリに関連付けられた下位のカテゴリが一覧表示されます。この場合、現在の用語はサブカテゴリを指します。2 つ目のインスタンスは、通常、現在の用語の子用語と孫用語を返します。つまり、サブカテゴリの下位カテゴリとさらにもう 1 層下位のカテゴリを返します。

TaxonomyDataSource は Data プロパティをオーバーライドし、用語ストアからポータル分類を取得します。Data プロパティを使用する主な目的は、XML ドキュメントを作成し、XmlDataSource が AspMenu に渡すノードを作成できるようにすることです。Data プロパティは、次のコードに示すように、まず SharePoint 2010 managed metadata API を使用して、ポータル分類を格納している用語セットにアクセスします。

TaxonomySession taxonomySession = new TaxonomySession(SPContext.Current.Site);
TermStore termStore = taxonomySession.TermStores[this.TermStore];
Group group = termStore.Groups[this.Group];
TermSet termSet = group.TermSets[this.TermSet];

IsGlobal の値が true の場合は、Data プロパティは用語セットのすべての用語を使用します。

termsToReturn = termSet.Terms;

IsGlobal の値が false の場合は、Data プロパティはまず現在の用語の GUID にアクセスします。GUID は、CurrentTermId クエリ文字列パラメーターから公開されます。次に、現在の用語の子用語と孫用語を使用します。

Term currentTerm = taxonomySession.GetTerm(
  new Guid(this.Page.Request.QueryString["CurrentTermId"]));
termsToReturn = currentTerm.Terms;

次に、Data プロパティは XML ドキュメントの作成を開始します。この XML ドキュメントは <Terms> という名前のドキュメント要素を持ち、<Term> 要素から成る階層を含みます。TaxonomyDataSource は、用語ストアから取得する各用語を表す <Term> 要素を個別に作成します。このような XML ドキュメントの例を次に示します。

<Terms>
  <Term Name="Term1" URL="PageUrl?CurrentTermId=">
    <Term Name="Term11" URL="PageUrl?CurrentTermId=">
      <Term Name="Term111" URL="PageUrl?CurrentTermId="/>
    </Term>
  </Term>
  <Term Name="Term2" URL="PageUrl?CurrentTermId=">
    <Term Name="Term21" URL="PageUrl?CurrentTermId="/>
  </Term>
</Terms>

<Term> 要素には、Name と URL という 2 つの属性があることに注意してください。Name 属性には用語の名前を、URL 属性には用語のタグが付けられたページの URL をそれぞれ設定します。URL 属性には、現在の用語の GUID を格納する CurrentTermId というクエリ文字列パラメーターを含みます。

Data プロパティは取得した用語を反復処理し、列挙された用語ごとに GetXmlFragment メソッドを呼び出します。このメソッドの主な目的は、列挙された用語を表す <Term> 要素と、列挙された用語の子用語と孫用語を表す <Term> サブ要素を構築することです。

foreach (Term term in termsToReturn)
{
  GetXmlFragment(publishingPageCollection, term, ref xml);
}

TaxonomyDataSource は、SharePoint 発行 API を使用して、発行ページを含むコレクションにアクセスすることに注意してください。

次に、GetXmlFragment の実装について説明します。ただし、まず管理されたメタデータ タイプの、Tags サイト内の列の意味を理解する必要があります。Tags サイト内の列を作成し、ポータル分類を含む用語セットにバインドしたうえで、関連する発行ページ レイアウトのコンテンツ タイプに追加することが必要です。Tags サイト内の列により、コンテンツの作成者はポータル分類の用語で、発行ページにタグを付けることができます。

GetXmlFragment は 3 つの部分から構成されます。最初の部分では、Pages ドキュメント ライブラリのページから特定の用語でタグが付けられた最初のページを検索し、その用語を表すために <Term> 要素をレンダリングします (図 4 参照)。

図 4 GetXmlFragment の最初の部分

foreach (PublishingPage publishingPage in publishingPageCollection)
{
  TaxonomyFieldValueCollection values =
    publishingPage.ListItem["Tags"] as TaxonomyFieldValueCollection;
               
  foreach (TaxonomyFieldValue value in values)
  {
    if (value != null && value.TermGuid == term.Id.ToString())
    {
      url = publishingPage.Uri.AbsoluteUri;
      xml += "<Term Name='" + term.Name + "' URL='" + url +
        "?CurrentTermId=" + term.Id.ToString() + "'>";
      closeTerm = true;
      defaultPublishingPage = publishingPage;
      break;
    }
  }
 
  if (closeTerm)
    break;
}

<Term> 要素の URL 属性にページの URL を、CurrentTermId クエリ文字列パラメーターに用語の GUID をそれぞれ設定します。このページは、その特定の用語の既定のページとして機能します。その特定の用語を表すサイトを作成した場合、基本的には、サイトの既定のページと同じになります。

図 4 に示すコードは、次の XML フラグメントを生成します。

<Term Name='TermName' URL='DefaultPageURL?CurrentTermId=GUID>

<Term> 要素をまだ閉じていないことに注意してください。これは、子用語と孫用語を反復処理し、列挙された子用語と孫用語ごとに <Term> 要素内の <Term> サブ要素をレンダリングする必要があるためです。次に示すように、GetXmlFragment の 2 つ目の部分では、まさにこれを実行します。

foreach (Term cterm in term.Terms)
{
  GetXmlFragment(publishingPageCollection, cterm, ref xml);
}

その後、GetXmlFragment は親 <Term> 要素を閉じます。次に GetXmlFragment は、同じ用語でタグが付けられた Pages ドキュメント ライブラリの残りのページに <Term> 要素をレンダリングします。それらの <Term> 要素は、既定のページを表す <Term> 要素の兄弟要素として処理されます。これによりサイド リンク バーは、現在の用語でタグが付けられたすべてのページへのリンクをレンダリングします。用語を表すサイトを作成した場合、通常、サイトの既定のページ以外のページになります (図 5 参照)。

図 5 GetXmlFragment の第 3 の部分

if (!this.IsGlobal)
{
  foreach (PublishingPage publishingPage in publishingPageCollection)
  {
    if (publishingPage == defaultPublishingPage)
      continue;
 
    TaxonomyFieldValueCollection values =
      publishingPage.ListItem["Tags"] as TaxonomyFieldValueCollection;
                   
    foreach (TaxonomyFieldValue value in values)
    {
       if (value != null && value.TermGuid == term.Id.ToString())
       {
         url = publishingPage.Uri.AbsoluteUri;
         xml += "<Term Name='" + publishingPage.Title + "' URL='" +
           url + "?CurrentTermId=" + term.Id.ToString() + "'/>";
         break;
       }
     }
   }
 }

図 6 に例示するのは、TaxonomyDataSource を使用したマスター ページに基づくページです。
An Example Page Based on a Master Page that Uses TaxonomyDataSource
図 6 TaxonomyDataSource を使用したマスター ページに基づくページの例
TaxonomyDataSource により、画面上部と左のナビゲーション メニューには、用語ストアで一元管理されるポータル分類の異なる層が表示されます。

ListSiteMapPath コントロール

前述のように、ポータルのサイト構造の代わりに用語ストアのポータル分類を実装する方法には、2 つの課題があります。前のセクションで 1 つ目の課題について説明し、解決策を提示しました。ここでは、2 つ目の課題と解決策を説明します。

v4.master には PopoutMenu というコントロールがあり、ListSiteMapPath というコントロールをレンダリングします。ListSiteMapPath は、ページにアイコンとして表示される PopoutMenu をユーザーがクリックしたときに表示される階層リンクをレンダリングします。

ListSiteMapPath は、階層リンクのレンダリングに従来から使用されている SiteMapPath コントロールを継承しています。そして、default.master が SiteMapPath を使用するのに対し、v4.master は ListSiteMapPath を使用します。

ListSiteMapPath は、サイト マップ プロバイダー名のコンマ区切りのリストを格納する SiteMapProviders というプロパティを公開します。そのため、ListSiteMapPath は、複数のプロバイダーを操作できます。ListSiteMapPath はプロバイダーを反復処理し、列挙されたプロバイダーごとに次の手順を実行します。まず、プロバイダーの FindSiteMapNode メソッドを呼び出し、HttpContext を渡して現在のサイト マップ ノードを返します。次に、プロバイダーの GetParentNode メソッドを繰り返し呼び出し、ルート サイト マップ ノードに達するまで、現在のサイト マップ ノードのすべての先祖サイト マップ ノードにアクセスします。最後に、ルート サイト マップ ノードから始め現在のサイト マップ ノードに戻ってくるまで、それぞれの先祖サイト マップ ノードに階層リンクのアイテムをレンダリングします。

このように、ListSiteMapPath は列挙されたサイト マップ プロバイダーごとにアイテムの階層全体をレンダリングします。こうして、それぞれのサイト マップ プロバイダーが階層リンクに貢献します。そのため ListSiteMapPath は、さまざまな種類のソースからのサイト マップ ノードをレンダリングできます。この例では、用語ストアで管理されるポータル分類からサイト マップ ノードをレンダリングする ListSiteMapPath が必要です。そのため、TaxonomySiteMapProvider というカスタム サイト マップ プロバイダーを実装します。

TaxonomySiteMapProvider は、特定のコンテキストでそれぞれの SPListItem にアクセスする FindSiteMapNode をオーバーライドします。通常は、現在のコンテキストが使用されます。次に、このリスト アイテムの URL、ID、およびタイトルにアクセスし、リスト アイテムを表すサイト マップ ノードを作成します。発行サイトのリスト アイテムは、発行ページを表します。

次に示すように、ListSiteMapPath はこのメソッドを呼び出して、現在のサイト マップ ノードにアクセスします。

SPContext spContext = SPContext.GetContext(context);
SPListItem listItem = spContext.ListItem;
string url = listItem.Url;
string key = listItem.ID.ToString();
string title = listItem.Title;
return new SiteMapNode(this, key, url, title);

次に ListSiteMapPath は GetParentNode を呼び出し、現在のサイト マップ ノードを渡し、現在のノードの親を表すサイト マップ ノードを返します。現在のサイト マップ ノードは現在の発行ページを、親サイト マップ ノードは現在の発行ページの親を、それぞれ表します。この場合、発行ページの親には、現在の発行ページに付けられたタグの親用語でタグが付けられます。

GetParentNode をオーバーライドした TaxonomyDataSource は、まず現在の SharePoint リストにアクセスします。現在の SharePoint リストとは、発行ページが含まれた Pages ドキュメント ライブラリです。次に、現在の発行ページのリストを検索するために Collaborative Application Markup Language (CAML) クエリを作成し、現在のページに付けられているタグの用語にアクセスできるようにします。今回は、発行ページにアクセスするのに発行 API は使用しません。CAML クエリを使用する方がパフォーマンスが向上するためです。Pages ドキュメント ライブラリに数万ものページが含まれている場合はなおさらです。

GetParentNode の次のコード セクションでは、特定のノードが表す発行ページを返し、Tags フィールドの値 (ページに付けられているタグの用語) を取得します。

SPQuery query = new SPQuery();
 
query.ViewFields = "<FieldRef Name='Tags'/>";
query.Query = "<Where><Eq><FieldRef Name='ID'/><Value Type='Integer'>" +
  node.Key + "</Value></Eq></Where>";
SPListItemCollection listItems = list.GetItems(query);
SPListItem listItem = listItems[0];
 
TaxonomyFieldValueCollection values =
  listItem["Tags"] as TaxonomyFieldValueCollection;
TaxonomyFieldValue value = values[0];
 
Guid termGuid = new Guid(value.TermGuid);
TaxonomySession taxonomySession = new TaxonomySession(context.Site);
Term term = taxonomySession.GetTerm(termGuid);

次に、GetParentNode は現在の用語の親用語にアクセスし、Pages ドキュメント ライブラリからその親用語のタグが付けられた発行ページを検索します。最終的に、その発行ページの URL と ID にアクセスし、これら 2 つの情報と親用語の名前を使用して、親サイト マップ ノードを形成します (図 7 参照)。

図 7 親サイト マップ ノードの形成

Term parentTerm = term.Parent;
if (parentTerm != null)
{
  int[] wssIds = TaxonomyField.GetWssIdsOfTerm(context.Site, parentTerm.TermStore.Id,
    parentTerm.TermSet.Id, parentTerm.Id, false, 500);
  query = new SPQuery(list.DefaultView);
  query.Query =
    "<Where><In><FieldRef LookupId='True' Name='Tags'/><Values>";
  foreach (int wssId in wssIds)
  {
    query.Query += ("<Value Type='Integer'>" + wssId.ToString() + "</Value>");
  }
  query.Query += "</Values></In></Where>";
    listItems = list.GetItems(query);
    listItem = listItems[0];
 
    string url = listItem.Url;
    string key = listItem.ID.ToString();
    string title = parentTerm.Name;
 
      return new SiteMapNode(this, key, url, title);
}

図 7 に示したコードは、TaxonomyField クラスの GetWssIdsOfTerm 静的メソッドを使用します。このメソッドは、分類の隠しリストから特定の用語の Windows SharePoint Services (WSS) の ID を返します。隠しリストは、SharePoint がサイト コレクションで使用される用語をキャッシュする、サイト コレクション レベルの SharePoint リストです。アイテムに新たな用語でタグを付けるたびに、SharePoint は隠しリストにその用語のエントリを自動的に追加します。用語を再利用した場合などには、この分類の隠しリストに同じ用語のエントリが複数含まれることがあります。

GetWssIdsOfTerm は、分類の隠しリストの特定の用語を表す、すべてのリスト アイテムの ID を返します。管理されたメタデータ フィールド (この例では Tags フィールド) に基づきフィルター処理する、CAML クエリの ID を使用する必要があります。

図 8 は、TaxonomySiteMapProvider にバインドした ListSiteMapPath を示しています。ListSiteMapPath は、現在のページが属している階層全体をレンダリングすることに注意してください。

The ListSiteMapPath that Is Bound to the TaxonomySiteMapProvider
図 8 TaxonomySiteMapProvider にバインドされる ListSiteMapPath

ナレッジ マネージメント ポータル向けに情報アーキテクチャを構築する

上述のように、従来のガイド付きナビゲーションを使用する方法では、ユーザーがコンテンツを見つけるのに役立つ一連のメニュー オプションがありました。ソーシャル ネットワーキング ポータルはこれとは大きく異なり、次に示すような方法でユーザーがコンテンツを見つけるのを支援します。

  • 検索エンジン: ユーザーはコンテンツを見つけるのに、検索インデックスに照らして検索クエリを実行します。
  • メタデータのフィルター処理: ユーザーはメタデータのフィルター処理機能を使用して、検索結果をフィルター処理します。
  • Wiki 形式のリンク: ページは Wiki 形式で相互にリンクされます。ユーザーは Wiki 形式のリンクを使用してページ間を移動します。
  • ロールアップ Web パーツ: ページには、さまざまな場所からのコンテンツをまとめるロールアップ Web パーツがあります。ユーザーはロールアップ Web パーツのリンクを使用してページ間を移動します。

ソーシャル ネットワーキング ポータルはナビゲーションの方法として、従来のポータルで使用されていた選択肢の乏しいガイド付きのアプローチとは対照的な、フリーフロー アプローチを推進します。そのため、ユーザーはさまざまな手段でページにたどり着くことができます。ここからは、ソーシャル ネットワーキング ナビゲーション モデルを活用するナレッジ マネージメント ポータルの設計と実装について説明します。設計については、Microsoft SharePoint Conference 2009 のセッションで Sean Squires と Lincoln DeMaris が紹介しました。ここでは、設計のいくつかの側面を取り上げ、カスタマイズと強化の例を示します。まず、ナレッジ マネージメント ポータルのホームページについて説明します。

ホームページ

ホームページの主な目的は、検索ボックスとロールアップ Web パーツの 2 つの機能を提供することです。検索ボックスにより、ユーザーはコンテンツを検索できます。検索ボックスは、ホームページのメイン コンポーネントです。ロールアップ Web パーツは、エンタープライズ全体のさまざまな場所からのコンテンツをまとめます。

ユーザーにとって便利なコンテンツなら、すべて取得される可能性があります。たとえば、エンタープライズで最も閲覧や検索が行われているコンテンツを表示するのは、ユーザーにとって便利な場合があります。SharePoint 2010 組み込みの Web Analytics の Web パーツを構成して、そうしたコンテンツを表示できます。

ナレッジ マネージメント ポータルは、通常、ドキュメントを中央リポジトリに保存します。SharePoint には、ドキュメント センターという組み込みのサイト テンプレートがあります。このサイト テンプレートを使用して、ドキュメントを保存するサイトを作成できます。次に、ホームページにコンテンツ クエリ Web パーツを追加し、最近アップロードされたドキュメントをまとめます。

ユーザーがホームページに表示された検索ボックスを使用して検索クエリを実行すると、検索結果のページが表示されます。このページは SharePoint に標準で組み込まれている検索結果ページで、絞り込みパネルが付いています。絞り込みパネルには、ユーザーが検索結果をフィルター処理するのに使用できるカテゴリが含まれています。そうしたカテゴリの 1 つに、検索結果の種類があります。

検索結果の種類を選択して、関連する Web ページのみを表示できます。また、絞り込みパネルには Web ページに付けられたタグの用語が表示されます。これはポータル分類から取得される用語です。ユーザーはそれらの用語を使用して、目的のページにたどり着くまでページをフィルター処理できます。その後ユーザーは検索結果をクリックし、ページに移動できます。ページは、基本的にはエンタープライズ Wiki ページになります。

エンタープライズ Wiki ページの構造

ここではナレッジ マネージメント ポータルの全ページを、エンタープライズ Wiki ページ レイアウトをカスタマイズした同じバージョンで作成します。

ページ レイアウトをカスタマイズするには、まず Wiki の Categories フィールド コントロールを Tags フィールド コントロールに置き換えます。また、Tags フィールド コントロールは、ページが編集モードのときにのみ表示されるように EditModePanel に配置します。表示モードで Tags フィールド コントロールが表示されないようにするのは、画面左のナビゲーション メニューに Tags フィールド コントロールではなく、現在のページに付けられているタグの用語をレンダリングするためです。後で簡単に示すように、AspMenu を使用すれば現在の用語のみではなく、そのサブ用語やさらに下位の用語などをレンダリングできます。

また、クエリ文字列を使用せず、現在のページの Tags フィールドから現在の用語を取得するように、TaxonomyDataSource の実装に変更を加える必要があります。これは、従来のポータルで使用されていたガイド付きナビゲーション モデルとは異なり、画面上部のナビゲーション メニューを使用してユーザーが移動することはないからです。ユーザーは、どこからでも現在のページにアクセスできます。たとえば、ページに存在する Wiki リンクから現在のページに移動できる場合があります。そのため、現在の用語を表示するためのクエリ文字列パラメーターはありません。これは、現在のページに複数の用語でタグが付けられている場合は、現在の用語はもはや 1 つではないということでもあります。

変更後の TaxonomyDataSource は、まず現在のページに付けられているタグのすべての用語にアクセスします。次に、それらの用語を反復処理し、用語とその子孫用語の XML フラグメントを作成します (図 9 参照)。

図 9 変更後の TaxonomyDataSource

TaxonomyFieldValueCollection values =
  SPContext.Current.ListItem["Tags"] as TaxonomyFieldValueCollection;
Term currentTerm = null;
foreach (TaxonomyFieldValue value in values)
{
  currentTerm = taxonomySession.GetTerm(new Guid(value.TermGuid));
  GetXmlFragment(publishingPageCollection, currentTerm, ref xml);
  termsToReturn = currentTerm.Terms;
 
  if (termsToReturn != null)
  {
    foreach (Term term in termsToReturn)
    {
      GetXmlFragment(publishingPageCollection, term, ref xml);
    }
  }
}

図 10 に示すのは、エンタープライズ Wiki ページ レイアウトをカスタマイズして作成したページです。

A Page Based on a Customized Enterprise Wiki Layout
図 10 カスタマイズしたエンタープライズ Wiki レイアウトに基づくページ

ご覧のように、サイド リンク バーには、現在の用語、そのサブ用語、および現在の用語とそのサブ用語でタグが付けられたページが表示されます。また、表示モードではページに Tags フィールド コントロールが表示されないことにも注意してください。

図 11 に示すのは、Tags フィールドが表示された編集モードのページで、コンテンツの作成者はページにタグを付けたり、付け直したりできます。

A Page in Edit Mode, Allowing Tagging or Retagging
図 11 タグ付けやタグの付け直しが可能な編集モードのページ

TaxonomyDataSource により、画面左のナビゲーション メニューに現在のページと関連付けられたすべてのページへのリンクが公開されます。現在のページと同じ用語でタグが付けられたページのみではなく、現在の用語の子孫用語でタグが付けられたページへのリンクも公開されます。TaxonomyDataSource を改良すれば、どこまで子孫用語を表示するかをコンテンツの作成者が選択できるようになります (現在のページに付けられているタグの子用語のみ表示、子用語と孫用語を表示、子用語、孫用語、およびその子孫用語を表示など)。また、どこまで先祖用語を表示するかも選択可能にできます (現在のページに付けられているタグの親用語を表示、親用語および親の親に当たる用語を表示など)。

このように TaxonomyDataSource は、ページを閲覧したユーザーに、エンタープライズ全体の関連するページへのリンクを提供する強力なツールになります。ページを追加し、現在のページに付けられているタグと同じ用語、またはその子孫用語でタグを付けると、TaxonomyDataSource が自動的に取得し、サイド リンク バーが追加されたページへのリンクを含めて自動的に更新します。TaxonomyDataSource により、ポータル分類をエンタープライズ全体のすべてのページとドキュメントを連結する共通のスレッドとして使用できるようになります。

サイド リンク バーのリンクは、ポータルのページを関連付ける方法の 1 つにすぎません。Wiki 形式でページをリンクする方法もありますし、エンタープライズ全体から関連するコンテンツを取得するロールアップ Web パーツを使用する方法もあります。たとえば、ドキュメント センターからドキュメントを取得するようにコンテンツ クエリ Web パーツを構成し、現在のページに付けられているタグの用語に基づきフィルター処理を行うようにできます。新たなドキュメントをドキュメント センターにアップロードし、現在のページに付けられているタグと同じ用語でタグを付けると、コンテンツ クエリ Web パーツはそれらの新しいドキュメントを表示するように自動的に更新されます。

コンテンツの作成者がページに新たなタグの追加または既存のタグの編集や削除を行うと、ページ上のすべてのロールアップ Web パーツとサイド リンク バーのコンテンツが自動的に変更されます。これは、コンテンツが分類に基づいてページに表示される "コンテキスト対応型ソーシャル ネットワーキング (contextual social networking)" の一例です。

TaxonomyDataSource、Wiki 形式のリンク、およびロールアップ Web パーツにより、エンタープライズ全体から関連するコンテンツを取得して 1 つの場所にまとめ、ページに付けられたタグの用語に基づきフィルター処理するという主要な役割をページが担うことになります。ページは、もはやポータルの物理構造を反映して明示的に構造化されるものではありません。むしろ、分類、Wiki 形式のリンク、およびロールアップ Web パーツにより、ページの関係性を反映して暗黙のうちに構造化されるものになっています。

柔軟性が高くカスタマイズした情報アーキテクチャ

まとめになりますが、SharePoint 2010 ECM の新機能は、インターネット/イントラネット/エクストラネットに接続する発行ポータルとナレッジ マネージメント ポータルに、柔軟性の高い情報アーキテクチャを構築し実装するのに役立ちます。ソーシャル ネットワーキング サイトの急激な拡大に代表されるようにインターネットの利用法は変化しており、それに対応して Web ページとサイトのデザインを進化させるため、ますます柔軟性が求められるようになっています。今回は情報アーキテクチャの実装に使用できるいくつかのカスタム SharePoint コンポーネントの設計と実装について説明しましたが、ここで紹介した以外にもできることはたくさんあります。新たな可能性を探ってみてください。

Shahram Khosravi は、SharePoint のアーキテクチャ、設計、および開発の専門家で、IT 業界で豊富な経験があります。彼は、『Expert WSS 3.0 and MOSS 2007 Programming』(Wrox、2008 年)、『Professional SharePoint 2007 Workflow Programming』(Wrox、2008 年)、『ASP.NET AJAX Programmer’s Reference』(Wrox、2007 年)、『ASP.NET 2.0 Server Control and Component Development』(Wrox、2006 年)、および『IIS 7 and ASP.NET Integrated Programming』(Wrox、2007 年) の著者です。