#125 Dynamic Layouts

本文介绍了一种使用数据库内容动态更改布局的方法。通过Rails应用实现,可根据不同博客定制化显示样式。利用Liquid模板引擎解析自定义布局内容,并提供了一个线程安全的布局加载方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Discover how to dynamically change the layout using content in the database. Check out this episode for details.

script/generate migration add_layout_to_blogs layout_name:string custom_layout_content:text
rake db:migrate
gem install liquid

# controllers/application.rb
def load_blog
@current_blog = Blog.find_by_subdomain(current_subdomain)
if @current_blog.nil?
flash[:error] = "Blog invalid"
redirect_to root_url
else
self.class.layout(@current_blog.layout_name || 'application')
end
end

# config/environment.rb
config.gem 'liquid'

<!-- layouts/custom.html.erb -->
<%= Liquid::Template.parse(@current_blog.custom_layout_content).
render('page_content' => yield, 'page_title' => yield(:title)) %>

<!-- blogs/_form.html.erb -->
<p>
<%= f.label :layout_name %><br />
<%= f.select :layout_name, [["Standard", 'application'], ["Plain", 'plain'], ["Custom", 'custom']] %>
</p>
<p>
<%= f.label :custom_layout_content %><br />
<%= f.text_area :custom_layout_content, :rows => 12 %>
</p>


UPDATE: As Pratik mentioned in the comments, the above code is not thread safe. Here is a better way to handle the layout which is thread safe.

# application.rb
layout :set_layout

def load_blog
@current_blog = Blog.find_by_subdomain(current_subdomain)
if @current_blog.nil?
flash[:error] = "Blog invalid"
redirect_to root_url
end
end

def set_layout
(@current_blog && @current_blog.layout_name) || 'application'
end
按照上文修改后,点击登录浏览器控制台打印: dynamic.js:29 [Vue Router warn]: Parent route "manage" not found when adding child route {path: &#39;manage/index&#39;, name: &#39;-manage-index&#39;, meta: {…}, component: ƒ} Login.vue:84 失败日志: Login.vue:85 Error: Route paths should start with a "/": "manage/index" should be "/manage/index". at tokenizePath (vue-router.js?v=42376a9b:961:11) at createRouteRecordMatcher (vue-router.js?v=42376a9b:1071:33) at Object.addRoute (vue-router.js?v=42376a9b:1140:17) at Object.addRoute (vue-router.js?v=42376a9b:2366:20) at dynamic.js:29:18 at Array.forEach (<anonymous>) at addRoutes (dynamic.js:13:11) at addDynamicRoutes (dynamic.js:39:3) at login (Login.vue:78:7) 终端打印: [vite] (client) warning: invalid import "../${menu.component}". A file extension must be included in the static part of the import. For example: import(`./foo/${bar}.js`). Plugin: vite:dynamic-import-vars File: D:/companyProject/road-system-pc/src/router/dynamic.js 09:49:54 [vite] (client) warning: D:/companyProject/road-system-pc/src/router/dynamic.js 16 | path: menu.path.startsWith(&#39;/&#39;) ? menu.path.slice(1) : menu.path, 17 | name: menu.path.replace(/\//g, &#39;-&#39;), 18 | component: () => import(`@/${menu.component}`), | ^^^^^^ 19 | meta: { | ^^^^^^^^^^^^^^^ 20 | title: menu.name, The above dynamic import cannot be analyzed by Vite. See https://github.com/rollup/plugins/tree/master/packages/dynamic-import-vars#limitations for supported dynamic import formats. If this is intended to be left as-is, you can use the /* @vite-ignore */ comment inside the import() call to suppress this warning. Plugin: vite:import-analysis File: D:/companyProject/road-system-pc/src/router/dynamic.js
03-22
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值