Переменные less.css, инициализированные из базы данных

Я использую dotnetless (http://www.dotlesscss.org/) для приложений asp.net для веб-форм, и он отлично работает. Мне нравится использовать переменные для цветов, шрифтов и т.д. Но насколько я могу видеть, переменные значения являются статическими.

Можно ли использовать dotnetless для инициализации этих значений переменных из базы данных в зависимости от пользователя?

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

Приветствуется любое направление.

Ответ 1

Это определенно возможно, но, к сожалению, вы не можете запросить свою базу данных с самого LESS, поэтому вам в основном нужно написать LESS файл для пользователя с необходимыми значениями переменных, а затем загрузить его.

Вы можете найти пример из другого ответа здесь: fooobar.com/questions/488268/...

Ответ 2

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

Вы можете посмотреть Bundle Transformer LESS проект, который делает меньше перевода, используя бесчисленные. У него также есть IHttpHandler, от которого вы могли бы основываться.

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

Edit: Основная начальная точка для обработчика

public class LessHandler : IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
        var request = context.Request;
        var response = context.Response;
        var user = context.User;

        string assetUrl = request.Url.LocalPath;
        string assetPath = context.Server.MapPath(assetUrl);

        //load less file into the data.
        var data = "";
        using (var file = new StreamReader(assetPath))
        {
            data = file.ReadToEnd();
        }

        DotlessConfiguration lessEngineConfig = DotlessConfiguration.GetDefault();
        lessEngineConfig.MapPathsToWeb = false;
        lessEngineConfig.CacheEnabled = false;
        lessEngineConfig.DisableUrlRewriting = false;
        lessEngineConfig.Web = false;
        lessEngineConfig.MinifyOutput = true;
        lessEngineConfig.LessSource = typeof(VirtualFileReader);
        var lessEngineFactory = new EngineFactory(lessEngineConfig);
        ILessEngine lessEngine = lessEngineFactory.GetEngine();

        string vars = "";
        //TODO set default for vars
        if (user != null)
        {
            //TODO get vars for user
        }

        var content = lessEngine.TransformToCss(string.Format("{0}{1}", vars, data), null);

        // Output text content of asset
        response.ContentType = "text/css";
        response.Write(content);
        response.End();
    }

    public bool IsReusable
    {
        get { return true; }
    }
}

Ответ 3

Почему бы не создать настраиваемый плагин .LESS с функциями для выполнения необходимого поиска?

Код ниже был проверен, как показано. Я фактически не ищу данные в БД, но для этого должна быть доступна вся необходимая информация. Я подтвердил, что при работе в режиме проверки подлинности Windows на веб-сайте я смог получить текущего пользователя через HttpContext.Current.User.Identity.Name.

Чтобы использовать приведенную ниже функцию, вы должны ввести что-то вроде ниже в своем меньшем файле:

--lookup using custom function (hit db)
@brand_color:getCustomColor(usersThemeAttribute);

--then use the variable like normal
color: @brand_color;

код

[DisplayName("UserProfilePlugin")]
public class UserProfilePlugin : IFunctionPlugin
{
    public Dictionary<string, Type> GetFunctions()
    {
        return new Dictionary<string, Type> 
        {
            { "getCustomColor", typeof(GetCustomColorFunction) }
        };
    }
}

public class GetCustomColorFunction : Function
{
    protected override Node Evaluate(Env env)
    {
        Guard.ExpectNumArguments(1, Arguments.Count(), this, Location);
        Guard.ExpectNode<Keyword>(Arguments[0], this, Arguments[0].Location);
        //the idea is that you would have many colors in a theme, this would be the name for a given color like 'bgColor', or 'foreColor'
        var colorAttrName = Arguments[0] as Keyword;

        //Lookup username
        // string username = HttpContext.Current.User.Identity.Name;

        //perform some kind of DB lookup using the username, get user theme info
        // UserProfile up = new UserProfile();
        // System.Drawing.Color c = up.GetColorByAttribute(colorAttrName.Value);
        //return the appropriate color using RGB/etc...
        // return new Color(c.R, c.G, c.B);
        return new Color(129, 129, 129);
    }
}

Чтобы зарегистрировать плагин, добавьте его в web.config:

<dotless cache="false" >
    <plugin name="UserProfilePlugin" assembly="Your.Assebly.Name" />
</dotless>

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

Ссылка: https://github.com/dotless/dotless/wiki/FunctionPlugins

Ответ 4

Самое простое решение, вероятно, заключается в том, чтобы встроить ваш код LESS на свои веб-страницы: (как объяснено здесь)

<html>
  <head>
    <style type="text/less">
      // DB and user-dependent code here
    </style>
  </head>
  ...
</html>

Таким образом, вы можете настроить свои таблицы стилей LESS так же, как вы настраивали бы свои веб-страницы.

Если вы хотите использовать CSS с бесчисленным множеством, вы можете передать свои настроенные таблицы стилей в бесцельный парсер:

Less.Parse(".foo { font-size: <user-dependent-value>;}")

Затем вам нужно включить скомпилированный вывод CSS непосредственно на вашу веб-страницу:

<html>
  <head>
    <style type="text/css">
      // result of Less.Parse(...)
    </style>
  </head>
  ...
</html>

Ответ 5

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

Но если вы разрешаете каждому пользователю настраивать тему, чтобы было много (или неограниченное число) из них, было бы лучше построить, скомпилировать, оптимизировать файл .less(или CSS), когда тема будет изменил и сохранил результат. При каждой загрузке страницы вы ссылаетесь на этот файл темы, пока пользователь не выберет новую тему. В лучшем случае, он остается кэшированным в пользовательской системе в течение длительного времени.

Если это небольшое количество настроенных LESS/CSS, я бы избегал встроенного CSS-маршрута. Это добавит к каждому размеру/ширине файла страницы, поэтому медленнее загружается на мобильном устройстве. Вместо этого я бы использовал недавний пакет ASP.NET Web.Optimization, который поможет вам конструировать, скомпилировать и оптимизировать LESS → CSS при изменении темы и кешировать результат.

Таким образом, при загрузке страницы большинство страниц будут ссылаться на существующую, настраиваемую тему страницы, сохраненную в базе данных. После изменения темы вы пройдете весь процесс less → css.