最新の SharePoint 開発については SharePoint Framework を参照してください。(この開発手法は、古い情報です。)
SharePoint Add-ins 開発
- 概要
- .NET CSOM を使ったプログラミングと認証
- Cross-domain library を使ったプログラミング
- App Part の開発
- List Definition の開発と Client Side Rendering (CSR)
- Remote Event Receiver の開発と Debug
- UI Custom Action の開発 (Ribbon のカスタマイズ)
- Workflow の開発
- On-Premises (SharePoint Server) で動く SharePoint Add-ins の作成 (Authentication)
- クラウド ビジネス アプリ (Cloud Business App)
- Patterns and Practices (PnP) による CSOM 拡張ライブラリー
こんにちは。
今回は、カスタムのメニュー項目(ECB) やリボンをプログラミングするための UI Custom Action 開発について解説します。
SharePoint Add-ins における UI Custom Action
「SharePoint 2010 開発: カスタムの SharePoint リボンの作成」で紹介したように、SharePoint では、従来より、UI Custom Action と呼ばれるフィーチャーを実装して、リボン (Ribbon) カスタマイズがおこなえます。また、リボンだけでなく、カスタムの ECB (Edit Control Block) メニュー (下図) も、この方法で実装できます。
新しくなった SharePoint Add-ins (SharePoint アドイン, 旧 App for SharePoint) の UI Custom Action は、従来の Custom Action 開発とベースの概念は似ていますが (例えば、要素マニフェストに定義を記述する点など)、異なる点もいくつかあるので注意が必要です。
そこで、今回は、実際の構築手順を解説しながら、そうしたポイントを見て行きます。
UI Custom Action の構築
では、さっそく、カスタムのリボン (Ribbon) ボタンを構築してみましょう。
後述しますが、SharePoint Add-ins におけるリボン選択時の動作 (Custom Action) は、基本的に、Page の表示 (遷移) で実装します。この Page は、SharePoint-hosted (App web 上の Page)、Provider-hosted のどのホスト方法でも実装可能です。今回のサンプルでは、Provider-hosted を使用します。
まず、Visual Studio を起動し、[Apps for SharePoint 2013] (SharePoint Add-ins) のプロジェクトを新規作成します。今回は、上述の通り、Provider-hosted (プロバイダー向けホスト型) のアプリケーションを構築します。
つぎに、Visual Studio のソリューション エクスプローラーで、作成された Add-ins のプロジェクトをマウスで右クリックして、[追加] – [新しい項目] を選択します。表示される画面で、[リボンのカスタム アクション] (下図) を選択します。
後述しますが、Custom Action は、Host web と App web のどちらにもホストできます。
補足 : ただし、App web にホストした場合、後述する StandardTokens や認証 token は渡されません。(/_layouts/15/appredirect.aspx から redirect されないためです。)
App web の Custom Action では、同一サイト内の Page に飛ばしてください。
今回は、ユーザーが使用している Host web の「ドキュメント ライブラリー」(Document Library) にカスタムの Ribbon ボタンを配置しましょう。このため、次に表示される下記の画面 (ウィザード) で、[ホスト Web] (Host web) を選択し、動作の対象として [ドキュメント ライブラリー] (Document Library) を選択して、次に進みます。(App web に配置する場合など、個別のリスト インスタンスに設定することもできます。)
SharePoint Add-ins におけるリボン選択時 (クリック時) の動作 (Action) は、基本的に、Page の表示 (遷移) で実装します。次に表示されるウィザードで、下図の通り ~remoteAppUrl/Pages/Default.aspx を指定し、Provider-hosted の Page (Default.aspx) を表示するようにします。
従来の SharePoint Farm Solution や SharePoint Sandboxed Solution のように、JavaScript (JSOM) を使った Custom Action の動作 (Action) の実装はできないようです。(SharePoint Add-ins では、エラーになります。SharePoint 2010 時代の JavaScript を使った Custom Action の実装については、「SharePoint 2010 開発: カスタムの SharePoint リボンの作成」を参照してください。)
ただし、Page の表示を、ブラウザーの Page 遷移 (全画面の表示) でなく、SharePoint の Dialog Framework で表示することも可能です。このため、作り方次第では、JavaScript (JSOM) で実装した場合と類似の Experience (動作) を提供できます。この手法については、このあとで補足し、まずは、上記のページ (Pages/Default.aspx) を全画面で表示するようにしましょう。
なお、上図の [コントロールの場所] は、リボンのどの場所にボタンを配置するか (どのタブ、どのグループ) を指定します。今回は、下図の [管理] (Manage) グループの中に配置します。
ウィザードを完了すると、下記の Elements.xml (要素マニフェスト) が作成されます。
<?xml version="1.0" encoding="utf-8"?><Elements xmlns="http://schemas.microsoft.com/sharepoint/"> <CustomAction Id="7b6d4ac0-6f2c-463d-8d9e-c282fb494645.RibbonCustomAction1"RegistrationType="List"RegistrationId="101"Location="CommandUI.Ribbon"Sequence="10001"title=''><CommandUIExtension> <CommandUIDefinitions><CommandUIDefinition Location="Ribbon.Documents.Manage.Controls._children"> <Button Id="Ribbon.Documents.Manage.RibbonCustomAction1Button"Sequence="100"Command="Invoke_RibbonCustomAction1ButtonRequest"LabelText="Apps Test Button"TemplateAlias="o1"Image32by32="_layouts/15/images/placeholder32x32.png"Image16by16="_layouts/15/images/placeholder16x16.png" /></CommandUIDefinition> </CommandUIDefinitions> <CommandUIHandlers><CommandUIHandler Command="Invoke_RibbonCustomAction1ButtonRequest" CommandAction="~remoteAppUrl/Pages/Default.aspx?{StandardTokens}"/> </CommandUIHandlers></CommandUIExtension > </CustomAction></Elements>
上記で、RegistrationId (上記の太字を参照) の 101 は、対象がドキュメント ライブラリー (Document Library) であることを意味しています。100 が Generic List、101 が Document library、104 が Announcements List など、Id が決まっています。
また、前述で設定したボタンの配置場所 (今回は、[ファイル] タブの [管理] グループ) は、上記の Location (太字を参照) に反映されています。
また、ボタンに使用するアイコンとして、今回は、既存のアイコン (placeholder16x16.png、placeholder32x32.png) を使用していますが、もちろん、独自のアイコンを Web 上にアップして参照できます。(リボン コントロールのサイズの動的変更にあわせて、2 種類のアイコンを用意しておきます。)
また、ボタンを押した際に表示されるページが上記の CommandAction に設定されています (太字を参照)。このページ (Default.aspx) には、「.NET CSOM を使ったプログラミングと認証 (Authentication)」で紹介したように、StandardToken (必要な情報を設定したクエリー文字列) や認証用の Token (HTTP の POST データ) が渡されるので、Page (Default.aspx) から SharePoint に接続して、SharePoint に対する検索や更新などの処理が可能です。
今回は、リスト アイテムの Id を取得して、そのファイル名を表示する簡単なページを構築するため、下記の通り CommandAction を変更しておきます。(リストとリスト アイテムの情報をページに渡します。)
. . .<CommandUIHandler Command="Invoke_RibbonCustomAction1ButtonRequest" CommandAction="~remoteAppUrl/Pages/Default.aspx?{StandardTokens}&list={SelectedListId}&item={SelectedItemId}"/>. . .
なお、ここで使用されている {StandardTokens}、{SelectedListId}、{SelectedItemId} はトークン (token) と呼ばれるもので、実行時に適切な値に変換されます。この他に、リストの Url を示す {ListUrlDir} や、ユーザーが見ている元のページの URL を示す {Source} などのトークンが使用できます。特に、画面を遷移して、また元のページに戻ってくるような処理を実装する場合は、{Source} は必要不可欠です。
なお、作成された Elements.xml の [配置タイプ] (Deployment Type) プロパティを Visual Studio で確認すると、「AppPackage」となっています。(下図を参照)
この場合、このカスタム アクションは .wsp (App web に配置されるパッケージ) に含まれず、Manifest Feature として展開されることを意味しています。(もちろん、作成される .app パッケージに、この Elements.xml は含まれます。ただし、.wsp パッケージには含まれません。)
一方、App web に配置する場合には「ElementManifest」となり、カスタム アクション (Elements.xml) は .wsp ファイル (App web に配置されるパッケージ) の中に含まれます。
つぎに、遷移先のページ (Default.aspx) をプログラミングしましょう。
今回は、上述の通り、選択されたリスト アイテムの名前 (ファイル名) を表示するプログラムなので、下記の通り実装します。
. . .protected void Page_Load(object sender, EventArgs e){ var token = TokenHelper.GetContextTokenFromRequest(Page.Request); var hostWeb = Page.Request["SPHostUrl"]; var listId = Page.Request["list"]; var itemId = Page.Request["item"]; using (var ctx = TokenHelper.GetClientContextWithContextToken(hostWeb,token,Request.Url.Authority)) {var list = ctx.Web.Lists.GetById(new Guid(listId));var item = list.GetItemById(int.Parse(itemId));ctx.Load(item);ctx.ExecuteQuery();Response.Write(item["FileLeafRef"]); }}. . .
補足 : なお、AppManifest.xml の StartPage として、この Default.aspx が使われていると思いますので、本来は、ListId や ItemId が null でもちゃんと動くようにプログラミングしておきましょう。(今回は、面倒なのでサボりました。。。)
さいごに、忘れずに、Permission の設定をおこなってください。(今回は、この解説は省略します。)
動作の確認
F5 でデバッグ実行をおこなうなどして配置後、ドキュメント ライブラリー (どのドキュメント ライブラリーでも構いません) を開いて、リボンの [ファイル] タブを選択してみてください。
下図の通り、[管理] (Manage) グループにカスタムのボタンが表示されているのがわかります。
ドキュメント (アイテム) を上図の通り選択 (チェック) してこのボタンを押すと、Remote App (Remote Web) の Default.aspx のページが表示され、下図の通り選択したアイテムのファイル名が表示されます。(SharePoint と連携して動作しています。)
補足 : EnableScript 属性を使って、アイテムが選択されたときだけ、このボタンを有効にできます。ここでは解説を省略しますが、詳細は「SharePoint 2010 開発: カスタムの SharePoint リボンの作成」を参照してください。
Dialog の Custom Action
上記のサンプルでは Page 全体を遷移 (表示) しましたが、上述の通り、SharePoint の Dialog Framework で表示することも可能です。(この方が、組み込まれた機能らしい動きになりますね。)
Dialog Framework を使ってページを表示するには、Elements.xml に下記の通り追記するだけです。(なお、なぜかマークアップのエラーが出ますが、まあ、細かいことは気にせず先に進みましょう。)
<?xml version="1.0" encoding="utf-8"?><Elements xmlns="http://schemas.microsoft.com/sharepoint/"> <CustomAction Id="7b6d4ac0-6f2c-463d-8d9e-c282fb494645.RibbonCustomAction1"RegistrationType="List"RegistrationId="101"Location="CommandUI.Ribbon"Sequence="10001"title=''HostWebDialog="true"HostWebDialogWidth="250"HostWebDialogHeight="100">. . .
Dialog を閉じる際、従来は SP.UI.ModalDialog.close や SP.UI.ModalDialog.commonModalDialogClose などを使用しました。しかし、SharePoint Add-ins の Dialog Framework は ifarme で表示されます。このため、今回は、親ウィンドウに、CloseCustomActionDialogRefresh か CloseCustomActionDialogNoRefresh をフレーム間通信 (postMessage) を使って呼び出します。(前者は Close と同時に Page を Refresh し、後者は Page を Refresh しません。)
例えば、上記の Default.aspx に下記のようにボタンを配置しておくと良いでしょう。
. . .<body> <form id="form1" runat="server"> <div><input type="button" value="Close" onclick="javascript: window.parent.postMessage('CloseCustomActionDialogRefresh', '*');" /></div> </form></body>. . .
この Add-ins を実行すると、下図の通り、Dialog で表示されるようになります。
また、[Close] ボタンを押すと、この Dialog は閉じて、背景にある一覧が更新 (再取得) されます。
補足 : 現在 (2013 年 02 月)、この HostWebDialog を使用した動作 (Action) は、Debug 実行でうまく動かないようなので注意してください。Debugger と SharePoint が既定で持っている JavaScript ライブラリーの相性が良くないみたいです。
なお、「MSDN : Apps for SharePoint compared with SharePoint solutions」に依ると、SharePoint Add-ins では、custom action groups と custom action hiding は不可能と書かれているので注意してください。
2013/02/22 訂正 : App web のカスタム リストで動作確認したところ、Hide も Group も可能でした。(下記)
<?xml version="1.0" encoding="utf-8"?><Elements xmlns="http://schemas.microsoft.com/sharepoint/"> <CustomActionId="0f00ab52-aafb-4d0f-b312-04dbf0829c13.RibbonCustomAction1"RegistrationType="List"RegistrationId="10000"Location="CommandUI.Ribbon"Sequence="10001"title=''><CommandUIExtension> <CommandUIDefinitions><!-- hide all --><CommandUIDefinition Location="Ribbon.ListItem.New" /><CommandUIDefinition Location="Ribbon.ListItem.Manage" /><CommandUIDefinition Location="Ribbon.ListItem.Actions" /><CommandUIDefinition Location="Ribbon.ListItem.Share" /><CommandUIDefinition Location="Ribbon.ListItem.Workflow" /><!-- new group and button --><CommandUIDefinition Location="Ribbon.ListItem.Groups._children"> <GroupId="Ribbon.ListItem.MyCustomGroup"Sequence="1"Description="This is group test."title=''Template="Ribbon.Templates.TestGroupTemplate"><Controls Id="Ribbon.ListItem.MyCustomGroup.Controls"> <ButtonId="Ribbon.ListItem.MyCustomGroup.New"Sequence="20"Image32by32="_layouts/15/images/placeholder32x32.png"Image16by16="_layouts/15/images/placeholder16x16.png"Command="Invoke_RibbonCustomAction1ButtonRequest"LabelText="Test Button"TemplateAlias="Area1"/></Controls> </Group></CommandUIDefinition><CommandUIDefinition Location="Ribbon.Templates._children" > <GroupTemplate Id="Ribbon.Templates.TestGroupTemplate"><Layout title='' Layouttitle=''> <Section Alignment="Top" Type="OneRow"><Row> <ControlRef DisplayMode="Large" TemplateAlias="Area1" /></Row> </Section></Layout> </GroupTemplate></CommandUIDefinition><CommandUIDefinition Location="Ribbon.ListItem.Scaling._children"> <MaxSize Id="Ribbon.ListItem.MyCustomGroup.Scaling.MaxSize"Sequence="35"GroupId="Ribbon.ListItem.MyCustomGroup"Size="OneLarge"/></CommandUIDefinition> </CommandUIDefinitions> <CommandUIHandlers><CommandUIHandler Command="Invoke_RibbonCustomAction1ButtonRequest" CommandAction="~site/Pages/Default.aspx"/> </CommandUIHandlers></CommandUIExtension > </CustomAction></Elements>
※ 変更履歴 :
2015/05/05 App for SharePoint (SharePoint 用アプリ) を SharePoint Add-ins (SharePoint アドイン) に名称変更
Categories: Uncategorized
10 replies»