特集:Umbraco入門

特集:Umbraco入門

開発者のための、エッジなCMS「Umbraco」の魅力

2013年6月21日

日本だけが知らない?! 世界中で定評のあるCMS「Umbraco」とは? ASP.NET MVCなど.NETの先端技術と組み合わせ可能な最新版の魅力を、実際の開発手順例を通して紹介する。

  • このエントリーをはてなブックマークに追加

 Umbraco(アンブラコ)は、オープンソースのCMSである。日本ではあまり知られていないがヨーロッパを中心に人気が高く、小規模なWebサイトからマイクロソフト社のASP.NETWired.co.ukのような大規模なWebサイトまで約16万を超えるサイトで使われている。

 Umbracoが海外で人気なのは、動作が軽快でデザインの自由度が高いことと、拡張性の高いことが大きなポイントになっていると筆者は考えている。拡張性の高さから開発者に人気があることは、「OurUmbraco」というフォーラムを見ていただければ、実に活発な議論がなされていることからもよく分かるだろう。

 本稿では、Umbracoの機能拡張について、特に最近大きく進歩した「ASP.NET MVC対応」を中心に紹介する。なお、コードはC#言語で記述する。

Umbracoの機能拡張について

 Umbracoは機能拡張が容易なCMSである。具体的には以前から、コンテンツなどを操作できる強力なUmbraco APIを備えており、XSLT、User Control(ユーザー・コントロール)、Custom Control(カスタム・コントロール)を使用して容易に機能拡張ができた。

 さらに最近では、ASP.NET MVCが得意な、フロントエンドを重視する分野で、Umbracoを広く活用しようということで、Umbracoの中でASP.NET MVCで機能拡張ができるように開発が進められてきた。バージョン4.6ではRazorエンジンが導入され、シンプルで強力な記述ができるようになっている。1年前にはASP.NET MVCベースのUmbraco 5の開発が中止されたものの、バージョン4.10でASP.NET MVCに対応し、バージョン6.0では、Umbraco APIが更新された。

 現在の最新版は、先日公開されたバージョン6.1である。これは、従来からのXSLT、User Controlなどによる機能拡張も可能なうえに、ASP.NET MVCによる機能拡張も可能となっており、一段と拡張性の高いCMSに仕上がっている。

 Webサイトを作るときに普通のCMSを利用すると、サイトそのものは簡単に構築できるが、いざ拡張しようとすると結構難しいことが多い。一方でフレームワークを使ってWebアプリケーションを作成すると、「ユーザーが自由に編集したい」という要望があっても、実装には結構手間がかかってしまう。Umbracoを使えば、後述するように(ASP.NET MVC対応したことで)ASP.NET MVC 4アプリケーションとシームレスに連携することが可能である。以下では、そのような連携の作成手順を説明することで、それがどういうものであるかを紹介しよう。

Umbracoの開発環境

 CMSでWebサイトを制作する場合には「統合開発環境は使わない」という人が多い。Umbracoの場合でもシンプルなWeb開発ツールである「WebMatrix」でのインストール方法が紹介されることが多い。しかし、Umbracoの場合は、簡単なサイトを作成する場合でも、Visual Studioを利用するのが便利だ。これは、NuGetを使ってUmbracoをインストールでき、Razor構文で記述したコードのデバッグも行えるためだ。

 手元にVisual Studioがない場合は、無料の「Visual Studio Express 2012 for Web」の利用がお勧めだ。このExpressエディションは商用利用も可能であり、「2010」などの以前のバージョンと違って、「2012」では単体テストとチーム開発の機能が標準で含まれているので、本格的な開発にも十分対応できる。

 少し話はそれるが、パソコン遠隔操作事件のときには、「Visual Studioは、高価な専門ツールであることから、素人が購入するとは考えにくい」というような見解が報道されたが、そういうイメージを持っている人が多いと思う。しかし、無料のVisual Studio ExpressをインストールするだけでWebアプリケーションの開発をすぐに始められるので、ほかのIDEと比較しても、本当は初心者が使ってもいいツールだと思っている。

ASP.NET MVCアプリケーションとのハイブリッド・アプリケーションの作成

 最初に、UmbracoとASP.NET MVC 4アプリケーションを1つのアプリケーションにしてしまう、すなわち「ハイブリッド・アプリケーション」を作成する方法を紹介する。

1. ASP.NET MVC 4アプリケーションの用意

 今回は、Visual Studioで「ASP.NET MVC 4 Web アプリケーション」プロジェクトを新規作成し、その新規作成中に選択できるプロジェクト・テンプレートから「インターネット アプリケーション」を選択したものを例として説明する。

2. NuGetによるUmbracoのパッケージのインストール

 NuGetのコンソール(=[パッケージ マネージャ コンソール])で次のコマンドを実行して、Umbracoのパッケージをインストールする。インストール中に「File 'Web.config' already exists in project '<プロジェクト名>'. Do you want to overwrite it? [Y] Yes [A] Yes to All [N] No [L] No to All [?] ヘルプ (既定は "N"):」と聞かれる場合があるが、この場合は[A]キーを押してWeb.configファイルを上書きする。

[パッケージ マネージャ コンソール]
PM> Install-Package UmbracoCms
UmbracoのパッケージをインストールするためのNuGetコマンド

*注意 TFS(Team Foundation Server)を利用している場合は、Umbracoの全てをNuGetでインストールしようとすると時間がかかる。そこで、NuGetでは「Umbraco Cms Core Binaries」の方をインストールして、残りは公式サイトのダウンロード・ページからCMSのZIPファイル(例えば「UmbracoCms.6.1.1.zip」など)をダウンロードしてきて、(それを展開した中で)「bin」フォルダー以外のものを上書きコピーした方が速い。

3. Web.configファイルのマージ

 プロジェクト・ルートおよび「Views」フォルダーにあるWeb.configファイルについては、最初にあるアプリケーションのものと、インストールしたUmbracoのものをマージする必要がある。

4. Umbracoの設定

 [デバッグ開始]などを実行してプロジェクトを起動すると、Webブラウザが立ち上がる。本稿はUmbracoの使い方を説明することが目的ではないので詳細は割愛するが、そのブラウザにはUmbracoのインストーラーが表示されるので画面の指示(英語)に従って(1 - Welcome|2 - License|3 - Database|4 - Create User|5 - Starter Kit|6 - You're Done、という)ウィザードを進めてインストールを完了させる。といってもUmbracoの設定はデータベースぐらいで、それも[SQL CE 4]を選択すると特に細かな設定なしでUmbracoの利用を開始できるので、今回はこれを選択する。スターター・キット(Starter Kit)では、「Simple」「Blog」「Personal」「Business」などのキット(=標準で用意されたいるWebデザインや機能のパッケージ)を選択できるので、好みのものを選択すればよい(本稿では「Simple」を選択。ちなみに、[No Thanks]を選択して、初期のキットは何もインストールしないようにすることもできる)。

 この段階で、Umbracoの方が正常に動作するのが確認できるだろう。

5. ASP.NET MVCの初期設定

 プロジェクトにUmbracoをインストールしたことにより、Webアプリケーションのルーティング処理はUmbracoの方がメインになる。このため、アプリケーションにはアクセスできなくなってしまう。その点については、ASP.NET MVCの初期設定のルーチンを追加してカスタム・ルーティングを設定すれば解消する。

 初期設定の方法は何通りかあるが、ここでは、Umbraco.Core名前空間に「IApplicationEventHandler」というクラスが用意されているので、それを利用する方法を紹介する。コードについては、以下のようになり、記述場所はどこでもよい(本稿の例では「Global.asax.cs」ファイル内に記述した)。なお、実際に記述するには、いったんデバッグ実行を停止する。

C#
using Umbraco.Core;
……省略……
 
public class AppStart: IApplicationEventHandler
{
  public void OnApplicationInitialized(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
  {
  }
 
  public void OnApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
  {
    AreaRegistration.RegisterAllAreas();
    WebApiConfig.Register(GlobalConfiguration.Configuration);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);
    AuthConfig.RegisterAuth();
  }
 
  public void OnApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
  {
  }
}
ASP.NET MVCの初期設定としてカスタム・ルーティングを定義するコード例(Global.asax.cs)

 ASP.NET MVCの初期設定をすることで、アプリケーションのルーティングが設定され、アプリケーションの方にアクセスできるようになる。しかし、今度はUmbracoにはアクセスできなくなってしまう。ASP.NET MVCのルーティングのデフォルトの定義(App_Start/RouteConfig.cs)では、デフォルトのルーティングが定義されているため、全てのアクセスがアプリケーション側に流れてしまうためである。Umbracoにもアクセスできるようにするためには、ルーティングの定義からデフォルトの定義を削除して必要なルーティングだけを個別に設定するように変更してやればよい。具体的には次のようなコードになる。

C#
public static void RegisterRoutes(RouteCollection routes)
{
  routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
 
  routes.MapRoute(
    name: "Home",
    url: "Home/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
  );
}
ASP.NET MVCのルーティングを定義するコード例(App_Start/RouteConfig.cs)

 以上で、Umbracoもアプリケーションもアクセスできるようになるが、もうひとつ不具合が生じる。現状のアプリケーションが「デバッグ・モードだと正常に表示されるのに、リリース・モードだとCSSが反映されない」という不具合だ。原因は、「インターネット アプリケーション」プロジェクトでは、ASP.NET MVC 4 の新機能であるCSSおよびJavaScriptファイルのバンドル&ミニフィケーションの機能を使っているためである。Umbracoは、ルーティングで定義したものについては除外処理をしてアプリケーション側にルーティングされるが、バンドル&ミニフィケーションの場合はルーティングに記載していないので、Umbraco側での処理となり403エラーが発生してしまう。

 この問題を解消するには、プロジェクト・ルートにあるWeb.configファイルの<appSettings>セクションにある「umbracoReservedPaths」キーの設定に、以下にようにバンドル&ミニフィケーションが使用するフォルダー(Content、Bundle)を追加してやればよい。これ以外にも自動除外されない場合があれば、「umbracoReservedUrls」キーまたは「umbracoReservedPaths」キーに追加で設定すればよい。

ASP.NET
<add key="umbracoReservedPaths" value="~/umbraco,~/install/,~/Content,~/Bundles"  />
バンドル&ミニフィケーションが使用するフォルダーを追加するためのキー設定(Web.config)

 以上で、Webアプリケーションを実行すると、Umbracoも動作するし、アプリケーションの方も正常に動作する。アプリケーションにUmbracoを組み込むだけであれば1時間もかからずにできてしまうが、それだけの簡単な作業で、アプリケーションはCMSの機能を持てるようになる。

Umbraco APIによる連携

 前節では、Umbracoとアプリケーションを1つのアプリケーションに統合したが、Umbraco APIを利用すれば、そのアプリケーション側からUmbracoのデータを操作することができる。ここで使うUmbraco APIは、Umbracoのコンテンツ(=本文など)やメディア(=画像など)などの情報にアクセスでき、CRUDもサポートしている。つまり、このAPIを利用すれば、アプリケーション側からUmbracoを思い通りに操作することが可能である。例えば社内システムで保有するデータを、システム側から自動的にWebページ(CMS側)に反映させるようなことも、Umbracoなら容易に実現できる。

 以下は、Umbracoのデータを取得するコードの例と、新規ページを作成するコードのサンプルである。APIはUmbraco 6で改良されて使い方がかなり整理されているので、このサンプルでも使い方の概要は理解できるだろう。詳細については、UmbracoのマニュアルのDevelopers Referenceのページ(英語)を参照して活用してほしい。

C#
using Umbraco.Core.Models;
using Umbraco.Core.Services;
……省略……
 
public ActionResult UseUmbracoApi()
{
  var contentService = new ContentService();
 
  // Umbracoのデータを取得
  if (contentService.HasChildren(1051)) // 1051はトップ・ページのID
  {
    var getContent = contentService.GetChildren(1051); // 子ページを取得
    ViewBag.Message = getContent.First().Name;
  }
  else
    ViewBag.Message = "子ページはありません";
 
  // Umbracoのページを作成
  var newContent = contentService.CreateContent(
    "APIを使ってみる", // ドキュメントの名前
    1051,              // ドキュメントを作成する親のID
    "umbTextpage",     // ドキュメント・タイプ(Document Type)のエイリアス名
    0                  // ユーザーID
    );
 
  string bodytext = @"
    <p>Umbraco API を使えば、Umbraco とアプリケーションの間でデータのやり取りができます。</p>
    <p>ドキュメントは、<a href='http://our.umbraco.org/documentation/reference/management-v6/'>こちら</a>です。</p>   
  ";
  newContent.SetValue("bodyText", bodytext); // Document TypeのbodyTextプロパティに値を設定
 
  // ドキュメントの保存・公開を行う。
  contentService.SaveAndPublish(newContent);
 
  return View();
}
……省略……
Umbracoのデータを取得するコードの例と、新規ページを作成するコードのサンプル(HomeController.cs)

Umbraco MVCによる連携

 次は、Umbraco側からのアプリケーションとの連携であるが、UmbracoがASP.NET MVCに対応したので、この連携はシームレスに行える。

 UmbracoでASP.NET MVCを使用するためには、設定ファイルを変更する必要がある。まだ既定の設定ではWebフォームを使用するようになっているためだ。ASP.NET MVCを使用するためには「config」フォルダーにある「umbracoSettings.config」ファイルの以下の部分で、「WebForms」を「Mvc」に変更する。

ASP.NET
<defaultRenderingEngine>WebForms</defaultRenderingEngine>
UmbracoでASP.NET MVCを使用するための設定の箇所(umbracoSettings.config)

 次に、Umbracoで、アプリケーションのHome/Indexと同じものを作成してみる。Umbracoの画面の作成については、大まかにいえば、

(1)まずフィールドの設定を[Document Types]で行い、
(2)Razor構文を使って、HTMLテンプレートにフィールドを埋め込んでいく

ことになる。このように「最初に[Document Types]を設定する」という作業をしないといけないので、この1ステップ分だけ少し手間がかかるものの、その代わりとしてデザインは完全に自由である。

 それではこの作業を実際にやってみよう。

フィールドの定義

 最初に、画面を構成するフィールドをどうするかを決める必要がある。アプリケーションのHome/Indexは、次のような画面なので、ここでは赤枠で囲った4つのフィールドを設定することにする。

フィールドの設定例(アプリケーションのHome/Indexページの表示例)

 各フィールドは、Umbracoの管理画面で[Document Types]の設定で定義する。なお、管理画面にログインするためには、Webブラウザで「/umbraco/」ディレクトリにアクセスすればよい。[Document Types]の設定は、次の画面のように(左下にある[Settings](設定)ボタンを開いたときに表示される)[設定](Settings)セクションにある。ドキュメント・タイプ(Document Type)を新規に作成する場合は、左側にあるツリーの[ドキュメントタイプ]またはその子アイテムを右クリックして(そこで表示されるコンテキスト・メニューから)[新規作成]を選択すればよい(ログイン中のユーザーの言語設定(=具体的には[Users]セクションの該当ユーザーの[Language]設定)が「Japanese」になっていない場合は、次の画面と同じように表示されないので注意してほしい)。

 今回のHome/Indexの場合、一番下部のフィールドについては通常の本文と同じ構造なので、既存のドキュメント・タイプ「Textpage」のbodyTextプロパティをそのまま利用できる。そのため今回は、「Textpage」を編集するのが簡単である。そこで、ツリー上でそのアイテムを選択しよう。

セクションにおける「Textpage」ドキュメント・タイプの編集(Umbracoの管理画面)

 ドキュメント・タイプの設定では、右側領域の上部にある各タブ([Info][Structure][Generic properties][Tabs])を順番に設定していく必要があるが、中心となるのは[Generic properties]タブである。上の画面では、次の画面のように、フィールド(Umbracoでは「Property(プロパティ)」と呼ぶ)の名前(Name)、エイリアス名(Alias)、タイプ(Type)を入力して設定を行うが、エイリアス名はシステムで使用する名前になる。タイプについてはHTMLフォームの部品に当たるものを選択できるようになっており、「Richtext edior」を選択すればTinyMCEを使ってHTMLソースを編集できるようになる。

ドキュメント・タイプのプロパティの設定画面

 ドキュメント・タイプの設定後に、[コンテンツ](Content)セクションで新規コンテンツを作成する際に、[選択 ドキュメントタイプ]から先ほどの「Textpage」を選択すれば、次の画面のようにそのドキュメント・タイプに対応した入力画面が表示される。そのため、ドキュメント・タイプの設定を工夫することにより、HTMLを全く知らない一般の人がWebページのデザインを崩すことなく更新できるCMSに仕上げることができる。

Umbracoのコンテンツの入力画面の例

この画面は、先ほどのドキュメント・タイプの設定で、「features」という新規タブを作成し、その[features]タブに対して、[title](Textstring)、「message」(Textstring)、「features」(Richtext edior)という3つのプロパティを設定した場合の表示例である。

テンプレートへのフィールドの埋め込み

 ドキュメント・タイプの設定が終われば、次は、そのドキュメント・タイプを表示するテンプレートを作成する。([設定]セクションで)テンプレートを新規作成すると、以下のようなひな型コードが表示される。

CSHTML
@inherits Umbraco.Web.Mvc.UmbracoTemplatePage
@{
  Layout = null;
}
テンプレート新規作成時のひな型コード

 Umbracoのテンプレートは、ASP.NET MVCでのビューと基本的に同じものである。

 テンプレート新規作成時に、名前がエイリアス名、拡張子が「.cshttml」のファイルがASP.NET MVCアプリケーションの「Views」フォルダーに保存されている。いったんテンプレートを作成してしまえば、そのファイルをVisual Studioや外部エディターで編集できる。

 テンプレートを以下のように修正して、先ほど作成したフィールドを埋め込むと、Home/Indexと同じようなものが表示できるようになる。なお、レイアウト・ページは、「Layout=null」を削除してアプリケーションのものを使用している。

CSHTML
@inherits Umbraco.Web.Mvc.UmbracoTemplatePage
@{
  ViewBag.Title = @Umbraco.Field("title");
}
@section featured {
  <section class="featured">
    <div class="content-wrapper">
      <hgroup class="title">
        <h1>@ViewBag.Title.</h1>
        <h2>@Umbraco.Field("message")</h2>
      </hgroup>
      @Umbraco.Field("features")
    </div>
  </section>
}
@Umbraco.Field("bodyText")
作成済みのフィールドを埋め込んだテンプレートのコード例

 ASP.NET MVCのビューとの違いといえば、「Umbraco.Web.Mvc.UmbracoTemplatePage」クラスを継承していること、Umbracoヘルパー・メソッドの「Umbraco.Field」を使って各フィールドをテンプレートに埋め込んでいることだろう。UmbracoTemplatePageクラス(Umbraco.Web.Mvc名前空間)を継承することで、静的型付け変数である「Model」、動的型付け変数である「CurrentPage」、Umbracoヘルパーなどのヘルパー・メソッドを使えるようになり、オブジェクト参照が容易に可能になる。例えば、Razor構文を使って以下のようなコードを書くと、子ページのメニューを表示できる。

CSHTML
@foreach (var page in CurrentPage.Children.Where("Visible"))
{
  <li>
    <a href="@page.Url">@page.Name</a>
  </li>
}
子ページのメニューを表示するための、Razor構文によるコード例
ASP.NET MVCアプリケーションとの連携について

 ここまでくれば、アプリケーションとの連携がシームレスにできることはすぐに分かるだろう。Umbracoのテンプレートでは、ASP.NET MVCのビューと全く同じことができる。例えば、Html.Actionメソッドを利用すれば、アプリケーションのアクション・メソッドを呼び出して、その結果を描画することが可能だ。上の例では全てのフィールドをUmbraco側で入力するようにしたが、システムで処理をした方がいいフィールドがあればHtml.Actionメソッドを使ってそのアクションを呼び出せばよいだけだ。なお、ASP.NET MVCのコントローラーをUmbracoからのチャイルド・アクションだけで利用したい場合は、SurfaceControllerクラス(Umbraco.Web.Mvc名前空間)を継承してコントローラーを作成すればよい。その場合は、ルーティングの設定が自動的にされる。

 また、ASP.NET MVCアプリケーション側のモデルでヘルパー・メソッドを定義してやれば、Umbracoのテンプレート共通で利用できるし、入力フォームが必要になった場合には、入力チェックのためのロジックを書く必要がありRazor構文で書くと結構複雑になるが、ASP.NET MVCのモデル・バインダによる検証の機能を使えばシンプルに記述できる。

 ASP.NET MVC 4の新機能であるモバイル対応を容易にするディスプレイ・モードの機能も動作する。そのためには、最初に説明した初期化のルーチンに、iPhoneであれば以下のようなコードを追加すればよい。そうすると、例えば「MvcApp」というテンプレートだと、「MvcApp.iPhone」というエイリアス名でテンプレートを用意すればiPhone専用のテンプレートになる。

C#
using System.Web.WebPages;
 
DisplayModeProvider.Instance.Modes.Insert(0, new DefaultDisplayMode("iPhone")
{
  ContextCondition = (context => context.GetOverriddenUserAgent().IndexOf
    ("iPhone", StringComparison.OrdinalIgnoreCase) >= 0)
});
iPhoneビューのディスプレイ・モードを追加するコード例(Global.asax.cs)

まとめ

 多くのWebサイトで採用されていることからも分かるように、(本稿ではCMS機能についてはあまり紹介できなかったが)Umbracoは充実した機能を持った本格的なCMSである。本格的なCMSであるUmbracoとASP.NET MVCを組み合わせた開発環境は、まとめると以下のようなメリットがあり、リッチなWebアプリケーションを少ない工数で構築できるということが理解していただけたと思う。

  • Umbracoは、機能が充実したCMSであり、そのCMSの機能がすぐに利用できる
  • Umbracoの機能拡張にASP.NET MVCが使えるので、拡張性が高いだけでなく学習コストも低い
  • どちらも軽快に動作し、大規模になっても大丈夫
  • どちらも出力するHTMLコードを完全にコントロールできるので、デザインは自由で、jQueryなどのJavaScriptライブラリを利用しやすい

 実際のところ、機能が充実しているCMSで、MVCフレームワークを使って機能拡張ができ、かつ軽快に動作するCMSは少ない。現にUmbraco自体もASP.NET MVC対応のUmbraco 5の開発で失敗したし、ASP.NET MVCで作られているOrchardは動作が重い。MVCフレームワークは、開発に使う分には便利であるが、処理が複雑になる分だけ重くなるようだ。

 コンシューマー向けのWebサイト構築では、「Ruby on RailsやCakePHPを使ってWebアプリケーションを作った」という話はよく聞くが、「ASP.NETを使ってアプリケーションを作った」というような話はほとんど聞かない。ASP.NETでの開発は、Visual StudioやWindows Serverに高価な費用が必要になるので、大規模開発向けだというイメージを持っている人が多いと思うし、数年前は事実そうだったと思う。

 しかし、今はVisual Studio ExpressとMicrosoft Azure(旧称:Windows Azure)にUmbracoやjQueryなどのオープンソースのソフトを利用すれば、開発は無料でできるし、環境の準備も簡単だし、機能は豊富なのでWebアプリケーションを少ない工数で構築できる。アプリケーションの公開についても、規模に応じてリーズナブルなコストで運用でき、スケールアップも容易である。ASP.NET MVCは機能の役割分担ができることから、大規模向け開発に向いているといわれているが、逆にいえば小さく始めて後から機能アップを図っていくこともできる。個人やベンチャー企業にとっても、LAMPやRubyの世界に負けない開発環境になってきているので、「ASP.NETでこんなサービス作ったよ」という話が出てくることを期待したい。

サイトからのお知らせ

Twitterでつぶやこう!