Как создать пользовательский CSS "на лету" на основе настроек учетной записи на сайте Django?
Итак, я пишу сайт на основе Django, который позволяет пользователям выбирать цветовую схему через интерфейс администрирования.
У меня уже есть промежуточные/контекстные процессоры, которые связывают текущий запрос (на основе домена) с учетной записью.
Мой вопрос заключается в том, как динамически обслуживать CSS с пользовательской цветовой схемой.
Я вижу два варианта:
-
Добавить блок CSS в базовый шаблон, который переопределяет стили w/variables, передаваемые через контекстные процессоры.
-
Используйте настраиваемый URL (например, "/static/dynamic/css/< website_id > /styles.css" ), который перенаправляется в представление, которое захватывает все необходимые значения и создает файл css.
Я согласен с любым вариантом, но мне было интересно, есть ли у кого-то еще проблемы с подобными проблемами и может дать некоторое представление о "лучших практиках".
Обновление. Я склоняюсь к варианту номер 2, так как я думаю, что это позволит лучше кэшировать дорогу. Таким образом, он динамический в первый раз, хранится в memcache (или что-то еще) и недействителен, когда пользователь обновляет свои настройки на сайте администратора.
Обновление. Во-первых, я хотел бы поблагодарить всех за их предложения. Все ответы до сих пор были сосредоточены на создании статических файлов. Хотя это будет отлично работать в производстве, оно ощущается как огромное бремя во время развития. Если бы я хотел добавить новый элемент в стиле или изменить существующие стили, мне пришлось бы пройти и воссоздать каждый файл css. Конечно, это можно сделать с помощью команды управления, но я просто не считаю, что это того стоит. Выполняя его динамически, вы добавили бы 1, возможно, 2 запроса к каждой загрузке страницы, на что я не беспокоюсь на этом этапе. Все, что мне нужно знать, это то, что в какой-то момент я смогу кэшировать его, не переписывая все это.
Ответы
Ответ 1
Я успешно использовал вариант №2. Есть два достойных способа обновления созданных статических файлов, о которых я знаю:
-
Используйте версию запроса, например /special _path.css?v=11452354234, где параметр v создается из поля базы данных, ключа в memcached или какого-либо другого постоянного файла. Версия обновляется администратором, или для разработки вы просто должны заставить генерацию не сохранять, если параметр был чем-то особенным, например v = -1. Вам понадобится процесс для очистки старых поколений через некоторое время.
-
Не используйте верификацию версии, но сначала посмотрите на сгенерированный файл, если он не может найти его, он генерирует его. Вы можете создать задание cron или приложение WSGI, которое ищет изменения в файловой системе для разработки, и у вас есть крючок с панели администратора, которая удаляет поколения после обновления. Вот пример мониторинга, который вам нужно будет преобразовать, чтобы быть конкретным для ваших поколений, а не для Django. http://code.google.com/p/modwsgi/wiki/ReloadingSourceCode#Monitoring%5FFor%5FCode%5FChanges
Ответ 2
Хороший вопрос.
Я бы предложил предварительно создать файл css после сохранения схемы цветов. Это окажет положительное влияние на кеширование и общее время загрузки страницы. Вы можете хранить ваши файлы css в каталоге /media/css/custom/<id or stometing>/styles.css
или /media/css/custom/<id or sth>.css
, а в шаблоне добавить <link rel="stylesheet" href="/media/css/custom/{{some_var_pointing _to_file_name}}" />
Вы также можете сделать трюк с некоторым случайным числом или датой в имени файла css, который можно было бы изменить каждый раз, когда файл будет сохранен. Благодаря этому браузер сразу же загрузит файл в случае изменений.
UPDATE: пример использования модели для улучшения этого примера
Чтобы упростить управление этими файлами, вы можете создать простую модель (по одному на каждого пользователя):
class UserCSS(models.Model):
bg_color = models.CharField(..)
...
...
Поля (например, bg_color) могут представлять части вашего файла css. Вы можете ovveride save
метод добавить логику, которая создает файл css для пользователя (путем рендеринга некоторого шаблона).
В случае изменения формата файла вы можете внести изменения в определение модели (с некоторыми значениями по умолчанию для новых полей), внести небольшие изменения в шаблон и запустить метод сохранения для каждого экземпляра exisintg класса. Это обновит ваши файлы css.
Это должно хорошо работать.
Ответ 3
Может генерировать css и хранить его в текстовом поле в той же модели, что и профиль пользователя/настройки. Тогда вы можете создать их, если вы измените стиль. Затем сделайте свой вариант 1 выше.
Ответ 4
Я бы создал ключ md5 с элементами темы, сохранил этот ключ в профиле пользователя и создал ccs файл с именем после этого ключа md5: вы получаете статический доступ к файлам и автоматическое обнаружение изменений темы.