所以我有一个rails管理系统,允许用户选择一个主题,基本上是一组SASS颜色变量,它们将使用新颜色重新编译application.css.scss。当用户从下拉列表中选择并提交时,如何才能更改此更改?我读了一些关于缓存和重新编译的问题,但我并不完全清楚如何设置它。
目前我有..
application.css.scss
@import "themes/whatever_theme";
@import "common";
@import "reset";
@import "base";
主题/ _whatever_theme
$theme_sprite_path: '/images/sprite_theme_name.png';
$main_color:#009DDD;
$secondary_color:#b3d929;
$light_background:#f2f2f2;
$border_line:#e6e6e6;
$off_white:#f9f9f9;
$white:#ffffff;
$font_body:#565b59;
$font_headers:#363a36;
假设我有5个不同的主题,用户将在它们之间切换,为Rails中的每个主题设置变量名称然后将它们传递给SASS并在运行中更改它们并重新编译将会很不错。这是解决这个问题的最好方法吗?
答案 0 :(得分:11)
3个简单的步骤:
部署后将所有主题编译为不同的文件。这将负责时间戳,压缩等。
使用默认主题渲染页面。
使用javascript加载备用主题CSS。
不需要乱用动态编译等等。
要动态加载CSS,您可以使用以下内容:
function loadCSS(url) {
var cssfile = document.createElement("link");
cssfile.setAttribute("rel", "stylesheet");
cssfile.setAttribute("type", "text/css");
cssfile.setAttribute("href", url);
}
答案 1 :(得分:8)
塞尔吉奥的回答是有效的,但省略了时髦的细节,我采用了稍微不同的方法。
你在Rails中使用SASS-不要对抗当前的Railsy并让资产管道预编译所有的CSS。除非您尝试使用数百个主题进行CSSZenGarden之类的极端操作,或者每个主题数千行,否则我建议您将每个主题设置为拥有CSS类而不是它自己的文件。
$(".ThemedElement").removeClass([all your themes]).addClass("MyLittlePonyTheme");
ThemedElement
类您也可以只更改顶级元素上的类并自由使用继承和!important
声明,但我发现其他方法更易于维护。
如果您认为可以使用类而不是文件来管理主题,那么我们将使用SASS生成它们。 SASS不支持json样式对象,所以我们必须回过头来设置一堆带有主题属性的并行数组。然后我们迭代每个主题,将动态属性替换为自动生成的主题类,然后你就参加了比赛:
<强> themes.css.scss 强>
@import "global.css.scss";
/* iterate over each theme and create a CSS class with the theme's properties */
@for $i from 1 through 4{
/* here are the names and dynamic properties for each theme class */
$name: nth(("DefaultTheme",
"MyLittlePonyTheme",
"BaconTheme",
"MySpaceTheme"
), $i);
$image: nth(("/assets/themes/bg_1.png",
"/assets/themes/bg_2.png",
"/assets/themes/bg_3.png",
"/assets/themes/bg_4.png"
), $i);
$primary: nth((#7ca8cb,
#3c6911,
#d25d3a,
#c20d2c
), $i);
$font: nth((Rosario,
Helvetica,
Comic Sans,
WingDings
), $i);
/* Now we write our Theme CSS and substitute our properties when desired */
.#{$name}{
&.Picker{
background-image:url($image);
}
color: $primary;
.BigInput, h1{
color: $primary;
font-family: $font, sans-serif !important;
}
.Frame{
background-image:url($image);
}
.Blank:hover{
background-color:mix('#FFF', $primary, 90%) !important;
}
.BigButton{
background-color:$primary;
@include box-shadow(0,0,10px, $primary);
}
/* and so on... */
}
这有点像黑客,但它对我们很有帮助。如果你的主题很复杂,或者你的主题太多,那么维护起来会更加痛苦。
答案 2 :(得分:2)
一个选项是在application.css之后简单地加载一组自定义CSS规则(您的主题),并让您的主题覆盖application.css中的默认颜色。你可以添加一个数据库列“theme”并动态加载带有这个名字的css,如。
SASS不是为动态编译动态数据而设计的。如果你想要动态css处理,你可以添加一个名为“custom_css”的控制器方法,并使其响应css格式并使用内联变量动态加载它,但我认为SASS根本不用于它。
答案 3 :(得分:1)
我相信你可以使用erb在sass中内联变量。我不是积极的,但我认为它看起来像这样:
主题/ _whatever_theme.sass.erb
$theme_sprite_path: '<%= Theme.sprite_path %>';
$main_color: <%= Theme.main_color %>;
$secondary_color: <%= Theme.secondary_color %>;
应为每个页面加载动态创建这些内容。我不确定缓存在这里是如何工作的。