サイトコアのワイルドカードアイテムを使用して URL を生成したり、逆にリクエストされたパスから、ワイルドカードアイテムのパス対応する文字列を抽出するシンプルなワイルドカードモジュールを作成してみました。マーケットプレースにすでにWildcard Moduleというアドオンが公開されていますが、そのモジュールが Sitecore 7.1 にまだ未対応であることおよびそのモジュールよりもお手軽に使えるように作成してみました。お手軽に使える分、マーケットプレースで公開されているWildcard Moduleと比較して構成用のアイテムを作成して柔軟にワイルドカードアイテムの位置とリクエストされるパスのマッピングをプログラムの修正なしに変更するということができなくなっています。

SitecoreのマーケットプレースにもWildcard Module というアドオンがあります。マーケットプレースのモジュールはワイルドカードアイテムの位置に対応するURLのパスの位置に名前を設定し、名前を使用してプログラムを作成できるようになっています。位置依存をなくなることで、 ワイルドカードアイテムの階層構造やワイルドカードアイテムとリクエストされたパスのマッピングの変更が発生した場合も構成アイテムの設定変更により比較的柔軟に対応できるようになっています。

1.プログラムの場所

Sitecore CMS 7.1 を対象に Visual Studio 2013 でプログラムを作成しました。Githubの以下のURLで公開しています。

simple-wildcard-module
https://github.com/madoibito/sitecore-simple-wildcard-module

2.使い方

プログラムのサンプルを使用して使い方を記載します。使用したいユーザーコントロールやWebフォームで使用する名前空間で以下の名前空間を追加します。

using Netplanetes.Sitecore.Wildcard;

あとは、下記のようにコードを記述することで、リクエストのパスからワイルドカードアイテムの位置に対応するパスのセグメントの文字列を抽出してくれます。ResolveWildcardValues メソッドは ワイルドカードアイテムの位置(0ベース)をキーとワイルドカードアイテムの位置に対応するパスの文字列を値とするディクショナリ(IDictionary)オブジェクトです。

SimpleWildcardManager manager = new SimpleWildcardManager();
var item = Sitecore.Context.Item;
var resolver = manager.CreateResolver(item);
var wildcards = resolver.ResolveWildcardValues(this.Request.Path).ToList();

逆に、ワイルドカードアイテムの位置に設定したい文字列から、URLを生成するには次のように0ベースでワイルドカードアイテムの位置とパスに使用する文字列を値として持つディクショナリを使用してCreateUrl メソッドを呼び出すことでワイルドカードアイテムの位置にディクショナリで指定した文字列が設定されたURLを生成することができます。

SimpleWildcardManager manager = new SimpleWildcardManager();
var resolver = manager.CreateResolver(item);
// create wild card url from test values
var dic = new Dictionary<int, string>
{
    { 0, "Hello"}, {1, "World"}
};
var url = resolver.CreateUrl(dic);

3.サンプル

サンプルとして、下図のようなワイルドカードアイテムを定義していることとします。Home/Test アイテム配下に2つのワイルドカードアイテムを作成しています。

サンプルとして、レイアウト用に次のWebフォームを作成します。

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WildcardLayout.aspx.cs" Inherits="SimpleWildcardSample.layouts.wc.WildcardLayout" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            Resolved Wildcard values:<br />
            <asp:Literal runat="server" ID="Literal1"></asp:Literal>
        </div>
        <div>
            Sample Wildcard url :<br />
            <asp:Literal runat="server" ID="Lieteral2"></asp:Literal>
        </div>
    </form>
</body>
</html>

コードビハインドファイルは次のようにします。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace SimpleWildcardSample.layouts.wc
{
    using Netplanetes.Sitecore.Wildcard;
    using System.Text;
    public partial class WildcardLayout : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            SimpleWildcardManager manager = new SimpleWildcardManager();
            var item = Sitecore.Context.Item;
            var resolver = manager.CreateResolver(item);

            // resolve wild card values from request path.
            var wildcards = resolver.ResolveWildcardValues(this.Request.Path).ToList();
            StringBuilder builder = new StringBuilder();
            foreach (var keyValue in wildcards)
            {
                //builder.AppendFormat("{0}:{1}", keyValue.Key, Sitecore.MainUtil.EncodeName(keyValue.Value));
                builder.AppendFormat("{0}:{1}", keyValue.Key, keyValue.Value);
                builder.Append("<br />");
            }
            Literal1.Text = builder.ToString();

            // create wild card url from test values
            var dic = new Dictionary<int, string>
            {
                { 0, "Hello"}, {1, "World"}
            };
            //var dic = new Dictionary<int, string>
            //{
            //    { 0, Sitecore.MainUtil.EncodeName("*")}, {1, Sitecore.MainUtil.EncodeName("?")}
            //};
            Lieteral2.Text = resolver.CreateUrl(dic);
        }
    }
}

一番下のワイルドカードアイテムに作成したレイアウトを割り当ててページを表示してみます。

例えば /Test/One/Two.aspx というURLでアクセスすると、 下図のように0番目のワイルドカードアイテムの値がOne, 1番目のワイルドカードアイテムおn値が Two と正しく抽出されていることがわかります。

また、ワイルドカードアイテムを使用するURLも プログラムで指定した Hello, World という文字列を使用して生成されていることがわかります。

下図は/Test/,-w-,/,-w-,.aspx でアクセスした例です。0,1番目のワイルドカードアイテムともに ,-w-, で値が取得されていることがわかります。

SimpleWildcardModule はリクエストされたパスからワイルドカードアイテムに対応するセグメントの文字列を抽出したり、ディクショナリで指定された位置に指定された文字列をURLの文字列としてそのまま設定します。Web.config の encodeNameReplacements 要素で設定した置換後の文字列を使用したい場合はSitecore.MainUtil.EncodeName メソッドやSitecore.MainUtil.DecodeName メソッドを使用してURLを生成する前やトークン文字列を取得した後に変換を行ってください。例えば MainUtil.DecodeName メソッドを使用することで、 ,-w-, として取得された文字列を置換前の * にさらに変換することができます。

4.コンフィグレーション

Simple Wildcard Module は ワイルドカードアイテムの文字が  ,-w-, という文字列にencodeNameReplacements の設定により変換されることを前提としています。もし、Web.config の encodeNameReplacements の設定値を変更している場合は、Web.config に Netplaetes.WildcardUrlString のタグを追加して変更した値をに設定してください。

<sc.variable name="Netplanetes.WildcardUrlString" value=",-w-,"/>

5.まとめ

説明は以上となります。自作したシンプルワイルドカードモジュールのご紹介でした。