mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-07-15 15:21:09 +08:00
Theme preview with black-bar style
--HG-- extra : convert_revision : svn%3A5ff7c347-ad56-4c35-b696-ccb81de16e03/trunk%4046081
This commit is contained in:
parent
2a72d27e74
commit
f96c27c1d8
@ -111,7 +111,10 @@
|
||||
<Compile Include="Scheduling\Models\Task.cs" />
|
||||
<Compile Include="Settings\Controllers\SiteSettingsDriver.cs" />
|
||||
<Compile Include="Settings\Permissions.cs" />
|
||||
<Compile Include="Themes\Preview\IPreviewTheme.cs" />
|
||||
<Compile Include="Themes\Preview\PreviewThemeFilter.cs" />
|
||||
<Compile Include="Themes\Services\AdminThemeSelector.cs" />
|
||||
<Compile Include="Themes\Preview\PreviewTheme.cs" />
|
||||
<Compile Include="Themes\Services\SafeModeThemeSelector.cs" />
|
||||
<Compile Include="Settings\AdminMenu.cs" />
|
||||
<Compile Include="Settings\Controllers\AdminController.cs" />
|
||||
@ -130,6 +133,7 @@
|
||||
<Compile Include="Themes\Records\ThemeSiteSettingsRecord.cs" />
|
||||
<Compile Include="Themes\Services\SiteThemeSelector.cs" />
|
||||
<Compile Include="Themes\Services\ThemeService.cs" />
|
||||
<Compile Include="Themes\ViewModels\PreviewViewModel.cs" />
|
||||
<Compile Include="Themes\ViewModels\ThemesIndexViewModel.cs" />
|
||||
<Compile Include="XmlRpc\Controllers\HomeController.cs" />
|
||||
<Compile Include="XmlRpc\Controllers\LiveWriterController.cs" />
|
||||
@ -184,6 +188,7 @@
|
||||
<Content Include="Themes\Theme.png" />
|
||||
<Content Include="Themes\Theme.txt" />
|
||||
<Content Include="Themes\Styles\site.css" />
|
||||
<Content Include="Themes\Views\Admin\ThemePreview.ascx" />
|
||||
<Content Include="Themes\Views\Admin\Install.aspx" />
|
||||
<Content Include="Themes\Views\Header.ascx" />
|
||||
<Content Include="Themes\Views\Document.aspx" />
|
||||
|
@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Web;
|
||||
using System.Web.Mvc;
|
||||
using Orchard.Core.Themes.Preview;
|
||||
using Orchard.Core.Themes.ViewModels;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Security;
|
||||
@ -12,11 +14,13 @@ namespace Orchard.Core.Themes.Controllers {
|
||||
[ValidateInput(false)]
|
||||
public class AdminController : Controller {
|
||||
private readonly IThemeService _themeService;
|
||||
private readonly IPreviewTheme _previewTheme;
|
||||
private readonly IAuthorizer _authorizer;
|
||||
private readonly INotifier _notifier;
|
||||
|
||||
public AdminController(IThemeService themeService, IAuthorizer authorizer, INotifier notifier) {
|
||||
public AdminController(IThemeService themeService, IPreviewTheme previewTheme, IAuthorizer authorizer, INotifier notifier) {
|
||||
_themeService = themeService;
|
||||
_previewTheme = previewTheme;
|
||||
_authorizer = authorizer;
|
||||
_notifier = notifier;
|
||||
T = NullLocalizer.Instance;
|
||||
@ -37,6 +41,48 @@ namespace Orchard.Core.Themes.Controllers {
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost, FormValueAbsent("submit.Apply"), FormValueAbsent("submit.Cancel")]
|
||||
public ActionResult Preview(string themeName, string returnUrl) {
|
||||
try {
|
||||
if (!_authorizer.Authorize(Permissions.ApplyTheme, T("Couldn't preview the current theme")))
|
||||
return new HttpUnauthorizedResult();
|
||||
_previewTheme.SetPreviewTheme(themeName);
|
||||
return Redirect(returnUrl ?? "~/");
|
||||
}
|
||||
catch (Exception exception) {
|
||||
_notifier.Error(T("Previewing theme failed: " + exception.Message));
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost, ActionName("Preview"), FormValueRequired("submit.Apply")]
|
||||
public ActionResult ApplyPreview(string themeName, string returnUrl) {
|
||||
try {
|
||||
if (!_authorizer.Authorize(Permissions.ApplyTheme, T("Couldn't preview the current theme")))
|
||||
return new HttpUnauthorizedResult();
|
||||
_previewTheme.SetPreviewTheme(null);
|
||||
return Redirect(returnUrl ?? "~/");
|
||||
}
|
||||
catch (Exception exception) {
|
||||
_notifier.Error(T("Previewing theme failed: " + exception.Message));
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost, ActionName("Preview"), FormValueRequired("submit.Cancel")]
|
||||
public ActionResult CancelPreview(string returnUrl) {
|
||||
try {
|
||||
if (!_authorizer.Authorize(Permissions.ApplyTheme, T("Couldn't preview the current theme")))
|
||||
return new HttpUnauthorizedResult();
|
||||
_previewTheme.SetPreviewTheme(null);
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
catch (Exception exception) {
|
||||
_notifier.Error(T("Previewing theme failed: " + exception.Message));
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public ActionResult Activate(string themeName) {
|
||||
try {
|
||||
@ -85,5 +131,32 @@ namespace Orchard.Core.Themes.Controllers {
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
}
|
||||
|
||||
class FormValueRequiredAttribute : ActionMethodSelectorAttribute {
|
||||
private readonly string _submitButtonName;
|
||||
|
||||
public FormValueRequiredAttribute(string submitButtonName) {
|
||||
_submitButtonName = submitButtonName;
|
||||
}
|
||||
|
||||
public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo) {
|
||||
var value = controllerContext.HttpContext.Request.Form[_submitButtonName];
|
||||
return !string.IsNullOrEmpty(value);
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
|
||||
class FormValueAbsentAttribute : ActionMethodSelectorAttribute {
|
||||
private readonly string _submitButtonName;
|
||||
|
||||
public FormValueAbsentAttribute(string submitButtonName) {
|
||||
_submitButtonName = submitButtonName;
|
||||
}
|
||||
|
||||
public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo) {
|
||||
var value = controllerContext.HttpContext.Request.Form[_submitButtonName];
|
||||
return string.IsNullOrEmpty(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
6
src/Orchard.Web/Core/Themes/Preview/IPreviewTheme.cs
Normal file
6
src/Orchard.Web/Core/Themes/Preview/IPreviewTheme.cs
Normal file
@ -0,0 +1,6 @@
|
||||
namespace Orchard.Core.Themes.Preview {
|
||||
public interface IPreviewTheme : IDependency {
|
||||
string GetPreviewTheme();
|
||||
void SetPreviewTheme(string themeName);
|
||||
}
|
||||
}
|
37
src/Orchard.Web/Core/Themes/Preview/PreviewTheme.cs
Normal file
37
src/Orchard.Web/Core/Themes/Preview/PreviewTheme.cs
Normal file
@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using System.Web;
|
||||
using System.Web.Routing;
|
||||
using Orchard.Themes;
|
||||
|
||||
namespace Orchard.Core.Themes.Preview {
|
||||
public class PreviewTheme : IPreviewTheme, IThemeSelector {
|
||||
private static readonly string PreviewThemeKey = typeof(PreviewTheme).FullName;
|
||||
private readonly HttpContextBase _httpContext;
|
||||
|
||||
public PreviewTheme(HttpContextBase httpContext) {
|
||||
_httpContext = httpContext;
|
||||
}
|
||||
|
||||
public string GetPreviewTheme() {
|
||||
return Convert.ToString(_httpContext.Session[PreviewThemeKey]);
|
||||
}
|
||||
|
||||
public void SetPreviewTheme(string themeName) {
|
||||
if (string.IsNullOrEmpty(themeName)) {
|
||||
_httpContext.Session.Remove(PreviewThemeKey);
|
||||
}
|
||||
else {
|
||||
_httpContext.Session[PreviewThemeKey] = themeName;
|
||||
}
|
||||
}
|
||||
|
||||
public ThemeSelectorResult GetTheme(RequestContext context) {
|
||||
var previewThemeName = GetPreviewTheme();
|
||||
if (string.IsNullOrEmpty(previewThemeName))
|
||||
return null;
|
||||
|
||||
return new ThemeSelectorResult { Priority = 90, ThemeName = previewThemeName };
|
||||
}
|
||||
|
||||
}
|
||||
}
|
46
src/Orchard.Web/Core/Themes/Preview/PreviewThemeFilter.cs
Normal file
46
src/Orchard.Web/Core/Themes/Preview/PreviewThemeFilter.cs
Normal file
@ -0,0 +1,46 @@
|
||||
using System.Linq;
|
||||
using System.Web.Mvc;
|
||||
using Orchard.Core.Themes.ViewModels;
|
||||
using Orchard.Mvc.Filters;
|
||||
using Orchard.Mvc.ViewModels;
|
||||
using Orchard.Themes;
|
||||
|
||||
namespace Orchard.Core.Themes.Preview {
|
||||
public class PreviewThemeFilter : FilterProvider, IResultFilter {
|
||||
private readonly IThemeService _themeService;
|
||||
private readonly IPreviewTheme _previewTheme;
|
||||
|
||||
public PreviewThemeFilter(IThemeService themeService, IPreviewTheme previewTheme) {
|
||||
_themeService = themeService;
|
||||
_previewTheme = previewTheme;
|
||||
}
|
||||
|
||||
public void OnResultExecuting(ResultExecutingContext filterContext) {
|
||||
var viewResult = filterContext.Result as ViewResult;
|
||||
if (viewResult == null)
|
||||
return;
|
||||
|
||||
var baseViewModel = viewResult.ViewData.Model as BaseViewModel;
|
||||
if (baseViewModel == null)
|
||||
return;
|
||||
|
||||
var previewThemeName = _previewTheme.GetPreviewTheme();
|
||||
if (string.IsNullOrEmpty(previewThemeName))
|
||||
return;
|
||||
|
||||
var themes = _themeService.GetInstalledThemes();
|
||||
var model = new PreviewViewModel {
|
||||
Themes = themes.Select(theme => new SelectListItem {
|
||||
Text = theme.DisplayName,
|
||||
Value = theme.ThemeName,
|
||||
Selected = theme.ThemeName == previewThemeName
|
||||
})
|
||||
};
|
||||
baseViewModel.Zones.AddRenderPartial("body:before", "Admin/ThemePreview", model);
|
||||
}
|
||||
|
||||
public void OnResultExecuted(ResultExecutedContext filterContext) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -18,7 +18,7 @@ namespace Orchard.Core.Themes.Services {
|
||||
if (!context.HttpContext.Request.Path.StartsWith(Path.Combine(siteUrl, "admin").Replace("\\", "/"), true, CultureInfo.InvariantCulture))
|
||||
return null;
|
||||
|
||||
return new ThemeSelectorResult { Priority = 0, ThemeName = "TheAdmin" };
|
||||
return new ThemeSelectorResult { Priority = 100, ThemeName = "TheAdmin" };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
11
src/Orchard.Web/Core/Themes/ViewModels/PreviewViewModel.cs
Normal file
11
src/Orchard.Web/Core/Themes/ViewModels/PreviewViewModel.cs
Normal file
@ -0,0 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.Mvc;
|
||||
|
||||
namespace Orchard.Core.Themes.ViewModels {
|
||||
public class PreviewViewModel {
|
||||
public IEnumerable<SelectListItem> Themes { get; set; }
|
||||
}
|
||||
}
|
@ -31,6 +31,11 @@
|
||||
<%=Html.Encode(theme.HomePage) %>
|
||||
</p>
|
||||
<div>
|
||||
<% using(Html.BeginFormAntiForgeryPost(Url.Action("Preview"), FormMethod.Post, new { @class = "inline" })) { %>
|
||||
<fieldset>
|
||||
<button type="submit" title="<%=_Encoded("Preview") %>" name="themeName" value="<%=theme.ThemeName %>"><%=_Encoded("Preview") %></button>
|
||||
</fieldset>
|
||||
<% } %>
|
||||
<% using(Html.BeginFormAntiForgeryPost(Url.Action("Activate"), FormMethod.Post, new { @class = "inline" })) { %>
|
||||
<fieldset>
|
||||
<button type="submit" title="<%=_Encoded("Activate") %>" name="themeName" value="<%=theme.ThemeName %>"><%=_Encoded("Activate") %></button>
|
||||
|
25
src/Orchard.Web/Core/Themes/Views/Admin/ThemePreview.ascx
Normal file
25
src/Orchard.Web/Core/Themes/Views/Admin/ThemePreview.ascx
Normal file
@ -0,0 +1,25 @@
|
||||
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl<PreviewViewModel>" %>
|
||||
<%@ Import Namespace="Orchard.Core.Themes.ViewModels"%>
|
||||
<style type="text/css">
|
||||
#themepreview, #themepreview fieldset, #themepreview input, #themepreview select
|
||||
{
|
||||
margin: 0; padding: 0; border:none; font-size: 1em; width:auto; color: #000;
|
||||
font-family:Frutiger,"Frutiger Linotype",Univers,Calibri,"Gill Sans","Gill Sans MT","Myriad Pro",Myriad,"DejaVu Sans Condensed","Liberation Sans","Nimbus Sans L",Tahoma,Geneva,"Helvetica Neue",Helvetica,Arial,sans-serif;
|
||||
}
|
||||
#themepreview { background: #000; font-size:15px; }
|
||||
#themepreview span {color: #ccc; }
|
||||
#themepreview fieldset { margin: 0; padding: 3px; }
|
||||
#themepreview button { font-size: .8em; }
|
||||
</style>
|
||||
<div id="themepreview">
|
||||
<% using(Html.BeginFormAntiForgeryPost(Url.Action("Preview", new{Controller="Admin", Area="Themes"}), FormMethod.Post, new { @class = "inline" })) { %>
|
||||
<fieldset>
|
||||
<span><%=T("You are previewing ")%></span>
|
||||
<%=Html.DropDownList("ThemeName", Model.Themes, new {onChange = "this.form.submit();"})%>
|
||||
<button type="submit" title="<%=_Encoded("Preview")%>" name="submit.Preview" value="<%=_Encoded("Preview")%>"><%=_Encoded("Preview")%></button>
|
||||
<button type="submit" title="<%=_Encoded("Apply")%>" name="submit.Apply" value="<%=_Encoded("Apply")%>"><%=_Encoded("Apply") %></button>
|
||||
<button type="submit" title="<%=_Encoded("Cancel")%>" name="submit.Cancel" value="<%=_Encoded("Cancel")%>"><%=_Encoded("Cancel")%></button>
|
||||
<%=Html.Hidden("ReturnUrl", Context.Request.Url)%>
|
||||
</fieldset>
|
||||
<% } %>
|
||||
</div>
|
Loading…
Reference in New Issue
Block a user