読者です 読者をやめる 読者になる 読者になる

だるろぐ

とてもだるだるした日記です http://about.daruyanagi.jp/

お知らせ

WebMatrix + ASP.NET Web Pages でキレイにコーディングしたい

WebMatrix ASP.net Web Pages

Razor 構文を使用する ASP.NET Web Pages は web framework および WebMatrix の一部で、Windows を使用した Web サイトの構築で必要なすべてが含まれます。

Download: Razor 構文を使用する ASP.NET Web Pages - Microsoft Download Center - Download Details

WebMatrix + ASP.NET Web Pages でキレイにコーディングしたいなぁ、と思うのだけれど、どうするのが正しいのかよくわからない。自分なりのテンプレみたいなのがほしいんだけれどね。

設定の共通化

まず、 Web サイト全体の設定は一元管理したい。たぶん、これは“_AppStart.cshtml”に記述するのが正しいのだろう。

@{
    App.Title = "daruyanagi.net";
    App.Author = "daruyanagi";
    App.Language = "ja";
    App.Encoding = "utf-8";
    App.Copyright = "Copyright © 2012 daruyanagi. All rights reserved.";
    App.Description = "This is the web site of Hidetoshi Yanagi a.k.a. daruyanagi.";
    App.Keyword = "daruyanagi";
}

これでも十分に簡素だけれど、設定ファイルやデータベースからロードできるようにすればもっとクールかもしれない。

f:id:daruyanagi:20120807050527p:plain

App(や、このあとにでてくる Page)は dynamic 型(WebPageExecutingBase.App*1)なので、あらかじめメンバーを定義しておかなくても、あとからいろいろ追加できる。

@{ 
    AppState["customAppName"] = "Application Name"; 
} 

ほんとは AppState というのを使うっぽいけど、まぁ、いいや。

レイアウトの共通化

つぎは、 Web サイトのデザインの共通化。 HTML 5 でレイアウトファイル(“~/Views/Shared/_Layout.cshtml”)記述して、 jQuery / Modernizr / html5.js あたりのスクリプトをロードしておくのがモダンなやり方というものだろう。あと、リセット CSS で一度スタイルをリセットし、そのあとに独自の CSS を充てるようにした。ブラウザー幅によってデザインを変更するレスポンシブな部分を担当する CSS を切り分ければ、より一層メンテナンス性は上がるかも。ただ、あんまりファイル数は多くしたくないな。

@{
    App.Title = App.Title ?? "Untitled Application";
    App.Language = App.Language ?? "en";
    App.Encoding = App.Encoding ?? "utf-8";
    Page.Title = Page.Title ?? "Untitled Page";
}
<!DOCTYPE html>

<html lang="@App.Language">
    <head>
        <title>@Page.Title - @App.Title</title>
        
        <meta charset="@App.Encoding" />
        <meta name="description" content="@App.Description">
        <meta name="keywords" content="@App.Keyword">
        <meta name="author" content="@App.Author">
        <meta name="copyright" content="@App.Copyright">
        <meta name="genarator" content="Microsoft WebMatrix 2.0">
        <meta name="viewport"
              content="width=device-width,initial-scale=1">

        <link rel="stylesheet" href="~/Content/Reset.css" />
        <link rel="stylesheet" href="~/Content/Site.css" />
        
        <!--[if lt IE 9]>
        <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
        <![endif]-->

        <script src="http://code.jquery.com/jquery-latest.js"></script>
        <script src="http://www.modernizr.com/downloads/modernizr-latest.js"></script>
    </head>
    <body>
        <header id="site-header">
@RenderPage("_Header.cshtml")    
        </header>

        <nav id="site-nav">
@RenderPage("_Navigation.cshtml")    
        </nav>
        
        <div id="site-content">
            <article id="site-body">
@RenderBody()           
            </article>
            <aside id="site-sidebar">
@RenderPage("_SideBar.cshtml")    
            </aside>
        </div>

        <footer id="site-footer">
@RenderPage("_Footer.cshtml")    
        </footer>
    </body>
</html>

冒頭は、“_AppStart.cshtml”で Title などを指定し忘れたときに、最低限のパラメータを指定しておくコード。今まで気づかなかったのだけれど、<meta name="author" content="@App.Author"> で @App.Author が null だと、 content 属性は出力されず、 <meta name="author"> だけが出力されるんだね。なかなか頭いいな。

f:id:daruyanagi:20120807042822p:plain

ヘッダーやナビゲーション、サイドバー、フッターは外部ファイルに追い出した。ここらへんは「分割し、統治せよ(divide et impera)」*2ってやつですな。

@{
    Layout = "~/Views/Shared/_Layout.cshtml";

    Page.Title = "Default";
}
<p>Web ページの内容。</p>

あとは、こんな感じで @RenderBody() でレンダリングする内容を記述すればいいというわけ。ページ固有のデータは、 dynamic 型の変数 Page に格納しておくことができる。

@{ 
    PageData["Color1"] = "Red"; 
    PageData["Color2"] = "Blue"; 
} 

PageData (IDictionary)に入れてもいいっぽい。 Page.Title にいれた値は、 PageData["Title"] で取り出せるし、たぶんその逆も可なので好きなほうを使うといい。もしかしたらパフォーマンス的な違いがあるのかもしれないけれど。

あとはこれを適当に CSS で装飾すると、こんな感じになる。

f:id:daruyanagi:20120807045124p:plain

これからの目標

今見返してふと思ったのは、比較的簡単にテーマ機能なんかを実装できるなということ。ただデザインを変えたいがために、毎回一からこんなの作るのはアホらしい。

あと、 @RenderPage("_Footer.cshtml") は @RenderFooter() などと記述できるとカッコいいな。「フッターはテーマフォルダ直下の“_Footer.cshtml”に書く」。なるべく規約ベースで。これも簡単にできそうだ。

汎用的な部分はガンガン外に追い出して、再利用できるといい。

まとめ

ASP.NET MVC はとてもすばらしい技術だと思うけれど、素人に毛の生えたレベルではどうもデカ過ぎる。その点、 ASP.NET Web Pages はちょうどいい。大規模なサービスを作ろうと思うとすぐぐちゃぐちゃになって破綻するけれど(そんな場合は MVC パターンの力を借りるべきだ)、“Template.html”をひたすらコピペして新しい記事を作るような個人サイトならば、 ASP.NET Web Pages で十分なんだ。サーバーを IIS にして、拡張子を html から cshtml にするだけでいい。たったこれだけで、 C# + Razor を使ってキレイにコーディングできる。今から覚えるんだったら、 PHP より C# + Razor のほうが簡潔かつ安全でいいと思うし。

ドキュメントは、とりあえずこれを読んどけばいい。わしも全部は読んでないけれど、これの紙バージョンをもっていてたまに読んでいる。お盆休み中に、また復習してみようと思う。

あとは、しばやんのやる気を待つしかない。

また、おいおい Razor に関しては備忘録をかねて書いていきたいと思うかも。

*1:WebPageExecutingBase は The base class for all Plan9 files (_pagestart, _appstart, and regular pages) らしいのだけれど、 Plan9 ってなんぞ。今度調べよう

*2:http://www.kitashirakawa.jp/taro/2011/05/divide-et-impera/