我们目前计划在客户端上以下列方式使用LESS和变量:
>从服务器下载相关的LESS文件
>调用Web服务以获取配置对象
>定义变量的有效LESS的表格字符串
>使用less.js编译器根据这些变量和步骤1中的固定LESS文件编译LESS
这种方法有许多缺点:
>客户可能表现不佳
>有些浏览器有less.js的问题
>编译需要时间
我们宁愿在服务器上处理这项工作,所以粗略地说,这发生在服务器上:
>客户端请求下载一个大的已编译样式表 – GET content / styles / {tenantName} .css
>使用tenantName,服务器获取配置
>使用模板和适当的变量(可能是string.Format或更复杂的东西)
>服务器将LESS编译为CSS字符串
>服务器返回具有适当Content-Type的CSS字符串
这是我的问题:
>这是否是实现上述结果的不寻常或不受欢迎的方式?
>如果没有为服务器端JavaScript设置架构,我怎样才能将LESS编译成CSS?
>我必须在控制器操作或路由配置中做什么才能让客户端认为服务器返回一个常规的旧CSS文件,完成缓存控制,而不是修改?
解决方法
它可能取决于您希望如何提供文件.如果您知道所有租户,那么只需添加每个租户应用程序的捆绑URL到捆绑包配置.
var themeStyles = new CustomStyleBundle("~bundles/theme/tenant").Include("~/Content/theme.less"); themeStyles.Builder = new ThemeBuilder(); BundleTable.Bundles.Add(themeStyles);
如果您不这样做并且租户在我们的情况下是灵活的,那么为您的主题添加以下控制器操作.
[Route("bundles/theme/{id}")] public ContentResult Theme(string id) { var tenantThemePath = string.Format("~/bundles/theme/{0}",id); // Check that bundle has not already been added. if (BundleTable.Bundles.All(x => x.Path != tenantThemePath)) { var themeStyles = new CustomStyleBundle(tenantThemePath ).Include("~/Content/theme.less"); themeStyles.Builder = new ThemeBuilder(); BundleTable.Bundles.Add(themeStyles); } var context = new BundleContext(HttpContext,BundleTable.Bundles,institutionPath); var response = BundleTable.Bundles.GetBundleFor(tenantThemePath).GenerateBundleResponse(context); Response.Cache.SetCacheability(response.Cacheability); return Content(response.Content,response.ContentType); }
BundleTransformer的ThemeBuilder实现
public class ThemeBuilder : IBundleBuilder { public string BuildBundleContent(Bundle bundle,BundleContext context,IEnumerable<BundleFile> files) { var lessTranslator = bundle.Transforms.OfType<StyleTransformer>() .Where(x => x != null) .Select(x => x.Translators.OfType<LessTranslator>().FirstOrDefault()) .FirstOrDefault(); if (lessTranslator == null) { return string.Empty; } lessTranslator.GlobalVariables = GetThemeVariables(); return string.Empty; } private string GetThemeVariables() { // Simplified for brevity // This will be translated to less variables by the BundleTransformer // themeColour should correspond to a variable name in your less file. return string.Format("themeColour={0}",themeColour); } }
您将需要获取主题颜色,我们将这些变量存储在HttpContext存储中,以便我们可以使用GetThemeVariables方法中的扩展方法将它们拉出来.
我希望这有帮助.
UPDATE
我扩展了我的原始答案,并创建了一个包含主题的更可重用的方式.
演示网站:http://bundletransformer-theme-builder.azurewebsites.net/
GitHub回复:https://github.com/benembery/bundle-transformer-theme-builder