我想制作一个 Rails 应用程序,让用户输入数据,然后允许他们更改页面的主题。这样,他们的数据可以根据他们选择的主题进行不同的样式设置。我该怎么做呢?
- 更改样式表?
- 具有不同类/元素的两个独立视图?
- 动态地改变类/ID/选择器?
- ?
谢谢
我想制作一个 Rails 应用程序,让用户输入数据,然后允许他们更改页面的主题。这样,他们的数据可以根据他们选择的主题进行不同的样式设置。我该怎么做呢?
谢谢
为站点设置主题的最简单方法是简单地链接到不同的样式表。您可以使用以下方法动态执行此操作:
# in app/views/layouts/application.html.erb
<%= stylesheet_link_tag :application %>
<%= stylesheet_link_tag #{current_theme} %>
# in app/helpers/application_helper
def current_theme
# You'll have to implement the logic for a user choosing a theme
# and how to record that in the model.
# Also, come up with a better name for your default theme, like 'twentyeleven' ;)
current_user.theme || 'default'
end
然后你可以有几个主题清单。例如,您的资产目录可能如下所示:
这将使您开始使用纯 CSS 主题。在某些时候,您可能还想要它们的 javascript 和 html 布局。当您开始发现需要在 html 中执行以下操作时:
<% if current_theme == 'theme1' %>
<li>...
<% elsif current_theme == 'theme2' %>
<b>...
<% end %>
那么是时候实现一个更强大的主题框架了:
render_themed_partial
注意:这都是针对静态主题的。对于动态主题(例如管理员可以登录和编辑样式表或 html),您必须将主题信息存储在数据库中。根据您的架构,您可以提供一组静态主题,然后提供另一个从数据库中动态获取样式数据的主题。但是,此时您正在开发一个 CMS,因此它超出了此答案的范围:)
如果我们为每个主题创建不同的样式表并进行小的更改,那么我们需要在所有样式表中进行相同的更改。真的会很头疼。另一种方法是使用 SASS 概念(mixins)。
添加你的 Gemfile
gem 'sass-rails'
然后
bundle install
现在您需要在一个 SCSS 文件中包含您的 css 样式。 basic_styles.scss
$font_color: #565656;
$font-size: 13px;
$success-color: #088A08;
$error-color: #B40404;
@mixin basic_styles($dark_color,$light_color,$bullet_image)
{
.footer
{
background-color: rgba($dark_color,0.9);
color: $light_color;
text-align: center;
position: fixed;
bottom:0;
left:0;
width: 100%;
height: 15px;
border-top: 1px solid lighten($dark_color, 9%);
padding-left: 10px;
padding-right: 10px;
font-size: $font_size - 2;
}
h3,hr,a,input
{
color: $dark_color;
}
h3
{
margin-top: 2px;
margin-bottom: 2px;
}
hr {
border-color: lighten($dark_color, 30%) -moz-use-text-color #FFFFFF;
border-left: 0 none;
border-right: 0 none;
border-style: solid none;
border-width: 1px 0;
}
.btn
{
background-color: $dark_color;
border-color: darken($dark_color, 15%);
border-radius: 4px 4px 4px 4px;
border-style: solid;
border-width: 1px;
color: #FFFFFF;
cursor: pointer;
display: inline-block;
line-height: 18px;
padding: 3px 10px 3px 10px;
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.25);
vertical-align: middle;
}
.btn:hover
{
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.75);
-moz-box-shadow: 0px 0px 2px 1px lighten($dark_color, 10%);
-webkit-box-shadow: 0px 0px 2px 1px lighten($dark_color, 10%);
box-shadow: 0px 0px 2px 1px lighten($dark_color, 10%);
}
.success
{
color: $success-color;
}
.error
{
color: $error-color;
}
}
然后,您可以创建任意数量的主题。例如Theme_Blue.scss
@import "basic_styles";
$dark_color: #08c;
$light_color: #FFFFFF;
$bullet_image: 'bullet_blue.png';
@include basic_styles($dark_color,$light_color,$bullet_image);
现在在你的 html 中
<%= stylesheet_link_tag "Theme_Blue" %>
将使用basic_styles.scss中指定的所有 css 类和蓝色。
您可以添加任意数量的主题文件,例如Theme_Blue.scss。并更改为
<%= stylesheet_link_tag current_user.theme %>
这样,您只需要修改basic_styles.scss即可进行任何修改。
我设法从 Chamnap 的答案中提取了精髓(由于某种原因它不起作用 - 也许是 Rails 的版本?)。
class ApplicationController < ActionController::Base
layout :layout_selector
def layout_selector
# puts "*** layout_selector #{session.to_json}"
name = ['bootstrap', 'mytheme'][session[:theme].to_i]
# puts "*** loading theme #{name}"
prepend_view_path "app/themes/#{name}/views"
name
end
你可以在这里阅读它:
您可能必须添加到资产路径和预编译列表(或者使用 gem 而不使用theme
方法)。
Dir.glob("#{Rails.root}/app/themes/*/assets/*").each do |dir|
config.assets.paths << dir
end
config.assets.precompile += [ Proc.new { |path, fn| fn =~ /app\/themes/ && !%w(.js .css).include?(File.extname(path)) } ]
config.assets.precompile += Dir["app/themes/*"].map { |path| "#{path.split('/').last}/all.js" }
config.assets.precompile += Dir["app/themes/*"].map { |path| "#{path.split('/').last}/all.css" }
请记住在具有主题名称的子目录中包含 JS 和图像。它们在服务器上可能是分开的,但对于浏览器和缓存来说,/images/logo.png
这两个主题看起来是一样的。所以你必须使用/images/theme1/logo.png
and /images/theme2/logo.png
。