これまたASP.NET MVCをつかったCMS。バージョンが0.8でずいぶん進んでるのに今まで全然知らなかったです。
同じジャンル・ターゲットのプロダクトとして最近Oxiteが出てきたけど、OxiteがMetaWeblogAPIなのに対して、こっちはAtomPub API。
機能的にはほぼ互角な感じだけど、動かすと最初にウィザード形式で設定する分、使う人にとってはすこしとっつきやすいかも。
API 実装してるからか、編集機能はWebアプリケーションとして実装しない(してても適当、Oxiteもそうだけど)で、Live Writerとかの外部エディタに任せるスタイル。これはコレでいい割り切りだと思うな。プロバイダサービスみたいに沢山の人にたいして、使ってもらうんじゃなくて会社のサイトや個人のサイトをターゲットプラットフォームとして考えた場合、妥当な選択。編集機能にリソースをさくより、API実装に専念しておけばいいよね。
初期のデータプロバイダがDBじゃなくてファイルベースのXMLだったりする。でも、もちろんLINQ to SQLのプロバイダもあって、テーブル構築用のSQLも用意されてます。でも、コードを追っかけるとRepositoryを直接インスタンス化してる箇所がWebMvcプロジェクト(Webアプリ)にもあるから、ファイルストレージを前提として開発してるんだろうね。開発チーム内で分業されてるからかな?
ファイルストレージで気になるのはファイルフォーマット。どういう形式でファイルに保持してるのかなと思ってみてみたら、Atom形式のXml。全部が全部 Atom。で、Atom関係のモデルクラスはDomainプロジェクトに集約されてて、そのモデルを使うので、DBのモデルを直接使うなんて事はしてないんですな。AtomPub APIをとことん使いこなす設計ですばらしい。
んで、ファイルだからIO負荷が気になるところだけど、そこはシンプルにRepository実装内で、staticなDictionaryを持ってて、そこで保持。ファイルが書き換わったときにDictionary内のデータを破棄するために、ちょっとオシャレな作り方してて参考になるので、ここで引用。
RepositoryプロジェクトのFile/XmlCache.csの最後の所。
public void CacheItem(string filename, T item)
{
if (!objs.ContainsKey(filename)) objs.Add(filename, item);
//items aren't actually put in http cache, but an object handle is
HttpRuntime.Cache.Insert(filename, new object(), new CacheDependency(filename),
Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(30) /*TODO: make configurable*/, CacheItemPriority.Normal,
//remove from cache
new CacheItemRemovedCallback((key, value, reason) => objs.Remove(key))
);
}
実体をキャッシュに入れちゃえばいいじゃんと思うけど、なんかあるのかな。CacheDependencyの削除コールバックがラムダ式で書かれてて、コードがあっちこっち行かなくて素敵でしょ? 中でTidy.NETっていう別のオープンソースプロダクトを使ってて、HTMLの整形をしてるのかな? 同じく別のライブラリでSgmlReaderっていうのも使ってる。
それぞれ用途が違うのかな。どっちかだけでいいって物でもないの?整形するのとパースするのとで使い分けてるのかな。
SourceForge.net: Tidy.NET SgmlReader – Home
WebMvc プロジェクトにASP.NET MVCの実装が入ってるけど、テーマをサポートするために(ASP.NETのテーマとは違う)、独自のViewEngineとして ThemeViewEngineを使ってる。といっても、View/MasterPartialViewそれぞれのLocationFormatをセットして、Find系を実装するのみ。
フォルダ構成のなかにViewがなくて、themesっていうのがあるけど、そこにすべてのViewPageが入ってます。で、defaultとの差分のみをそれぞれのテーマフォルダに入れておけば、無いものはdefaultフォルダのものを使うように LocationFormatに登録されてるから問題なし。 ※default以外にはテーマ毎のイメージとCSS、テーマ説明のAtomEntry XMLとサムネイル画像が入ってるくらい。
URIで各ページの拡張子にフォーマット指定でxhtmlってつけるのをルールにしてるのは、RESTfulを意識してるからなのかな。
ソースをダウンロードして、動かそうとするといきなりコンパイルエラーがでるのはご愛敬。
単純に文字列閉じてないだけ。なのでDomainプロジェクトのAtomText.cs 行50の部分を↓変更。 デフォルトのtrailerがなんなのかオンラインでソースを確認しても化けててわかんないので、とりあえずなんか入れとくってことで"..."を使う。 ※trailerは文字列を指定の長さに切り抜いて、元文字列が指定長以上なら後ろにくっつける文字列。
public string ToStringPreview(int length)
{
return ToString().AbbreviateText(length, "...");
}
AtomPub APIを公開するのにあわせて、Atom実装のコードがたくさんあるけど、その他はパッと見シンプルな実装な感じ。
ViewPageも型指定(強い型付け)でViewDataを扱ってるし、コードをほとんど含まないように書かれててOxiteよりも綺麗な印象。好みの問題?
ちょっとOxiteのコードは量が多くて、冗長な感じがしなくもないし...。 このBlogsvc.netもCMS+Blogエンジンとして(Oxiteだけじゃなく)十分いけてる気がするね!