インドカレーファンクラブ

パソコン、カメラ

【ASP.NET】【Rails】ASP.NETとRailsでViewのLayout

便宜上、ここではLayoutを利用するページを元のページと呼ぶことにする
(適切な呼び方がわからない)

かきかた

ASP.NET

RazorではViews/_ViewStart.cshtmlファイルの中で全てのViewに共通するレイアウトを指定する

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

これによって各Viewの中で指定通りView/Shared/_Layout.cshtmlがデフォルトのレイアウトファイルとして読み込まれる

他のレイアウトを利用したい場合、Layoutを無効化したい場合は各Viewの側で以下のように指定する

@{
    Layout = _HogeLayout;
    #Layout = null; # 無効化するとき
}

Rails

Railsでは暗黙的にviews/layouts/application.html.erbが共通のレイアウトとされる

他のレイアウトを利用したい場合、Layoutを無効化したい場合はControllerで指定する

class UsersController < ApplicationController
  layout 'user'
  # layout false 無効にしたい場合
  ...
  # Action単位での指定もできる
  def index
    render :layout => 'index'
    # render :layout => false 無効にしたい場合
  end
  ...
end

参考: https://www.javadrive.jp/rails/template/index3.html

変数の伝播

ASP.NET

元のページからLayout, Partialに変数を渡す場合はViewBag, ViewData, TempDataでもできるけど、
ASP.NETが標準としているMVVMのViewModelを使った方が型が自明でわかりやすいと思う
ということで以下の例ではそのように書いている

実運用的には元のページのViewのViewModelにはLayout用のViewModelを継承しておくといい感じ 例えばLayout用の親となるViewModelにはTitleやHeader, Footer用のフィールドを持たせて、元のページのViewModelには各ページで必要となるフィールドを持たせるようなイメージ

Layout

@model = Foo.Bar.LayoutViewModel

<!DOCTYPE html>
<html>
  <head>
    <title>@Model.Title</title>
  </head>
  <body>
    @RenderBody() @* ここでLayoutを利用する元のページを表示 *@
    <hr>
    <div>
        @*
          元のページの"Sub"という名称のセクションを表示
          必須指定なのでセクションがなかったらエラー
        *@
        @RenderSection("Sub", required: true)
    </div>
  </body>
</html>

元のページ

@*
  UserViewModelがLayoutViewModelを継承していれば
  Layoutでも元のページでも同じViewModelを使えばよくて楽
*@
@model = Foo.Bar.UserViewModel
<div>
  <p>UserName: @Model.User.Name</p>
</div>

@section Sub {
    <p>コンテンツ</p>
}

Rails

型がないので気楽といえば気楽

Layout

<!DOCTYPE html>
<html>
  <head>
    <title>タイトル</title>
  </head>
  <body>
    <%= yield %>
    <hr>
    <div>
      <%# Section相当の物 %>
      <%= yield :sub %>
    </div>
  </body>
</html>

元のページ

<div>
  <p>UserName: @user.name</p>
</div>

<% content_for :sub do %>
<p>コンテンツ</p>
<% end %>

yield がメソッドであることに注意
yield :sub は分かりにくいけど yield(:sub) と等価である

また以下のようにすれば元のページからLaytoutに変数を渡すことができる
(RailsだとView->ViewだけどASP.NETだとViewModel->Viewで渡す内容かな)

Layout

<% yield :hoge %>

元のページ

<% provide(:hoge, 'ほげ') %>

シンボルで値を渡すのがポイント <% provide(@hoge, 'ほげ') %> だとダメみたい

そもそも 元のページ→Layout と変数を渡すんじゃなくて
Controllerで@hogeを設定してその値をそのままLayoutで呼べばいい
でもControllerじゃなくてView(元のページ)で演算をした結果をLayoutに渡したかったらこのprovideを使うことになるはず