ایجاد قابلیت قالب یا Theme در ASP.NET MVC
نویسنده: ایمان محمدی
تاریخ: ۱۳۹۵/۰۳/۰۵ ۱۱:۴۰
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
ViewEngine.ViewLocationFormats= "~/Views/{controller}/{action}.cshtml" "~/Themes/{ThemeName}/Views/{controller}/{action}.cshtml" public static void Themeable(this VirtualPathProviderViewEngine engine)
{
var ThemePath = "~/Themes";
var ThemeName = WebConfigurationManager.AppSettings["MvcTheme"];
if (string.IsNullOrEmpty(ThemeName))
return;
var themeFolder = HttpContext.Current.Server.MapPath(string.Format("{0}/{1}/", ThemePath, ThemeName));
if (!Directory.Exists(themeFolder))
throw new DirectoryNotFoundException(string.Format("Theme folder not exists: {0}/{1}}", ThemePath,
ThemeName));
var newViewLocations = new[]
{
string.Format("{0}/{1}/Views/{2}/{3}.cshtml", ThemePath, ThemeName, "{1}", "{0}"),
string.Format("{0}/{1}/Views/Shared/{2}.cshtml", ThemePath, ThemeName, "{0}"),
// vb.net :
// string.Format("{0}/{1}/Views/{2}/{3}.vbhtml", ThemePath, ThemeName, "{1}", "{0}"),
// string.Format("{0}/{1}/Views/Shared/{2}.vbhtml", ThemePath, ThemeName, "{0}"),
};
engine.ViewLocationFormats = newViewLocations;
engine.PartialViewLocationFormats = newViewLocations;
} <appSettings>
...
<add key="MvcTheme" value="Test1" />
</appSettings> ViewEngines.Engines.OfType<RazorViewEngine>().Single().Themeable();
@{
// Layout = "~/Views/Shared/_Layout.cshtml";
Layout = "~/themes/test1/Views/Shared/_Layout.cshtml";
} public class ThemeBundle
{
public BundleType BundleType { get; set; }
public string VirtualPath { get; set; }
public string[] Urls { get; set; }
}
public enum BundleType
{
Style, Script
} public static void RegisterThemeBundels(BundleCollection bundles)
{
var ThemePath = "~/Themes";
var ThemeName = WebConfigurationManager.AppSettings["MvcTheme"];
var ThemeBundleFileName = "ThemeBundle.json";
List<ThemeBundle> list;
try
{
JavaScriptSerializer jss = new JavaScriptSerializer();
var jsonaddress =
System.Web.HttpContext.Current.Server.MapPath(string.Format("{0}/{1}/{2}", ThemePath, ThemeName, ThemeBundleFileName));
var json = System.IO.File.ReadAllText(jsonaddress);
list = jss.Deserialize<List<ThemeBundle>>(json);
}
catch (Exception ex)
{
throw new Exception(string.Format("Cannot read {0}. see more error in inner exception.", ThemeBundleFileName), ex);
}
foreach (var themeBundle in list)
{
switch (themeBundle.BundleType)
{
case BundleType.Script:
bundles.Add(new ScriptBundle(themeBundle.VirtualPath).Include(
themeBundle.Urls));
break;
case BundleType.Style:
bundles.Add(new StyleBundle(themeBundle.VirtualPath).Include(
themeBundle.Urls));
break;
default:
throw new ArgumentOutOfRangeException(nameof(themeBundle.BundleType));
}
}
} public class BundleConfig
{
public static void RegisterBundles(BundleCollection bundles)
{
if (MvcTheme.ThemeName != null)
{
MvcTheme.RegisterThemeBundels(bundles);
return;
}
bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
"~/Scripts/jquery-{version}.js"));
bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
"~/Scripts/jquery.validate*"));
...
}
} [
{
"BundleType": "Script",
"VirtualPath": "~/themes/test1/js/jquery",
"Urls": [ "~/themes/test1/js/jquery-1.10.2.js" ]
},
{
"BundleType": "Script",
"VirtualPath": "~/themes/test1/js/jqueryval",
"Urls": [ "~/themes/test1/js/jquery.validate.js",
"~/themes/test1/js/jquery.validate.unobtrusive.js" ]
},
{
"BundleType": "Script",
"VirtualPath": "~/themes/test1/js/modernizr",
"Urls": [ "~/themes/test1/js/modernizr-2.6.2.js" ]
},
{
"BundleType": "Script",
"VirtualPath": "~/themes/test1/js/bootstrap",
"Urls": [ "~/themes/test1/js/bootstrap.js",
"~/themes/test1/js/respond.js" ]
},
{
"BundleType": "Style",
"VirtualPath": "~/themes/test1/css/css",
"Urls": [ "~/themes/test1/css/bootstrap.css",
"~/themes/test1/css/site.css" ]
}
] Themes ├───Test1 │ │ThemeBundle.json │ ├───Css │ ├───Fonts │ ├───Images │ ├───Js │ └───Views ├───Test2 │ │ThemeBundle.json │ ├───Css │ ├───Fonts │ ├───Images │ ├───Js │ └───Views
public static class MvcTheme
{
public static string ThemeName { get; }
public static string ThemePath { get; set; }
private const string AppSettingName = "MvcTheme";
private const string ThemeBundleFileName = "ThemeBundle.json";
static MvcTheme()
{
ThemePath = "~/Themes";
ThemeName = WebConfigurationManager.AppSettings[AppSettingName];
}
public static void Themeable(this VirtualPathProviderViewEngine engine)
{
if (string.IsNullOrEmpty(ThemeName))
return;
var themeFolder = HttpContext.Current.Server.MapPath(string.Format("{0}/{1}/", ThemePath, ThemeName));
if (!Directory.Exists(themeFolder))
throw new DirectoryNotFoundException(string.Format("Theme folder not exists: {0}/{1}}", ThemePath,
ThemeName));
var newViewLocations = new[]
{
string.Format("{0}/{1}/Views/{2}/{3}.cshtml", ThemePath, ThemeName, "{1}", "{0}"),
string.Format("{0}/{1}/Views/Shared/{2}.cshtml", ThemePath, ThemeName, "{0}"),
// vb.net :
// string.Format("{0}/{1}/Views/{2}/{3}.vbhtml", ThemePath, ThemeName, "{1}", "{0}"),
// string.Format("{0}/{1}/Views/Shared/{2}.vbhtml", ThemePath, ThemeName, "{0}"),
};
engine.ViewLocationFormats = newViewLocations;
engine.PartialViewLocationFormats = newViewLocations;
}
public static void RegisterThemeBundels(BundleCollection bundles)
{
if(ThemeName == null)
return;
var list = ReadThemeBundles();
foreach (var themeBundle in list)
{
switch (themeBundle.BundleType)
{
case BundleType.Script:
bundles.Add(new ScriptBundle(themeBundle.VirtualPath).Include(
themeBundle.Urls));
break;
case BundleType.Style:
bundles.Add(new StyleBundle(themeBundle.VirtualPath).Include(
themeBundle.Urls));
break;
default:
throw new ArgumentOutOfRangeException(nameof(themeBundle.BundleType));
}
}
}
public static List<ThemeBundle> ReadThemeBundles()
{
try
{
JavaScriptSerializer jss = new JavaScriptSerializer();
var jsonaddress =
System.Web.HttpContext.Current.Server.MapPath(string.Format("{0}/{1}/{2}", ThemePath, ThemeName, ThemeBundleFileName));
var json = System.IO.File.ReadAllText(jsonaddress);
var list = jss.Deserialize<List<ThemeBundle>>(json);
return list;
}
catch (Exception ex)
{
throw new Exception(string.Format("Cannot read {0}. see more error in inner exception.", ThemeBundleFileName), ex);
}
}
}
public class ThemeBundle
{
public BundleType BundleType { get; set; }
public string VirtualPath { get; set; }
public string[] Urls { get; set; }
}
public enum BundleType
{
Style, Script
} - نکته دو: نام bundle را حتما هم عمق با آدرس قالب تعریف کنید تا وقتی فایل css به پوشهی images یا فونت مجاور خود اشاره میکند، آدرس دهی معتبر باشد.
bundles.Add(new StyleBundle(
"~/Content/fa",
ContentDeliveryNetwork.MaxCdn.FontAwesomeUrl)
.Include("~/Content/fontawesome/site.css",new CssRewriteUrlTransform()));