Chiroru's Diary

日々の学びをちょこちょこメモしていきます

ページごとにサイドバーのコンテンツを切替える

お手伝いしているRailsのサービスサイトで、サイドバーに全ページに共通の広告を表示しているのですが、掲載数の変更に伴いページごとに種類を変えて広告バナーを表示することにしました。

現状としてはapplication.html.erbで統一されたサイドバーを表示していますが、 これをページごとに分割するのに「名前付きyield」が使えそうです。

【目次】

名前付きyieldの指定

まずapplication.html.slim側では、= yield :nameの形式でyieldに名前をつけます。

現在広告バナーはページのcol-md-3の部分に表示しているため、col-md-9はそのまま現状のものを表示できるよう= yieldを、そしてxxxページ・yyyページでそれぞれバナーを変更したいcol-md-3の内部に名前付きyieldを記述します。

.row
  .col-md-9
    = yield
  .col-md-3
    .sidebar-content
      = yield :xxx
      = yield :yyy

viewのメイン部分は常に「名前なしyield」としてレンダリングされるため、コンテンツを名前付きのyieldとしてレンダリングするには、content_forメソッドを使用します。

content_forメソッドでレイアウトに挿入

名前付きのyieldとしてレイアウトに挿入する場合、各ページ(index.html.slim)でcontent_for :name doの形式で指定します。

xxx/index.html.slim

= h1 名前なしyieldとして挿入される

- content_for :xxx do
  .sidebar-content
    h2 名前付きyieldとして挿入される
    .card

yyy/index.html.slim

= h1 名前なしyieldとして挿入される(yyy)

- content_for :yyy do
  .sidebar-content
    h2 名前付きyieldとして挿入される(yyy)
    .card

これらのレンダリング結果がレイアウトに挿入されると、最終的には以下のようなHTMLとして出力されます。

xxx/index.html

<div class="row">
  <div class="col-md-9">
    <h1>名前なしyieldとして挿入される</h1>
  <div class="col-md-3">
    <div class="sidebar-content">
      <h2>名前付きyieldとして挿入される</h2>
      <div class="card">

yyy/index.html

<div class="row">
  <div class="col-md-9">
    <h1>名前なしyieldとして挿入される(yyy)</h1>
  <div class="col-md-3">
    <div class="sidebar-content">
      <h2>名前付きyieldとして挿入される(yyy)</h2>
      <div class="card">

これでxxxページ・yyyページそれぞれ異なる広告バナーを表示させることができるようになりました!

レイアウトをコントローラーごとに指定するのもいいかも

今回は各ページで広告バナーのみ切替がしたかったので使用しませんでしたが、コントローラーにレイアウトを指定することで表示を変える方法も良さそうです。

例えばxxx_controllerのshowページでは、applicationファイルのようなサイドバナー広告の表示が不要であるとします。

そんな時はviews/layouts下に、別途レイアウトファイルを作成し、コントローラーでlayoutメソッドを指定することで切り替えられます。
今回はバナーなしのno_banner.html.slimを作成したとします。

作成できたら、xxxコントローラーにて以下のように指定しましょう。

layout "no_banner", only: :show

# または

def show
  render layout: "no_banner"
end

参考