Rails:如何更改页面标题?


160

在不使用插件的情况下为Rails应用程序中的页面创建自定义标题的最佳方法是什么?

Answers:


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_forand 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完美搭配!
斯坦尼米尔·迪米特罗夫'18

1
当我使用时,<h1><%= content_for(:title, "Title for specific page") %></h1>我看不到任何输出到DOM中(即,我<h1></h1>没有内容)。但是我<title>Title for specific page</title>的工作正常。有任何想法吗?
JoshuaESummers

118

这是我喜欢使用的一个简单选项

在您的布局中

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

在页面模板的顶部(第一行)

<% @title="Home" %>

由于布局和页面模板的解析方式,在呈现布局之前先评估@ title =“ Home”。


32
值得注意的是,这不适用于Rails视图缓存。在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变量。


4
如何设置的值@content_for_title
Jordan Feldstein

@JordanFeldstein我不知道他是什么意思@content_for_title。应该是(content_for(:title) + ' &mdash; ' if content_for?(:title)).to_s + 'My Cool Site'。然后从您的角度进行设置,只需<% content_for :title, 'My Page Title' %>
Tobias J

1
@content_for_title是您content_for在撰写本评论时使用时曾经发生的事情。我相信情况已不再如此,但我最近没看过。Toby J的评论对今天的Rails是正确的。我将更新原始答案。
奥帕霍

20

一个改进@opsb和更完整的形式@FouZ的:

application.html.erb

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

在erb文件或其控制器中:

<% @title = "Unique Page Title" %>


6

如果没有关于您要满足的用例或需求的更多详细信息,我可以考虑以下几种选择:

1)在其中一个版面页面中切换标题,并使用存储在其中的帮助方法 application_helper.rb

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

这种方法将为您提供每个布局页面的唯一标题。

2)Railscasts建议使用局部加载来加载HEAD标签之间显示的内容

3)如果您需要在load事件之后更改标题,请使用javascript / ajax调用来操作DOM。

也许您并不是真的想要更改title元素标记的内容。也许您确实需要某种形式的面包屑,以便您的用户始终知道他们相对于站点导航层次结构的位置。尽管我对goldberg插件的工作做得很好,但我确信还有其他方法可以实现相同的功能。


3

我使用nifty_generator的“ nifty_layout”,它提供了一个title变量,我可以使用以下命令在页面上调用它:

<% title "Title of page" %>

我还<% title "Title of page", false %>可以使标题仅显示在浏览器标题中,而不显示在页面本身中。


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方法中设置条件,以为控制器中的不同操作设置不同的标题。很高兴能够在控制器中看到所有相关的页面标题。


2
不幸的是,使用这种方式是很常见的做法,但是将页面标题放在控制器中却是不好的做法。页面标题与视图更相关。例如,如果要提供XML替代视图,则页面标题有什么相关性?
奥帕霍

是的,我同意这不是一个好主意,但是,在某些情况下需要从复杂的条件中衍生出不同的页面标题的情况下,这是一个有用的选择吗?
JasonOng

1
嗯,我仍然认为它是视图的帮助者。我的规则是查看XML版本,看看是否需要该变量。如果没有,那就是个别视图需要的东西。使您的控制器尽可能轻。
奥帕霍


0

使用content_for方法和部分的页面标题的方法

1。部分名称:_page_title.html.erb

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

2。标题标签内application.html.erb中的用法

   <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

我喜欢opsb的方法,但是这种方法也可以。

<% provide(:title,"ttttttttttttttttttZ") %>
<html>
  <head><title><%= yield(:title) %></title></head>
   <body></body>
</html>

FWIW这里的方法是hartl的书的第3章中使用的方法,不是我推荐那本书,因为我觉得这有点麻烦,但是无论如何。
barlop

-1

最好的/干净的方法来做到这一点:

<title><%= @page_title or 'Page Title' %></title>

-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变量来为页面定义更具体的标题。


1
我想您在过去的六年中已经学到了分离关注点的概念,但是对于那些可能对这个答案为何获得负面评价感到困惑的其他人,我只会把它付诸实践。
nurettin
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.