如何为 page_layout 设置自定义控制器
how to set custom controller for page_layout
我正在尝试为 page_layout 设置我自己的控制器,因为我想覆盖操作以将其他模型放入视图中。
编辑: 前端渲染现在可用。只有后端有问题
根据文档,我做了:
# config/alchemy/page_layouts.yml
- name: index
unique: true
elements: [article, other_element]
autogenerate: [article]
controller: 'my_custom'
action: 'index'
并创建了 app/controllers/my_custom_controller.rb
:
# app/controllers/my_custom_controller.rb
class MyCustomController < Alchemy::PagesController
def index
@some_values = Value.all
end
end
我的 routes.rb 看起来像这样:
Rails.application.routes.draw do
root 'my_custom#index'
devise_for :users,
path_names: { sign_in: 'login', sign_out: 'logout' },
controllers: { sessions: 'users/sessions', passwords: 'users/passwords' }
mount Alchemy::Engine => '/'
根页面在 alchemy 中有 page_type 索引。
当我去localhost:3000
时,我得到了我想要的
但是在 alchemy 后端,编辑页面时,渲染时出现错误:
NoMethodError in Alchemy::Admin::Pages#show
Showing app/views/alchemy/elements/_some_element_view.html.erb where line #2 raised:
undefined method `each' for nil:NilClass
Extracted source (around line #2):
<div class="row">
<% for @value in @some_values %>
<%= render 'value/basic_view' %>
<% end %>
</div>
可能是因为 @some_values 没有初始化,这意味着我的控制器没有用来渲染它。
我做错了什么吗?
Edit2:也许我完全走错了路。我想要一个 Alchemy-Element,它可以从数据库(自定义模型)中呈现内容。我所做的是,创建一个元素,呈现@some_values。通过在可以放置此元素的每个页面类型上指定我的自定义控制器,我允许我的编辑将那些 @some_values 放在他们想要的地方。
看起来这不是您想要的正确方法。出于路由原因,引入了页面布局的自定义控制器。这样编辑器就可以管理自定义控制器的导航。它们不是用来装饰默认元素和页面呈现的。
您可能想要的是 on_page_layout
回调:http://www.rubydoc.info/github/AlchemyCMS/alchemy_cms/Alchemy/OnPageLayout
你的情况:
class ApplicationController < ActionController::Base
extend Alchemy::OnPageLayout
on_page_layout :foo do
@some_values = Value.all
end
end
或者,更简单的方法是,在元素视图中加载值。有点 PHPish,但还可以。
编辑:
从性能的角度来看,在您的控制器中使用低级 rails 缓存是一个很好的做法:
...
on_page_layout :foo do
@some_values = Rails.cache.fetch('some/cache/key', expires_in: 10.minutes) do
Value.all
end
end
...
我正在尝试为 page_layout 设置我自己的控制器,因为我想覆盖操作以将其他模型放入视图中。
编辑: 前端渲染现在可用。只有后端有问题
根据文档,我做了:
# config/alchemy/page_layouts.yml
- name: index
unique: true
elements: [article, other_element]
autogenerate: [article]
controller: 'my_custom'
action: 'index'
并创建了 app/controllers/my_custom_controller.rb
:
# app/controllers/my_custom_controller.rb
class MyCustomController < Alchemy::PagesController
def index
@some_values = Value.all
end
end
我的 routes.rb 看起来像这样:
Rails.application.routes.draw do
root 'my_custom#index'
devise_for :users,
path_names: { sign_in: 'login', sign_out: 'logout' },
controllers: { sessions: 'users/sessions', passwords: 'users/passwords' }
mount Alchemy::Engine => '/'
根页面在 alchemy 中有 page_type 索引。
当我去localhost:3000
时,我得到了我想要的
但是在 alchemy 后端,编辑页面时,渲染时出现错误:
NoMethodError in Alchemy::Admin::Pages#show
Showing app/views/alchemy/elements/_some_element_view.html.erb where line #2 raised:
undefined method `each' for nil:NilClass
Extracted source (around line #2):
<div class="row">
<% for @value in @some_values %>
<%= render 'value/basic_view' %>
<% end %>
</div>
可能是因为 @some_values 没有初始化,这意味着我的控制器没有用来渲染它。 我做错了什么吗?
Edit2:也许我完全走错了路。我想要一个 Alchemy-Element,它可以从数据库(自定义模型)中呈现内容。我所做的是,创建一个元素,呈现@some_values。通过在可以放置此元素的每个页面类型上指定我的自定义控制器,我允许我的编辑将那些 @some_values 放在他们想要的地方。
看起来这不是您想要的正确方法。出于路由原因,引入了页面布局的自定义控制器。这样编辑器就可以管理自定义控制器的导航。它们不是用来装饰默认元素和页面呈现的。
您可能想要的是 on_page_layout
回调:http://www.rubydoc.info/github/AlchemyCMS/alchemy_cms/Alchemy/OnPageLayout
你的情况:
class ApplicationController < ActionController::Base
extend Alchemy::OnPageLayout
on_page_layout :foo do
@some_values = Value.all
end
end
或者,更简单的方法是,在元素视图中加载值。有点 PHPish,但还可以。
编辑:
从性能的角度来看,在您的控制器中使用低级 rails 缓存是一个很好的做法:
...
on_page_layout :foo do
@some_values = Rails.cache.fetch('some/cache/key', expires_in: 10.minutes) do
Value.all
end
end
...