如何在Rails中做静态内容?


73

寻找不同的选择:

一种是只将静态页面放在public /文件夹中,但是我确实希望布局/应用程序中的标头保持一致。

我试过了,但是出现错误:

# in routes.rb:
map.connect '*path', :controller => 'content', :action => 'show'

# in content_controller.rb:
def show
  render :action => params[:path].join('/')
end

我想要的是一种简单的方法,只需创建一个.rhtml,即可将诸如常见问题,联系方式,tos,隐私和其他非应用程序类型页面等内容组合在一起。谁做的?

Answers:



178

对于Rails6Rails5Rails4,您可以执行以下操作:

将以下行放在route.rb的末尾

  get ':action' => 'static#:action'

然后请求root / welcome,将呈现/app/views/static/welcome.html.erb

即使您不必在其中放置任何东西,也不要忘记创建一个“静态”控制器。

限制:如果有人尝试访问不存在的页面,则将引发应用程序错误。请参阅下面的可解决404的解决方案

对于Rails3,您必须使用“匹配”而不是“获取”

  match ':action' => 'static#:action'

4
+1太棒了,正是我所需要的。这应该获得更多的投票,因为它是最新的Rails。
2011年

14
如果其他人想知道,这里的“:action”是不可思议的。如果您将其命名为“:id”或“:title”之类的话,它将不起作用。
mahemoff 2011年

1
在Rails4中,我在开发模式下收到一条警报,说要用“ get”替换“ match”。
约瑟夫2013年

1
@RolandStuder对不起,我不清楚-您所要做的就是将“ match”替换为“ get”,并且效果很好。:)
约瑟夫

2
由于这是万能的,如何避免例外?理想情况下,您要提供404,而不触发异常。我试图查找如何记录该文档,它没有触发丢失的方法,它只是在磁盘上查找视图。
阿马拉2014年

22

取决于url结构,如果您想使路径脱离/(例如/ about_us),则:

map.connect ':action', :controller => "static"

这应该放在路由文件的末尾,将.html.erb文件扔到app / views / static中,就可以了。

例如:抛出about_us.html.erb,将在/ about_us上提供一个页面。

您的问题中的项目非常适合全路径搜索,您可以在处分析给定的数组params[:path]。有关更多信息,请访问http://railscasts.com/episodes/46-catch-all-route


13

渲染动作没有任何意义。您将要使用布局渲染模板(或文件)。

# Path relative to app/views with controller's layout
render :template => params[:path]

# ... OR

# Absolute path. You need to be explicit about rendering with a layout
render :file => params[:path], :layout => true

您可以通过具有页面缓存的单个操作来提供各种不同的模板。

# app/controllers/static_controller.rb
class StaticController < ApplicationController
  layout 'static'

  caches_page :show

  def show
    valid = %w(static1 static2 static3)
    if valid.include?(params[:path])
      render :template => File.join('static', params[:path])
    else
      render :file   => File.join(Rails.root, 'public', '404.html'), 
             :status => 404
    end
  end
end

最后,我们需要定义一条路线。

# config/routes.rb
map.connect 'static/:path', :controller => 'static', :action => 'show'

尝试访问这些静态页面。如果路径不包含有效的模板,我们将渲染404文件并返回404状态。

  • http://localhost:3000/static/static1
  • http://localhost:3000/static/static3
  • http://localhost:3000/static/static2

如果查看app / public,您会注意到带有static1.html,static2.html和static3.html的static /目录。首次访问页面后,由于页面缓存,所有后续请求将完全是静态的。


2

考虑您是否有1个家庭控制器,并且具有show,aboutus,privacy等夫妇方法:

class HomesController < ApplicationController
  def show
  end
  def privacy
  end
  def aboutus
  end
end

并将show方法映射到您的根目录,并将另一个映射到一些命名的路由,例如

map.root      :controller => "homes", :action => "show"
map.aboutus "/aboutus", :controller => "homes", :action => "aboutus"
map.privacy "/privacy", :controller => "homes", :action => "privacy"

并为每个视图

app/views/homes/aboutus.html.erb --> you get http://localhost:3000/aboutus
app/views/homes/show.html.erb --> you get http://localhost:3000 (root)
app/views/homes/privacy.html.erb --> you get http://localhost:3000/privacy

所有应用都在app / views / layout / application.html.erb中使用相同的布局


2

Lindsaar解决方案是我见过的最好的解决方案之一。他构建了一个缓存静态页面,该页面在git版本更改时已过期。

<%= cache "site-page-#{@page_name}-#{App.git_revision}" do %>
  <%= render :partial => @page_name %>
<% end %>

1

为您的静态页面(例如联系人)创建一个PagesController并插入

def contact_page
end

在config / routes.rb中插入

get 'contact' => 'pages#contact_page'

它将显示views / pages / contact_page.html.erb中的内容


为什么要投票?我很感谢我对Rails 4的回答,但是仍然会回答别人的问题。
2015年

1

我从给出的答案中使用了通用控制器的概念,但是我想捕获404,因此我在其中添加了一个操作来处​​理两种情况:

# app/controllers/static_controller.rb
class StaticController < ApplicationController
    def static_or_404
        render params[:static]
    rescue ActionView::MissingTemplate
        render :not_found
    end
end

然后在我的路由的最底部:

# config/routes.rb
get '*static', to: 'static#static_or_404'

app/views/static以与路径相同的名称提供视图,如果没有这样的视图,则提供app/views/static/not_found.html.erb。一个人也可以替换render :not_foundredirect_to root_path其他人想要发生的事情。


很棒的东西!我只是回到我的答案,想写出如何处理404,然后看到您已经做到了,现在我链接到您的解决方案。从某种程度上来说,更新我的可见性答案仍然是一件好事。或者,也许您想对我的答案进行修改,以使您有所归属。当之无愧的赞誉。我希望最好的答案不会以最少的票数停留太久。
罗兰·史都德
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.