Переключение пользовательских тем с SASS - Ruby on Rails - PullRequest
9 голосов
/ 05 января 2012

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

В настоящее время у меня есть ..

application.css.scss

@import "themes/whatever_theme";
@import "common";
@import "reset";
@import "base";

themes / _whwhat_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 ]

11 голосов
/ 05 января 2012

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

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

  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);
}
8 голосов
/ 05 января 2012

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

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

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

Вы можете в качестве альтернативы просто изменить класс вашего элемента верхнего уровня и свободно использовать наследование и!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 голосов
/ 05 января 2012

Один из вариантов - просто загрузить набор пользовательских правил css (вашей темы) после вашего application.css и позволить вашей теме переопределить цвета по умолчанию из application.css. Вы можете просто добавить столбец базы данных «theme» и загрузить css с этим именем динамически, как.

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

1 голос
/ 05 января 2012

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

themes / _whwhat_theme.sass.erb

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...