为动态主题创建 ThemeBuilder
Create ThemeBuilder for dynamic themes
我正在开发一个多租户应用程序,它有一个基于主题颜色等定义设置的主题构建器。
我将这种方法 http://bundletransformer-theme-builder.azurewebsites.net/ 用于 bootstrap 3。但是,由于我们已经升级到 Bootstrap 4,它现在处于 .scss
。
所以我对项目实施Bootstrap4的做法是添加以下内容:
theme/theme-variables.scss
/*
* Application global variables.
*/
$orcid-color : #96D72F;
$primary-color: #1c223d;
@import "../bootstrap/_functions.scss";
@import "../bootstrap/_variables.scss";
theme/theme.scss
/*
* Global application theme.
*/
@import "theme-variables";
html,
body {
height: 100%;
}
body {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
// ...
main.scss
/*
* Entry point of global application style.
*/
// Theme variables, must be included before the libraries to allow overriding defaults
@import "theme/theme-variables";
// 3rd party libraries
@import "bootstrap/bootstrap.scss";
// Theme customization
@import "theme/theme";
现在在BundleConfig中定义了下面这个
public class BundleConfig
{
public static void RegisterBundles(BundleCollection bundles)
{
bundles.Add(new CustomStyleBundle("~/bundles/styles")
.Include("~/Contents/main.scss"));
}
}
然后创建以下代码..
[Route("bundles/themes/{id}"), AllowAnonymous]
public ContentResult Themes(int id)
{
var id = 1;
var institutionPath = string.Format("~/bundles/themes/{0}", id);
if (BundleTable.Bundles.All(x => x.Path != institutionPath))
{
var themeStyles = new CustomStyleBundle(institutionPath)
.Include("~/Contents/main.scss", new InjectContentItemTransform($"$primary-color: red;"));
BundleTable.Bundles.Add(themeStyles);
}
return null;
}
public sealed class InjectContentItemTransform : IItemTransform
{
private readonly string _content;
public InjectContentItemTransform(string content)
{
_content = content;
}
public string Process(string includedVirtualPath, string input)
{
if (!_content.HasValue())
{
return input;
}
var builder = new StringBuilder();
builder.Append(_content);
return builder.ToString();
}
}
然后在主布局中...
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="shortcut icon" href="~/favicon.ico">
@Styles.Render(string.Format("~/bundles/themes/{0}", 1))
@Styles.Render("~/bundles/styles")
<title>@ViewBag.Title</title>
</head>
<body class="body">
<!-- //.... -->
</body>
</html>
添加变量或覆盖变量以应用颜色等值的正确方法是什么?
Sass不像LESS,不支持修改变量值,所以使用item转换只能定义变量。
首先,您应该从 theme/theme-variables.scss
文件中删除变量定义:
/*
* Application global variables.
*/
$orcid-color : #96D72F;
//$primary-color: #1c223d;
@import "../bootstrap/_functions.scss";
@import "../bootstrap/_variables.scss";
您对 InjectContentItemTransform
class 的实施包含一个错误:只有变量定义将始终包含在包内容中。这是正确的实现:
public sealed class InjectContentItemTransform : IItemTransform
{
private readonly string _content;
public InjectContentItemTransform(string content)
{
_content = content;
}
public string Process(string includedVirtualPath, string input)
{
if (!_content.HasValue())
{
return input;
}
var builder = new StringBuilder();
builder.AppendLine(_content);
builder.Append(input);
return builder.ToString();
}
}
要在调试模式下应用项目转换,您必须注册自定义包解析器:
…
using BundleTransformer.Core.Resolvers;
…
public class BundleConfig
{
public static void RegisterBundles(BundleCollection bundles)
{
BundleResolver.Current = new CustomBundleResolver();
…
}
}
许多创建多租户 Web 应用程序的开发人员必须编写自己的 System.Web.Optimization.IBundleCache
接口实现,System.Web.Hosting.VirtualPathProvider
class 和自己的 BundleTransformer.SassAndScss.HttpHandlers.SassAndScssAssetHandler
class 使用重写的 GetCacheKey
方法。我建议您熟悉 SmartStore.NET 项目的源代码。
我正在开发一个多租户应用程序,它有一个基于主题颜色等定义设置的主题构建器。
我将这种方法 http://bundletransformer-theme-builder.azurewebsites.net/ 用于 bootstrap 3。但是,由于我们已经升级到 Bootstrap 4,它现在处于 .scss
。
所以我对项目实施Bootstrap4的做法是添加以下内容:
theme/theme-variables.scss
/*
* Application global variables.
*/
$orcid-color : #96D72F;
$primary-color: #1c223d;
@import "../bootstrap/_functions.scss";
@import "../bootstrap/_variables.scss";
theme/theme.scss
/*
* Global application theme.
*/
@import "theme-variables";
html,
body {
height: 100%;
}
body {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
// ...
main.scss
/*
* Entry point of global application style.
*/
// Theme variables, must be included before the libraries to allow overriding defaults
@import "theme/theme-variables";
// 3rd party libraries
@import "bootstrap/bootstrap.scss";
// Theme customization
@import "theme/theme";
现在在BundleConfig中定义了下面这个
public class BundleConfig
{
public static void RegisterBundles(BundleCollection bundles)
{
bundles.Add(new CustomStyleBundle("~/bundles/styles")
.Include("~/Contents/main.scss"));
}
}
然后创建以下代码..
[Route("bundles/themes/{id}"), AllowAnonymous]
public ContentResult Themes(int id)
{
var id = 1;
var institutionPath = string.Format("~/bundles/themes/{0}", id);
if (BundleTable.Bundles.All(x => x.Path != institutionPath))
{
var themeStyles = new CustomStyleBundle(institutionPath)
.Include("~/Contents/main.scss", new InjectContentItemTransform($"$primary-color: red;"));
BundleTable.Bundles.Add(themeStyles);
}
return null;
}
public sealed class InjectContentItemTransform : IItemTransform
{
private readonly string _content;
public InjectContentItemTransform(string content)
{
_content = content;
}
public string Process(string includedVirtualPath, string input)
{
if (!_content.HasValue())
{
return input;
}
var builder = new StringBuilder();
builder.Append(_content);
return builder.ToString();
}
}
然后在主布局中...
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="shortcut icon" href="~/favicon.ico">
@Styles.Render(string.Format("~/bundles/themes/{0}", 1))
@Styles.Render("~/bundles/styles")
<title>@ViewBag.Title</title>
</head>
<body class="body">
<!-- //.... -->
</body>
</html>
添加变量或覆盖变量以应用颜色等值的正确方法是什么?
Sass不像LESS,不支持修改变量值,所以使用item转换只能定义变量。
首先,您应该从 theme/theme-variables.scss
文件中删除变量定义:
/*
* Application global variables.
*/
$orcid-color : #96D72F;
//$primary-color: #1c223d;
@import "../bootstrap/_functions.scss";
@import "../bootstrap/_variables.scss";
您对 InjectContentItemTransform
class 的实施包含一个错误:只有变量定义将始终包含在包内容中。这是正确的实现:
public sealed class InjectContentItemTransform : IItemTransform
{
private readonly string _content;
public InjectContentItemTransform(string content)
{
_content = content;
}
public string Process(string includedVirtualPath, string input)
{
if (!_content.HasValue())
{
return input;
}
var builder = new StringBuilder();
builder.AppendLine(_content);
builder.Append(input);
return builder.ToString();
}
}
要在调试模式下应用项目转换,您必须注册自定义包解析器:
…
using BundleTransformer.Core.Resolvers;
…
public class BundleConfig
{
public static void RegisterBundles(BundleCollection bundles)
{
BundleResolver.Current = new CustomBundleResolver();
…
}
}
许多创建多租户 Web 应用程序的开发人员必须编写自己的 System.Web.Optimization.IBundleCache
接口实现,System.Web.Hosting.VirtualPathProvider
class 和自己的 BundleTransformer.SassAndScss.HttpHandlers.SassAndScssAssetHandler
class 使用重写的 GetCacheKey
方法。我建议您熟悉 SmartStore.NET 项目的源代码。