Rails: Как изменить заголовок страницы?

160

Каков наилучший способ создания пользовательского заголовка для страниц в приложении Rails без использования плагина?

wusher
источник

Ответы:

244

По вашему мнению сделайте что-то вроде этого:

<% content_for :title, "Title for specific page" %>
<!-- or -->
<h1><%= content_for(:title, "Title for specific page") %></h1>

Следующее идет в файле макета:

<head>
  <title><%= yield(:title) %></title>
  <!-- Additional header tags here -->
</head>
<body>
  <!-- If all pages contain a headline tag, it's preferable to put that in the layout file too -->
  <h1><%= yield(:title) %></h1>
</body>

Кроме того , можно инкапсулировать content_forи yield(:title)утверждение в вспомогательных методах (как и другие уже предложили). Тем не менее, в простых случаях, таких как этот, мне нравится помещать необходимый код непосредственно в конкретные представления без пользовательских помощников.

Кристоф Шиссл
источник
24
Я объединил этот ответ с приведенным ниже, чтобы создать «заголовок по умолчанию» для каждой страницы: <title><%= (yield(:title) + " - " unless yield(:title).blank?).to_s + "This is always shown" %></title>в макете и <% content_for :title, "Conditional title" %>в представлениях.
Джон
1
Прекрасно работает с Rails 5.2.0!
Станимир Димитров
1
Когда я использую, <h1><%= content_for(:title, "Title for specific page") %></h1>я не вижу ничего, что выводится в мой DOM (т.е. у меня <h1></h1>нет содержимого). Однако мой <title>Title for specific page</title>работает правильно. Любые идеи?
Иисус Навин
118

Вот простой вариант, который мне нравится использовать

В вашем макете

<head>
  <title><%= @title %></title>
</head>

И в верхней части страницы шаблона (первая строка)

<% @title="Home" %>

Из-за способа анализа макета и шаблонов страницы @ title = "Home" оценивается до отображения макета.

opsb
источник
32
Стоит отметить, что это не будет работать с кэшированием просмотра рельсов. В rails 3 content_for достаточно умен, чтобы правильно работать с кэшированием (см. Выбранный ответ).
opsb
4
переменные не должны быть установлены внутри контроллера?
2
@SajjadMerchant, как правило, я согласен, да переменные должны быть установлены в контроллере. В этом случае шаблон кажется более подходящим, потому что вы указываете атрибут, специфичный для внешнего вида страницы. Также возможно, что действие контроллера будет использоваться двумя различными представлениями (не то, чтобы это происходило очень часто, я использую это, чтобы показать, насколько тесно привязан заголовок к определенному шаблону).
opsb
50

Лучшая практика - использовать content_for.

Сначала добавьте пару вспомогательных методов (например, вставьте в app / helpers / application_helper.rb):

def page_title(separator = " – ")
  [content_for(:title), 'My Cool Site'].compact.join(separator)
end

def page_heading(title)
  content_for(:title){ title }
  content_tag(:h1, title)
end

Тогда в вашем макете вы можете просто использовать:

<title><%= page_title %></title>

... и в самом представлении:

<%= page_heading "Awesome" %>

Этот способ имеет то преимущество, что позволяет вам перетасовывать туда, где вы прикрепляете тег h1 для вашего заголовка, и сохраняет ваш контроллер красивым и свободным от случайных переменных @title.

Aupajo
источник
4
Как установить значение @content_for_title?
Джордан Фельдштейн
@JordanFeldstein Понятия не имею, что он имел в виду @content_for_title. Должно быть (content_for(:title) + ' &mdash; ' if content_for?(:title)).to_s + 'My Cool Site'. Затем, чтобы установить его с вашей точки зрения, просто<% content_for :title, 'My Page Title' %>
Тобиас J
1
@content_for_titleэто то, что случалось, когда вы использовали content_for, во время написания этого комментария. Я считаю, что это больше не так, но я не смотрел в последнее время. Комментарий Тоби Дж является правильным для сегодняшних Rails. Я обновлю свой оригинальный ответ.
Aupajo
20

Улучшение @opsb и более полная форма @FouZ :

В application.html.erb:

<title><%= @title || "Default Page Title" %></title>

В файле представления erb или его контроллере:

<% @title = "Unique Page Title" %>
boulder_ruby
источник
6

Без дополнительной информации о сценарии использования или требованиях, которые вы пытаетесь удовлетворить, я могу придумать несколько альтернатив:

1) Переключите заголовок на одной из ваших страниц макета и используйте вспомогательный метод, хранящийся в application_helper.rb

<title><%= custom_title %></title>

Этот подход даст вам уникальный заголовок для каждой страницы макета.

2) Railscasts предлагает использовать частичное для загрузки того, что отображается между тегами HEAD

3) Используйте вызовы javascript / ajax для манипулирования DOM, если вам нужно изменить заголовок после события загрузки.

Возможно, вы на самом деле не хотите менять содержимое, помеченное titleэлементом. Возможно, вам действительно нужны какие-то хлебные крошки, чтобы ваши пользователи всегда знали, где они находятся относительно иерархии навигации вашего сайта. Хотя я хорошо справился с плагином goldberg, я уверен, что есть и другие способы реализовать ту же функциональность.

Алан
источник
3

Я использую nifty_generator "nifty_layout", который предоставляет переменную title, которую я могу затем вызвать на странице, используя:

<% title "Title of page" %>

Я также могу позволить пользователю <% title "Title of page", false %>отображать заголовок только в заголовке браузера, а не на самой странице.

Sent-Хил
источник
2

Вы также можете установить его в before_filter в вашем контроллере.

# foo_controller.rb

class FooController < ApplicationController

  before_filter :set_title

  private

  def set_title
    @page_title = "Foo Page"
  end

end

# application.html.erb

<h1><%= page_title %></h1>

Затем вы можете установить условия в методе set_title, чтобы установить разные заголовки для разных действий в контроллере. Приятно иметь возможность видеть все соответствующие заголовки страниц в вашем контроллере.

JasonOng
источник
2
Это (к сожалению) обычная практика - использовать этот способ, но плохая практика - помещать заголовки страниц в свой контроллер. Заголовок страницы является чем-то более связанным с представлением. Если бы вы предлагали альтернативное представление XML, например, какое отношение имеет заголовок страницы?
Aupajo
Да, я согласен, что это не совсем хорошая идея, но, тем не менее, это альтернатива, которая может быть полезна в некоторых случаях, когда разные заголовки страниц необходимо извлекать из сложных условий?
JasonOng
1
Хм, я все еще думаю, что это то, что принадлежит как помощник для представления. Мое правило - посмотреть на версию XML и посмотреть, нужна ли ей эта переменная или нет. Если нет, то это то, что нужно индивидуальному представлению. Сделайте ваш контроллер максимально легким.
Aupajo
0

подход для заголовка страницы с использованием метода content_for и частичного

1 частичное имя: _page_title.html.erb

<%content_for :page_title do %>
 <%=title%>
<%end%>

2 Использование в application.html.erb внутри тега title

   <title><%=yield :page_title %></title>

3 Использование в соответствующем * .html.erb, исключая application.html.erb. Просто вставьте это в любой .html.erb и укажите заголовок страницы.

    e.g : inside index.html.erb

    <%=render '_page_title', title: 'title_of_page'%>
Кофи Асаре
источник
0

Короче говоря, я могу записать это следующим образом

<%content_for :page_title do %><%= t :page_title, "Name of Your Page" %> <% end %>
Мукеш Кумар Гупта
источник
0

Мне нравится метод opsb, но этот метод тоже работает.

<% provide(:title,"ttttttttttttttttttZ") %>
<html>
  <head><title><%= yield(:title) %></title></head>
   <body></body>
</html>
barlop
источник
ПОЭТОМУ метод здесь - метод, используемый в главе 3 книги Хартла, не то, чтобы я рекомендовал эту книгу, поскольку я нахожу это немного хлопотным, чтобы следовать, но так или иначе.
Бароп
-1

Лучший / чистый способ сделать это:

<title><%= @page_title or 'Page Title' %></title>
FouZ
источник
-9

Я хотел бы добавить свой довольно простой вариант.

В ApplicationController определите этот метод:

  def get_title
    @action_title_name || case controller_name
                            when 'djs'
                              'Djs'
                            when 'photos'
                              'Photos'
                            when 'events'
                              'Various events'
                            when 'static'
                              'Info'
                            when 'club'
                              'My club'
                            when 'news'
                              'News'
                            when 'welcome'
                              'Welcome!'
                            else
                              'Other'
                          end
  end

После этого вы можете вызвать get_title из тега заголовка вашего макета. Вы можете определить более конкретный заголовок для своей страницы, определив переменную @action_title_name в своих действиях.

IDBD
источник
1
Полагаю, вы изучили концепцию разделения интересов за последние шесть лет, но я просто изложу ее другим, которые могут быть смущены тем, почему этот ответ получил отрицательные оценки.
nurettin