サイトコアには データテンプレート、ブランっテンプレートの他に、 コマンドテンプレート というテンプレートが用意されています。 コマンドテンプレートは .NET (C#) を使ったプログラムによる実装が必要なテンプレートです。作りこみが必要な分、もっとも強力なアイテムの作成方法になります。

コマンドテンプレートを使用することでたとえば、ウィザード形式でユーザーがにフォームに入力した結果を利用して アイテムを作成するといったことができるようになります。

今回作成する コマンドテンプレートは Data Definition Cookbook に掲載されているコマンドテンプレートを参考にしています。

今回は Data Definition Cookbook に記載されている コマンドテンプレートを実際に実装してみます。

検証環境は次の通りです

  • Sitecore CMS 6.6 Service Pack1
  • .NET 4.0

1. コマンドクラスの実装

コマンドテンプレートの定義アイテムを作成する場合は、コマンドを選択したときに実行されるクラスを実装する必要があります。今回は NewAssignedFolder というコマンドクラスを作成します。コマンドテンプレートでコマンドを実行するクラスは Sitecore.Shell.Framework.Commands.Command クラスを継承する必要があります。コマンドクラスは Execute メソッドをオーバーライドしてコマンドを実装します。

NewAssigedFolder では、最初に(args.IsPostBack=falseのとき)アイテム名を入力する画面を表示します。ユーザーがアイテム名を入力してOKボタンをクリックしたとき(args.IsPostBack = true) 入力された名前のフォルダー型のアイテムを作成します。アイテム作成時に親アイテムの挿入オプションと挿入ルールを作成したフォルダ型のアイテムにコピーしています。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Collections.Specialized;

namespace SCSupport.Core
{
    public class NewAssignedFolder : Sitecore.Shell.Framework.Commands.Command
    {
        public override void Execute(Sitecore.Shell.Framework.Commands.CommandContext context)
        {
            if (context.Items.Length == 1)
            {
                Sitecore.Data.Items.Item item = context.Items[0];
                NameValueCollection parameters = new NameValueCollection();
                parameters["id"] = item.ID.ToString();
                parameters["language"] = item.Language.ToString();
                parameters["database"] = item.Database.Name;
                // ユーザーがNewAssignedFolderコマンドテンプレートを選択するとRunメソッドが実行される。
                Sitecore.Context.ClientPage.Start(this, "Run", parameters);
            }
        }

        protected void Run(Sitecore.Web.UI.Sheer.ClientPipelineArgs args)
        {
            if (args.IsPostBack)
            {
                if (!string.IsNullOrEmpty(args.Result) && args.Result != "null")
                {
                    // テキストボックスに入力があった場合のみ処理実施
                    Sitecore.Data.Database database = Sitecore.Configuration.Factory.GetDatabase(args.Parameters["database"]);
                    Sitecore.Data.Items.Item parent = database.GetItem(args.Parameters["id"],
                        Sitecore.Globalization.Language.Parse(args.Parameters["language"]));
                    // フォルダ型のデータテンプレート取得
                    Sitecore.Data.Items.TemplateItem tamplate = database.Templates[Sitecore.TemplateIDs.Folder];
                    // 親アイテムに テキストボックスで入力された名前をもつ フォルダ型のサブアイテムを作成
                    Sitecore.Data.Items.Item item = parent.Add(args.Result, tamplate);

                    // 親アイテムに挿入ルールか挿入オプションがある場合は、そのフィールド値をコピー
                    if (!(string.IsNullOrEmpty(parent[Sitecore.FieldIDs.Branches]) &&
                        string.IsNullOrEmpty(parent["__Insert Rules"])))
                    {
                        item.Editing.BeginEdit();
                        if (!string.IsNullOrEmpty(parent[Sitecore.FieldIDs.Branches]))
                        {
                            item.Fields[Sitecore.FieldIDs.Branches].Value = parent[Sitecore.FieldIDs.Branches];
                        }
                        if (!string.IsNullOrEmpty(parent["__Insert Rules"]))
                        {
                            item.Fields["__Insert Rules"].Value = parent["__Insert Rules"];
                        }
                        item.Editing.EndEdit();                        
                    }
                    Sitecore.Context.ClientPage.SendMessage(this, "item:load(id=" + item.ID.ToString() + ")");


                }
            }
            else
            {
                // ページを初期表示
                // アイテム名を入力するテキストボックスを表示。検証にはWeb.configのItemNameValidationで設定した正規表現を使用する。
                Sitecore.Context.ClientPage.ClientResponse.Input("Enter the name of the new folder:",
                    Sitecore.Globalization.Translate.Text("New folder"),
                    Sitecore.Configuration.Settings.ItemNameValidation, "'$input' is not a valid name.", 100);
                args.WaitForPostBack();
            }
        }
    }
}

コマンドクラスの実装が完了しました。

2. Command.config のコメントの定義を作成

作成したコマンドクラス用のコマンドを Commands.config に定義します。

  <command name="sample:contenteditor:newassigendfolder" type="SCSupport.Core.NewAssignedFolder, SCSupport"/>

コマンドの準備は完了です。

3. コマンドテンプレート定義アイテムの作成

コマンドを使用するコマンドテンプレート型のアイテムを作成します。/sitecore/テンプレート配下の任意の場所にコマンドテンプレート型のアイテムを作成できますが、今回は、下図のように ユーザー定義アイテム配下のアイテムを選択して、 挿入オプションの テンプレートから挿入 を選択してアイテムを作成しました。

テンプレートから挿入で /テンプレート/システム/ブランチ/コマンドテンプレート データテンプレートを選択します。名前は NewAssignedFolder という名前でコマンドテンプレートアイテムを作成しました。

作成したアイテムには コマンドフィールドがあります。コマンドフィールドには namespace:category:command(id=$ParentID) という文字列を設定しています。 Commands.config に追加したコマンドの引数に id=$ParentID を設定するようにしています。このように記述することで、コマンドに親のIDが渡されるようになります。Data Definition Cookbook によると、id=$ParentID というパラメーターを指定しないと、挿入グループから作成するアイテムの種類を選択する前にコンテンツツリーで別のアイテムを右クリックすると、親のアイテムではなく、右クリックしたアイテムのIDがコマンドテンプレートのコマンドに渡されることがあるそうです。

これで準備完了です。

4. 動作確認

実際にアイテムを作成してみます。コマンドテンプレートを使用する場合は、アイテムの挿入オプションにコマンドテンプレートを設定しておく必要があります。今回はホームアイテムの挿入オプションに作成した NewAssigedFolder コマンドテンプレートを設定してみました。下図のようにホームアイテムを選択して挿入グループから NewAssigedFolder をクリックします。

新しいフォルダーの名前を入力してください というダイアログが表示されます。作成するフォルダー型のアイテムの名前を指定します。試しにデフォルトの新しいフォルダー のまま OK ボタンをクリックしてみます。

プログラムのコードで指定した エラーメッセージが表示されます。

今度は Test という名前を入力して OK ボタンをクリックします。

アイテムが作成されました。Testアイテムをクリックすると 挿入グループに ホームアイテムの 挿入オプションの設定が引き継がれている(コピーされている)のが確認できます。

5.まとめ

説明は以上となります。今回は簡単ですが データ定義クックブックで紹介されている  サンプルのコマンドテンプレートを作成してみました。

間違いや指摘点などございましたらご連絡ください。