13

我正在将 dotnetless ( http://www.dotlesscss.org/ ) 用于asp.netWeb 表单应用程序,效果很好。我喜欢对颜色、字体大小等使用变量。但据我所知,变量值是静态的。

有没有办法使用 dotnetless 根据用户 ID 从数据库中初始化这些变量值?

基本上我想将此 Web 应用程序转换为基于主题的网站,因此每个用户都可以选择自己的颜色、字体、字体大小等。

任何方向将不胜感激。

4

5 回答 5

6

这绝对是可能的,但不幸的是你不能从 LESS 本身查询你的数据库,所以你基本上需要用所需的变量值为用户编写 LESS 文件,然后加载它。

您可以在此处找到另一个答案的示例:https ://stackoverflow.com/a/11628325/2330244

于 2013-06-03T14:24:40.837 回答
5

我认为,如果那是您想要采用的路径,您应该创建一个 IHttpHandler 来替换无点的 LessCssHttpHandler。这个处理程序将执行与 LessCssHttpHandler 基本相同的操作,但会在编译成 css 之前将数据库变量插入到 less 中。

您可以查看Bundle Transformer LESS 项目,该项目使用 dotless 进行的翻译较少。它还有一个 IHttpHandler ,您可以以此为基础。

正如其他人所说,这可能不是最好的行动方案

编辑: 处理程序的基本起点

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; }
    }
}
于 2013-06-06T15:35:09.157 回答
5

为什么不创建一个具有执行所需查找功能的自定义 .LESS 插件呢?

下面的代码经过测试,如图所示。我实际上并没有在数据库中查找数据,但所有必要的信息都应该可用。我验证了在网站上以 Windows 身份验证模式运行时,我能够通过HttpContext.Current.User.Identity.Name.

要使用下面的函数,您可以在 less 文件中键入如下内容:

--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>

考虑禁用dotless 的缓存,以便用户所做的更改立即生效。

链接:https ://github.com/dotless/dotless/wiki/FunctionPlugins

于 2013-06-07T19:27:48.343 回答
2

最简单的解决方案可能是在您的网页中内联您的 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>
于 2013-06-05T14:21:47.830 回答
1

这取决于您将拥有多少个主题。如果您的数量有限,最好(对于性能和复杂性)将用户映射到您预编译的 .less 主题之一。

但是,如果您允许每个用户自定义主题以便有很多(或无限数量)主题,最好在主题更改并保存时构建、编译、优化 .less(或 CSS)文件结果。在每次页面加载时,您都会引用该主题文件,直到用户选择一个新主题。最好的情况是,它会在用户系统上缓存很长时间。

除非是少量定制的 LESS/CSS,否则我会避免使用内联 CSS 路由。它将增加每个页面的文件大小/带宽,因此在移动设备上加载更慢。相反,我会使用最近的ASP.NET Web.Optimization包来帮助您在主题更改时构建、编译和优化 LESS -> CSS 并缓存结果。

因此,在页面加载时,大多数页面将引用保存在数据库中的现有自定义页面主题。更改主题后,您将经历完整的 less -> css 过程。

于 2013-06-06T14:21:41.987 回答