如何使用RoR更改页面标题基于:id?

时间:2015-08-15 04:33:10

标签: ruby-on-rails ruby

我有一个使用Ruby on Rails(后端)和React.js(前端)构建的网站,因此所有内容都是动态加载的,并且页面更改通过AJAX实现。如果用户正在浏览文章,我想将html页面标题更改为文章标题。因此,如果用户访问website.com/discuss/14,我希望页面标题更新为文章标题,其中topic_id = 14.但是,如果用户访问website.com/#contactpage或任何其他页面不是一个讨论页面,然后应该有一个默认的标题。

现在,我的代码仅适用于SEO的_escaped_fragment_,但不适用于普通用户。

这是代码:

--- frontend.html.erb

<!DOCTYPE html>
<html>
<head>

  <% if params["_escaped_fragment_"].present?  %>
    <%= render partial: 'layouts/escaped_title' %>
  <% elsif Rails.application.routes.recognize_path('discuss') %>
    <%= render partial: 'layouts/discuss_title' %>
  <% else %>
    <title>website.com:default title</title>
  <% end %> 
.....rest of my page code

所以第一个条件(转义片段)完全正常。这是失败的第二个条件(路线 - >讨论)。这是每个部分的代码:

---- _escaped_title.html.erb

<% if params[:_escaped_fragment_] %>
  <% if params[:_escaped_fragment_].match(/\/discuss\/(\d+)/) %>
    <% topic = Topic.statistic.find_by_id($1) %>
    <% if topic %>
      <% opts = {sector: true, statistic: true, background: true} %>
      <% json = topic.show_data(opts) %>
     <% plain_question = ActionView::Base.full_sanitizer.sanitize(topic.question) %>
      <title><%= plain_question %> - on website.com</title>

    <% end %> 
  <% end %>
<% end %>

---- _discuss_title.html.erb

<% topic = Topic.find_by_id(params[:id]) %>
 <% if topic %>
    <% opts = {sector: true, statistic: true, background: true} %>
    <% json = topic.show_data(opts) %>
    <% plain_question = ActionView::Base.full_sanitizer.sanitize(topic.question) %>
    <title><%= plain_question %> - on website.com</title>    
 <% end %>  

我怀疑_discuss_title.html.erb的前几行不正确,但我不知道如何正确地执行此操作。如何正确获取当前主题ID并将其传递给变量以便搜索我的数据库?

非常感谢!

1 个答案:

答案 0 :(得分:2)

首先通过创建辅助方法来简化视图:

module ApplicationHelper
  def title
    content_tag(:title, @title || "Some default title")
  end
end

使用的是:

<!DOCTYPE html>
<html>
<head>
  <%= title %>
</head>

我们现在已经将复杂性移出视图,我们可以通过设置视图上下文实例变量@title来控制页面标题。

实现这一点的最简单方法是在控制器中实际设置实际需要自定义标题的标题:

class DiscussionController < ApplicationController

  before_filter :set_discussion, only: [:show, :edit, :delete, :update]
  before_filter :set_title, only: [:show], if: lambda{ |controller| controller.request.format.html? }

  private

  def set_discussion
    @discussion = Discussion.find(params[:id])
  end

  def set_title
     # since we get the value from the database record and 
     # not the params we don't need to worry about escaping.
     @title = "Discussing article #{ @discussion.id }"
  end
end