在我的项目中,我有几个文件: 的 1。 main.rb的
require 'sinatra'
set :public_folder, 'public'
set :views, 'views'
set :erb, :layout => :base
get '/' do
erb :layout
end
get '/about' do
erb :about
end
get '/contact' do
erb :contact
end
2。 layout.erb
<% title="Songs By Sinatra" %>
<!doctype html>
<html lang="en">
<head>
<title>
<%=title %>
</title>
<meta charset="utf-8">
</head>
<body>
<header>
<h1><%= title %></h1>
<nav>
<ul>
<li><a href="/" title="Home">Home</a>
</li>
<li><a href="/about" title="About">About</a>
</li>
<li><a href="/contact" title="Contact">Contact</a>
</li>
</ul>
</nav>
</header>
<section>
<%=yield %>
</section>
</body>
</html>
<p>Welcome to this website that's all about the songs of the great Frank Sinatra.</p>
<img src="/images/sinatra.jpg" alt="Frank Sinatra">
第3。 about.erb
<p>
This site is a demonstration of how to build a website using Sinatra.
</p>
当我转到http://localhost:4567/about时,一切正常,页面加载,但当我转到http://localhost:4567/时,我收到错误:没有给出阻止(收益)。 < / p>
任何人都可以解释什么是问题,以及可能的解决方案。
非常感谢你。
答案 0 :(得分:0)
你需要在
中传递一个块erb :layout
要使<%=yield %>
中的layout.erb
起作用,您需要传递一个块,其输出将放在`yield的位置。在最简单的形式中,您可以这样做:
erb :layout { "This is what I want in output" }
通常,您渲染另一个模板:
erb :layout do
erb :about
end
documentation中的更多详情。
答案 1 :(得分:0)
TLDR; @wandmaker所说的 - 你需要将一个块传递给:layout。
理解yield
对理解Ruby至关重要。基本上,yield
将控制从一个范围传递到另一个范围。 Ruby中的所有方法都接受块,但除非它们明确地产生或调用它们,否则它们会忽略它们:
"A RUBY STRING".downcase { p "I'm in a block!" }
# => "a ruby string"
但是如果方法调用yield,则控制权被传递给块,然后传递回调用范围:
def yield_me
yield
end
yield_me { p "I'm in a block!" }
# => "I'm in a block!"
或者,您可以将块作为参数捕获:
def catch_me(&block)
block.call
end
catch_me { p "I'm in a block" }
# => "I'm in a block!"
所以考虑到这一点,你应该更清楚你的Sinatra模板正在做什么 - 它渲染layout.erb但是当它命中yield
时,它试图控制一个块 - 在这种情况下是非存在的。
所以你的所有回复都应该提供一个块或子模板,如:
erb :layout { "<p>This is the about page</p>" }
或
erb :index