Ruby on Rails - 布局
Ruby on Rails - 布局 (Layouts)
Section titled “Ruby on Rails - 布局 (Layouts)”在 Rails 中,布局(Layouts)定义了围绕视图(views)的通用结构。它们允许您在应用程序的多个页面上保持一致的页眉(header)、页脚(footer)、导航(navigation)以及整体外观和感觉。布局文件位于 app/views/layouts/ 目录。
默认情况下,Rails 使用一个名为 application.html.erb 的布局文件。当控制器动作(controller action)渲染视图时,Rails 会将该视图的内容包装在此布局中。
创建自定义布局
Section titled “创建自定义布局”让我们为图书馆应用程序创建一个自定义布局。我们将其命名为 library_layout.html.erb 并放置在 app/views/layouts/ 目录中。
将以下 HTML 和 ERB 代码添加到 app/views/layouts/library_layout.html.erb 文件中:
<!DOCTYPE html><html><head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1"> <title>Library Info System</title> <%= csrf_meta_tags %> <%= csp_meta_tag %>
<%= stylesheet_link_tag "application", media: "all", "data-turbo-track": "reload" %> <%= javascript_include_tag "application", "data-turbo-track": "reload", defer: true %></head><body id="library-app"> <div id="container"> <header id="main-header"> <h1>Library Information System</h1> <h3>Powered by Ruby on Rails</h3> </header>
<nav id="main-nav"> <!-- Navigation links can go here --> <%= link_to "Home (Books List)", books_path %> </nav>
<main id="content"> <%# Display flash messages %> <% flash.each do |type, msg| %> <div class="alert alert-<%= type %>"><%= msg %></div> <% end %>
<%= yield %> <%# This is where the content of individual views will be inserted %> </main>
<aside id="sidebar"> <!-- Sidebar content can go here --> <h4>Subjects</h4> <ul id="subjects-sidebar"> <%# You might load @subjects here if available globally or via a helper %> <%# Subject.all.each do |subject| %> <%# content_tag :li, link_to(subject.name, subject_path(subject)) %> <%# end %> </ul> </aside>
<footer id="main-footer"> <p>© <%= Time.now.year %> Library Info System</p> </footer> </div></body></html>此布局中的关键元素:
<!DOCTYPE html>:标准的 HTML5 文档类型声明。<meta charset="utf-8">和<meta name="viewport" ...>:必要的元标签。csrf_meta_tags和csp_meta_tag:Rails 提供的与安全相关的助手方法。stylesheet_link_tag "application", ...:包含应用程序编译后的 CSS(由 Sprockets 或 Webpacker/Shakapacker 通过app/assets/stylesheets/application.css或类似文件管理)。javascript_include_tag "application", ...:包含应用程序编译后的 JavaScript。<%= yield %>:这是最重要的部分。它是您的特定视图(例如index.html.erb、show.html.erb)的内容将被插入的地方。- 闪现消息(Flash messages):一种常见的模式,用于向用户显示信息性消息或错误。
- 导航(Navigation)、页眉(header)、页脚(footer)、侧边栏(sidebar):常见的结构元素。
使用自定义布局
Section titled “使用自定义布局”要告知您的 BooksController(或任何其他控制器)使用此新布局,您可以在控制器文件的顶部指定它:
class BooksController < ApplicationController layout 'library_layout'
def index @books = Book.all # Assuming you want to show all subjects in the sidebar of the layout # This is just one way; helpers or before_actions are also options for shared data @all_subjects_for_layout = Subject.order(:name) end # ... other actions ...end如果您希望应用程序中的所有控制器默认使用此布局,可以将 library_layout.html.erb 重命名为 application.html.erb,或在 ApplicationController 中指定它:
class ApplicationController < ActionController::Base layout 'library_layout'end现在,当您浏览由 BooksController 处理的页面时,它们将在 library_layout.html.erb 结构中渲染。
应用程序的样式通常在 app/assets/stylesheets/ 中管理。application.css(或 application.scss/application.sass)文件通常充当清单文件(manifest),导入其他样式表。
创建或编辑 app/assets/stylesheets/application.css(或创建一个新文件,如 custom_styles.css,并使用 *= require custom_styles 将其导入到 application.css)。
/* Example styles for app/assets/stylesheets/custom_styles.css */body#library-app { font-family: Helvetica, Geneva, Arial, sans-serif; font-size: medium; color: #333; background-color: #f4f4f4; margin: 0; padding: 0;}
#container { width: 960px; margin: 20px auto; background-color: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 0 10px rgba(0,0,0,0.1);}
#main-header h1, #main-header h3 { text-align: center; color: #2c3e50;}
#main-header h1 { margin-bottom: 0; }#main-header h3 { margin-top: 5px; color: #7f8c8d; }
#content { padding: 15px; min-height: 300px; /* Example */}
/* Add more specific styles for your elements */ul#books, ul#subjects-sidebar { list-style-type: none; padding-left: 0;}
ul#books li, ul#subjects-sidebar li { line-height: 1.6; margin-bottom: 5px; padding: 5px; border-bottom: 1px dotted #eee;}
.alert { padding: 10px; margin-bottom: 15px; border: 1px solid transparent; border-radius: 4px;}.alert-notice { background-color: #dff0d8; border-color: #d6e9c6; color: #3c763d; }.alert-alert { background-color: #f2dede; border-color: #ebccd1; color: #a94442; }确保此 CSS 由 Sprockets(或您选择的资产管道工具)处理。如果您创建了 custom_styles.css,请确保 app/assets/stylesheets/application.css 包含了它,例如,如果 application.css 是清单文件,可以使用 *= require custom_styles;如果是 application.scss,可以使用 @import "custom_styles";。
在添加样式后刷新浏览器,您应该会看到应用程序呈现出由您的布局和 CSS 定义的新外观和感觉。
下一步是什么?
Section titled “下一步是什么?”布局提供了一致的外壳。下一章将讨论脚手架(Scaffolding),这是 Rails 的一个特性,可以快速为某个资源生成一套完整的模型(model)、视图(views)、控制器(controller)和路由(routes),这可以作为很好的起点或学习工具。