February, 2012

  • リボンメニューのタブを権限に従って表示 / 非表示にする方法

    こんにちは。SharePoint サポートの多田です。

    今回は、マスターページにおいてリボンメニューのタブを権限に従って表示 / 非表示にする方法をご案内したいと思います。

    今回表示 / 非表示を実現する部分は以下になります。

     

    ・ページタブ

    li タグ: <li class="ms-cui-tt" id="Ribbon.WikiPageTab-title" role="tab" unselectable="on">

     

    ・リストツール

     

    li タグ : <li class="ms-cui-cg ms-cui-cg-lb" id="Ribbon.ListContextualGroup" unselectable="on">

     

    ・ライブラリツール

     

    li タグ : <li class="ms-cui-cg ms-cui-cg-db" id="Ribbon.LibraryContextualGroup" unselectable="on">

     

    ・予定表ツール

     

    li タグ : <li class="ms-cui-cg ms-cui-cg-gr" id="Ribbon.Calendar" unselectable="on">

     

    ※ リボンメニューの li タグの id は後述する実現手順で使用します。また、リボンメニューの li タグを確認する場合は、IE F12 キーを押し開発者ツールを起動し、"矢印" マークをクリックしリボンメニューをポイントすることで確認可能です。

     

    - 実施手順

    1. SharePoint Designer を起動し、マスターページ (v4.master) をチェックアウトして開きます。

    2. <div id="s4-ribboncont"> タグを探します。このタグがリボン部分を示すタグになります。

    3. <div id="s4-ribboncont"> タグのタグを閉じる部分の直下に以下の記述を加え、マスターページを保存し、チェックインします。またマスターページの変更を有効化するにはマスターページの承認が必要になります。

     

    記述を加える部分

    --------

    <div id="s4-ribboncont">

    ・・・

    ・・・

    ・・・

    </div>

    <---- ここに記述します。

    --------

     

    加える記述

    --------

    <!-- ページタブの表示 / 非表示 -->

    <script type="text/javascript">

                document.getElementById("Ribbon.WikiPageTab-title").style.display = "none";

    </script>

    <Sharepoint:SPSecurityTrimmedControl ID="SPSecurityTrimmedControl2" runat="server" PermissionsString="FullMask">

        <script type="text/javascript">

            document.getElementById("Ribbon.WikiPageTab-title").style.display = "block";

        </script>

    </Sharepoint:SPSecurityTrimmedControl>

     

    <!-- ライブラリツールの表示 / 非表示 -->

    <script type="text/javascript">

                document.getElementById("Ribbon.LibraryContextualGroup").style.display = "none";

    </script>

    <Sharepoint:SPSecurityTrimmedControl ID="SPSecurityTrimmedControl3" runat="server" PermissionsString="FullMask">

        <script type="text/javascript">

            document.getElementById("Ribbon.LibraryContextualGroup").style.display = "block";

        </script>

    </Sharepoint:SPSecurityTrimmedControl>

     

    <!-- リストツールの表示 / 非表示 -->

    <script type="text/javascript">

                document.getElementById("Ribbon.ListContextualGroup").style.display = "none";

    </script>

    <Sharepoint:SPSecurityTrimmedControl ID="SPSecurityTrimmedControl4" runat="server" PermissionsString="FullMask">

        <script type="text/javascript">

            document.getElementById("Ribbon.ListContextualGroup").style.display = "block";

        </script>

    </Sharepoint:SPSecurityTrimmedControl>

     

    <!-- 予定表ツールの表示 / 非表示 -->

    <script type="text/javascript">

                document.getElementById("Ribbon.Calendar").style.display = "none";

    </script>

    <Sharepoint:SPSecurityTrimmedControl ID="SPSecurityTrimmedControl5" runat="server" PermissionsString="FullMask">

        <script type="text/javascript">

            document.getElementById("Ribbon.Calendar").style.display = "block";

        </script>

    </Sharepoint:SPSecurityTrimmedControl>

     --------

     

    ※ 上記のサンプルでは各リボンメニューごとに記述を分けています。これは以下のように JavaScript の記述をまとめて書くと JavaScript エラーが発生し、後続の処理が行われないためです。例えば Ribbon.WikiPageTab-title id がないドキュメント ライブラリなどのページにアクセスした時は以下のサンプルの 1 行目で JavaScript エラーが発生し後続の処理が行われません。上記のサンプルでは同じく JavaScript エラーは発生しますが、1 つずつスクリプトタグで閉じているため後続の処理が行われます。JavaScript エラーを発生させないようにする場合は、null チェック等の機能を実装します。

    <script type="text/javascript">

                document.getElementById("Ribbon.WikiPageTab-title").style.display = "none";

                document.getElementById("Ribbon.ListContextualGroup").style.display = "none";

                document.getElementById("Ribbon.ListContextualGroup").style.display = "none";

                document.getElementById("Ribbon.LibraryContextualGroup").style.display = "none";

                document.getElementById("Ribbon.Calendar").style.display = "none";

    </script>

     

     

    - 記述内容の説明

    まずはじめに JavaScript を使用してページタブ、リストツール、ライブラリツール、予定表ツールを一旦非表示にしています。

     

    document.getElementById("Ribbon.WikiPageTab-title").style.display = "none";

     

    次に SPSecurityTrimmedControl コントロールを使用しています。SPSecurityTrimmedControl コントロールは、SPSecurityTrimmedControl コントロールタグで囲まれたコードを、PermissionsString 属性に指定された権限セットを持つユーザーのみに表示させるものになります。

    今回は FullMask がついておりますので、フルコントロールを持つユーザー (サイトの所有者等) のみに SPSecurityTrimmedControl コントロールタグ内のコードを表示させる動作になります。

     

    <Sharepoint:SPSecurityTrimmedControl ID="SPSecurityTrimmedControl2" runat="server" PermissionsString="FullMask">

     

    SPSecurityTrimmedControl コントロールタグ内で JavaScript を使用して、一旦非表示にしたページタブ、リストツール、ライブラリツール、予定表ツールをフルコントロールを持つユーザーのみに表示させております。

     

    document.getElementById("Ribbon.Calendar").style.display = "block";

     

    SPSecurityTrimmedControl コントロールについては以下の資料をご覧ください。

     

    タイトル : SPSecurityTrimmedControl Class

    アドレス : http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.webcontrols.spsecuritytrimmedcontrol.aspx

     

    タイトル : SPBasePermissions Enumeration

    アドレス : http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spbasepermissions.aspx

     

     

    - マスターページかフィーチャーか?

    今回はマスターページをカスタマイズしてリボンメニューを操作しておりますが、既存のリボンメニューを非表示にしたり、新規のリボンメニューを追加したりする場合は CustomAction 属性を使用してフィーチャーを作成することでも実現可能です。

    しかしながらフィーチャーは、サイト単位やサイトコレクション単位など、機能を有効化する範囲を選べる利点がある一方、バージョン管理が煩雑であり、バージョンアップさせるために一度フィーチャーをアンインストールする必要がある場合がございます。

    そのため、サイト単位を超えた広範囲で機能を有効化したい場合や、アセンブリを含む高機能なアプリケーションを展開する場合はフィーチャーを使用することをおすすめします。サイト内のみで有効化する場合は今回ご案内しているマスターページを編集する方法が有効になります。

    CustomAction 属性を使用してリボンメニューを操作する方法については以下の技術資料をご覧下さい。

     

    タイトル : SharePoint 2010 Server リボンのカスタマイズと展開

    アドレス : http://msdn.microsoft.com/ja-jp/library/gg552606.aspx

     

    タイトル : [チュートリアル] Server リボンからボタンを削除する

    アドレス : http://msdn.microsoft.com/ja-jp/library/ff408060.aspx

     

    タイトル : 既定のサーバー リボンのカスタマイズの場所

    アドレス : http://msdn.microsoft.com/ja-jp/library/ee537543.aspx

     

     

    - 補足事項

    弊社 SharePoint サポートでは、SharePoint 2010 で公開されているクライアント オブジェクトモデル (JavaScript のクラスライブラリ) 以外の JavaScript によるカスタマイズに関するサポートサービスを実施しておりません。恐れ入りますがご了承くださいますようお願いいたします。

     

    (※ 2012/06/04 追記)

    上記の方法では、アイテムを選択した際に JavaScript によりリボンメニューの再レンダリングが行われ、リボンメニューが表示されます

    アイテムを選択した際にもリボンメニューを表示させたくない場合には、アイテムがクリックされた際に呼ばれる JavaScript の関数内にて、権限に応じてリボンメニューの再レンダリングをキャンセルする必要があります。

    アイテムがクリックされた際には、init.js の SelectRibbonTab メソッドが呼ばれリボンメニューの再レンダリングが行われます。リボンメニューを再レンダリングさせないためには、以下のように、権限に応じてこのメソッドの処理をキャンセルする方法が考えられます。

     

    1. Boolean 値を用意し、既定値として false を設定しておきます

    2. 上記の手順で追加している SPSecurityTrimmedControl コントロール内で、手順 1 で用��した Boolean 値に true を設定します。(権限のあるユーザーでページにアクセスした場合のみ
    Boolean 値が True となります。)

    3. SelectRibbonTab メソッド内で手順 1. で作成した Boolean 値のチェックを行い、false だった場合は、return 等で処理をキャンセルしてリボンメニューがレンダリングされないようにします。

     

    ※ init.js は既定では以下のディレクトリに存在します。

    C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\1041 (日本語環境の場合)

    C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\1033 (英語環境の場合)

     

    弊社では JavaScript を使用したカスタマイズ方法をサポートしておりません。このため、本方法は広範囲なテストを実施していないため、採用頂く場合は十分なテストを実施した上でご使用ください。また、14 ハイブ以下のファイルの編集については以下の内容についてご注意ください。

    - 14 ハイブ以下のカスタマイズはファーム全体に影響を及ぼします。

    - 14 ハイブ以下のカスタマイズはファーム内のすべてのサーバーにおいて実施する必要がございます。

    - 14 ハイブ以下に配置された既定のファイルは、今後のサービスパックや修正プログラムで上書きされる場合があります。ファイルが上書きされた場合、再度上書きされたファイルに同様の修正を実施する必要がございます。

    - この変更によって万が一予期せぬ動作が生じた場合は、バックアップ ファイルより変更を元に戻す必要がございます。

     

    (※ 2012/06/05 追記)

    リボンの "参照" タブをクリックした際もリボンメニューの再レンダリングが行われ、リボンメニューが表示されます。

    "参照" タブは以下のコードにより非表示にすることが可能です。一度 "参照" タブを非表示にし、SPSecurityTrimmedControl コントロール内で再表示する等してお使いください。

     document.getElementById("Ribbon.Read-title").style.display = "none";

    リボンの "参照" タブをクリックした際には init.js 内の EnsureScript メソッドにてリボンメニューが再レンダリングされますが、EnsureScript メソッドは他の多数のメソッドから呼ばれるため、編集しないことをおすすめします。

     

  • カスタム リスト定義開発時の注意点

    こんにちは、SharePoint サポート 森 健吾 (kenmori) です。

    今回の投稿では、SharePoint におけるカスタマイズ手法の 1 つであるカスタムリスト定義の開発に着目し、開発および運用を実施するにあたり陥りやすい落とし穴について事前にご紹介します。

    本投稿の構成は以下となります。

     

    目次

    1.    はじめに

    2.    注意点 (1) ListTemplate 要素 Type 属性

    3.    注意点 (2) アンインストール時の注意点

     

    1. はじめに

     

    カスタム リスト定義は、特にパッケージ製品として独自のリスト設定を SharePoint のアドインとして提供するカスタマイズとなります。Visual Studio 2010 (および VS2008 + VSeWSS 1.3) ではリスト定義のためのプロジェクト テンプレートが用意されているため、これを選択するだけで、すぐにでも開発を始めることが可能です。

     

    ウィザードに合わせて、リスト定義の開発を進めていきます。

     

    この画面が出ました。もうこの時点で、[ビルド] [ソリューションの配置] を実施するだけでカスタムのリスト定義をインストール可能です。もちろん、何の設定もしていないので、この時点では通常のリストと変わりはありません。

    Elements.xml ListTemplate 要素を編集して、今回はカスタム ドキュメント ライブラリを作るため、BaseType 属性等の以下の項目を編集します。(下の 2 つはどうでも良いですが、BaseType 属性は重要です。)

     

    BaseType=1

    DisplayName=SuperDocumentLibrary

    Description=”スーパー ドキュメント ライブラリ”

     

    リストの基本型として 1 (ドキュメント ライブラリ) を指定します。BaseType 属性については以下の技術資料をご参照ください。

     

    タイトル : ListTemplate 要素 (リスト テンプレート)

    アドレス : http://msdn.microsoft.com/ja-jp/library/ms462947(v=office.14).aspx

     

    あとは、Schema.xml イベント レシーバーなどを追加 (プロジェクトを右クリック [追加] [新しい項目の追加] で “イベントレシーバー” を追加) するなど調整して独自のリスト定義を作っていってください。

     

    タイトル : List 要素 (リスト)

    アドレス : http://msdn.microsoft.com/ja-jp/library/ms415091(v=office.14).aspx

     

    タイトル : Collaborative Application Markup Language のコア スキーマ

    アドレス : http://msdn.microsoft.com/ja-jp/library/ms462365.aspx

     

      これで、[ビルド] [ソリューションの配置] を実施して、無事にスーパー ドキュメント ライブラリが作成できる状態になりました。

    本番環境に展開する場合は、ソリューション パッケージをご使用ください。

     

    2. 注意点 (1) ListTemplate 要素 Type 属性

     

    上述の Elements.xml の記載にもありますが、この Type 属性はリスト定義を識別する番号であり、基本的には重複しないよう固有の値を設定することが極めて重要です。

    Type 属性は SharePoint が該当リストやライブラリを識別するのに使用するもっとも重要なキー情報です。(Type が重複した時には、Sequence が小さい順に優先されます。)

      

    SharePoint 2007 に対して提供していた VSeWSS の初期値は、元にしたリストまたはライブラリと同じ番号が指定されていました。

    そのため、当時よくお問い合わせとして上がっていた問題としては、Type 属性が組み込みの SharePoint 2007 の番号と競合するため、カスタムのリスト定義が既定のリスト定義より優先されてロードされ、カスタムのリスト定義で動いてしまうという内容でした。

    例えば、発行サイトを作った際に自動生成される “ドキュメント” ライブラリ (Type=101 : ドキュメント ライブラリ) が、代わりにカスタムのライブラリ定義で作られてしまうといった影響が発生します。

    (画面上から、新しいリストまたはライブラリの作成より手動で作成した場合は、正常に動作する傾向があります。)

     

    また、SharePoint 2010 では、10000 が既定で設定されます。10000 以降 SharePoint として予約されている値ではないため問題発生頻度が下げられているものの、複数のベンダーが同じ番号 10000 を設定した場合は、SharePoint 組み込みのリスト定義とは競合しないものの、異なるソリューション ベンダーのパッケージどうしでこのような競合が発生するリスクがあります。

     

    上記の状況をふまえ、Type 属性の値は 10000 以降にすることはもちろんのこと、さらにその上で一般的な番号 (10000など) を避け他社が使用しないような番号を選んで採番してください。

    そして、本番環境において想定と異なる動作をした場合は、最初に Type 属性の重複がないかを FEATURES フォルダなどを grep して疑う必要があります。

     

     3. 注意点 (2) アンインストール時の注意点

     

    本番環境でリスト定義をインストールしたら、アンインストールしないということをお勧めします。

    もしも、アンインストールするのであれば、該当のリスト定義で作ったリストを全て消去した上でアンインストールしてください。場合によっては、深刻な問題を引き起こす可能性がありますので、本番環境へのインストールは軽い気持ちでは実施できません。

     

    以下の手順で運用したと仮定します。

    1)     リスト定義をインストール

    2)     リスト定義からサイトにリストを作成

    3)     リスト定義をアンインストール

     

    その結果、物理ファイルとして Elements.xml Schema.xml 定義が存在しない状態のリストがコンテンツDB 内に残る形になります。このリストは再度リスト定義をインストールしない限り削除できません。

     

     また、このような定義ファイルの存在しないリストが残っていることの影響も報告されています。

    例えば、SharePoint Designer などで該当サイトのリスト・ライブラリの一覧を表示するとリストやライブラリが 1 件も表示されない現象や、サイトの設定画面から [コンテンツと構造] の画面に遷移した際にエラーとなってしまう現象などが確認されています。

     

    リスト定義再インストールで復旧できれば良いです。しかし、最悪の状況としてリスト定義自体も手元にないということであれば、サイトを再作成して、リストやライブラリの情報をリスト テンプレートや手動コピー等で全て移行しないと復旧できないことが想定されます。

     

    SharePoint としては、リスト定義がアンインストールされた状態でその定義を参照しているリストが残っている状況は想定外ですので、この点につきましては十分な注意をしてください。

     

    補足

     

    カスタマイズの内容は各ファーム単位でソリューション パッケージを使用してインストールを実施いただく必要がありますので、以下の手順でもアンインストールした状態と同じ状況になります。

     

    1)    ファーム Aでリスト定義をインストール

    2)    リスト定義からサイトにリストを作成

    3)    ファームA から、サイトコレクション バックアップ、サイトのエクスポート、サイト テンプレート、リスト テンプレート、いずれかの手法でデータを抽出します。

    4)    ファーム B へ、これらのデータを復元します。 

     

     ファーム B では、リスト定義がインストールされていないため同様の現象が発生します。このように移行を実施する際には、移行元環境にインストールされているリスト定義などのソリューションを事前に移行先環境にインストールしてください。

     

    今回の投稿は以上となります。