我找到了一个似乎运行良好的解决方案。如果您有一堆非常大的主题,我可以看到这种方法可能不实用,因为它会预编译每个主题。但是,我发现这对我的项目来说是一个很好的解决方案。如果有人发现任何潜在的问题,我很想听听他们的意见,因为我对其中的一些内容还有些陌生,并且不想打破常规......
我的样式表文件夹如下所示:
app/assets/stylesheets/
_forms.scss
_layout.scss
_manifest.scss
_mixins.scss
_tables.scss
_utilities.scss
light_theme.scss
dark_theme.scss
我已将我的所有组件分成多个部分以进行组织。 “_manifest.scss”文件为我的主题导入了我所有的组件。
app/assets/stylesheets/_manifest.scss
// ---------------- Import all CSS components ----------------
@import 'bootstrap';
@import 'utilities';
@import 'layout';
@import 'tables';
@import 'forms';
我为每个主题制作了一个 .scss 文件,顶部的颜色变量然后导入清单。请注意,使用相同的变量名称,以便轻松换出。
app/assets/stylesheets/light_theme.scss
// ---------------- LIGHT THEME ----------------
// Theme Colors
$light: #f4f3ef;
$medium: #9a9a9a;
$dark: #252422;
$ocean: #36414f;
$accent: cadetblue;
$red: #ed4033;
$orange: #ff8c65;
$yellow: #f4ba58;
$green: #76c29d;
$blue: #65b4c6;
// Import all components
@import 'manifest';
app/assets/stylesheets/dark_theme.scss
// ---------------- DARK THEME ----------------
// Theme Colors
$light: #d5d6fa;
$medium: #9e9ed6;
$dark: #0d1118;
$ocean: #1f2c44;
$accent: #806df3;
$red: #f24e77;
$orange: #f2a23b;
$yellow: #f2c54a;
$green: #34d07e;
$blue: #2c8fef;
// Import all components
@import 'manifest';
我在我的 CSS 框架中使用 bootstrap,所以我的大部分颜色特定的 css 都是通过像“btn-blue”“text-orange”这样的类来设置的。这样,当我想切换主题时,我可以筛选和更改更少的代码。文本橙色仍然是橙色,只是深色主题上的橙色较亮,浅色主题上的橙色是柔和的橙色,这就是为什么简单的变量交换如此必要的原因。
有些元素需要特别标注,所以我也为每个主题使用了一个 body 类。这让您可以针对特定主题进行更改。
app/assets/stylesheets/_layout.scss
body.light_theme {
background-color: $light;
color: $dark;
}
body.dark_theme {
background-color: $lake;
color: $white;
}
接下来我希望我的用户能够设置自己的主题。我创建了一个迁移,在我的用户表中添加了一列:
class AddThemeToUsers < ActiveRecord::Migration[5.1]
def change
add_column :users, :user_theme, :string
end
end
在我的用户表单上,他们可以通过下拉菜单选择他们的主题。您的选择选项在这里很重要,因为名称会变成变量,因此请保持命名一致。
app/views/users/_form.html.erb
<div class="form-group">
<%= form.label :user_theme, 'Theme' %>
<%= form.select :user_theme, ['Light Theme', 'Dark Theme'], class: 'form-control' %>
</div>
现在我在应用程序控制器中设置我的主题。如果用户已登录,则使用他们的主题设置,否则默认为 Light Theme。如果您将 user_theme 行添加到 existing 用户表,请确保在添加以下内容之前运行迁移以为每个用户设置默认主题,否则您将收到错误,因为该单元格为空。或者添加一些代码来检查 current_user.user_theme 是否为空,然后默认为另一个主题。 (可能更好...)
application_controller.rb
class ApplicationController < ActionController::Base
before_action :set_theme
private
def set_theme
if current_user
@user_theme = current_user.user_theme.parameterize.underscore
else
@user_theme = 'light_theme'
end
end
end
在布局文件中,我将主题作为一个类添加到正文中:
app/views/layouts/application.html.erb(布局文件)
<body class="<%= @user_theme %>">
...
</body>
您可能会遇到另一个问题,如果您遇到资产编译错误,请将其添加到您的 config/intitializers/assets.rb 中,为每个主题文件添加一个。
Rails.application.config.assets.precompile += %w( dark_theme.css )
Rails.application.config.assets.precompile += %w( light_theme.css )