Rails: วิธีการเปลี่ยนชื่อของหน้า?


160

วิธีที่ดีที่สุดในการสร้างชื่อที่กำหนดเองสำหรับหน้าในแอพ Rails โดยไม่ต้องใช้ปลั๊กอินคืออะไร?

คำตอบ:


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" %>ในมุมมอง
John

1
ทำงานได้สมบูรณ์แบบด้วย Rails 5.2.0!
Stanimir Dimitrov

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 3 content_for ฉลาดพอที่จะทำงานอย่างถูกต้องกับการแคช (ดูคำตอบที่เลือก)
opsb

4
ไม่ควรตั้งค่าตัวแปรภายในคอนโทรลเลอร์

2
@SajjadMerchant โดยทั่วไปฉันเห็นด้วยใช่ควรตั้งค่าตัวแปรไว้ในคอนโทรลเลอร์ ในกรณีนี้เทมเพลตจะรู้สึกว่าเหมาะสมกว่าเพราะคุณกำลังระบุแอททริบิวที่เฉพาะเจาะจงกับรูปลักษณ์ อาจเป็นไปได้ที่การกระทำของคอนโทรลเลอร์จะถูกใช้โดยมุมมองสองแบบที่แตกต่างกัน (ไม่ใช่ว่ามันเกิดขึ้นบ่อยมากฉันใช้มันเพื่อแสดงให้เห็นว่า
opsb

50

แนวทางปฏิบัติที่ดีที่สุดคือการใช้ content_for

ขั้นแรกให้เพิ่มวิธีการช่วยเหลือสองสามวิธี (เช่นติดใน app / ผู้ช่วยเหลือ / 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 สำหรับชื่อของคุณและทำให้คอนโทรลเลอร์ของคุณดีและไม่มีตัวแปร pesky @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 ในปัจจุบัน ฉันจะอัปเดตคำตอบดั้งเดิมของฉัน
Aupajo

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) ใช้การเรียก javascript / ajax เพื่อจัดการ DOM หากคุณต้องการเปลี่ยนชื่อหลังจากเหตุการณ์โหลด

บางทีคุณอาจไม่ต้องการเปลี่ยนเนื้อหาที่แท็กtitleองค์ประกอบ บางทีคุณอาจต้องการ breadcrumb บางประเภทเพื่อให้ผู้ใช้ของคุณรู้อยู่เสมอว่าพวกเขาอยู่ที่ไหนเกี่ยวกับลำดับชั้นการนำทางของไซต์ของคุณ ในขณะที่ฉันทำดีกับปลั๊กอินทองคำฉันแน่ใจว่ามีวิธีอื่นในการดึงฟังก์ชันการทำงานเดียวกัน


3

ฉันใช้ "nifty_layout" ของ nifty_generator ซึ่งมีตัวแปรชื่อเรื่องที่ฉันสามารถเรียกใช้ในหน้านั้นโดยใช้:

<% 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 ตัวอย่างเช่นชื่อหน้ามีความเกี่ยวข้องอะไร
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><%=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>

FWIW วิธีการที่นี่เป็นวิธีที่ใช้ในหนังสือเล่มที่ 3 ของ hartl ไม่ใช่ว่าฉันแนะนำหนังสือเล่มนี้เพราะฉันพบว่ามันเป็นเรื่องยุ่งยากในการติดตาม แต่อย่างใด
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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.