Переключение темы пользователя с помощью Sass-Ruby on Rails

поэтому у меня есть система администрирования rails, которая позволит пользователю выбрать тему, в основном набор переменных цвета SASS, которые будут перекомпилировать приложение.стиль CSS.СКС с новыми цветами. Как было бы лучше всего изменить это, когда пользователь выбирает из раскрывающегося списка и отправляет? Я прочитал некоторые проблемы с кэшированием и перекомпиляцией, но я не совсем понимаю, как его настроить.

В Настоящее Время I иметь..

приложение.стиль 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 и изменить их на лету и перекомпилировать. Это лучший способ сделать это?

4 ответов


3 простых шага:

  1. скомпилируйте все темы в разные файлы после развертывания. Это позаботится о timestamping, zipping и т. д.

  2. страница рендеринга с темой по умолчанию.

  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);
}

ответ Серхио действителен, но опускает нахальные детали, и я использовал немного другой подход.

вы используете SASS в Rails-не боритесь с текущим, будьте Railsy и позвольте конвейеру активов предварительно скомпилировать все ваши CSS. Если вы не пытаетесь сделать что-то экстремальное, как CSSZenGarden С сотни темы, или каждая тема тысячи строк Я бы рекомендовал установить каждую тему как собственный класс CSS, а не собственный файл.

  • 1kb дополнительного CSS в отображаемом приложении.CSS-файл не увязнуть пользователи
  • легко переключать тематические классы с помощью JQuery:$(".ThemedElement").removeClass([all your themes]).addClass("MyLittlePonyTheme");
  • как подразумевается, вам придется пометить элементы, которые вы хотите обновить с помощью ThemedElement класс

вы могли бы также просто изменить класс на элемент верхнего уровня и сделать либеральное использование наследования и !important декларация, хотя я нахожу другой подход более ремонтопригодный.

если вы думаете, что можете управлять своими темами с помощью классов, а не файлов, вот как мы генерируем их с помощью SASS. SASS не поддерживает объекты стиля json, поэтому мы должны вернуться назад и настроить кучу параллельных массивов со свойствами темы. Затем мы перебираем каждую тему, подставляем динамические свойства В автоматически созданный класс темы, и вы переходите к гонки:

темы.стиль 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... */
       }

это немного хак, но он служил нам очень хорошо. Если ваши темы uber сложны или у вас их слишком много, становится более болезненным поддерживать.


один из вариантов-просто загрузить набор пользовательских правил css (ваша тема) после вашего приложения.css и пусть ваша тема переопределяет цвета по умолчанию из приложения.стиль CSS. Вы можете просто добавить столбец базы данных "тема" и динамически загрузить css с этим именем.

SASS не предназначен для компиляции динамических данных на лету. Если вы хотите динамическую обработку css, вы можете добавить метод контроллера под названием "custom_css" и заставить его реагировать на формат css и загрузить это динамически с встроенными переменными, но я не думаю, что SASS предназначен для его использования вообще.


Я считаю, что вы можете использовать erb для встроенных переменных в sass. Я не уверен, но я думаю, это будет выглядеть примерно так:

темы/_whatever_theme.дерзость.Эрб

$theme_sprite_path: '<%= Theme.sprite_path %>';
$main_color: <%= Theme.main_color %>;
$secondary_color: <%= Theme.secondary_color %>;

они должны создаваться динамически при каждой загрузке страницы. Я не уверен, как кэширование будет работать здесь.