diff --git a/src/Orchard.Web/Modules/Orchard.Modules/Controllers/AdminController.cs b/src/Orchard.Web/Modules/Orchard.Modules/Controllers/AdminController.cs index 3475b3c4e..856fdcb12 100644 --- a/src/Orchard.Web/Modules/Orchard.Modules/Controllers/AdminController.cs +++ b/src/Orchard.Web/Modules/Orchard.Modules/Controllers/AdminController.cs @@ -92,9 +92,13 @@ namespace Orchard.Modules.Controllers { modules = modules.Skip((pager.Page - 1) * pager.PageSize).Take(pager.PageSize); } + // This way we can more or less reliably handle this implicit dependency. + var installModules = _featureManager.GetEnabledFeatures().FirstOrDefault(f => f.Id == "PackagingServices") != null; + modules = modules.ToList(); foreach (ModuleEntry moduleEntry in modules) { moduleEntry.IsRecentlyInstalled = _moduleService.IsRecentlyInstalled(moduleEntry.Descriptor); + moduleEntry.CanUninstall = installModules; if (_extensionDisplayEventHandler != null) { foreach (string notification in _extensionDisplayEventHandler.Displaying(moduleEntry.Descriptor, ControllerContext.RequestContext)) { @@ -103,9 +107,10 @@ namespace Orchard.Modules.Controllers { } } + return View(new ModulesIndexViewModel { Modules = modules, - InstallModules = _featureManager.GetEnabledFeatures().FirstOrDefault(f => f.Id == "PackagingServices") != null, + InstallModules = installModules, Options = options, Pager = Shape.Pager(pager).TotalItemCount(totalItemCount) }); diff --git a/src/Orchard.Web/Modules/Orchard.Modules/Models/ModuleEntry.cs b/src/Orchard.Web/Modules/Orchard.Modules/Models/ModuleEntry.cs index 7f67c69ae..f63898e1d 100644 --- a/src/Orchard.Web/Modules/Orchard.Modules/Models/ModuleEntry.cs +++ b/src/Orchard.Web/Modules/Orchard.Modules/Models/ModuleEntry.cs @@ -32,5 +32,10 @@ namespace Orchard.Modules.Models { /// List of module notifications. /// public List Notifications { get; set; } + + /// + /// Indicates whether the module can be uninstalled by the user. + /// + public bool CanUninstall { get; set; } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Modules/Views/Admin/Index.cshtml b/src/Orchard.Web/Modules/Orchard.Modules/Views/Admin/Index.cshtml index ec095798f..3a8b0c424 100644 --- a/src/Orchard.Web/Modules/Orchard.Modules/Views/Admin/Index.cshtml +++ b/src/Orchard.Web/Modules/Orchard.Modules/Views/Admin/Index.cshtml @@ -17,16 +17,17 @@ if (Model.InstallModules) { - @Html.ActionLink(T("Install a module from your computer").ToString(), "AddModule", "PackagingServices", new { area = "Orchard.Packaging", returnUrl = HttpContext.Current.Request.RawUrl }, null) -} + @Html.ActionLink(T("Install a module from your computer").ToString(), "AddModule", "PackagingServices", new { area = "Orchard.Packaging", returnUrl = HttpContext.Current.Request.RawUrl }, null) + } if (Model.Modules.Any()) { - } else { + } + else {

@T("No modules available").ToString()

} diff --git a/src/Orchard.Web/Modules/Orchard.Modules/Views/Admin/Recipes.cshtml b/src/Orchard.Web/Modules/Orchard.Modules/Views/Admin/Recipes.cshtml index a9166145d..5170a5f0c 100644 --- a/src/Orchard.Web/Modules/Orchard.Modules/Views/Admin/Recipes.cshtml +++ b/src/Orchard.Web/Modules/Orchard.Modules/Views/Admin/Recipes.cshtml @@ -6,34 +6,34 @@ } @using (Html.BeginFormAntiForgeryPost()) { if (Model.Modules.Any()) { - + } + else { +

@T("No modules available").ToString()

+ } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Modules/Views/ModuleEntry.cshtml b/src/Orchard.Web/Modules/Orchard.Modules/Views/ModuleEntry.cshtml index 7f4040354..28fba2d08 100644 --- a/src/Orchard.Web/Modules/Orchard.Modules/Views/ModuleEntry.cshtml +++ b/src/Orchard.Web/Modules/Orchard.Modules/Views/ModuleEntry.cshtml @@ -2,30 +2,46 @@ @using Orchard.Mvc.Html; @using Orchard.Modules.ViewModels; @using Orchard.Environment.Extensions.Models; +@using Orchard.Utility.Extensions; -@{ string moduleClasses = Model.ContentPart.IsRecentlyInstalled ? "recentlyInstalledModule" : string.Empty; } +@{ + Script.Require("ShapesBase").AtFoot(); + + Orchard.Modules.Models.ModuleEntry module = Model.Module; + var moduleClasses = module.IsRecentlyInstalled ? "class=\"recentlyInstalledModule\"" : String.Empty; +}
- @if (Model.ContentPart.Notifications != null && Model.ContentPart.Notifications.Count > 0) { -
- @foreach (string notification in Model.ContentPart.Notifications) { + @if (module.Notifications != null && module.Notifications.Count > 0) { +
+ @foreach (var notification in module.Notifications) {
@Html.Raw(notification)
} -
- } +
+ }
- class="@moduleClasses"}}>@Model.ContentPart.Descriptor.Name - @T("Version: {0}", !string.IsNullOrEmpty(Model.ContentPart.Descriptor.Version) ? Model.ContentPart.Descriptor.Version : T("1.0").ToString()) +

+ @module.Descriptor.Name - @T("Version: {0}", !String.IsNullOrEmpty(module.Descriptor.Version) ? module.Descriptor.Version : T("1.0").ToString()) +

- @if (!string.IsNullOrEmpty(Model.ContentPart.Descriptor.Description)) { -

@Model.ContentPart.Descriptor.Description

+ @Html.ActionLink( + T("Uninstall").Text, + "UninstallModule", + "PackagingServices", + new { ModuleId = module.Descriptor.Id, ReturnUrl = Request.ToUrlString(), Area = "Orchard.Packaging" }, + new { itemprop = "RemoveUrl UnsafeUrl" }) + + @if (!String.IsNullOrEmpty(module.Descriptor.Description)) { +

@module.Descriptor.Description

}
    - @{ IEnumerable features = Model.ContentPart.Descriptor.Features; } -
  • @T("Features: {0}", MvcHtmlString.Create(string.Join(", ", features.Select(f => Html.Link(string.IsNullOrEmpty(f.Name) ? f.Id : f.Name, string.Format("{0}#{1}", Url.Action("features", new { area = "Orchard.Modules" }), f.Id.AsFeatureId(n => T(n)))).ToString()).OrderBy(s => s).ToArray())))
  • -
  •  | @T("Author: {0}", !string.IsNullOrEmpty(Model.ContentPart.Descriptor.Author) ? Model.ContentPart.Descriptor.Author : T("Unknown").ToString())
  • -
  •  | @T("Website: ") - @if (!string.IsNullOrEmpty(Model.ContentPart.Descriptor.WebSite)) { @Model.ContentPart.Descriptor.WebSite } + @{ var features = module.Descriptor.Features; } +
  • @T("Features: {0}", MvcHtmlString.Create(String.Join(", ", features.Select(f => Html.Link(String.IsNullOrEmpty(f.Name) ? f.Id : f.Name, String.Format("{0}#{1}", Url.Action("features", new { area = "Orchard.Modules" }), f.Id.AsFeatureId(n => T(n)))).ToString()).OrderBy(s => s).ToArray())))
  • +
  •  | @T("Author: {0}", !String.IsNullOrEmpty(module.Descriptor.Author) ? module.Descriptor.Author : T("Unknown").ToString())
  • +
  • +  | @T("Website: ") + @if (!String.IsNullOrEmpty(module.Descriptor.WebSite)) { @module.Descriptor.WebSite } else { @T("Unknown").ToString() }
diff --git a/src/Orchard.Web/Modules/Orchard.Packaging/Controllers/PackagingServicesController.cs b/src/Orchard.Web/Modules/Orchard.Packaging/Controllers/PackagingServicesController.cs index 7c70e20c2..30681f4fc 100644 --- a/src/Orchard.Web/Modules/Orchard.Packaging/Controllers/PackagingServicesController.cs +++ b/src/Orchard.Web/Modules/Orchard.Packaging/Controllers/PackagingServicesController.cs @@ -2,10 +2,12 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Net; using System.Web.Hosting; using System.Web.Mvc; using System.Xml.Linq; using NuGet; +using Orchard.Environment; using Orchard.Environment.Configuration; using Orchard.Environment.Extensions.Models; using Orchard.FileSystems.AppData; @@ -33,6 +35,7 @@ namespace Orchard.Packaging.Controllers { private readonly IPackagingSourceManager _packagingSourceManager; private readonly IAppDataFolderRoot _appDataFolderRoot; private readonly IModuleService _moduleService; + private readonly IHostEnvironment _hostEnvironment; private readonly IRecipeHarvester _recipeHarvester; private readonly IRecipeManager _recipeManager; @@ -42,8 +45,9 @@ namespace Orchard.Packaging.Controllers { IPackagingSourceManager packagingSourceManager, IAppDataFolderRoot appDataFolderRoot, IOrchardServices services, - IModuleService moduleService) - : this(shellSettings, packageManager, packagingSourceManager, appDataFolderRoot, services, moduleService, null, null) { + IModuleService moduleService, + IHostEnvironment hostEnvironment) + : this(shellSettings, packageManager, packagingSourceManager, appDataFolderRoot, services, moduleService, hostEnvironment, null, null) { } public PackagingServicesController( @@ -53,6 +57,7 @@ namespace Orchard.Packaging.Controllers { IAppDataFolderRoot appDataFolderRoot, IOrchardServices services, IModuleService moduleService, + IHostEnvironment hostEnvironment, IRecipeHarvester recipeHarvester, IRecipeManager recipeManager) { @@ -60,6 +65,7 @@ namespace Orchard.Packaging.Controllers { _packageManager = packageManager; _appDataFolderRoot = appDataFolderRoot; _moduleService = moduleService; + _hostEnvironment = hostEnvironment; _recipeHarvester = recipeHarvester; _recipeManager = recipeManager; _packagingSourceManager = packagingSourceManager; @@ -80,14 +86,30 @@ namespace Orchard.Packaging.Controllers { return View(); } - [HttpPost, ActionName("RemoveTheme")] - public ActionResult RemoveThemePOST(string themeId, string returnUrl, string retryUrl) { + [HttpPost, ActionName("UninstallTheme")] + public ActionResult UninstallThemePost(string themeId, string returnUrl, string retryUrl) { + if (String.IsNullOrEmpty(themeId)) { + return new HttpStatusCodeResult(HttpStatusCode.BadRequest); + } + if (_shellSettings.Name != ShellSettings.DefaultName || !Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to remove themes"))) return new HttpUnauthorizedResult(); return UninstallPackage(PackageBuilder.BuildPackageId(themeId, DefaultExtensionTypes.Theme), returnUrl, retryUrl); } + [HttpPost, ActionName("UninstallModule")] + public ActionResult UninstallModulePost(string moduleId, string returnUrl, string retryUrl) { + if (String.IsNullOrEmpty(moduleId)) { + return new HttpStatusCodeResult(HttpStatusCode.BadRequest); + } + + if (_shellSettings.Name != ShellSettings.DefaultName || !Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to remove modules"))) + return new HttpUnauthorizedResult(); + + return UninstallPackage(PackageBuilder.BuildPackageId(moduleId, DefaultExtensionTypes.Module), returnUrl, retryUrl); + } + public ActionResult AddModule(string returnUrl) { if (_shellSettings.Name != ShellSettings.DefaultName || !Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to add modules"))) return new HttpUnauthorizedResult(); @@ -105,7 +127,7 @@ namespace Orchard.Packaging.Controllers { } try { - PackageInfo packageInfo = _packageManager.Install(packageId, version, source.FeedUrl, HostingEnvironment.MapPath("~/")); + PackageInfo packageInfo = _packageManager.Install(packageId, version, source.FeedUrl, MapAppRoot()); if (DefaultExtensionTypes.IsTheme(packageInfo.ExtensionType)) { Services.Notifier.Information(T("The theme has been successfully installed. It can be enabled in the \"Themes\" page accessible from the menu.")); @@ -147,7 +169,7 @@ namespace Orchard.Packaging.Controllers { string fullFileName = Path.Combine(_appDataFolderRoot.RootFolder, Path.GetFileName(httpPostedFileBase.FileName)).Replace(Path.DirectorySeparatorChar, '/'); httpPostedFileBase.SaveAs(fullFileName); var package = new ZipPackage(fullFileName); - PackageInfo packageInfo = _packageManager.Install(package, _appDataFolderRoot.RootFolder, HostingEnvironment.MapPath("~/")); + PackageInfo packageInfo = _packageManager.Install(package, _appDataFolderRoot.RootFolder, MapAppRoot()); ExtensionDescriptor extensionDescriptor = package.GetExtensionDescriptor(packageInfo.ExtensionType); System.IO.File.Delete(fullFileName); @@ -247,20 +269,21 @@ namespace Orchard.Packaging.Controllers { return Redirect(redirectUrl); } - public ActionResult UninstallPackage(string id, string returnUrl, string retryUrl) { - if (_shellSettings.Name != ShellSettings.DefaultName || !Services.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to uninstall packages"))) - return new HttpUnauthorizedResult(); - + private ActionResult UninstallPackage(string id, string returnUrl, string retryUrl) { try { - _packageManager.Uninstall(id, HostingEnvironment.MapPath("~/")); + _packageManager.Uninstall(id, MapAppRoot()); } catch (Exception exception) { Services.Notifier.Error(T("Uninstall failed: {0}", exception.Message)); - return Redirect(retryUrl); + return Redirect(!String.IsNullOrEmpty(retryUrl) ? retryUrl : returnUrl); } Services.Notifier.Information(T("Uninstalled package \"{0}\"", id)); return this.RedirectLocal(returnUrl, "~/"); } + + private string MapAppRoot() { + return _hostEnvironment.MapPath("~/"); + } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Packaging/Orchard.Packaging.csproj b/src/Orchard.Web/Modules/Orchard.Packaging/Orchard.Packaging.csproj index 41fb44184..50846ff2a 100644 --- a/src/Orchard.Web/Modules/Orchard.Packaging/Orchard.Packaging.csproj +++ b/src/Orchard.Web/Modules/Orchard.Packaging/Orchard.Packaging.csproj @@ -110,6 +110,7 @@ + diff --git a/src/Orchard.Web/Modules/Orchard.Packaging/Services/PackageManager.cs b/src/Orchard.Web/Modules/Orchard.Packaging/Services/PackageManager.cs index 1f25d630f..03f0bfa41 100644 --- a/src/Orchard.Web/Modules/Orchard.Packaging/Services/PackageManager.cs +++ b/src/Orchard.Web/Modules/Orchard.Packaging/Services/PackageManager.cs @@ -5,6 +5,8 @@ using NuGet; using Orchard.Environment.Extensions; using Orchard.Environment.Extensions.Folders; using Orchard.Environment.Extensions.Models; +using Orchard.Environment.Features; +using Orchard.Environment.State; using Orchard.Localization; using Orchard.Packaging.Models; @@ -13,15 +15,24 @@ namespace Orchard.Packaging.Services { public class PackageManager : IPackageManager { private readonly IExtensionManager _extensionManager; private readonly IPackageBuilder _packageBuilder; - private readonly IPackageInstaller _packageExpander; + private readonly IPackageInstaller _packageInstaller; + private readonly IShellStateManager _shellStateManager; + private readonly IFeatureManager _featureManager; + private readonly IPackageUninstallHandler _packageUninstallHandler; public PackageManager( IExtensionManager extensionManager, IPackageBuilder packageBuilder, - IPackageInstaller packageExpander) { + IPackageInstaller packageInstaller, + IShellStateManager shellStateManager, + IFeatureManager featureManager, + IPackageUninstallHandler packageUninstallHandler) { _extensionManager = extensionManager; _packageBuilder = packageBuilder; - _packageExpander = packageExpander; + _packageInstaller = packageInstaller; + _shellStateManager = shellStateManager; + _featureManager = featureManager; + _packageUninstallHandler = packageUninstallHandler; T = NullLocalizer.Instance; } @@ -61,15 +72,38 @@ namespace Orchard.Packaging.Services { } public PackageInfo Install(IPackage package, string location, string applicationPath) { - return DoInstall(() => _packageExpander.Install(package, location, applicationPath)); + return DoInstall(() => _packageInstaller.Install(package, location, applicationPath)); } public PackageInfo Install(string packageId, string version, string location, string applicationPath) { - return DoInstall(() => _packageExpander.Install(packageId, version, location, applicationPath)); + return DoInstall(() => _packageInstaller.Install(packageId, version, location, applicationPath)); } public void Uninstall(string packageId, string applicationPath) { - _packageExpander.Uninstall(packageId, applicationPath); + var extensionToUninstall = _extensionManager.AvailableExtensions() + .FirstOrDefault(extension => PackageBuilder.BuildPackageId(extension.Id, extension.ExtensionType) == packageId); + + if (extensionToUninstall == null) { + throw new OrchardException(T("There is no extension that has the package ID \"{0}\".", packageId)); + } + + var featureIdsToUninstall = extensionToUninstall.Features.Select(feature => feature.Id); + var shellState = _shellStateManager.GetShellState(); + var featureStates = shellState.Features.Where(featureState => featureIdsToUninstall.Contains(featureState.Name)); + + // This means that no feature from this extension wasn enabled yet, can be uninstalled directly. + if (!featureStates.Any()) { + _packageUninstallHandler.QueuePackageUninstall(packageId); + } + else { + _featureManager.DisableFeatures(extensionToUninstall.Features.Select(feature => feature.Id), true); + + // Installed state can't be deduced from the shell state changes like for enabled state, so have to + // set that explicitly. + foreach (var featureState in featureStates) { + _shellStateManager.UpdateInstalledState(featureState, Environment.State.Models.ShellFeatureState.State.Falling); + } + } } #endregion diff --git a/src/Orchard.Web/Modules/Orchard.Packaging/Services/PackageUninstallHandler.cs b/src/Orchard.Web/Modules/Orchard.Packaging/Services/PackageUninstallHandler.cs new file mode 100644 index 000000000..77fb61a7e --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Packaging/Services/PackageUninstallHandler.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using Orchard.Environment; +using Orchard.Environment.Configuration; +using Orchard.Environment.Descriptor; +using Orchard.Environment.Extensions.Models; +using Orchard.Environment.State; +using Orchard.Events; + +namespace Orchard.Packaging.Services { + public interface IPackageUninstallHandler : IEventHandler { + /// + /// Queues a package to be uninstalled after the request is processed. + /// + /// The textual ID of the package. + void QueuePackageUninstall(string packageId); + + /// + /// Uninstalls the given package from the system. + /// + /// The textual ID of the package. + void UninstallPackage(string packageId); + } + + public class PackageUninstallHandler : IFeatureEventHandler, IPackageUninstallHandler { + private readonly ShellSettings _shellSettings; + private readonly IShellDescriptorManager _shellDescriptorManager; + private readonly IProcessingEngine _processingEngine; + private readonly IHostEnvironment _hostEnvironment; + private readonly IPackageInstaller _packageInstaller; + + public PackageUninstallHandler( + ShellSettings shellSettings, + IShellDescriptorManager shellDescriptorManager, + IProcessingEngine processingEngine, + IHostEnvironment hostEnvironment, + IPackageInstaller packageInstaller) { + _shellSettings = shellSettings; + _shellDescriptorManager = shellDescriptorManager; + _processingEngine = processingEngine; + _hostEnvironment = hostEnvironment; + _packageInstaller = packageInstaller; + } + + public void Installing(Feature feature) { + } + + public void Installed(Feature feature) { + } + + public void Enabling(Feature feature) { + } + + public void Enabled(Feature feature) { + } + + public void Disabling(Feature feature) { + } + + public void Disabled(Feature feature) { + } + + public void Uninstalling(Feature feature) { + } + + public void Uninstalled(Feature feature) { + QueuePackageUninstall(PackageBuilder.BuildPackageId(feature.Descriptor.Extension.Id, feature.Descriptor.Extension.ExtensionType)); + } + + public void QueuePackageUninstall(string packageId) { + _processingEngine.AddTask( + _shellSettings, + _shellDescriptorManager.GetShellDescriptor(), + "IPackageUninstallHandler.UninstallPackage", + new Dictionary { { "packageId", packageId } }); + } + + public void UninstallPackage(string packageId) { + _packageInstaller.Uninstall(packageId, _hostEnvironment.MapPath("~/")); + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Themes/Views/Admin/Index.cshtml b/src/Orchard.Web/Modules/Orchard.Themes/Views/Admin/Index.cshtml index f833ad4ec..751bd1496 100644 --- a/src/Orchard.Web/Modules/Orchard.Themes/Views/Admin/Index.cshtml +++ b/src/Orchard.Web/Modules/Orchard.Themes/Views/Admin/Index.cshtml @@ -12,25 +12,27 @@ @T("There is no current theme in the application. The built-in theme will be used.")
@Html.ActionLink(T("Install a new Theme").ToString(), "Install")

-} else { +} +else {

@T("Current Theme")

- @Display.ThemeEntry_Current(ContentPart: Model.CurrentTheme) + @Display.ThemeEntry_Current(Theme: Model.CurrentTheme) }

@T("Available")

@if (Model.InstallThemes) { - @Html.ActionLink(T("Install a theme from your computer").ToString(), "AddTheme", "PackagingServices", new { area = "Orchard.Packaging", returnUrl = HttpContext.Current.Request.RawUrl }, null) -} + @Html.ActionLink(T("Install a theme from your computer").ToString(), "AddTheme", "PackagingServices", new { area = "Orchard.Packaging", returnUrl = HttpContext.Current.Request.RawUrl }, null) + }
@if (Model.Themes == null || Model.Themes.Count() <= 0) {

@T("There are no additional themes installed.")

-} else { +} +else {
    - @foreach (ThemeEntry themeEntry in Model.Themes) { -
  • @Display.ThemeEntry(ContentPart: themeEntry)
  • + @foreach (var themeEntry in Model.Themes) { +
  • @Display.ThemeEntry(Theme: themeEntry)
  • }
} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Themes/Views/ThemeEntry.Current.cshtml b/src/Orchard.Web/Modules/Orchard.Themes/Views/ThemeEntry.Current.cshtml index 36cd94744..b06bcb7b8 100644 --- a/src/Orchard.Web/Modules/Orchard.Themes/Views/ThemeEntry.Current.cshtml +++ b/src/Orchard.Web/Modules/Orchard.Themes/Views/ThemeEntry.Current.cshtml @@ -2,17 +2,23 @@ @using Orchard.Mvc.Html @using Orchard.Environment.Extensions.Models +@{ + Orchard.Themes.Models.ThemeEntry theme = Model.Theme; +} +
- @Html.Image(Href(Html.ThemePath((ExtensionDescriptor)Model.ContentPart.Descriptor, "/Theme.png")), Html.Encode((string)Model.ContentPart.Name), new { @class = "themePreviewImage" }) + @Html.Image(Href(Html.ThemePath(theme.Descriptor, "/Theme.png")), Html.Encode(theme.Name), new { @class = "themePreviewImage" })
-

@Model.ContentPart.Name

-
@T("By") @Model.ContentPart.Descriptor.Author
- @T("Version:") @Model.ContentPart.Descriptor.Version
- @if (Model.ContentPart.Descriptor.WebSite != null) { - @Model.ContentPart.Descriptor.WebSite
- }
- -

@Model.ContentPart.Descriptor.Description

+

@theme.Name

+
+ @T("By") @theme.Descriptor.Author
+ @T("Version:") @theme.Descriptor.Version
+ @if (theme.Descriptor.WebSite != null) { + @theme.Descriptor.WebSite
+ } +
+ +

@theme.Descriptor.Description

\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Themes/Views/ThemeEntry.cshtml b/src/Orchard.Web/Modules/Orchard.Themes/Views/ThemeEntry.cshtml index 9be67fd69..e479567ec 100644 --- a/src/Orchard.Web/Modules/Orchard.Themes/Views/ThemeEntry.cshtml +++ b/src/Orchard.Web/Modules/Orchard.Themes/Views/ThemeEntry.cshtml @@ -1,65 +1,74 @@ @using Orchard.Themes.Models @using Orchard.Mvc.Html @using Orchard.Environment.Extensions.Models +@using Orchard.Utility.Extensions; -@{ string themeClasses = Model.ContentPart.IsRecentlyInstalled ? "recentlyInstalledTheme" : string.Empty; } +@{ + Script.Require("ShapesBase").AtFoot(); + + Orchard.Themes.Models.ThemeEntry theme = Model.Theme; + var themeClasses = theme.IsRecentlyInstalled ? "class=\"recentlyInstalledTheme\"" : String.Empty; +}
- class="@themeClasses"}}>@Model.ContentPart.Name +

@theme.Name

- @Html.Image(Href(Html.ThemePath((ExtensionDescriptor) Model.ContentPart.Descriptor, "/Theme.png")), Html.Encode((string)Model.ContentPart.Name), null) + @Html.Image(Href(Html.ThemePath((ExtensionDescriptor)theme.Descriptor, "/Theme.png")), Html.Encode((string)theme.Name), null) @using (Html.BeginFormAntiForgeryPost(Url.Action("Activate"), FormMethod.Post, new { @class = "inline" })) { - @Html.Hidden("themeId", (string)Model.ContentPart.Descriptor.Id) + @Html.Hidden("themeId", (string)theme.Descriptor.Id) } @using (Html.BeginFormAntiForgeryPost(Url.Action("Preview"), FormMethod.Post, new { @class = "inline" })) { - @Html.Hidden("themeId", (string)Model.ContentPart.Descriptor.Id) + @Html.Hidden("themeId", (string)theme.Descriptor.Id) }

- @T("By") @Model.ContentPart.Descriptor.Author
- @T("Version:") @Model.ContentPart.Descriptor.Version
- @Model.ContentPart.Descriptor.Description
- @if (Model.ContentPart.Descriptor.WebSite != null) { - @Model.ContentPart.Descriptor.WebSite
+ @T("By") @theme.Descriptor.Author
+ @T("Version:") @theme.Descriptor.Version
+ @theme.Descriptor.Description
+ @if (theme.Descriptor.WebSite != null) { + @theme.Descriptor.WebSite
}

- @if (Model.ContentPart.Notifications != null && Model.ContentPart.Notifications.Count > 0) { + @if (theme.Notifications != null && theme.Notifications.Count > 0) {
    - @foreach (string notification in Model.ContentPart.Notifications) { -
  • @notification
  • - } + @foreach (string notification in theme.Notifications) { +
  • @notification
  • + }
} - @if (Model.ContentPart.Enabled) { + @if (theme.Enabled) { using (Html.BeginFormAntiForgeryPost(Url.Action("Disable"), FormMethod.Post, new { @class = "inline link" })) { - @Html.Hidden("themeId", (string)Model.ContentPart.Descriptor.Id) + @Html.Hidden("themeId", (string)theme.Descriptor.Id) } } else { using (Html.BeginFormAntiForgeryPost(Url.Action("Enable"), FormMethod.Post, new { @class = "inline link" })) { - @Html.Hidden("themeId", (string)Model.ContentPart.Descriptor.Id) + @Html.Hidden("themeId", (string)theme.Descriptor.Id) } } - @if (Model.ContentPart.NeedsUpdate) { + @if (theme.NeedsUpdate) { | using (Html.BeginFormAntiForgeryPost(Url.Action("Update"), FormMethod.Post, new { @class = "inline link" })) { - @Html.Hidden("themeId", (string)Model.ContentPart.Descriptor.Id) -
+ @Html.Hidden("themeId", (string)theme.Descriptor.Id) +
} } - @if (Model.ContentPart.CanUninstall) { + @if (theme.CanUninstall) { | - using (Html.BeginFormAntiForgeryPost(Url.Action("RemoveTheme", "PackagingServices", new { area = "Orchard.Packaging", returnUrl = HttpContext.Current.Request.RawUrl, retryUrl = HttpContext.Current.Request.RawUrl, themeId = Model.ContentPart.Descriptor.Id }), FormMethod.Post, new { @class = "inline link" })) { - - } + @Html.ActionLink( + T("Uninstall").Text, + "UninstallTheme", + "PackagingServices", + new { ThemeId = theme.Descriptor.Id, ReturnUrl = Request.ToUrlString(), Area = "Orchard.Packaging" }, + new { itemprop = "RemoveUrl UnsafeUrl" }) }
\ No newline at end of file