Added FileRegistrationContext to help scope file registrations for theming.

--HG--
extra : convert_revision : svn%3A5ff7c347-ad56-4c35-b696-ccb81de16e03/trunk%4044232
This commit is contained in:
ErikPorter
2009-12-17 20:02:43 +00:00
parent c2b870637f
commit 46918f8745
10 changed files with 128 additions and 69 deletions

View File

@@ -1,6 +1,7 @@
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<BaseViewModel>" %> <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<BaseViewModel>" %>
<%@ Import Namespace="Orchard.Mvc.ViewModels"%> <%@ Import Namespace="Orchard.Mvc.ViewModels"%>
<%@ Import Namespace="Orchard.Mvc.Html" %><% <%@ Import Namespace="Orchard.Mvc.Html" %><%
Html.RegisterStyle("site.css");
Html.RegisterStyle("site.css"); %> Html.RegisterStyle("site.css"); %>
<div class="page"> <div class="page">
<div id="header"><% <div id="header"><%

View File

@@ -1,8 +1,18 @@
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<string>" %> <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<string>" %>
<%@ Import Namespace="System.Web.Mvc.Html" %> <%@ Import Namespace="System.Web.Mvc.Html" %>
<%-- todo: (heskew) need script include and init script to not be duplicated --%> <%@ Import Namespace="Orchard.Mvc.Html" %>
<%--<script src="<%=ResolveUrl("~/Packages/TinyMce/scripts/tiny_mce.js") %>" type="text/javascript"></script>--%> <% Html.RegisterScript("tiny_mce.js"); %>
<%=Html.TextArea("", Model, 25, 80, new { @class = "html" }) %> <%=Html.TextArea("", Model, 25, 80, new { @class = "html" }) %>
<%--<script type="text/javascript"> <script type="text/javascript">
tinyMCE.init({ theme: "advanced", mode: "textareas", plugins: "fullscreen,autoresize", theme_advanced_toolbar_location: "top", theme_advanced_toolbar_align: "left", theme_advanced_buttons3_add: "fullscreen" }); tinyMCE.init({
</script>--%> theme: "advanced",
mode: "specific_textareas",
editor_selector: "html",
plugins: "fullscreen,autoresize,searchreplace",
theme_advanced_toolbar_location: "top",
theme_advanced_toolbar_align: "left",
theme_advanced_buttons1: "search,replace,|,cut,copy,paste,|,undo,redo,|,image,|,link,unlink,charmap,emoticon,codeblock,|,bold,italic,|,numlist,bullist,formatselect,|,code,fullscreen",
theme_advanced_buttons2: "",
theme_advanced_buttons3: ""
});
</script>

View File

@@ -10,22 +10,6 @@
<%-- todo: (heskew) this should come from the admin "page" (partial) <%-- todo: (heskew) this should come from the admin "page" (partial)
todo: (heskew) should have at the minimum something like, say, includeScript(scriptName[, releaseScriptName], scriptPath[, releaseScriptPath]) todo: (heskew) should have at the minimum something like, say, includeScript(scriptName[, releaseScriptName], scriptPath[, releaseScriptPath])
--%><script src="<%=Page.ResolveClientUrl("~/Scripts/jquery-1.3.2.js") %>" type="text/javascript"></script> --%><script src="<%=Page.ResolveClientUrl("~/Scripts/jquery-1.3.2.js") %>" type="text/javascript"></script>
<%-- todo: (heskew) this should come from the admin "page" (partial)
todo: (heskew) use the TinyMCE jQuery package instead?
--%><script type="text/javascript" src="<%=ResolveUrl("~/Packages/TinyMce/Scripts/tiny_mce.js") %>"></script>
<script type="text/javascript">
tinyMCE.init({
theme: "advanced",
mode: "specific_textareas",
editor_selector: "html",
plugins: "fullscreen,autoresize,searchreplace",
theme_advanced_toolbar_location: "top",
theme_advanced_toolbar_align: "left",
theme_advanced_buttons1: "search,replace,|,cut,copy,paste,|,undo,redo,|,image,|,link,unlink,charmap,emoticon,codeblock,|,bold,italic,|,numlist,bullist,formatselect,|,code,fullscreen",
theme_advanced_buttons2: "",
theme_advanced_buttons3: ""
});
</script>
</head> </head>
<body><% <body><%
Html.ZoneBody("body"); %> Html.ZoneBody("body"); %>

View File

@@ -0,0 +1,40 @@
using System;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.UI;
namespace Orchard.Mvc.Html {
public class FileRegistrationContext : RequestContext {
public FileRegistrationContext(ViewContext viewContext, IViewDataContainer viewDataContainer, string fileName)
: base(viewContext.HttpContext, viewContext.RouteData) {
TemplateControl container = viewDataContainer as TemplateControl;
if (container != null)
ContainerVirtualPath = container.AppRelativeVirtualPath.Substring(0,
container.AppRelativeVirtualPath.
IndexOf("/Views",
StringComparison.
InvariantCultureIgnoreCase));
FileName = fileName;
}
public TemplateControl Container { get; set; }
public string ContainerVirtualPath { get; set; }
public string FileName { get; set; }
public override bool Equals(object obj)
{
FileRegistrationContext incoming = obj as FileRegistrationContext;
return incoming != null &&
string.Equals(ContainerVirtualPath, incoming.ContainerVirtualPath,
StringComparison.InvariantCultureIgnoreCase) &&
string.Equals(FileName, incoming.FileName, StringComparison.InvariantCultureIgnoreCase);
}
internal string GetFilePath(string containerRelativePath) {
return ContainerVirtualPath.Replace("~/", "/") + containerRelativePath + FileName;
}
}
}

View File

@@ -56,15 +56,15 @@ namespace Orchard.Mvc.Html {
} }
public static void RegisterStyle(this HtmlHelper html, string fileName) { public static void RegisterStyle(this HtmlHelper html, string fileName) {
html.Resolve<IResourceManager>().RegisterStyle(fileName); html.Resolve<IResourceManager>().RegisterStyle(fileName, html);
} }
public static void RegisterScript(this HtmlHelper html, string fileName) { public static void RegisterScript(this HtmlHelper html, string fileName) {
html.Resolve<IResourceManager>().RegisterHeadScript(fileName); html.Resolve<IResourceManager>().RegisterHeadScript(fileName, html);
} }
public static void RegisterFootScript(this HtmlHelper html, string fileName) { public static void RegisterFootScript(this HtmlHelper html, string fileName) {
html.Resolve<IResourceManager>().RegisterFootScript(fileName); html.Resolve<IResourceManager>().RegisterFootScript(fileName, html);
} }
} }
} }

View File

@@ -125,6 +125,7 @@
<Compile Include="Environment\IOrchardShellEvents.cs" /> <Compile Include="Environment\IOrchardShellEvents.cs" />
<Compile Include="Extensions\ExtensionDescriptor.cs" /> <Compile Include="Extensions\ExtensionDescriptor.cs" />
<Compile Include="Extensions\ExtensionEntry.cs" /> <Compile Include="Extensions\ExtensionEntry.cs" />
<Compile Include="Mvc\Html\FileRegistrationContext.cs" />
<Compile Include="Themes\ExtensionManagerExtensions.cs" /> <Compile Include="Themes\ExtensionManagerExtensions.cs" />
<Compile Include="Extensions\Helpers\PathHelpers.cs" /> <Compile Include="Extensions\Helpers\PathHelpers.cs" />
<Compile Include="Extensions\IExtensionManager.cs" /> <Compile Include="Extensions\IExtensionManager.cs" />

View File

@@ -4,11 +4,16 @@ using Orchard.Extensions;
namespace Orchard.Themes { namespace Orchard.Themes {
public static class ExtensionManagerExtensions { public static class ExtensionManagerExtensions {
public static string GetThemeLocation(this IExtensionManager extensionManager, ITheme theme) { public static ExtensionDescriptor GetExtensionDescriptor(this IExtensionManager extensionManager, string extensionType, string extensionName) {
var themeDescriptor = extensionManager.AvailableExtensions() return
.Single(x => x.ExtensionType == "Theme" && x.Name == theme.ThemeName); extensionManager.AvailableExtensions().FirstOrDefault(
ed => ed.ExtensionType == extensionType && ed.Name == extensionName);
}
return Path.Combine(themeDescriptor.Location, themeDescriptor.Name); public static string GetThemeLocation(this IExtensionManager extensionManager, ITheme theme) {
ExtensionDescriptor descriptor = extensionManager.GetExtensionDescriptor("Theme", theme.ThemeName);
return descriptor != null ? Path.Combine(descriptor.Location, descriptor.Name) : null;
} }
} }
} }

View File

@@ -4,12 +4,12 @@ using System.Web.Routing;
namespace Orchard.UI.Resources { namespace Orchard.UI.Resources {
public interface IResourceManager : IDependency { public interface IResourceManager : IDependency {
void RegisterMeta(string name, string content); void RegisterMeta(string name, string content);
void RegisterStyle(string fileName); void RegisterStyle(string fileName, HtmlHelper html);
void RegisterHeadScript(string fileName); void RegisterHeadScript(string fileName, HtmlHelper html);
void RegisterFootScript(string fileName); void RegisterFootScript(string fileName, HtmlHelper html);
MvcHtmlString GetMetas(); MvcHtmlString GetMetas();
MvcHtmlString GetStyles(RequestContext requestContext); MvcHtmlString GetStyles();
MvcHtmlString GetHeadScripts(RequestContext requestContext); MvcHtmlString GetHeadScripts();
MvcHtmlString GetFootScripts(RequestContext requestContext); MvcHtmlString GetFootScripts();
} }
} }

View File

@@ -15,9 +15,9 @@ namespace Orchard.UI.Resources {
if (model != null) { if (model != null) {
model.Zones.AddAction("head:metas", html => html.ViewContext.HttpContext.Response.Output.Write(_resourceManager.GetMetas())); model.Zones.AddAction("head:metas", html => html.ViewContext.HttpContext.Response.Output.Write(_resourceManager.GetMetas()));
model.Zones.AddAction("head:styles", html => html.ViewContext.HttpContext.Response.Output.Write(_resourceManager.GetStyles(filterContext.RequestContext))); model.Zones.AddAction("head:styles", html => html.ViewContext.HttpContext.Response.Output.Write(_resourceManager.GetStyles()));
model.Zones.AddAction("head:scripts", html => html.ViewContext.HttpContext.Response.Output.Write(_resourceManager.GetHeadScripts(filterContext.RequestContext))); model.Zones.AddAction("head:scripts", html => html.ViewContext.HttpContext.Response.Output.Write(_resourceManager.GetHeadScripts()));
model.Zones.AddAction("body:after", html => html.ViewContext.HttpContext.Response.Output.Write(_resourceManager.GetFootScripts(filterContext.RequestContext))); model.Zones.AddAction("body:after", html => html.ViewContext.HttpContext.Response.Output.Write(_resourceManager.GetFootScripts()));
} }
} }

View File

@@ -4,6 +4,7 @@ using System.Linq;
using System.Web.Mvc; using System.Web.Mvc;
using System.Web.Routing; using System.Web.Routing;
using Orchard.Extensions; using Orchard.Extensions;
using Orchard.Mvc.Html;
using Orchard.Themes; using Orchard.Themes;
namespace Orchard.UI.Resources { namespace Orchard.UI.Resources {
@@ -14,9 +15,9 @@ namespace Orchard.UI.Resources {
private const string StyleFormat = "\r\n<link rel=\"stylesheet\" type=\"text/css\" href=\"{0}\" />"; private const string StyleFormat = "\r\n<link rel=\"stylesheet\" type=\"text/css\" href=\"{0}\" />";
private const string ScriptFormat = "\r\n<script type=\"text/javascript\" src=\"{0}\"></script>"; private const string ScriptFormat = "\r\n<script type=\"text/javascript\" src=\"{0}\"></script>";
private readonly Dictionary<string, string> _metas; private readonly Dictionary<string, string> _metas;
private readonly List<string> _styles; private readonly List<FileRegistrationContext> _styles;
private readonly List<string> _headScripts; private readonly List<FileRegistrationContext> _headScripts;
private readonly List<string> _footScripts; private readonly List<FileRegistrationContext> _footScripts;
public ResourceManager(IThemeService themeService, public ResourceManager(IThemeService themeService,
IExtensionManager extensionManager) { IExtensionManager extensionManager) {
@@ -24,9 +25,9 @@ namespace Orchard.UI.Resources {
_extensionManager = extensionManager; _extensionManager = extensionManager;
//TODO: (erikpo) Not sure if generator should be initialized here or somewhere else //TODO: (erikpo) Not sure if generator should be initialized here or somewhere else
_metas = new Dictionary<string, string>(20) {{"generator", "Orchard"}}; _metas = new Dictionary<string, string>(20) {{"generator", "Orchard"}};
_styles = new List<string>(10); _styles = new List<FileRegistrationContext>(10);
_headScripts = new List<string>(10); _headScripts = new List<FileRegistrationContext>(10);
_footScripts = new List<string>(5); _footScripts = new List<FileRegistrationContext>(5);
} }
public void RegisterMeta(string name, string content) { public void RegisterMeta(string name, string content) {
@@ -34,19 +35,34 @@ namespace Orchard.UI.Resources {
_metas.Add(name, content); _metas.Add(name, content);
} }
public void RegisterStyle(string fileName) { public void RegisterStyle(string fileName, HtmlHelper html) {
if (!string.IsNullOrEmpty(fileName) && !_styles.Contains(fileName)) if (string.IsNullOrEmpty(fileName))
_styles.Add(fileName); return;
FileRegistrationContext context = new FileRegistrationContext(html.ViewContext, html.ViewDataContainer, fileName);
if (!_styles.Contains(context))
_styles.Add(context);
} }
public void RegisterHeadScript(string fileName) { public void RegisterHeadScript(string fileName, HtmlHelper html) {
if (!string.IsNullOrEmpty(fileName) && !_headScripts.Contains(fileName) && !_footScripts.Contains(fileName)) if (string.IsNullOrEmpty(fileName))
_headScripts.Add(fileName); return;
FileRegistrationContext context = new FileRegistrationContext(html.ViewContext, html.ViewDataContainer, fileName);
if (!_headScripts.Contains(context))
_headScripts.Add(context);
} }
public void RegisterFootScript(string fileName) { public void RegisterFootScript(string fileName, HtmlHelper html) {
if (!string.IsNullOrEmpty(fileName) && !_headScripts.Contains(fileName) && !_footScripts.Contains(fileName)) if (string.IsNullOrEmpty(fileName))
_footScripts.Add(fileName); return;
FileRegistrationContext context = new FileRegistrationContext(html.ViewContext, html.ViewDataContainer, fileName);
if (!_footScripts.Contains(context))
_footScripts.Add(context);
} }
public MvcHtmlString GetMetas() { public MvcHtmlString GetMetas() {
@@ -54,34 +70,36 @@ namespace Orchard.UI.Resources {
MvcHtmlString.Create(string.Join("\r\n", MvcHtmlString.Create(string.Join("\r\n",
_metas.Select(m => string.Format(MetaFormat, m.Key, m.Value)).ToArray())); _metas.Select(m => string.Format(MetaFormat, m.Key, m.Value)).ToArray()));
} }
public MvcHtmlString GetStyles(RequestContext requestContext) {
return GetFiles(_styles, StyleFormat, s => GetThemePath("/styles/" + s, requestContext)); public MvcHtmlString GetStyles() {
return GetFiles(_styles, StyleFormat, "/styles/");
} }
public MvcHtmlString GetHeadScripts(RequestContext requestContext) { public MvcHtmlString GetHeadScripts() {
return GetFiles(_headScripts, ScriptFormat, s => GetThemePath("/scripts/" + s, requestContext)); return GetFiles(_headScripts, ScriptFormat, "/scripts/");
} }
public MvcHtmlString GetFootScripts(RequestContext requestContext) { public MvcHtmlString GetFootScripts() {
return GetFiles(_footScripts, ScriptFormat, s => GetThemePath("/scripts/" + s, requestContext)); return GetFiles(_footScripts, ScriptFormat, "/scripts/");
} }
private static MvcHtmlString GetFiles(IEnumerable<string> files, string fileFormat, Func<string, string> getPath) { private static MvcHtmlString GetFiles(IEnumerable<FileRegistrationContext> fileRegistrationContexts, string fileFormat, string containerRelativePath) {
return return
MvcHtmlString.Create(string.Join("\r\n", MvcHtmlString.Create(string.Join("\r\n",
files.Select(s => string.Format(fileFormat, getPath(s))).ToArray())); fileRegistrationContexts.Select(c => string.Format(fileFormat, c.GetFilePath(containerRelativePath))).ToArray()));
} }
private string GetThemePath(string fileName, RequestContext requestContext) { //TODO: (erikpo) Old code that may be needed later
var requestTheme = _themeService.GetRequestTheme(requestContext); // <- todo: (erikpo) will need context eventually //private string GetThemePath(string fileName, RequestContext requestContext) {
// var requestTheme = _themeService.GetRequestTheme(requestContext); // <- todo: (erikpo) will need context eventually
if (requestTheme == null) // if (requestTheme == null)
return fileName; // return fileName;
//todo: (erikpo) this might be the worst code ever so resolve for real // //todo: (erikpo) this might be the worst code ever so resolve for real
return (_extensionManager.GetThemeLocation(requestTheme) + fileName) // return (_extensionManager.GetThemeLocation(requestTheme) + fileName)
.Replace("~", "") // .Replace("~", "")
.Replace("\\", "/"); // .Replace("\\", "/");
} //}
} }
} }