在 Rails 中显示/隐藏部分/模板的更干燥的方式

Posted

技术标签:

【中文标题】在 Rails 中显示/隐藏部分/模板的更干燥的方式【英文标题】:A more DRY way to show/hide partials/template in rails 【发布时间】:2014-10-07 13:29:34 【问题描述】:

通常推荐的解决方案是父布局文件中的content_for。但这导致必须在每个视图中指定它,因为如果内容不存在于子视图部分中,默认将不显示它。

例如,如果我有一个要隐藏在身份验证页面中的侧边栏,但在其他任何地方都有,我现在必须在除身份验证页面之外的每个视图文件中指定侧边栏的内容。不干燥。

这比以前更麻烦且不枯燥,我可以在布局中渲染侧边栏部分并完成它(但没有选择它在哪里渲染或不渲染的好处)。

如果您能以某种方式在布局模板中指定调用侧边栏部分为不招标,如果它是会话控制器或设计控制器,那就太好了。

有没有办法做到这一点?我试过使用

unless devise_controller?
  render "layouts/sidebar"

但这似乎没有按预期工作。


以 Devise 为例,我有一个这样的 application.html.slim 文件

.row
  main
    .col-sm-9
      = yield
    - unless devise_controller?
      .col-sm-3
        == render 'layouts/sidebar'

暂时忽略这些列。要点是=yield 呈现普通模板以及设计模板。所以我不能在一个 DRY 笔划中选择性地禁用侧边栏。我必须将侧边栏渲染调用放在每个视图文件中,但不要将其包含在我的设计视图中。这并不比在每个非设计视图文件中使用 content_for 更好或更干燥。

回到列,我希望生成的设计视图全宽为 12 列,而不是 9 列。但这只是奖励,不是主要问题。

【问题讨论】:

你可以为认证页面设置一个特殊的布局,你不会呈现侧边栏,不是吗? 如果您指的是设计视图文件,我认为不是。我在 application.html 文件中有一个=yield,它呈现设计视图模板。因此设计视图受制于其父级的样式。让我在 OP 中添加更多代码。 你能提供一些关于你在说什么的细节吗? @Sergio Tulentsev?我不知道它是哪个文件,也不知道你想到了什么设计模式。 我认为您可以继承设计控制器并指定自定义布局。 github.com/plataformatec/devise/wiki/… 【参考方案1】:

如果您坚持检查控制器名称,您可以这样做:

<% if controller.controller_name == 'devise' %>
...
<% else %>
  <%= render 'sidebar' %>
<% end %>

【讨论】:

我只坚持有一个干if条件。这似乎比设计布局更直接。也许我高估了复杂性。 该代码对我不起作用。 devise_controller? 也不起作用的原因肯定是一样的。 您可能需要调整 == '设计部分'。您是否尝试过像这样输出控制器名称 并对其进行检查。此外,它可能是注册控制器。试一试。【参考方案2】:

我只是实现了冗长的做事方式。我将使用一个复杂的示例,因为它可能更有帮助。

在这里,我设置了完整的案例,这取决于我是否需要侧边栏,主要是因为引导列和行的工作方式。如果您使用的是引导程序,您会注意到,一旦您阻止侧边栏呈现,您将剩下的主要内容不会占用侧边栏不再占用的空间。这是因为您之前必须将侧边栏和主要内容放在特定的列宽中,并且放在一行中(以便它们并排显示)。由于您希望在侧边栏消失时填充主要内容并占据整个宽度,因此在这种情况下您必须应用完全不同的列宽。因此完整的 if - else 语句。

因此,像这样实现它,确保在每个主要生成的视图文件中包含 .rows.col-*-*

application.html

  - if hide_sidebar?
    main
      = yield
  - else
    .row
      .col-xs-12.col-sm-9
        main
          = yield
      .col-xs-12.col-sm-3
        == render 'layouts/sidebar'

如果您希望拥有或不拥有侧边栏的页面列表变得比某个控制器的所有操作更复杂,请实现一个单独的辅助方法来指定所有条件。

这是在控制器中执行此操作的一种方法。在我的示例中,当它是注册控制器和用户控制器的显示操作时,我想隐藏侧边栏。我只是在辅助方法中 || 输出。

application_helper.rb

def want_sidebar?
  (controller_name == 'registrations') || ( (controller_name == 'users') && action_name == 'show' )
end

【讨论】:

以上是关于在 Rails 中显示/隐藏部分/模板的更干燥的方式的主要内容,如果未能解决你的问题,请参考以下文章

在编辑视图中保留实体密钥的更安全方法?

您如何在 Rails 3.1 中使用 Sprockets 编写干燥的模块化咖啡脚本?

rails:保持干燥,达到什么水平? [关闭]

如何在 Rails 中对常用视图代码进行分组和干燥

使用嵌套资源干燥 Rails 视图

在Rails 5.1模板中显示pg_search的循环计数