From 89f7a31beff6bb065b5722c4a7fc69523f66a917 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 2 Oct 2013 20:00:01 +1000 Subject: [PATCH 01/31] Updates the Create/AddMenu overloads to ensure a name is specified, fixes all localization of all menu items for all new trees. --- .../MyPackage/Common/Js/MyPackage.js | 59 ------------- .../ServerSidePropertyEditorsController.cs | 15 ---- .../MyPackage/System/MyStartupHandler.cs | 41 --------- .../MyPackage/Trees/LegacyTestTree.cs | 35 +++++++- .../ServerEnvironment.cshtml | 9 -- .../App_Plugins/MyPackage/Views/Web.config | 58 ------------ src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 7 +- .../Trees/ContentTreeController.cs | 51 +++++------ .../Trees/ContentTreeControllerBase.cs | 4 +- .../Trees/DataTypeTreeController.cs | 7 +- .../Trees/LegacyTreeDataConverter.cs | 2 +- src/Umbraco.Web/Trees/MediaTreeController.cs | 16 ++-- src/Umbraco.Web/Trees/MemberTreeController.cs | 8 +- src/Umbraco.Web/Trees/Menu/MenuItem.cs | 12 ++- .../Trees/Menu/MenuItemCollection.cs | 88 ++++++++++++------- 15 files changed, 139 insertions(+), 273 deletions(-) delete mode 100644 src/Umbraco.Web.UI/App_Plugins/MyPackage/Common/Js/MyPackage.js delete mode 100644 src/Umbraco.Web.UI/App_Plugins/MyPackage/Controllers/ServerSidePropertyEditorsController.cs delete mode 100644 src/Umbraco.Web.UI/App_Plugins/MyPackage/System/MyStartupHandler.cs delete mode 100644 src/Umbraco.Web.UI/App_Plugins/MyPackage/Views/ServerSidePropertyEditors/ServerEnvironment.cshtml delete mode 100644 src/Umbraco.Web.UI/App_Plugins/MyPackage/Views/Web.config diff --git a/src/Umbraco.Web.UI/App_Plugins/MyPackage/Common/Js/MyPackage.js b/src/Umbraco.Web.UI/App_Plugins/MyPackage/Common/Js/MyPackage.js deleted file mode 100644 index 9e84ccb37d..0000000000 --- a/src/Umbraco.Web.UI/App_Plugins/MyPackage/Common/Js/MyPackage.js +++ /dev/null @@ -1,59 +0,0 @@ -'use strict'; - -(function () { - - angular.module("myPackage.directives", []); - angular.module("myPackage.controllers", []); - - angular.module("myPackage.directives").directive('valPostcode', function () { - - /// - /// A custom directive to validate for postcodes - /// - - return { - require: 'ngModel', - link: function (scope, elm, attrs, ctrl) { - - if (!attrs.valPostcode) - throw "valPostcode requires an attribute value specifying the country for the postcode"; - - var patternValidator = function (viewValue) { - //NOTE: we don't validate on empty values, use required validator for that - if (viewValue) { - var country = scope.$eval(attrs.valPostcode); - switch (country) { - case "Australia": - if (/^\d{4}$/.test(viewValue)) { - ctrl.$setValidity('valPostcode', true); - //reset the error msg - ctrl.errorMsg = ""; - return viewValue; - } - else { - // it is invalid, return undefined (no model update) - ctrl.$setValidity('valPostcode', false); - //assign an error msg property to the current validator - ctrl.errorMsg = "Australian postcodes must be a 4 digit number"; - return undefined; - } - - default: - throw "The country specified does not have validation logic applied"; - } - } - else { - // there is no value to validate so return that it is valid. - ctrl.$setValidity('valPostcode', true); - return viewValue; - } - }; - - ctrl.$formatters.push(patternValidator); - ctrl.$parsers.push(patternValidator); - } - }; - }); - - -})(); \ No newline at end of file diff --git a/src/Umbraco.Web.UI/App_Plugins/MyPackage/Controllers/ServerSidePropertyEditorsController.cs b/src/Umbraco.Web.UI/App_Plugins/MyPackage/Controllers/ServerSidePropertyEditorsController.cs deleted file mode 100644 index 5671a9a870..0000000000 --- a/src/Umbraco.Web.UI/App_Plugins/MyPackage/Controllers/ServerSidePropertyEditorsController.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.Web.Mvc; - -namespace Umbraco.Web.UI.App_Plugins.MyPackage.Controllers -{ - - public class ServerSidePropertyEditorsController : Controller - { - [HttpGet] - public ActionResult ServerEnvironment() - { - return View(); - } - - } -} diff --git a/src/Umbraco.Web.UI/App_Plugins/MyPackage/System/MyStartupHandler.cs b/src/Umbraco.Web.UI/App_Plugins/MyPackage/System/MyStartupHandler.cs deleted file mode 100644 index 00d9904919..0000000000 --- a/src/Umbraco.Web.UI/App_Plugins/MyPackage/System/MyStartupHandler.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System.Collections.Generic; -using System.Web; -using System.Web.Mvc; -using System.Web.Routing; -using Umbraco.Core; -using Umbraco.Web.UI.JavaScript; - -namespace Umbraco.Web.UI.App_Plugins.MyPackage.System -{ - public class MyStartupHandler : ApplicationEventHandler - { - protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) - { - base.ApplicationStarted(umbracoApplication, applicationContext); - - //create a custom server variable to be exposed in JS - ServerVariablesParser.Parsing += (sender, dictionary) => - { - - var httpContext = HttpContext.Current; - if (httpContext == null) return; - - var urlHelper = new UrlHelper(new RequestContext(new HttpContextWrapper(httpContext), new RouteData())); - - dictionary.Add("MyPackage", new Dictionary() - { - {"serverEnvironmentView", urlHelper.Action("ServerEnvironment", "ServerSidePropertyEditors", new {area = "MyPackage"})} - }); - }; - - //For testing for now we'll route to /Belle/Main - var route = RouteTable.Routes.MapRoute( - "umbraco-server-side-property-editors", - "Belle/PropertyEditors/{controller}/{action}/{id}", - new { controller = "ServerSidePropertyEditors", action = "Index", id = UrlParameter.Optional }); - //assign it to an area so that the plugin view engine looks for us - route.DataTokens.Add("area", "MyPackage"); - } - - } -} \ No newline at end of file diff --git a/src/Umbraco.Web.UI/App_Plugins/MyPackage/Trees/LegacyTestTree.cs b/src/Umbraco.Web.UI/App_Plugins/MyPackage/Trees/LegacyTestTree.cs index 0cd5d43d8a..8655af9b11 100644 --- a/src/Umbraco.Web.UI/App_Plugins/MyPackage/Trees/LegacyTestTree.cs +++ b/src/Umbraco.Web.UI/App_Plugins/MyPackage/Trees/LegacyTestTree.cs @@ -1,8 +1,41 @@ -using System.Text; +using System; +using System.Net.Http.Formatting; +using System.Text; +using Umbraco.Core; +using Umbraco.Web.Mvc; +using Umbraco.Web.Trees; +using Umbraco.Web.Trees.Menu; using umbraco.cms.presentation.Trees; +using Constants = Umbraco.Core.Constants; namespace Umbraco.Web.UI.App_Plugins.MyPackage.Trees { + //[Tree(Constants.Applications.Settings, "myTree", "My Tree")] + //[PluginController("MyPackage")] + //public class MyCustomTree : TreeController + //{ + // protected override TreeNodeCollection GetTreeNodes(string id, FormDataCollection queryStrings) + // { + // if (id == Constants.System.Root.ToInvariantString()) + // { + // var tree = new TreeNodeCollection + // { + // CreateTreeNode("1", queryStrings, "My Node 1"), + // CreateTreeNode("2", queryStrings, "My Node 2"), + // CreateTreeNode("3", queryStrings, "My Node 3") + // }; + // return tree; + // } + // throw new NotSupportedException(); + // } + + // protected override MenuItemCollection GetMenuForNode(string id, FormDataCollection queryStrings) + // { + // var menu = new MenuItemCollection(); + // menu.AddMenuItem(new MenuItem("create", "Create")); + // } + //} + public class LegacyTestTree : BaseTree { public LegacyTestTree(string application) : base(application) diff --git a/src/Umbraco.Web.UI/App_Plugins/MyPackage/Views/ServerSidePropertyEditors/ServerEnvironment.cshtml b/src/Umbraco.Web.UI/App_Plugins/MyPackage/Views/ServerSidePropertyEditors/ServerEnvironment.cshtml deleted file mode 100644 index f949999089..0000000000 --- a/src/Umbraco.Web.UI/App_Plugins/MyPackage/Views/ServerSidePropertyEditors/ServerEnvironment.cshtml +++ /dev/null @@ -1,9 +0,0 @@ -@model dynamic - - -

- Computer Name@Environment.MachineName -

-

- Computer Time@DateTime.Now -

\ No newline at end of file diff --git a/src/Umbraco.Web.UI/App_Plugins/MyPackage/Views/Web.config b/src/Umbraco.Web.UI/App_Plugins/MyPackage/Views/Web.config deleted file mode 100644 index f179ab8806..0000000000 --- a/src/Umbraco.Web.UI/App_Plugins/MyPackage/Views/Web.config +++ /dev/null @@ -1,58 +0,0 @@ - - - - - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 2e2b2089e2..06b5f301ab 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -292,11 +292,9 @@ Properties\SolutionInfo.cs - - default.aspx @@ -590,7 +588,6 @@ - @@ -615,8 +612,6 @@ - - 404handlers.config @@ -2540,8 +2535,8 @@ - + diff --git a/src/Umbraco.Web/Trees/ContentTreeController.cs b/src/Umbraco.Web/Trees/ContentTreeController.cs index ffa35655e1..080ca2a559 100644 --- a/src/Umbraco.Web/Trees/ContentTreeController.cs +++ b/src/Umbraco.Web/Trees/ContentTreeController.cs @@ -106,8 +106,8 @@ namespace Umbraco.Web.Trees .Select(x => new MenuItem(x)); //these two are the standard items - menu.AddMenuItem(); - menu.AddMenuItem(true).ConvertLegacyMenuItem(null, "content", "content"); + menu.AddMenuItem(ui.Text("actions", ActionNew.Instance.Alias)); + menu.AddMenuItem(ui.Text("actions", ActionSort.Instance.Alias), true).ConvertLegacyMenuItem(null, "content", "content"); //filter the standard items FilterUserAllowedMenuItems(menu, nodeActions); @@ -118,14 +118,9 @@ namespace Umbraco.Web.Trees } // add default actions for *all* users - menu.AddMenuItem().ConvertLegacyMenuItem(null, "content", "content"); - menu.AddMenuItem(true); - - foreach (var menuItem in menu.MenuItems) - { - menuItem.Name = ui.Text("actions", menuItem.Alias); - } - + menu.AddMenuItem(ui.Text("actions", ActionRePublish.Instance.Alias)).ConvertLegacyMenuItem(null, "content", "content"); + menu.AddMenuItem(ui.Text("actions", ActionRefresh.Instance.Alias), true); + return menu; } @@ -150,10 +145,6 @@ namespace Umbraco.Web.Trees //set the default to create nodeMenu.DefaultMenuAlias = ActionNew.Instance.Alias; - foreach (var menuItem in nodeMenu.MenuItems) - { - menuItem.Name = ui.Text("actions", menuItem.Alias); - } return nodeMenu; } @@ -170,26 +161,26 @@ namespace Umbraco.Web.Trees protected MenuItemCollection GetAllNodeMenuItems(IUmbracoEntity item) { var menu = new MenuItemCollection(); - menu.AddMenuItem(); - menu.AddMenuItem(true); + menu.AddMenuItem(ui.Text("actions", ActionNew.Instance.Alias)); + menu.AddMenuItem(ui.Text("actions", ActionDelete.Instance.Alias)); //need to ensure some of these are converted to the legacy system - until we upgrade them all to be angularized. - menu.AddMenuItem(true); - menu.AddMenuItem(); - - menu.AddMenuItem(true).ConvertLegacyMenuItem(item, "content", "content"); + menu.AddMenuItem(ui.Text("actions", ActionMove.Instance.Alias), true); + menu.AddMenuItem(ui.Text("actions", ActionCopy.Instance.Alias)); - menu.AddMenuItem().ConvertLegacyMenuItem(item, "content", "content"); - menu.AddMenuItem(true).ConvertLegacyMenuItem(item, "content", "content"); - menu.AddMenuItem().ConvertLegacyMenuItem(item, "content", "content"); - menu.AddMenuItem().ConvertLegacyMenuItem(item, "content", "content"); - menu.AddMenuItem().ConvertLegacyMenuItem(item, "content", "content"); - menu.AddMenuItem(true).ConvertLegacyMenuItem(item, "content", "content"); - menu.AddMenuItem(true).ConvertLegacyMenuItem(item, "content", "content"); - menu.AddMenuItem(true).ConvertLegacyMenuItem(item, "content", "content"); - menu.AddMenuItem().ConvertLegacyMenuItem(item, "content", "content"); + menu.AddMenuItem(ui.Text("actions", ActionSort.Instance.Alias), true).ConvertLegacyMenuItem(item, "content", "content"); - menu.AddMenuItem(true); + menu.AddMenuItem(ui.Text("actions", ActionRollback.Instance.Alias)).ConvertLegacyMenuItem(item, "content", "content"); + menu.AddMenuItem(ui.Text("actions", ActionPublish.Instance.Alias), true).ConvertLegacyMenuItem(item, "content", "content"); + menu.AddMenuItem(ui.Text("actions", ActionToPublish.Instance.Alias)).ConvertLegacyMenuItem(item, "content", "content"); + menu.AddMenuItem(ui.Text("actions", ActionAssignDomain.Instance.Alias)).ConvertLegacyMenuItem(item, "content", "content"); + menu.AddMenuItem(ui.Text("actions", ActionRights.Instance.Alias)).ConvertLegacyMenuItem(item, "content", "content"); + menu.AddMenuItem(ui.Text("actions", ActionProtect.Instance.Alias), true).ConvertLegacyMenuItem(item, "content", "content"); + menu.AddMenuItem(ui.Text("actions", ActionUnPublish.Instance.Alias), true).ConvertLegacyMenuItem(item, "content", "content"); + menu.AddMenuItem(ui.Text("actions", ActionNotify.Instance.Alias), true).ConvertLegacyMenuItem(item, "content", "content"); + menu.AddMenuItem(ui.Text("actions", ActionSendToTranslate.Instance.Alias)).ConvertLegacyMenuItem(item, "content", "content"); + + menu.AddMenuItem(ui.Text("actions", ActionRefresh.Instance.Alias), true); return menu; } diff --git a/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs b/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs index a1e646e70a..ff4a6f2fd1 100644 --- a/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs +++ b/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs @@ -96,8 +96,8 @@ namespace Umbraco.Web.Trees if (RecycleBinId.ToInvariantString() == id) { var menu = new MenuItemCollection(); - menu.AddMenuItem(); - menu.AddMenuItem(true); + menu.AddMenuItem(ui.Text("actions", ActionEmptyTranscan.Instance.Alias)); + menu.AddMenuItem(ui.Text("actions", ActionRefresh.Instance.Alias), true); return menu; } return PerformGetMenuForNode(id, queryStrings); diff --git a/src/Umbraco.Web/Trees/DataTypeTreeController.cs b/src/Umbraco.Web/Trees/DataTypeTreeController.cs index 278b4a188b..348fa88628 100644 --- a/src/Umbraco.Web/Trees/DataTypeTreeController.cs +++ b/src/Umbraco.Web/Trees/DataTypeTreeController.cs @@ -7,6 +7,7 @@ using System.Web.Http; using Umbraco.Core; using Umbraco.Web.Mvc; using Umbraco.Web.Trees.Menu; +using umbraco; using umbraco.BusinessLogic.Actions; using Constants = Umbraco.Core.Constants; @@ -45,13 +46,13 @@ namespace Umbraco.Web.Trees if (id == Constants.System.Root.ToInvariantString()) { // root actions - menu.AddMenuItem(); - menu.AddMenuItem(true); + menu.AddMenuItem(ui.Text("actions", ActionNew.Instance.Alias)); + menu.AddMenuItem(ui.Text("actions", ActionRefresh.Instance.Alias), true); return menu; } //only have delete for each node - menu.AddMenuItem(); + menu.AddMenuItem(ui.Text("actions", ActionDelete.Instance.Alias)); return menu; } } diff --git a/src/Umbraco.Web/Trees/LegacyTreeDataConverter.cs b/src/Umbraco.Web/Trees/LegacyTreeDataConverter.cs index d7fb72d053..290c722cd0 100644 --- a/src/Umbraco.Web/Trees/LegacyTreeDataConverter.cs +++ b/src/Umbraco.Web/Trees/LegacyTreeDataConverter.cs @@ -147,7 +147,7 @@ namespace Umbraco.Web.Trees } else { - var menuItem = collection.AddMenuItem(t); + var menuItem = collection.AddMenuItem(t, ui.Text("actions", t.Alias)); var currentAction = t; diff --git a/src/Umbraco.Web/Trees/MediaTreeController.cs b/src/Umbraco.Web/Trees/MediaTreeController.cs index e4ebb5a5e0..8f806f980e 100644 --- a/src/Umbraco.Web/Trees/MediaTreeController.cs +++ b/src/Umbraco.Web/Trees/MediaTreeController.cs @@ -76,9 +76,9 @@ namespace Umbraco.Web.Trees } // root actions - menu.AddMenuItem(); - menu.AddMenuItem(true).ConvertLegacyMenuItem(null, "media", "media"); - menu.AddMenuItem(true); + menu.AddMenuItem(ui.Text("actions", ActionNew.Instance.Alias)); + menu.AddMenuItem(ui.Text("actions", ActionSort.Instance.Alias), true).ConvertLegacyMenuItem(null, "media", "media"); + menu.AddMenuItem(ui.Text("actions", ActionRefresh.Instance.Alias), true); return menu; } @@ -93,11 +93,11 @@ namespace Umbraco.Web.Trees throw new HttpResponseException(HttpStatusCode.NotFound); } //return a normal node menu: - menu.AddMenuItem(); - menu.AddMenuItem(); - menu.AddMenuItem(); - menu.AddMenuItem().ConvertLegacyMenuItem(null, "media", "media"); - menu.AddMenuItem(true); + menu.AddMenuItem(ui.Text("actions", ActionNew.Instance.Alias)); + menu.AddMenuItem(ui.Text("actions", ActionMove.Instance.Alias)); + menu.AddMenuItem(ui.Text("actions", ActionDelete.Instance.Alias)); + menu.AddMenuItem(ui.Text("actions", ActionSort.Instance.Alias)).ConvertLegacyMenuItem(null, "media", "media"); + menu.AddMenuItem(ui.Text("actions", ActionRefresh.Instance.Alias), true); return menu; } diff --git a/src/Umbraco.Web/Trees/MemberTreeController.cs b/src/Umbraco.Web/Trees/MemberTreeController.cs index 081f7c8c33..50c22812eb 100644 --- a/src/Umbraco.Web/Trees/MemberTreeController.cs +++ b/src/Umbraco.Web/Trees/MemberTreeController.cs @@ -79,13 +79,13 @@ namespace Umbraco.Web.Trees menu.DefaultMenuAlias = ActionNew.Instance.Alias; // root actions - menu.AddMenuItem(); - menu.AddMenuItem(true); + menu.AddMenuItem(ui.Text("actions", ActionNew.Instance.Alias)); + menu.AddMenuItem(ui.Text("actions", ActionRefresh.Instance.Alias), true); return menu; } - menu.AddMenuItem(); - menu.AddMenuItem(true); + menu.AddMenuItem(ui.Text("actions", ActionDelete.Instance.Alias)); + menu.AddMenuItem(ui.Text("actions", ActionRefresh.Instance.Alias), true); return menu; } } diff --git a/src/Umbraco.Web/Trees/Menu/MenuItem.cs b/src/Umbraco.Web/Trees/Menu/MenuItem.cs index a417a0043c..ed5d9c5778 100644 --- a/src/Umbraco.Web/Trees/Menu/MenuItem.cs +++ b/src/Umbraco.Web/Trees/Menu/MenuItem.cs @@ -2,6 +2,7 @@ using System.Runtime.Serialization; using umbraco.interfaces; using System.Collections.Generic; +using Umbraco.Core; namespace Umbraco.Web.Trees.Menu { @@ -16,10 +17,17 @@ namespace Umbraco.Web.Trees.Menu AdditionalData = new Dictionary(); } - public MenuItem(IAction legacyMenu) + public MenuItem(string alias, string name) : this() { - Name = legacyMenu.Alias; + Alias = alias; + Name = name; + } + + public MenuItem(IAction legacyMenu, string name = "") + : this() + { + Name = name.IsNullOrWhiteSpace() ? legacyMenu.Alias : name; Alias = legacyMenu.Alias; SeperatorBefore = false; Icon = legacyMenu.Icon; diff --git a/src/Umbraco.Web/Trees/Menu/MenuItemCollection.cs b/src/Umbraco.Web/Trees/Menu/MenuItemCollection.cs index 6f88ddfdb6..626a7f9f20 100644 --- a/src/Umbraco.Web/Trees/Menu/MenuItemCollection.cs +++ b/src/Umbraco.Web/Trees/Menu/MenuItemCollection.cs @@ -42,7 +42,9 @@ namespace Umbraco.Web.Trees.Menu /// /// Adds a menu item /// - internal MenuItem AddMenuItem(IAction action) + /// + /// The text to display for the menu item, will default to the IAction alias if not specified + internal MenuItem AddMenuItem(IAction action, string name) { var item = new MenuItem(action); @@ -68,14 +70,21 @@ namespace Umbraco.Web.Trees.Menu { _menuItems.Add(item); } - - //TODO: Implement more overloads for MenuItem with dictionary vals - - public TMenuItem AddMenuItem(bool hasSeparator = false, IDictionary additionalData = null) + + /// + /// Adds a menu item + /// + /// + /// + /// + /// The text to display for the menu item, will default to the IAction alias if not specified + /// + /// + public TMenuItem AddMenuItem(string name, bool hasSeparator = false, IDictionary additionalData = null) where TAction : IAction where TMenuItem : MenuItem, new() { - var item = CreateMenuItem(hasSeparator, additionalData); + var item = CreateMenuItem(name, hasSeparator, additionalData); if (item == null) return null; var customMenuItem = new TMenuItem @@ -95,11 +104,12 @@ namespace Umbraco.Web.Trees.Menu /// /// Adds a menu item /// + /// The text to display for the menu item, will default to the IAction alias if not specified /// - public MenuItem AddMenuItem() + public MenuItem AddMenuItem(string name) where T : IAction { - return AddMenuItem(false, null); + return AddMenuItem(name, false, null); } /// @@ -108,23 +118,51 @@ namespace Umbraco.Web.Trees.Menu /// /// /// + /// The text to display for the menu item, will default to the IAction alias if not specified /// - public MenuItem AddMenuItem(string key, string value, bool hasSeparator = false) + public MenuItem AddMenuItem(string name, string key, string value, bool hasSeparator = false) where T : IAction { - return AddMenuItem(hasSeparator, new Dictionary { { key, value } }); + return AddMenuItem(name, hasSeparator, new Dictionary { { key, value } }); } - internal MenuItem CreateMenuItem(bool hasSeparator = false, IDictionary additionalData = null) + /// + /// Adds a menu item with a dictionary which is merged to the AdditionalData bag + /// + /// + /// + /// /// The text to display for the menu item, will default to the IAction alias if not specified + /// + public MenuItem AddMenuItem(string name, bool hasSeparator = false, IDictionary additionalData = null) + where T : IAction + { + var item = CreateMenuItem(name, hasSeparator, additionalData); + if (item != null) + { + _menuItems.Add(item); + return item; + } + return null; + } + + /// + /// + /// + /// + /// + /// The text to display for the menu item, will default to the IAction alias if not specified + /// + /// + internal MenuItem CreateMenuItem(string name, bool hasSeparator = false, IDictionary additionalData = null) where T : IAction { var item = ActionsResolver.Current.GetAction(); if (item != null) { - var menuItem = new MenuItem(item) - { - SeperatorBefore = hasSeparator - }; + var menuItem = new MenuItem(item, name) + { + SeperatorBefore = hasSeparator + }; if (additionalData != null) { @@ -134,7 +172,7 @@ namespace Umbraco.Web.Trees.Menu } } - DetectLegacyActionMenu(typeof (T), menuItem); + DetectLegacyActionMenu(typeof(T), menuItem); //TODO: Once we implement 'real' menu items, not just IActions we can implement this since // people may need to pass specific data to their menu items @@ -147,24 +185,6 @@ namespace Umbraco.Web.Trees.Menu return null; } - /// - /// Adds a menu item with a dictionary which is merged to the AdditionalData bag - /// - /// - /// - /// - public MenuItem AddMenuItem(bool hasSeparator = false, IDictionary additionalData = null) - where T : IAction - { - var item = CreateMenuItem(hasSeparator, additionalData); - if (item != null) - { - _menuItems.Add(item); - return item; - } - return null; - } - /// /// Checks if the IAction type passed in is attributed with LegacyActionMenuItemAttribute and if so /// ensures that the correct action metadata is added. From 6560865f61ae5b248564d91949dc537f0c141d35 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 2 Oct 2013 20:20:02 +1000 Subject: [PATCH 02/31] Fixed view path conventions for menu items --- .../src/common/services/navigation.service.js | 16 ++++++++++------ .../App_Plugins/MyPackage/Package.manifest | 1 - src/Umbraco.Web/Trees/Menu/MenuItemExtensions.cs | 14 ++++++++++++-- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/services/navigation.service.js b/src/Umbraco.Web.UI.Client/src/common/services/navigation.service.js index ff47aec1da..b039134ff8 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/navigation.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/navigation.service.js @@ -324,6 +324,9 @@ angular.module('umbraco.services') if (!args.action) { throw "The args parameter must have an 'action' property as the clicked menu action object"; } + if (!args.node) { + throw "The args parameter must have a 'node' as the active tree node"; + } //ensure the current dialog is cleared before creating another! if (this.ui.currentDialog) { @@ -348,11 +351,7 @@ angular.module('umbraco.services') var templateUrl; var iframe; - //TODO: fix hardcoded hack for content/media... once these trees are converted over to - // new c# trees we won't need to do this any longer. - var isCreateForContent = args.action.alias === "create" && (this.ui.currentSection === "content" || this.ui.currentSection === "media"); - - if (args.action.metaData["actionUrl"] && !isCreateForContent) { + if (args.action.metaData["actionUrl"]) { templateUrl = args.action.metaData["actionUrl"]; iframe = true; } @@ -361,7 +360,12 @@ angular.module('umbraco.services') iframe = false; } else { - templateUrl = "views/" + this.ui.currentSection + "/" + args.action.alias + ".html"; + + //by convention we will look into the /views/{treetype}/{action}.html + // for example: /views/content/create.html + + templateUrl = "views/" + treeService.getTreeAlias(args.node) + "/" + args.action.alias + ".html"; + iframe = false; } diff --git a/src/Umbraco.Web.UI/App_Plugins/MyPackage/Package.manifest b/src/Umbraco.Web.UI/App_Plugins/MyPackage/Package.manifest index bdc8d9f211..84f51aa8a9 100644 --- a/src/Umbraco.Web.UI/App_Plugins/MyPackage/Package.manifest +++ b/src/Umbraco.Web.UI/App_Plugins/MyPackage/Package.manifest @@ -45,7 +45,6 @@ } ], javascript: [ - '~/App_Plugins/MyPackage/Common/Js/MyPackage.js', '~/App_Plugins/MyPackage/PropertyEditors/Js/CsvEditor.js', '~/App_Plugins/MyPackage/PropertyEditors/Js/PostcodeEditor.js', '~/App_Plugins/MyPackage/PropertyEditors/Js/RegexEditor.js' diff --git a/src/Umbraco.Web/Trees/Menu/MenuItemExtensions.cs b/src/Umbraco.Web/Trees/Menu/MenuItemExtensions.cs index 0576991eac..fadae7b1b3 100644 --- a/src/Umbraco.Web/Trees/Menu/MenuItemExtensions.cs +++ b/src/Umbraco.Web/Trees/Menu/MenuItemExtensions.cs @@ -10,12 +10,22 @@ namespace Umbraco.Web.Trees.Menu /// Used as a key for the AdditionalData to specify a specific dialog title instead of the menu title /// internal const string DialogTitleKey = "dialogTitle"; + + /// + /// Used to specify the URL that the dialog will launch to in an iframe + /// internal const string ActionUrlKey = "actionUrl"; + + internal const string ActionUrlMethodKey = "actionUrlMethod"; + + /// + /// Used to specify the angular view that the dialog will launch + /// internal const string ActionViewKey = "actionView"; /// - /// Sets the menu item to display a dialog based on a view path + /// Sets the menu item to display a dialog based on an angular view path /// /// /// @@ -27,7 +37,7 @@ namespace Umbraco.Web.Trees.Menu } /// - /// Sets the menu item to display a dialog based on a url path + /// Sets the menu item to display a dialog based on a url path in an iframe /// /// /// From 92efd6d645f22a437ab1f40410b1058142652c5d Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 2 Oct 2013 20:48:15 +1000 Subject: [PATCH 03/31] Got menu items working with external packages to look for views by convention inside of their package folder. --- .../common/mocks/umbraco.servervariables.js | 1 + .../src/common/services/navigation.service.js | 12 ++++- .../MyPackage/Trees/LegacyTestTree.cs | 49 ++++++++++--------- src/Umbraco.Web.UI/config/trees.config | 1 + .../Editors/BackOfficeController.cs | 2 + src/Umbraco.Web/Mvc/PluginViewEngine.cs | 2 +- .../Trees/Menu/MenuItemCollection.cs | 34 +++++++++++-- .../Trees/Menu/MenuItemExtensions.cs | 20 +++++++- 8 files changed, 90 insertions(+), 31 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/mocks/umbraco.servervariables.js b/src/Umbraco.Web.UI.Client/src/common/mocks/umbraco.servervariables.js index 32bb9b084c..058a8366ae 100644 --- a/src/Umbraco.Web.UI.Client/src/common/mocks/umbraco.servervariables.js +++ b/src/Umbraco.Web.UI.Client/src/common/mocks/umbraco.servervariables.js @@ -20,6 +20,7 @@ Umbraco.Sys.ServerVariables = { }, umbracoSettings: { "umbracoPath": "/umbraco", + "appPluginsPath" : "/App_Plugins", "imageFileTypes": "jpeg,jpg,gif,bmp,png,tiff,tif" }, isDebuggingEnabled: true diff --git a/src/Umbraco.Web.UI.Client/src/common/services/navigation.service.js b/src/Umbraco.Web.UI.Client/src/common/services/navigation.service.js index b039134ff8..eca8f70576 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/navigation.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/navigation.service.js @@ -364,7 +364,17 @@ angular.module('umbraco.services') //by convention we will look into the /views/{treetype}/{action}.html // for example: /views/content/create.html - templateUrl = "views/" + treeService.getTreeAlias(args.node) + "/" + args.action.alias + ".html"; + //we will also check for a 'packageName' in metaData, if it exists, we'll look by convention in that folder + // for example: /App_Plugins/{mypackage}/umbraco/{treetype}/create.html + + if (args.action.metaData["packageName"]) { + + templateUrl = Umbraco.Sys.ServerVariables.umbracoSettings.appPluginsPath + + "/umbraco/views/" + treeService.getTreeAlias(args.node) + "/" + args.action.alias + ".html"; + } + else { + templateUrl = "views/" + treeService.getTreeAlias(args.node) + "/" + args.action.alias + ".html"; + } iframe = false; } diff --git a/src/Umbraco.Web.UI/App_Plugins/MyPackage/Trees/LegacyTestTree.cs b/src/Umbraco.Web.UI/App_Plugins/MyPackage/Trees/LegacyTestTree.cs index 8655af9b11..78a9085b7f 100644 --- a/src/Umbraco.Web.UI/App_Plugins/MyPackage/Trees/LegacyTestTree.cs +++ b/src/Umbraco.Web.UI/App_Plugins/MyPackage/Trees/LegacyTestTree.cs @@ -10,31 +10,32 @@ using Constants = Umbraco.Core.Constants; namespace Umbraco.Web.UI.App_Plugins.MyPackage.Trees { - //[Tree(Constants.Applications.Settings, "myTree", "My Tree")] - //[PluginController("MyPackage")] - //public class MyCustomTree : TreeController - //{ - // protected override TreeNodeCollection GetTreeNodes(string id, FormDataCollection queryStrings) - // { - // if (id == Constants.System.Root.ToInvariantString()) - // { - // var tree = new TreeNodeCollection - // { - // CreateTreeNode("1", queryStrings, "My Node 1"), - // CreateTreeNode("2", queryStrings, "My Node 2"), - // CreateTreeNode("3", queryStrings, "My Node 3") - // }; - // return tree; - // } - // throw new NotSupportedException(); - // } + [Tree(Constants.Applications.Settings, "myTree", "My Tree")] + [PluginController("MyPackage")] + public class MyCustomTreeController : TreeController + { + protected override TreeNodeCollection GetTreeNodes(string id, FormDataCollection queryStrings) + { + if (id == Constants.System.Root.ToInvariantString()) + { + var tree = new TreeNodeCollection + { + CreateTreeNode("1", queryStrings, "My Node 1"), + CreateTreeNode("2", queryStrings, "My Node 2"), + CreateTreeNode("3", queryStrings, "My Node 3") + }; + return tree; + } + throw new NotSupportedException(); + } - // protected override MenuItemCollection GetMenuForNode(string id, FormDataCollection queryStrings) - // { - // var menu = new MenuItemCollection(); - // menu.AddMenuItem(new MenuItem("create", "Create")); - // } - //} + protected override MenuItemCollection GetMenuForNode(string id, FormDataCollection queryStrings) + { + var menu = new MenuItemCollection("MyPackage"); + menu.AddMenuItem(new MenuItem("create", "Create")); + return menu; + } + } public class LegacyTestTree : BaseTree { diff --git a/src/Umbraco.Web.UI/config/trees.config b/src/Umbraco.Web.UI/config/trees.config index 46a523ce38..acafac91f1 100644 --- a/src/Umbraco.Web.UI/config/trees.config +++ b/src/Umbraco.Web.UI/config/trees.config @@ -39,4 +39,5 @@ + \ No newline at end of file diff --git a/src/Umbraco.Web/Editors/BackOfficeController.cs b/src/Umbraco.Web/Editors/BackOfficeController.cs index a8a5dc2a63..641d809ca7 100644 --- a/src/Umbraco.Web/Editors/BackOfficeController.cs +++ b/src/Umbraco.Web/Editors/BackOfficeController.cs @@ -3,6 +3,7 @@ using System.IO; using System.Text; using System.Web.Mvc; using Umbraco.Core.Configuration; +using Umbraco.Core.IO; using Umbraco.Core.Manifest; using Umbraco.Core; using Umbraco.Web.Mvc; @@ -79,6 +80,7 @@ namespace Umbraco.Web.Editors "umbracoSettings", new Dictionary { {"umbracoPath", GlobalSettings.Path}, + {"appPluginsPath", IOHelper.ResolveUrl(SystemDirectories.AppPlugins).TrimEnd('/')}, {"imageFileTypes", string.Join(",",UmbracoConfig.For.UmbracoSettings().Content.ImageFileTypes)}, } diff --git a/src/Umbraco.Web/Mvc/PluginViewEngine.cs b/src/Umbraco.Web/Mvc/PluginViewEngine.cs index fe39978b6e..96f393920e 100644 --- a/src/Umbraco.Web/Mvc/PluginViewEngine.cs +++ b/src/Umbraco.Web/Mvc/PluginViewEngine.cs @@ -7,7 +7,7 @@ using Umbraco.Core.IO; namespace Umbraco.Web.Mvc { /// - /// A view engine to look into the App_Plugins/Packages folder for views for packaged controllers + /// A view engine to look into the App_Plugins folder for views for packaged controllers /// public class PluginViewEngine : FixedRazorViewEngine { diff --git a/src/Umbraco.Web/Trees/Menu/MenuItemCollection.cs b/src/Umbraco.Web/Trees/Menu/MenuItemCollection.cs index 626a7f9f20..4c99a255c7 100644 --- a/src/Umbraco.Web/Trees/Menu/MenuItemCollection.cs +++ b/src/Umbraco.Web/Trees/Menu/MenuItemCollection.cs @@ -12,6 +12,7 @@ namespace Umbraco.Web.Trees.Menu [DataContract(Name = "menuItems", Namespace = "")] public class MenuItemCollection { + private readonly string _packageFolderName; private readonly List _menuItems; public MenuItemCollection() @@ -24,6 +25,18 @@ namespace Umbraco.Web.Trees.Menu _menuItems = new List(items); } + public MenuItemCollection(string packageFolderName) + : this() + { + _packageFolderName = packageFolderName; + } + + public MenuItemCollection(string packageFolderName, IEnumerable items) + { + _packageFolderName = packageFolderName; + _menuItems = new List(items); + } + /// /// Sets the default menu item alias to be shown when the menu is launched - this is optional and if not set then the menu will just be shown normally. /// @@ -50,7 +63,7 @@ namespace Umbraco.Web.Trees.Menu DetectLegacyActionMenu(action.GetType(), item); - _menuItems.Add(item); + AddItemToCollection(item); return item; } @@ -68,7 +81,7 @@ namespace Umbraco.Web.Trees.Menu /// public void AddMenuItem(MenuItem item) { - _menuItems.Add(item); + AddItemToCollection(item); } /// @@ -96,7 +109,7 @@ namespace Umbraco.Web.Trees.Menu Action = item.Action }; - _menuItems.Add(customMenuItem); + AddItemToCollection(customMenuItem); return customMenuItem; } @@ -139,7 +152,7 @@ namespace Umbraco.Web.Trees.Menu var item = CreateMenuItem(name, hasSeparator, additionalData); if (item != null) { - _menuItems.Add(item); + AddItemToCollection(item); return item; } return null; @@ -211,5 +224,18 @@ namespace Umbraco.Web.Trees.Menu } } + /// + /// This handles adding a menu item to the internal collection and will configure it accordingly + /// + /// + private void AddItemToCollection(MenuItem menuItem) + { + if (_packageFolderName.IsNullOrWhiteSpace() == false) + { + menuItem.SetPackageFolder(_packageFolderName); + } + _menuItems.Add(menuItem); + } + } } \ No newline at end of file diff --git a/src/Umbraco.Web/Trees/Menu/MenuItemExtensions.cs b/src/Umbraco.Web/Trees/Menu/MenuItemExtensions.cs index fadae7b1b3..019b42ab19 100644 --- a/src/Umbraco.Web/Trees/Menu/MenuItemExtensions.cs +++ b/src/Umbraco.Web/Trees/Menu/MenuItemExtensions.cs @@ -6,6 +6,11 @@ namespace Umbraco.Web.Trees.Menu { public static class MenuItemExtensions { + /// + /// Used as a key for the AdditionalData to specify which package folder the menu launcher should look in for views + /// + internal const string PackageName = "packageName"; + /// /// Used as a key for the AdditionalData to specify a specific dialog title instead of the menu title /// @@ -16,7 +21,10 @@ namespace Umbraco.Web.Trees.Menu /// internal const string ActionUrlKey = "actionUrl"; - + //TODO: some action's want to launch a new window like live editing, we support this in the menu item's metadata with + // a key called: "actionUrlMethod" which can be set to either: Dialog, BlankWindow. Normally this is always set to Dialog + // if a URL is specified in the "actionUrl" metadata. For now I'm not going to implement launching in a blank window, + // though would be v-easy, just not sure we want to ever support that? internal const string ActionUrlMethodKey = "actionUrlMethod"; /// @@ -24,6 +32,16 @@ namespace Umbraco.Web.Trees.Menu /// internal const string ActionViewKey = "actionView"; + /// + /// Sets the package folder to look for views in + /// + /// + /// + internal static void SetPackageFolder(this MenuItem menuItem, string packageFolder) + { + menuItem.AdditionalData[PackageName] = packageFolder; + } + /// /// Sets the menu item to display a dialog based on an angular view path /// From dc42c1ebb79ec439e3691176649778ffc4af2a26 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 2 Oct 2013 21:03:51 +1000 Subject: [PATCH 04/31] More work on streamlining package development for views and conventions. --- src/Umbraco.Web.UI.Client/src/routes.js | 8 ++- .../MyPackage/Trees/LegacyTestTree.cs | 7 +-- .../Trees/Menu/MenuItemCollection.cs | 2 +- src/Umbraco.Web/Trees/TreeController.cs | 61 +++++++++++++++++++ 4 files changed, 72 insertions(+), 6 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/routes.js b/src/Umbraco.Web.UI.Client/src/routes.js index bbda26b835..792fa23bd7 100644 --- a/src/Umbraco.Web.UI.Client/src/routes.js +++ b/src/Umbraco.Web.UI.Client/src/routes.js @@ -88,9 +88,15 @@ app.config(function ($routeProvider) { if (!rp.tree || !rp.method) { return "views/common/dashboard.html"; } - + + //TODO: Here we need to figure out if this route is for a package and if so then we need + // to change it's convention view path to: + // /App_Plugins/{mypackage}/umbraco/{treetype}/{method}.html + + //we don't need to put views into section folders since theoretically trees // could be moved among sections, we only need folders for specific trees. + return 'views/' + rp.tree + '/' + rp.method + '.html'; }, resolve: checkAuth(true) diff --git a/src/Umbraco.Web.UI/App_Plugins/MyPackage/Trees/LegacyTestTree.cs b/src/Umbraco.Web.UI/App_Plugins/MyPackage/Trees/LegacyTestTree.cs index 78a9085b7f..347c55503a 100644 --- a/src/Umbraco.Web.UI/App_Plugins/MyPackage/Trees/LegacyTestTree.cs +++ b/src/Umbraco.Web.UI/App_Plugins/MyPackage/Trees/LegacyTestTree.cs @@ -30,10 +30,9 @@ namespace Umbraco.Web.UI.App_Plugins.MyPackage.Trees } protected override MenuItemCollection GetMenuForNode(string id, FormDataCollection queryStrings) - { - var menu = new MenuItemCollection("MyPackage"); - menu.AddMenuItem(new MenuItem("create", "Create")); - return menu; + { + MenuItems.AddMenuItem(new MenuItem("create", "Create")); + return MenuItems; } } diff --git a/src/Umbraco.Web/Trees/Menu/MenuItemCollection.cs b/src/Umbraco.Web/Trees/Menu/MenuItemCollection.cs index 4c99a255c7..5e4f305848 100644 --- a/src/Umbraco.Web/Trees/Menu/MenuItemCollection.cs +++ b/src/Umbraco.Web/Trees/Menu/MenuItemCollection.cs @@ -14,7 +14,7 @@ namespace Umbraco.Web.Trees.Menu { private readonly string _packageFolderName; private readonly List _menuItems; - + public MenuItemCollection() { _menuItems = new List(); diff --git a/src/Umbraco.Web/Trees/TreeController.cs b/src/Umbraco.Web/Trees/TreeController.cs index e6ea6abe75..e7df099c53 100644 --- a/src/Umbraco.Web/Trees/TreeController.cs +++ b/src/Umbraco.Web/Trees/TreeController.cs @@ -1,11 +1,14 @@ using System; +using System.Collections.Concurrent; using System.Globalization; using System.Linq; using System.Net.Http.Formatting; using Umbraco.Core; +using Umbraco.Web.Mvc; using Umbraco.Web.Trees.Menu; using Umbraco.Web.WebApi; using Umbraco.Web.WebApi.Filters; +using Constants = Umbraco.Core.Constants; namespace Umbraco.Web.Trees { @@ -15,6 +18,7 @@ namespace Umbraco.Web.Trees public abstract class TreeController : UmbracoAuthorizedApiController { private readonly TreeAttribute _attribute; + private readonly MenuItemCollection _menuItemCollection; /// /// Remove the xml formatter... only support JSON! @@ -41,6 +45,19 @@ namespace Umbraco.Web.Trees //assign the properties of this object to those of the metadata attribute _attribute = treeAttributes.First(); + + //Create the menu item collection with the area nem already specified + _menuItemCollection = Metadata.AreaName.IsNullOrWhiteSpace() + ? new MenuItemCollection() + : new MenuItemCollection(Metadata.AreaName); + } + + /// + /// Returns a menu item collection to be used to return the menu items from GetMenuForNode + /// + public MenuItemCollection MenuItems + { + get { return _menuItemCollection; } } /// @@ -300,6 +317,7 @@ namespace Umbraco.Web.Trees #endregion + #region Events public static event EventHandler TreeNodesRendering; private static void OnTreeNodesRendering(TreeController instance, TreeNodesRenderingEventArgs e) @@ -314,6 +332,49 @@ namespace Umbraco.Web.Trees { var handler = RootNodeRendering; if (handler != null) handler(instance, e); + } + #endregion + + #region Metadata + /// + /// stores the metadata about plugin controllers + /// + private static readonly ConcurrentDictionary MetadataStorage = new ConcurrentDictionary(); + + /// + /// Returns the metadata for this instance + /// + internal PluginControllerMetadata Metadata + { + get { return GetMetadata(this.GetType()); } } + + /// + /// Returns the metadata for a PluginController + /// + /// + /// + internal static PluginControllerMetadata GetMetadata(Type type) + { + + return MetadataStorage.GetOrAdd(type, type1 => + { + var attribute = type.GetCustomAttribute(false); + + var meta = new PluginControllerMetadata() + { + AreaName = attribute == null ? null : attribute.AreaName, + ControllerName = ControllerExtensions.GetControllerName(type), + ControllerNamespace = type.Namespace, + ControllerType = type + }; + + MetadataStorage.TryAdd(type, meta); + + return meta; + }); + + } + #endregion } } From 9ec30860b0632fb54fd834dc61cc6b7a99b576e6 Mon Sep 17 00:00:00 2001 From: mortenbock Date: Wed, 2 Oct 2013 17:48:44 +0200 Subject: [PATCH 05/31] Wrap all ViewEngines in a profiler Wrap all ViewEngines in a custom profiler view engine, using the ProfilerResolver to track performance --- src/Umbraco.Core/Profiling/ProfilingView.cs | 28 +++++++++++ .../Profiling/ProfilingViewEngine.cs | 48 +++++++++++++++++++ src/Umbraco.Core/Umbraco.Core.csproj | 2 + src/Umbraco.Web/WebBootManager.cs | 18 ++++--- 4 files changed, 90 insertions(+), 6 deletions(-) create mode 100644 src/Umbraco.Core/Profiling/ProfilingView.cs create mode 100644 src/Umbraco.Core/Profiling/ProfilingViewEngine.cs diff --git a/src/Umbraco.Core/Profiling/ProfilingView.cs b/src/Umbraco.Core/Profiling/ProfilingView.cs new file mode 100644 index 0000000000..110ab14925 --- /dev/null +++ b/src/Umbraco.Core/Profiling/ProfilingView.cs @@ -0,0 +1,28 @@ +using System.IO; +using System.Web.Mvc; + +namespace Umbraco.Core.Profiling +{ + public class ProfilingView : IView + { + private readonly IView _inner; + private readonly string _name; + private readonly string _viewPath; + + public ProfilingView(IView inner) + { + _inner = inner; + _name = inner.GetType().Name; + var razorView = inner as RazorView; + _viewPath = razorView != null ? razorView.ViewPath : "Unknown"; + } + + public void Render(ViewContext viewContext, TextWriter writer) + { + using (ProfilerResolver.Current.Profiler.Step(string.Format("{0}.Render: {1}", _name, _viewPath))) + { + _inner.Render(viewContext, writer); + } + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Profiling/ProfilingViewEngine.cs b/src/Umbraco.Core/Profiling/ProfilingViewEngine.cs new file mode 100644 index 0000000000..5df2b6f811 --- /dev/null +++ b/src/Umbraco.Core/Profiling/ProfilingViewEngine.cs @@ -0,0 +1,48 @@ +using System.Web.Mvc; + +namespace Umbraco.Core.Profiling +{ + public class ProfilingViewEngine: IViewEngine + { + private readonly IViewEngine _inner; + private readonly string _name; + + public ProfilingViewEngine(IViewEngine inner) + { + _inner = inner; + _name = inner.GetType().Name; + } + + public ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache) + { + using (ProfilerResolver.Current.Profiler.Step(string.Format("{0}.FindPartialView, {1}, {2}", _name, partialViewName, useCache))) + { + return WrapResult(_inner.FindPartialView(controllerContext, partialViewName, useCache)); + } + } + + public ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache) + { + using (ProfilerResolver.Current.Profiler.Step(string.Format("{0}.FindView, {1}, {2}, {3}", _name, viewName, masterName, useCache))) + { + return WrapResult(_inner.FindView(controllerContext, viewName, masterName, useCache)); + } + } + + private static ViewEngineResult WrapResult(ViewEngineResult innerResult) + { + var profiledResult = innerResult.View != null ? + new ViewEngineResult(new ProfilingView(innerResult.View), innerResult.ViewEngine) : + new ViewEngineResult(innerResult.SearchedLocations); + return profiledResult; + } + + public void ReleaseView(ControllerContext controllerContext, IView view) + { + using (ProfilerResolver.Current.Profiler.Step(string.Format("{0}.ReleaseView, {1}", _name, view.GetType().Name))) + { + _inner.ReleaseView(controllerContext, view); + } + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index dc95d29ab4..1386f52e2a 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -562,6 +562,8 @@ + + diff --git a/src/Umbraco.Web/WebBootManager.cs b/src/Umbraco.Web/WebBootManager.cs index 35869fb76b..cca270acd3 100644 --- a/src/Umbraco.Web/WebBootManager.cs +++ b/src/Umbraco.Web/WebBootManager.cs @@ -9,7 +9,6 @@ using StackExchange.Profiling.MVCHelpers; using Umbraco.Core; using Umbraco.Core.Configuration; using Umbraco.Core.Dictionary; -using Umbraco.Core.Dynamics; using Umbraco.Core.Logging; using Umbraco.Core.ObjectResolution; using Umbraco.Core.Profiling; @@ -25,9 +24,8 @@ using Umbraco.Web.PublishedCache; using Umbraco.Web.Routing; using Umbraco.Web.WebApi; using umbraco.BusinessLogic; -using umbraco.businesslogic; -using umbraco.cms.businesslogic; using umbraco.presentation.cache; +using ProfilingViewEngine = Umbraco.Core.Profiling.ProfilingViewEngine; namespace Umbraco.Web @@ -73,9 +71,9 @@ namespace Umbraco.Web new MasterControllerFactory(FilteredControllerFactoriesResolver.Current)); //set the render view engine - ViewEngines.Engines.Add(new ProfilingViewEngine(new RenderViewEngine())); + ViewEngines.Engines.Add(new RenderViewEngine()); //set the plugin view engine - ViewEngines.Engines.Add(new ProfilingViewEngine(new PluginViewEngine())); + ViewEngines.Engines.Add(new PluginViewEngine()); //set model binder ModelBinders.Binders.Add(new KeyValuePair(typeof(RenderModel), new RenderModelBinder())); @@ -129,7 +127,15 @@ namespace Umbraco.Web /// public override IBootManager Complete(Action afterComplete) { - //set routes + //Wrap viewengines in the profiling engine + IViewEngine[] engines = ViewEngines.Engines.Select(e => e).ToArray(); + ViewEngines.Engines.Clear(); + foreach (var engine in engines) + { + ViewEngines.Engines.Add(new ProfilingViewEngine(engine)); + } + + //set routes CreateRoutes(); base.Complete(afterComplete); From 24020cfea35bd1592fd68a28fb89ee9243a94e2d Mon Sep 17 00:00:00 2001 From: mortenbock Date: Wed, 2 Oct 2013 18:30:59 +0200 Subject: [PATCH 06/31] Make sure the profilingengine doesn't wrap itself --- src/Umbraco.Web/WebBootManager.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web/WebBootManager.cs b/src/Umbraco.Web/WebBootManager.cs index cca270acd3..4c9757fe95 100644 --- a/src/Umbraco.Web/WebBootManager.cs +++ b/src/Umbraco.Web/WebBootManager.cs @@ -132,7 +132,8 @@ namespace Umbraco.Web ViewEngines.Engines.Clear(); foreach (var engine in engines) { - ViewEngines.Engines.Add(new ProfilingViewEngine(engine)); + var wrappedEngine = engine is ProfilingViewEngine ? engine : new ProfilingViewEngine(engine); + ViewEngines.Engines.Add(wrappedEngine); } //set routes From 6126a52156d911a74b44ae2561a9cc3065c39431 Mon Sep 17 00:00:00 2001 From: perploug Date: Wed, 2 Oct 2013 19:22:34 +0200 Subject: [PATCH 07/31] child action icon alignment tweak --- src/Umbraco.Web.UI.Client/src/less/tree.less | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/tree.less b/src/Umbraco.Web.UI.Client/src/less/tree.less index 40cee95c94..78aca06998 100644 --- a/src/Umbraco.Web.UI.Client/src/less/tree.less +++ b/src/Umbraco.Web.UI.Client/src/less/tree.less @@ -304,8 +304,8 @@ li.root > div > a.umb-options { } .umb-actions-child i { font-size: 32px; - vertical-align: top; } + .umb-actions-child li.add { margin-top: 20px; border-top: 1px solid #e9e9e9; @@ -346,6 +346,7 @@ width:100%; height:1px; overflow:hidden; } + .umb-tree li div.l div, div.umb-loader{ background-color: @blue; margin-top:0; @@ -365,7 +366,7 @@ margin-left:-100%; -o-animation-name:bounce_loadingProgressG; -o-animation-duration:1s; -o-animation-iteration-count:infinite; --o-animation-timing-function:linear; +-o-animationtiming-function:linear; animation-name:bounce_loadingProgressG; animation-duration:1s; animation-iteration-count:infinite; @@ -374,6 +375,7 @@ width:100%; height:1px; } + @-moz-keyframes bounce_loadingProgressG{ 0%{ margin-left:-100%; @@ -422,11 +424,14 @@ height:1px; 0%{ margin-left:-100%; } - 100%{ margin-left:100%; } } +//loader defaults +.umb-loader{ + height: 10px; margin: 10px 10px 10px 10px; +} body.touch .umb-tree .icon{font-size: 17px;} From bb1a47aa810d34a2e4e5b205f9e02465c3f51eba Mon Sep 17 00:00:00 2001 From: perploug Date: Wed, 2 Oct 2013 19:22:54 +0200 Subject: [PATCH 08/31] Permissions dialog polish --- src/Umbraco.Web.UI/umbraco/dialogs/cruds.aspx | 27 ++++----- .../umbraco/dialogs/cruds.aspx | 27 ++++----- .../umbraco/dialogs/cruds.aspx.cs | 56 ++++++++++++------- .../umbraco/dialogs/cruds.aspx.designer.cs | 23 ++++---- 4 files changed, 71 insertions(+), 62 deletions(-) diff --git a/src/Umbraco.Web.UI/umbraco/dialogs/cruds.aspx b/src/Umbraco.Web.UI/umbraco/dialogs/cruds.aspx index d8e3131a6f..fd7621f677 100644 --- a/src/Umbraco.Web.UI/umbraco/dialogs/cruds.aspx +++ b/src/Umbraco.Web.UI/umbraco/dialogs/cruds.aspx @@ -8,21 +8,18 @@ - - - - - - - - - -
- -   or   - <%=umbraco.ui.Text("general", "cancel", this.getUser())%> - -
+
+ + + + + + +
+
\ No newline at end of file diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/cruds.aspx b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/cruds.aspx index d8e3131a6f..fd7621f677 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/cruds.aspx +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/cruds.aspx @@ -8,21 +8,18 @@ - - - - - - - - - -
- -   or   - <%=umbraco.ui.Text("general", "cancel", this.getUser())%> - -
+
+ + + + + + +
+
\ No newline at end of file diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/cruds.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/cruds.aspx.cs index 7a96b7ae3e..0759b77783 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/cruds.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/cruds.aspx.cs @@ -8,6 +8,7 @@ using System.Web.SessionState; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.HtmlControls; +using System.Collections.Generic; namespace umbraco.dialogs { @@ -41,36 +42,46 @@ namespace umbraco.dialogs node = new cms.businesslogic.CMSNode(int.Parse(helper.Request("id"))); - HtmlTable ht = new HtmlTable(); - ht.CellPadding = 4; + HtmlTable ht = new HtmlTable(); + ht.Attributes.Add("class", "table"); + + HtmlTableRow names = new HtmlTableRow(); + + var corner = new HtmlTableCell("th"); + corner.Style.Add("border", "none"); + names.Cells.Add(corner); - HtmlTableRow captions = new HtmlTableRow(); - captions.Cells.Add(new HtmlTableCell()); ArrayList actionList = BusinessLogic.Actions.Action.GetAll(); + Dictionary permissions = new Dictionary(); + + foreach (interfaces.IAction a in actionList) { if (a.CanBePermissionAssigned) { - HtmlTableCell hc = new HtmlTableCell(); - hc.Attributes.Add("class", "guiDialogTinyMark"); - hc.Controls.Add(new LiteralControl(ui.Text("actions", a.Alias))); - captions.Cells.Add(hc); + + HtmlTableRow permission = new HtmlTableRow(); + HtmlTableCell label = new HtmlTableCell(); + label.InnerText = ui.Text("actions", a.Alias); + permission.Cells.Add(label); + permissions.Add(a.Alias, permission); } } - ht.Rows.Add(captions); + + ht.Rows.Add(names); + foreach (BusinessLogic.User u in BusinessLogic.User.getAll()) { // Not disabled users and not system account if (!u.Disabled && u.Id > 0) { - HtmlTableRow hr = new HtmlTableRow(); - - HtmlTableCell hc = new HtmlTableCell(); - hc.Attributes.Add("class", "guiDialogTinyMark"); - hc.Controls.Add(new LiteralControl(u.Name)); - hr.Cells.Add(hc); + HtmlTableCell hc = new HtmlTableCell("th"); + hc.InnerText = u.Name; + hc.Style.Add("text-align", "center"); + hc.Style.Add("border", "none"); + names.Cells.Add(hc); foreach (interfaces.IAction a in BusinessLogic.Actions.Action.GetAll()) { @@ -80,17 +91,22 @@ namespace umbraco.dialogs { if (u.GetPermissions(node.Path).IndexOf(a.Letter) > -1) c.Checked = true; - HtmlTableCell cell = new HtmlTableCell(); + + HtmlTableCell cell = new HtmlTableCell(); cell.Style.Add("text-align", "center"); cell.Controls.Add(c); - permissions.Add(c); - hr.Cells.Add(cell); + + permissions[a.Alias].Cells.Add(cell); } } - ht.Rows.Add(hr); } } + + //add all collected rows + foreach (var perm in permissions.Values) + ht.Rows.Add(perm); + PlaceHolder1.Controls.Add(ht); } @@ -128,7 +144,7 @@ namespace umbraco.dialogs //FeedBackMessage.Text = "
" + ui.Text("rights") + " " + ui.Text("ok") + "
"; feedback1.type = umbraco.uicontrols.Feedback.feedbacktype.success; feedback1.Text = ui.Text("rights") + " " + ui.Text("ok"); - pane_form.Visible = false; + PlaceHolder1.Visible = false; panel_buttons.Visible = false; diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/cruds.aspx.designer.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/cruds.aspx.designer.cs index 633eb38373..0c8fa6d2d0 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/cruds.aspx.designer.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/cruds.aspx.designer.cs @@ -1,10 +1,9 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:2.0.50727.4200 // // Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. +// the code is regenerated. // //------------------------------------------------------------------------------ @@ -13,15 +12,6 @@ namespace umbraco.dialogs { public partial class cruds { - /// - /// feedback1 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::umbraco.uicontrols.Feedback feedback1; - /// /// pane_form control. /// @@ -31,6 +21,15 @@ namespace umbraco.dialogs { /// protected global::umbraco.uicontrols.Pane pane_form; + /// + /// feedback1 control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::umbraco.uicontrols.Feedback feedback1; + /// /// PlaceHolder1 control. /// @@ -47,7 +46,7 @@ namespace umbraco.dialogs { /// Auto-generated field. /// To modify move field declaration from designer file to code-behind file. /// - protected global::System.Web.UI.WebControls.Panel panel_buttons; + protected global::System.Web.UI.HtmlControls.HtmlGenericControl panel_buttons; /// /// Button1 control. From 92a32a8f8d27905ec80f433d1db094c93e128680 Mon Sep 17 00:00:00 2001 From: perploug Date: Wed, 2 Oct 2013 19:23:04 +0200 Subject: [PATCH 09/31] rollback dialog polish --- .../umbraco/dialogs/rollBack.aspx | 141 +++++++++++------- .../umbraco/dialogs/rollBack.aspx.cs | 104 +++++-------- .../umbraco/dialogs/rollBack.aspx.designer.cs | 16 +- 3 files changed, 137 insertions(+), 124 deletions(-) diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/rollBack.aspx b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/rollBack.aspx index db2b592305..1fd831bedc 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/rollBack.aspx +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/rollBack.aspx @@ -1,68 +1,99 @@ -<%@ Page Language="c#" Codebehind="rollBack.aspx.cs" MasterPageFile="../masterpages/umbracoDialog.Master"AutoEventWireup="True" Inherits="umbraco.presentation.dialogs.rollBack" %> +<%@ Page Language="c#" CodeBehind="rollBack.aspx.cs" MasterPageFile="../masterpages/umbracoDialog.Master" AutoEventWireup="True" Inherits="umbraco.presentation.dialogs.rollBack" %> + <%@ Register TagPrefix="cc1" Namespace="umbraco.uicontrols" Assembly="controls" %> <%@ Register TagPrefix="umb" Namespace="ClientDependency.Core.Controls" Assembly="ClientDependency.Core" %> - + var functionsFrame = this; + var tabFrame = this; + var isDialog = true; + var submitOnEnter = true; + + - + .diff { + margin-top: 10px; + height: 100%; + overflow: auto; + border-top: 1px solid #ccc; + border-top: 1px solid #ccc; + padding: 5px; + } + + .diff table td { + border-bottom: 1px solid #ccc; + padding: 3px; + } + + .diff del { + background: rgb(255, 230, 230) none repeat scroll 0%; + -moz-background-clip: -moz-initial; + -moz-background-origin: -moz-initial; + -moz-background-inline-policy: -moz-initial; + } + + .diff ins { + background: rgb(230, 255, 230) none repeat scroll 0%; + -moz-background-clip: -moz-initial; + -moz-background-origin: -moz-initial; + -moz-background-inline-policy: -moz-initial; + } + + .diff .diffnotice { + text-align: center; + margin-bottom: 10px; + } + + - +
+ - + - - () - - - - - Diff - Html - - - - + + + + () + + + - -
-
-

- -

-
- - - -
-
- -

- -   <%=umbraco.ui.Text("general", "or", this.getUser())%>   - <%=umbraco.ui.Text("general", "cancel", this.getUser())%> -

-
- - + + + + Diff + Html + + + +
+ + +
+
+

+ +

+
+ + + +
+
+
+
+ +
- \ No newline at end of file diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/rollBack.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/rollBack.aspx.cs index 88e9933945..0d4e739cdc 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/rollBack.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/rollBack.aspx.cs @@ -28,10 +28,11 @@ namespace umbraco.presentation.dialogs protected void version_load(object sender, EventArgs e) { - if (allVersions.SelectedValue != "") { + if (allVersions.SelectedValue != "") + { diffPanel.Visible = true; Document rollback = new Document(currentDoc.Id, new Guid(allVersions.SelectedValue)); - + propertiesCompare.Text = "" + ui.Text("general", "name") + ":" + rollback.Text + ""; propertiesCompare.Text += "" + ui.Text("content", "createDate") + ":" + rollback.VersionDate.ToLongDateString() + " " + rollback.VersionDate.ToLongTimeString() + ui.Text("general", "by") + ": " + rollback.User.Name + ""; @@ -42,50 +43,63 @@ namespace umbraco.presentation.dialogs var props = rollback.GenericProperties; - foreach (Property p in props) { - try { + foreach (Property p in props) + { + try + { - if (p.Value != null) { + if (p.Value != null) + { //new property value... string thevalue = p.Value.ToString(); - if (rbl_mode.SelectedValue == "diff") { - + if (rbl_mode.SelectedValue == "diff") + { + //if display mode is set to diff... thevalue = library.StripHtml(p.Value.ToString()); Property cP = currentDoc.getProperty(p.PropertyType); - if (cP != null && cP.Value != null) { + if (cP != null && cP.Value != null) + { string cThevalue = library.StripHtml(cP.Value.ToString()); propertiesCompare.Text += "" + p.PropertyType.Name + ":" + library.ReplaceLineBreaks(cms.businesslogic.utilities.Diff.Diff2Html(cThevalue, thevalue)) + ""; - - } else { + + } + else + { //If no current version of the value... display with no diff. propertiesCompare.Text += "" + p.PropertyType.Name + ":" + thevalue + ""; } - - } else { + + } + else + { //If display mode is html propertiesCompare.Text += "" + p.PropertyType.Name + ":" + thevalue + ""; } - - //previewVersionContent.Controls.Add(new LiteralControl("

" + p.PropertyType.Name + "
")); - //previewVersionContent.Controls.Add(new LiteralControl(thevalue)); - + + //previewVersionContent.Controls.Add(new LiteralControl("

" + p.PropertyType.Name + "
")); + //previewVersionContent.Controls.Add(new LiteralControl(thevalue)); + } //previewVersionContent.Controls.Add(new LiteralControl("

")); - } catch { } + } + catch { } } - doRollback.Enabled = true; - doRollback.Attributes.Add("onclick", "return confirm('" + ui.Text("areyousure") + "');"); - - }else + pl_buttons.Visible = true; + + } + else + { diffPanel.Visible = false; + pl_buttons.Visible = false; + } } @@ -105,50 +119,8 @@ namespace umbraco.presentation.dialogs foreach (DocumentVersionList dl in currentDoc.GetVersions()) { allVersions.Items.Add(new ListItem(dl.Text + " (" + ui.Text("content", "createDate") + ": " + dl.Date.ToShortDateString() + " " + dl.Date.ToShortTimeString() + ")", dl.Version.ToString())); } - doRollback.Text = ui.Text("actions", "rollback"); + Button1.Text = ui.Text("actions", "rollback"); } - - /* - foreach(Property p in d.getProperties) - { - string thevalue = p.Value.ToString(); - if (CheckBoxHtml.Checked) - thevalue = Server.HtmlEncode(thevalue); - currentVersionContent.Controls.Add(new LiteralControl("

" + p.PropertyType.Name + "
" + thevalue + "

")); - } - - if (allVersions.SelectedValue != "") - { - Document rollback = new Document(d.Id, new Guid(allVersions.SelectedValue)); - previewVersionTitle.Text = rollback.Text; - previewVersionDetails.Text = "Created at: " + rollback.VersionDate.ToLongDateString() + " " + rollback.VersionDate.ToLongTimeString() + " by: " + rollback.User.Name; - foreach(Property p in rollback.getProperties) - { - try - { - previewVersionContent.Controls.Add(new LiteralControl("

" + p.PropertyType.Name + "
")); - if (p.Value != null) - { - string thevalue = p.Value.ToString(); - if (CheckBoxHtml.Checked) - thevalue = Server.HtmlEncode(thevalue); - previewVersionContent.Controls.Add(new LiteralControl(thevalue)); - } - previewVersionContent.Controls.Add(new LiteralControl("

")); - } - catch {} - } - doRollback.Enabled = true; - doRollback.Attributes.Add("onClick", "return confirm('" + ui.Text("areyousure") + "');"); - } - else - { - doRollback.Enabled = false; - previewVersionTitle.Text = "No version selected..."; - } - - - */ } #region Web Form Designer generated code @@ -182,8 +154,10 @@ namespace umbraco.presentation.dialogs Document rollback = new Document(d.Id, new Guid(allVersions.SelectedValue)); feedBackMsg.type = global::umbraco.uicontrols.Feedback.feedbacktype.success; string[] vars = {rollback.Text, rollback.VersionDate.ToLongDateString()}; + feedBackMsg.Text = ui.Text("rollback", "documentRolledBack", vars, new global::umbraco.BusinessLogic.User(0)) + "

" + ui.Text("closeThisWindow") + ""; - diffPanel.Height = new Unit(200, UnitType.Pixel); + diffPanel.Visible = false; + pl_buttons.Visible = false; ClientTools.ChangeContentFrameUrl("editContent.aspx?Id=" + d.Id.ToString()); } diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/rollBack.aspx.designer.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/rollBack.aspx.designer.cs index c78e06b6d9..ff4420468b 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/rollBack.aspx.designer.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/rollBack.aspx.designer.cs @@ -1,10 +1,9 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:2.0.50727.4200 // // Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. +// the code is regenerated. // //------------------------------------------------------------------------------ @@ -131,12 +130,21 @@ namespace umbraco.presentation.dialogs { protected global::System.Web.UI.WebControls.Literal propertiesCompare; ///

- /// doRollback control. + /// pl_buttons control. /// /// /// Auto-generated field. /// To modify move field declaration from designer file to code-behind file. /// - protected global::System.Web.UI.WebControls.Button doRollback; + protected global::System.Web.UI.HtmlControls.HtmlGenericControl pl_buttons; + + /// + /// Button1 control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Button Button1; } } From a371ebe84102c0d329d1c1486fbf65ff6b366113 Mon Sep 17 00:00:00 2001 From: perploug Date: Wed, 2 Oct 2013 19:23:20 +0200 Subject: [PATCH 10/31] Progressbart convert to css3 from gif --- .../umbraco/dialogs/rollBack.aspx | 138 +++++++++++------- src/Umbraco.Web/Umbraco.Web.csproj | 8 +- src/umbraco.controls/ProgressBar.cs | 7 +- 3 files changed, 93 insertions(+), 60 deletions(-) diff --git a/src/Umbraco.Web.UI/umbraco/dialogs/rollBack.aspx b/src/Umbraco.Web.UI/umbraco/dialogs/rollBack.aspx index db2b592305..62d7d9492b 100644 --- a/src/Umbraco.Web.UI/umbraco/dialogs/rollBack.aspx +++ b/src/Umbraco.Web.UI/umbraco/dialogs/rollBack.aspx @@ -1,68 +1,98 @@ <%@ Page Language="c#" Codebehind="rollBack.aspx.cs" MasterPageFile="../masterpages/umbracoDialog.Master"AutoEventWireup="True" Inherits="umbraco.presentation.dialogs.rollBack" %> + <%@ Register TagPrefix="cc1" Namespace="umbraco.uicontrols" Assembly="controls" %> <%@ Register TagPrefix="umb" Namespace="ClientDependency.Core.Controls" Assembly="ClientDependency.Core" %> - + var functionsFrame = this; + var tabFrame = this; + var isDialog = true; + var submitOnEnter = true; + + - + .diff { + margin-top: 10px; + height: 100%; + overflow: auto; + border-top: 1px solid #efefef; + padding: 5px; + } + + .diff table td { + border-bottom: 1px solid #ccc; + padding: 3px; + } + + .diff del { + background: rgb(255, 230, 230) none repeat scroll 0%; + -moz-background-clip: -moz-initial; + -moz-background-origin: -moz-initial; + -moz-background-inline-policy: -moz-initial; + } + + .diff ins { + background: rgb(230, 255, 230) none repeat scroll 0%; + -moz-background-clip: -moz-initial; + -moz-background-origin: -moz-initial; + -moz-background-inline-policy: -moz-initial; + } + + .diff .diffnotice { + text-align: center; + margin-bottom: 10px; + } + + - +
+ - + - - () - - - - - Diff - Html - - - - + + + + () + + + - -
-
-

- -

-
- - - -
-
- -

- -   <%=umbraco.ui.Text("general", "or", this.getUser())%>   - <%=umbraco.ui.Text("general", "cancel", this.getUser())%> -

-
- - + + + + Diff + Html + + + +
+ + +
+
+

+ +

+
+ + + +
+
+
+
+ +
- \ No newline at end of file diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 161e183bc4..c11fa14d2c 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -1840,7 +1840,9 @@ ASPXCodeBehind - + + ASPXCodeBehind + @@ -1857,7 +1859,9 @@ ASPXCodeBehind - + + ASPXCodeBehind + diff --git a/src/umbraco.controls/ProgressBar.cs b/src/umbraco.controls/ProgressBar.cs index 5304e92fb5..89cff8fe24 100644 --- a/src/umbraco.controls/ProgressBar.cs +++ b/src/umbraco.controls/ProgressBar.cs @@ -7,7 +7,7 @@ using System.Web.UI.WebControls; namespace umbraco.uicontrols { [Obsolete("Use Umbraco.Web.UI.Controls.ProgressBar")] - public class ProgressBar : System.Web.UI.WebControls.Image + public class ProgressBar : System.Web.UI.WebControls.Panel { private string _title = umbraco.ui.Text("publish", "inProgress", null); public string Title { get; set; } @@ -17,9 +17,8 @@ namespace umbraco.uicontrols if(!string.IsNullOrEmpty(Title)) _title = Title; - base.ImageUrl = IO.SystemDirectories.Umbraco_client + "/images/progressBar.gif"; - base.AlternateText = _title; - + base.CssClass = "umb-loader"; + base.Render(writer); } } From 6c20815210cfefa25cec61d5e2d74b92e11c94ff Mon Sep 17 00:00:00 2001 From: perploug Date: Wed, 2 Oct 2013 19:23:36 +0200 Subject: [PATCH 11/31] Initial commit of rte prevalue editor --- .../src/views/prevalueeditors/rte.controller.js | 0 src/Umbraco.Web.UI.Client/src/views/prevalueeditors/rte.html | 0 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/views/prevalueeditors/rte.controller.js create mode 100644 src/Umbraco.Web.UI.Client/src/views/prevalueeditors/rte.html diff --git a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/rte.controller.js b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/rte.controller.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/rte.html b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/rte.html new file mode 100644 index 0000000000..e69de29bb2 From b09a743beba2f5d7b5e6cb0db1239bfb30c2ab22 Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 3 Oct 2013 11:25:26 +1000 Subject: [PATCH 12/31] Gets view paths to load in dynamically based on whether a core or plugin tree is rendering, this allows us to store view files based on conventions for packages. Completes: U4-2849 Ensure editor views, etc... can exist outside of the /umbraco folder for package devs --- .../common/mocks/umbraco.servervariables.js | 5 ++ .../src/common/services/navigation.service.js | 13 ++-- .../src/common/services/tree.service.js | 27 +++++++++ src/Umbraco.Web.UI.Client/src/routes.js | 31 +++++++--- .../unit/common/services/tree-service.spec.js | 18 +++++- .../MyPackage/Trees/LegacyTestTree.cs | 8 ++- .../Editors/BackOfficeController.cs | 34 +++++++++++ src/Umbraco.Web/PluginManagerExtensions.cs | 3 +- .../Trees/ApplicationTreeRegistrar.cs | 3 + .../Trees/ContentTreeController.cs | 1 + .../Trees/DataTypeTreeController.cs | 1 + src/Umbraco.Web/Trees/MediaTreeController.cs | 1 + src/Umbraco.Web/Trees/MemberTreeController.cs | 1 + .../Trees/Menu/MenuItemCollection.cs | 36 ++--------- .../Trees/Menu/MenuItemExtensions.cs | 15 ----- src/Umbraco.Web/Trees/TreeAttribute.cs | 12 ++++ src/Umbraco.Web/Trees/TreeController.cs | 59 +------------------ 17 files changed, 146 insertions(+), 122 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/mocks/umbraco.servervariables.js b/src/Umbraco.Web.UI.Client/src/common/mocks/umbraco.servervariables.js index 058a8366ae..d4fe75e80c 100644 --- a/src/Umbraco.Web.UI.Client/src/common/mocks/umbraco.servervariables.js +++ b/src/Umbraco.Web.UI.Client/src/common/mocks/umbraco.servervariables.js @@ -23,5 +23,10 @@ Umbraco.Sys.ServerVariables = { "appPluginsPath" : "/App_Plugins", "imageFileTypes": "jpeg,jpg,gif,bmp,png,tiff,tif" }, + umbracoPlugins: { + trees: [ + { alias: "myTree", packageFolder: "MyPackage" } + ] + }, isDebuggingEnabled: true }; \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/common/services/navigation.service.js b/src/Umbraco.Web.UI.Client/src/common/services/navigation.service.js index eca8f70576..70d7dc577c 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/navigation.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/navigation.service.js @@ -364,16 +364,19 @@ angular.module('umbraco.services') //by convention we will look into the /views/{treetype}/{action}.html // for example: /views/content/create.html - //we will also check for a 'packageName' in metaData, if it exists, we'll look by convention in that folder + //we will also check for a 'packageName' for the current tree, if it exists then the convention will be: // for example: /App_Plugins/{mypackage}/umbraco/{treetype}/create.html - if (args.action.metaData["packageName"]) { + var treeAlias = treeService.getTreeAlias(args.node); + var packageTreeFolder = treeService.getTreePackageFolder(treeAlias); - templateUrl = Umbraco.Sys.ServerVariables.umbracoSettings.appPluginsPath + - "/umbraco/views/" + treeService.getTreeAlias(args.node) + "/" + args.action.alias + ".html"; + if (packageTreeFolder) { + templateUrl = Umbraco.Sys.ServerVariables.umbracoSettings.appPluginsPath + + "/" + packageTreeFolder + + "/umbraco/" + treeAlias + "/" + args.action.alias + ".html"; } else { - templateUrl = "views/" + treeService.getTreeAlias(args.node) + "/" + args.action.alias + ".html"; + templateUrl = "views/" + treeAlias + "/" + args.action.alias + ".html"; } iframe = false; diff --git a/src/Umbraco.Web.UI.Client/src/common/services/tree.service.js b/src/Umbraco.Web.UI.Client/src/common/services/tree.service.js index f241ea6cab..b34cd72c79 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/tree.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/tree.service.js @@ -58,6 +58,33 @@ function treeService($q, treeResource, iconHelper, notificationsService, $rootSc } }, + /** + * @ngdoc method + * @name umbraco.services.treeService#getTreePackageFolder + * @methodOf umbraco.services.treeService + * @function + * + * @description + * Determines if the current tree is a plugin tree and if so returns the package folder it has declared + * so we know where to find it's views, otherwise it will just return undefined. + * + * @param {String} treeAlias The tree alias to check + */ + getTreePackageFolder: function(treeAlias) { + //we determine this based on the server variables + if (Umbraco.Sys.ServerVariables.umbracoPlugins && + Umbraco.Sys.ServerVariables.umbracoPlugins.trees && + angular.isArray(Umbraco.Sys.ServerVariables.umbracoPlugins.trees)) { + + var found = _.find(Umbraco.Sys.ServerVariables.umbracoPlugins.trees, function(item) { + return item.alias === treeAlias; + }); + + return found ? found.packageFolder : undefined; + } + return undefined; + }, + /** clears the tree cache */ clearCache: function() { treeArray = []; diff --git a/src/Umbraco.Web.UI.Client/src/routes.js b/src/Umbraco.Web.UI.Client/src/routes.js index 792fa23bd7..94ec046e81 100644 --- a/src/Umbraco.Web.UI.Client/src/routes.js +++ b/src/Umbraco.Web.UI.Client/src/routes.js @@ -84,21 +84,34 @@ app.config(function ($routeProvider) { resolve: checkAuth(true) }) .when('/:section/:tree/:method/:id', { - templateUrl: function (rp) { - if (!rp.tree || !rp.method) { - return "views/common/dashboard.html"; + //This allows us to dynamically change the template for this route since you cannot inject services into the templateUrl method. + template: "
", + //This controller will execute for this route, then we replace the template dynamnically based on the current tree. + controller: function ($scope, $route, $routeParams, treeService) { + + if (!$routeParams.tree || !$routeParams.method) { + $scope.templateUrl = "views/common/dashboard.html"; } - - //TODO: Here we need to figure out if this route is for a package and if so then we need + + // Here we need to figure out if this route is for a package tree and if so then we need // to change it's convention view path to: // /App_Plugins/{mypackage}/umbraco/{treetype}/{method}.html + // otherwise if it is a core tree we use the core paths: + // views/{treetype}/{method}.html - //we don't need to put views into section folders since theoretically trees - // could be moved among sections, we only need folders for specific trees. + var packageTreeFolder = treeService.getTreePackageFolder($routeParams.tree); + + if (packageTreeFolder) { + $scope.templateUrl = Umbraco.Sys.ServerVariables.umbracoSettings.appPluginsPath + + "/" + packageTreeFolder + + "/umbraco/" + $routeParams.tree + "/" + $routeParams.method + ".html"; + } + else { + $scope.templateUrl = 'views/' + $routeParams.tree + '/' + $routeParams.method + '.html'; + } - return 'views/' + rp.tree + '/' + rp.method + '.html'; - }, + }, resolve: checkAuth(true) }) .otherwise({ redirectTo: '/login' }); diff --git a/src/Umbraco.Web.UI.Client/test/unit/common/services/tree-service.spec.js b/src/Umbraco.Web.UI.Client/test/unit/common/services/tree-service.spec.js index f5ed2935a4..230a5ad015 100644 --- a/src/Umbraco.Web.UI.Client/test/unit/common/services/tree-service.spec.js +++ b/src/Umbraco.Web.UI.Client/test/unit/common/services/tree-service.spec.js @@ -40,7 +40,23 @@ describe('tree service tests', function () { beforeEach(inject(function ($injector) { treeService = $injector.get('treeService'); - })); + })); + + describe('lookup plugin based trees', function() { + + it('can find a plugin based tree', function () { + //we know this exists in the mock umbraco server vars + var found = treeService.getTreePackageFolder("myTree"); + expect(found).toBe("MyPackage"); + }); + + it('returns undefined for a not found tree', function () { + //we know this exists in the mock umbraco server vars + var found = treeService.getTreePackageFolder("asdfasdf"); + expect(found).not.toBeDefined(); + }); + + }); describe('query existing node structure of the tree', function () { diff --git a/src/Umbraco.Web.UI/App_Plugins/MyPackage/Trees/LegacyTestTree.cs b/src/Umbraco.Web.UI/App_Plugins/MyPackage/Trees/LegacyTestTree.cs index 347c55503a..4971384529 100644 --- a/src/Umbraco.Web.UI/App_Plugins/MyPackage/Trees/LegacyTestTree.cs +++ b/src/Umbraco.Web.UI/App_Plugins/MyPackage/Trees/LegacyTestTree.cs @@ -30,9 +30,11 @@ namespace Umbraco.Web.UI.App_Plugins.MyPackage.Trees } protected override MenuItemCollection GetMenuForNode(string id, FormDataCollection queryStrings) - { - MenuItems.AddMenuItem(new MenuItem("create", "Create")); - return MenuItems; + { + var menu = new MenuItemCollection(); + + menu.AddMenuItem(new MenuItem("create", "Create")); + return menu; } } diff --git a/src/Umbraco.Web/Editors/BackOfficeController.cs b/src/Umbraco.Web/Editors/BackOfficeController.cs index 641d809ca7..dabbd6b12c 100644 --- a/src/Umbraco.Web/Editors/BackOfficeController.cs +++ b/src/Umbraco.Web/Editors/BackOfficeController.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.IO; +using System.Linq; using System.Text; using System.Web.Mvc; using Umbraco.Core.Configuration; @@ -85,12 +86,45 @@ namespace Umbraco.Web.Editors string.Join(",",UmbracoConfig.For.UmbracoSettings().Content.ImageFileTypes)}, } }, + { + "umbracoPlugins", new Dictionary + { + {"trees", GetTreePluginsMetaData()} + } + }, { "isDebuggingEnabled", HttpContext.IsDebuggingEnabled } }; return JavaScript(ServerVariablesParser.Parse(d)); } + private IEnumerable> GetTreePluginsMetaData() + { + var treeTypes = PluginManager.Current.ResolveAttributedTreeControllers(); + //get all plugin trees with their attributes + var treesWithAttributes = treeTypes.Select(x => new + { + tree = x, attributes = + x.GetCustomAttributes(false) + }).ToArray(); + + var pluginTreesWithAttributes = treesWithAttributes + //don't resolve any tree decorated with CoreTreeAttribute + .Where(x => x.attributes.All(a => (a is CoreTreeAttribute) == false)) + //we only care about trees with the PluginControllerAttribute + .Where(x => x.attributes.Any(a => a is PluginControllerAttribute)) + .ToArray(); + + return (from p in pluginTreesWithAttributes + let treeAttr = p.attributes.OfType().Single() + let pluginAttr = p.attributes.OfType().Single() + select new Dictionary + { + {"alias", treeAttr.Alias}, {"packageFolder", pluginAttr.AreaName} + }).ToArray(); + + } + /// /// Returns the JavaScript blocks for any legacy trees declared /// diff --git a/src/Umbraco.Web/PluginManagerExtensions.cs b/src/Umbraco.Web/PluginManagerExtensions.cs index ab0846f530..bda4b3a95f 100644 --- a/src/Umbraco.Web/PluginManagerExtensions.cs +++ b/src/Umbraco.Web/PluginManagerExtensions.cs @@ -25,8 +25,7 @@ namespace Umbraco.Web /// internal static IEnumerable ResolveAttributedTreeControllers(this PluginManager resolver) { - //don't cache the result of this because it is only used once during app startup, caching will just add a bit more mem overhead for no reason - return resolver.ResolveTypesWithAttribute(cacheResult: false); + return resolver.ResolveTypesWithAttribute(); } internal static IEnumerable ResolveSurfaceControllers(this PluginManager resolver) diff --git a/src/Umbraco.Web/Trees/ApplicationTreeRegistrar.cs b/src/Umbraco.Web/Trees/ApplicationTreeRegistrar.cs index 2cdd43be38..6666936c70 100644 --- a/src/Umbraco.Web/Trees/ApplicationTreeRegistrar.cs +++ b/src/Umbraco.Web/Trees/ApplicationTreeRegistrar.cs @@ -7,6 +7,9 @@ using umbraco.businesslogic; namespace Umbraco.Web.Trees { + //TODO: Is there any way to get this to execute lazily when needed? + // i.e. When the back office loads so that this doesn't execute on startup for a content request. + /// /// A startup handler for putting the tree config in the config file based on attributes found /// diff --git a/src/Umbraco.Web/Trees/ContentTreeController.cs b/src/Umbraco.Web/Trees/ContentTreeController.cs index 080ca2a559..1d66121de2 100644 --- a/src/Umbraco.Web/Trees/ContentTreeController.cs +++ b/src/Umbraco.Web/Trees/ContentTreeController.cs @@ -22,6 +22,7 @@ namespace Umbraco.Web.Trees [LegacyBaseTree(typeof(loadContent))] [Tree(Constants.Applications.Content, Constants.Trees.Content, "Content")] [PluginController("UmbracoTrees")] + [CoreTree] public class ContentTreeController : ContentTreeControllerBase { protected override TreeNode CreateRootNode(FormDataCollection queryStrings) diff --git a/src/Umbraco.Web/Trees/DataTypeTreeController.cs b/src/Umbraco.Web/Trees/DataTypeTreeController.cs index 348fa88628..a5203da563 100644 --- a/src/Umbraco.Web/Trees/DataTypeTreeController.cs +++ b/src/Umbraco.Web/Trees/DataTypeTreeController.cs @@ -15,6 +15,7 @@ namespace Umbraco.Web.Trees { [Tree(Constants.Applications.Developer, Constants.Trees.DataTypes, "Data Types")] [PluginController("UmbracoTrees")] + [CoreTree] public class DataTypeTreeController : TreeController { protected override TreeNodeCollection GetTreeNodes(string id, FormDataCollection queryStrings) diff --git a/src/Umbraco.Web/Trees/MediaTreeController.cs b/src/Umbraco.Web/Trees/MediaTreeController.cs index 8f806f980e..22fabe5da8 100644 --- a/src/Umbraco.Web/Trees/MediaTreeController.cs +++ b/src/Umbraco.Web/Trees/MediaTreeController.cs @@ -18,6 +18,7 @@ namespace Umbraco.Web.Trees [LegacyBaseTree(typeof(loadMedia))] [Tree(Constants.Applications.Media, Constants.Trees.Media, "Media")] [PluginController("UmbracoTrees")] + [CoreTree] public class MediaTreeController : ContentTreeControllerBase { protected override TreeNode CreateRootNode(FormDataCollection queryStrings) diff --git a/src/Umbraco.Web/Trees/MemberTreeController.cs b/src/Umbraco.Web/Trees/MemberTreeController.cs index 50c22812eb..8350662265 100644 --- a/src/Umbraco.Web/Trees/MemberTreeController.cs +++ b/src/Umbraco.Web/Trees/MemberTreeController.cs @@ -17,6 +17,7 @@ namespace Umbraco.Web.Trees [LegacyBaseTree(typeof (loadMembers))] [Tree(Constants.Applications.Members, Constants.Trees.Members, "Members")] [PluginController("UmbracoTrees")] + [CoreTree] public class MemberTreeController : TreeController { protected override TreeNodeCollection GetTreeNodes(string id, FormDataCollection queryStrings) diff --git a/src/Umbraco.Web/Trees/Menu/MenuItemCollection.cs b/src/Umbraco.Web/Trees/Menu/MenuItemCollection.cs index 5e4f305848..bd71a8d595 100644 --- a/src/Umbraco.Web/Trees/Menu/MenuItemCollection.cs +++ b/src/Umbraco.Web/Trees/Menu/MenuItemCollection.cs @@ -12,7 +12,7 @@ namespace Umbraco.Web.Trees.Menu [DataContract(Name = "menuItems", Namespace = "")] public class MenuItemCollection { - private readonly string _packageFolderName; + //private readonly string _packageFolderName; private readonly List _menuItems; public MenuItemCollection() @@ -24,19 +24,7 @@ namespace Umbraco.Web.Trees.Menu { _menuItems = new List(items); } - - public MenuItemCollection(string packageFolderName) - : this() - { - _packageFolderName = packageFolderName; - } - - public MenuItemCollection(string packageFolderName, IEnumerable items) - { - _packageFolderName = packageFolderName; - _menuItems = new List(items); - } - + /// /// Sets the default menu item alias to be shown when the menu is launched - this is optional and if not set then the menu will just be shown normally. /// @@ -63,7 +51,7 @@ namespace Umbraco.Web.Trees.Menu DetectLegacyActionMenu(action.GetType(), item); - AddItemToCollection(item); + _menuItems.Add(item); return item; } @@ -81,7 +69,7 @@ namespace Umbraco.Web.Trees.Menu ///
public void AddMenuItem(MenuItem item) { - AddItemToCollection(item); + _menuItems.Add(item); } /// @@ -109,7 +97,7 @@ namespace Umbraco.Web.Trees.Menu Action = item.Action }; - AddItemToCollection(customMenuItem); + _menuItems.Add(customMenuItem); return customMenuItem; } @@ -152,7 +140,7 @@ namespace Umbraco.Web.Trees.Menu var item = CreateMenuItem(name, hasSeparator, additionalData); if (item != null) { - AddItemToCollection(item); + _menuItems.Add(item); return item; } return null; @@ -224,18 +212,6 @@ namespace Umbraco.Web.Trees.Menu } } - /// - /// This handles adding a menu item to the internal collection and will configure it accordingly - /// - /// - private void AddItemToCollection(MenuItem menuItem) - { - if (_packageFolderName.IsNullOrWhiteSpace() == false) - { - menuItem.SetPackageFolder(_packageFolderName); - } - _menuItems.Add(menuItem); - } } } \ No newline at end of file diff --git a/src/Umbraco.Web/Trees/Menu/MenuItemExtensions.cs b/src/Umbraco.Web/Trees/Menu/MenuItemExtensions.cs index 019b42ab19..32dfecc13a 100644 --- a/src/Umbraco.Web/Trees/Menu/MenuItemExtensions.cs +++ b/src/Umbraco.Web/Trees/Menu/MenuItemExtensions.cs @@ -6,11 +6,6 @@ namespace Umbraco.Web.Trees.Menu { public static class MenuItemExtensions { - /// - /// Used as a key for the AdditionalData to specify which package folder the menu launcher should look in for views - /// - internal const string PackageName = "packageName"; - /// /// Used as a key for the AdditionalData to specify a specific dialog title instead of the menu title /// @@ -32,16 +27,6 @@ namespace Umbraco.Web.Trees.Menu /// internal const string ActionViewKey = "actionView"; - /// - /// Sets the package folder to look for views in - /// - /// - /// - internal static void SetPackageFolder(this MenuItem menuItem, string packageFolder) - { - menuItem.AdditionalData[PackageName] = packageFolder; - } - /// /// Sets the menu item to display a dialog based on an angular view path /// diff --git a/src/Umbraco.Web/Trees/TreeAttribute.cs b/src/Umbraco.Web/Trees/TreeAttribute.cs index 72ae4044e9..5acf367738 100644 --- a/src/Umbraco.Web/Trees/TreeAttribute.cs +++ b/src/Umbraco.Web/Trees/TreeAttribute.cs @@ -2,6 +2,18 @@ namespace Umbraco.Web.Trees { + /// + /// Indicates that a tree is a core tree and shouldn't be treated as a plugin tree + /// + /// + /// This ensures that umbraco will look in the umbraco folders for views for this tree + /// + [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] + internal class CoreTreeAttribute : Attribute + { + + } + /// /// Identifies an application tree /// diff --git a/src/Umbraco.Web/Trees/TreeController.cs b/src/Umbraco.Web/Trees/TreeController.cs index e7df099c53..c624d75656 100644 --- a/src/Umbraco.Web/Trees/TreeController.cs +++ b/src/Umbraco.Web/Trees/TreeController.cs @@ -18,7 +18,6 @@ namespace Umbraco.Web.Trees public abstract class TreeController : UmbracoAuthorizedApiController { private readonly TreeAttribute _attribute; - private readonly MenuItemCollection _menuItemCollection; /// /// Remove the xml formatter... only support JSON! @@ -45,21 +44,8 @@ namespace Umbraco.Web.Trees //assign the properties of this object to those of the metadata attribute _attribute = treeAttributes.First(); - - //Create the menu item collection with the area nem already specified - _menuItemCollection = Metadata.AreaName.IsNullOrWhiteSpace() - ? new MenuItemCollection() - : new MenuItemCollection(Metadata.AreaName); } - - /// - /// Returns a menu item collection to be used to return the menu items from GetMenuForNode - /// - public MenuItemCollection MenuItems - { - get { return _menuItemCollection; } - } - + /// /// The method called to render the contents of the tree structure /// @@ -334,47 +320,6 @@ namespace Umbraco.Web.Trees if (handler != null) handler(instance, e); } #endregion - - #region Metadata - /// - /// stores the metadata about plugin controllers - /// - private static readonly ConcurrentDictionary MetadataStorage = new ConcurrentDictionary(); - - /// - /// Returns the metadata for this instance - /// - internal PluginControllerMetadata Metadata - { - get { return GetMetadata(this.GetType()); } - } - - /// - /// Returns the metadata for a PluginController - /// - /// - /// - internal static PluginControllerMetadata GetMetadata(Type type) - { - - return MetadataStorage.GetOrAdd(type, type1 => - { - var attribute = type.GetCustomAttribute(false); - - var meta = new PluginControllerMetadata() - { - AreaName = attribute == null ? null : attribute.AreaName, - ControllerName = ControllerExtensions.GetControllerName(type), - ControllerNamespace = type.Namespace, - ControllerType = type - }; - - MetadataStorage.TryAdd(type, meta); - - return meta; - }); - - } - #endregion + } } From b0dfc90557aaf34fbeb224bc4977391ddfaffb44 Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 3 Oct 2013 12:11:22 +1000 Subject: [PATCH 13/31] Added docs on creating trees and view path location conventions. --- .../tutorials/Creating-Editors-Trees.ngdoc | 165 ++++++++++++++++++ .../MyPackage/Trees/LegacyTestTree.cs | 25 +-- src/Umbraco.Web/Trees/Menu/MenuItem.cs | 1 + 3 files changed, 179 insertions(+), 12 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/docs/src/tutorials/Creating-Editors-Trees.ngdoc diff --git a/src/Umbraco.Web.UI.Client/docs/src/tutorials/Creating-Editors-Trees.ngdoc b/src/Umbraco.Web.UI.Client/docs/src/tutorials/Creating-Editors-Trees.ngdoc new file mode 100644 index 0000000000..095719b05f --- /dev/null +++ b/src/Umbraco.Web.UI.Client/docs/src/tutorials/Creating-Editors-Trees.ngdoc @@ -0,0 +1,165 @@ +@ngdoc overview +@name Creating a custom tree with an editor and dialog +@description + +##Overview + +This guide will explain how to create a simple custom tree an angular editor & dialog using standard conventions. This guide does not go into detail about how to persist data in your editors, it is a simple tutorial defining how routing interacts with your views and where your views need to be stored. + +So all the steps we will go through: + +- Creating a tree with a menu item +- Create an editor +- Create a dialog for the menu item + +##Create a tree + +First you need to define a tree class that inherits from `Umbraco.Web.Trees.TreeController` + + public class MyCustomTreeController : TreeController + { + } + +The name of your tree must be suffixed with the term 'Controller'. + +Next we need to add some attributes to the tree. The first one defines the section it belongs to, the tree alias and it's name. Ensure your tree alias is unique, tree aliases cannot overlap. + + [Tree("settings", "myTree", "My Tree")] + +The 2nd attribute does 2 things - Tells Umbraco how to route the tree and tells Umbraco where to find the view files. This attribute is not required but if you do not specify it then the view location conventions will not work. + + [PluginController("MyPackage")] + +There are 2 methods that need to be overriden from the TreeController class: `GetTreeNodes` & `GetMenuForNode`. This example will create 3 nodes underneath the root node: + + protected override TreeNodeCollection GetTreeNodes(string id, FormDataCollection queryStrings) + { + //check if we're rendering the root node's children + if (id == Constants.System.Root.ToInvariantString()) + { + var tree = new TreeNodeCollection + { + CreateTreeNode("1", queryStrings, "My Node 1"), + CreateTreeNode("2", queryStrings, "My Node 2"), + CreateTreeNode("3", queryStrings, "My Node 3") + }; + return tree; + } + //this tree doesn't suport rendering more than 1 level + throw new NotSupportedException(); + } + +Next we'll create a menu item for each node, in this case its a 'Create' menu item + + protected override MenuItemCollection GetMenuForNode(string id, FormDataCollection queryStrings) + { + var menu = new MenuItemCollection(); + menu.AddMenuItem(new MenuItem("create", "Create")); + return menu; + } + +That's it, the whole tree looks like this: + + [Tree("settings", "myTree", "My Tree")] + [PluginController("MyPackage")] + public class MyCustomTreeController : TreeController + { + protected override TreeNodeCollection GetTreeNodes(string id, FormDataCollection queryStrings) + { + //check if we're rendering the root node's children + if (id == Constants.System.Root.ToInvariantString()) + { + var tree = new TreeNodeCollection + { + CreateTreeNode("1", queryStrings, "My Node 1"), + CreateTreeNode("2", queryStrings, "My Node 2"), + CreateTreeNode("3", queryStrings, "My Node 3") + }; + return tree; + } + //this tree doesn't suport rendering more than 1 level + throw new NotSupportedException(); + } + protected override MenuItemCollection GetMenuForNode(string id, FormDataCollection queryStrings) + { + var menu = new MenuItemCollection(); + menu.AddMenuItem(new MenuItem("create", "Create")); + return menu; + } + } + +##View path conventions + +Now that we've created our tree it is important to understand Umbraco conventions and where it will look for your views for editors and dialogs. + +###Angular editor routes + +The main angular route to load in editors is */:section/:tree/:method/:id* + +Umbraco will load in views for this route based on these conventions: + + * If it is a core tree - views will be loaded from: */umbraco/views/{treetype}/{method}.html* + * If it is a custom (package) tree - views will be loaded from: */App_Plugins/{mypackage}/umbraco/{treetype}/{method}.html* + +###Editor locations + +By default each tree node's 'method' is assigned as 'edit' therefore these are the view paths for an editor when a tree node is clicked: + + * If it is a core tree - views will be loaded from: */umbraco/views/{treetype}/edit.html* + * If it is a custom (package) tree - views will be loaded from: */App_Plugins/{mypackage}/umbraco/{treetype}/edit.html* + +Developers can specify a custom `RoutePath` for any tree node which will cause umbraco to route to that specific location. + +###Dialog locations + +Dialog view path locations are similar to editors: + + * If it is a core tree - views will be loaded from: umbraco/views/{treetype}/{action}.html + * If it is a custom (package) tree - views will be loaded from: /App_Plugins/{mypackage}/umbraco/{treetype}/{action}.html + +'action' is the alias of your menu item, for example in the menu item in the example above this would be 'create'. + +##Create an editor + +An editor is simply an angular view (html file) so you can really do whatever you'd like! This tutorial will simply create a hello world editor showing the id of the item being edited. + +###Create a controller + +First thing we'll do is create an angular controller for the editor, this controller will be contained in a file found beside the view - *the file naming conventions are based on the controller file naming conventions in the Umbraco core*. + +/App_Plugins/MyPackage/Umbraco/MyTree/mypackage.mytree.edit.controller.js + +The controller is super simple, at it is going to do is assign a property to the $scope which shows the current item id being edited: + + 'use strict'; + (function () { + //create the controller + function myTreeEditController($scope, $routeParams) { + //set a property on the scope equal to the current route id + $scope.id = $routeParams.id; + }; + //register the controller + angular.module("umbraco").controller('MyPackage.MyTree.EditController', myTreeEditController); + })(); + +###Create a view + +As per the conventions above our editor view will need to be located at: + +/App_Plugins/MyPackage/Umbraco/MyTree/edit.html + +The view is simple, it is just going to show the current id being edited + +
+

Hello world!

+

+ You are current editing an item with id {{id}} +

+
+ +##Create a dialog + +This is the same principle as an editor, you just need to follow conventions. Based on the above conventions the 'create' dialog view will be located here: + +/App_Plugins/MyPackage/Umbraco/MyTree/create.html + diff --git a/src/Umbraco.Web.UI/App_Plugins/MyPackage/Trees/LegacyTestTree.cs b/src/Umbraco.Web.UI/App_Plugins/MyPackage/Trees/LegacyTestTree.cs index 4971384529..1dfaf4da44 100644 --- a/src/Umbraco.Web.UI/App_Plugins/MyPackage/Trees/LegacyTestTree.cs +++ b/src/Umbraco.Web.UI/App_Plugins/MyPackage/Trees/LegacyTestTree.cs @@ -10,29 +10,29 @@ using Constants = Umbraco.Core.Constants; namespace Umbraco.Web.UI.App_Plugins.MyPackage.Trees { - [Tree(Constants.Applications.Settings, "myTree", "My Tree")] + [Tree("settings", "myTree", "My Tree")] [PluginController("MyPackage")] public class MyCustomTreeController : TreeController { protected override TreeNodeCollection GetTreeNodes(string id, FormDataCollection queryStrings) { + //check if we're rendering the root node's children if (id == Constants.System.Root.ToInvariantString()) { var tree = new TreeNodeCollection - { - CreateTreeNode("1", queryStrings, "My Node 1"), - CreateTreeNode("2", queryStrings, "My Node 2"), - CreateTreeNode("3", queryStrings, "My Node 3") - }; + { + CreateTreeNode("1", queryStrings, "My Node 1"), + CreateTreeNode("2", queryStrings, "My Node 2"), + CreateTreeNode("3", queryStrings, "My Node 3") + }; return tree; } + //this tree doesn't suport rendering more than 1 level throw new NotSupportedException(); } - protected override MenuItemCollection GetMenuForNode(string id, FormDataCollection queryStrings) { var menu = new MenuItemCollection(); - menu.AddMenuItem(new MenuItem("create", "Create")); return menu; } @@ -40,7 +40,8 @@ namespace Umbraco.Web.UI.App_Plugins.MyPackage.Trees public class LegacyTestTree : BaseTree { - public LegacyTestTree(string application) : base(application) + public LegacyTestTree(string application) + : base(application) { } @@ -52,10 +53,10 @@ namespace Umbraco.Web.UI.App_Plugins.MyPackage.Trees public override int StartNodeID { get { return -1; } - } + } public override void RenderJS(ref StringBuilder javascript) - { + { } public override void Render(ref XmlTree tree) @@ -70,7 +71,7 @@ namespace Umbraco.Web.UI.App_Plugins.MyPackage.Trees protected override void CreateRootNode(ref XmlTreeNode rootNode) { - + } } } \ No newline at end of file diff --git a/src/Umbraco.Web/Trees/Menu/MenuItem.cs b/src/Umbraco.Web/Trees/Menu/MenuItem.cs index ed5d9c5778..031c585930 100644 --- a/src/Umbraco.Web/Trees/Menu/MenuItem.cs +++ b/src/Umbraco.Web/Trees/Menu/MenuItem.cs @@ -15,6 +15,7 @@ namespace Umbraco.Web.Trees.Menu public MenuItem() { AdditionalData = new Dictionary(); + Icon = "folder"; } public MenuItem(string alias, string name) From 6ac724951bc17071c64d54ad1ca30e8b2ff3d532 Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 3 Oct 2013 12:18:21 +1000 Subject: [PATCH 14/31] Explicitly adds automapper to the UI proj so we don't get that strange YSOD that says it's not there sometimes. --- src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 8 ++++++++ src/Umbraco.Web.UI/packages.config | 1 + 2 files changed, 9 insertions(+) diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 06b5f301ab..b79510e0e8 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -107,6 +107,14 @@ {07fbc26b-2927-4a22-8d96-d644c667fecc} UmbracoExamine + + False + ..\packages\AutoMapper.3.0.0\lib\net40\AutoMapper.dll + + + False + ..\packages\AutoMapper.3.0.0\lib\net40\AutoMapper.Net4.dll + False ..\packages\ClientDependency.1.7.0.4\lib\ClientDependency.Core.dll diff --git a/src/Umbraco.Web.UI/packages.config b/src/Umbraco.Web.UI/packages.config index 0e8d39bbe0..b4df6b2899 100644 --- a/src/Umbraco.Web.UI/packages.config +++ b/src/Umbraco.Web.UI/packages.config @@ -1,5 +1,6 @@  + From 55247fe31dac59ce7f2aa9adf1d39fb900a90564 Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 3 Oct 2013 12:45:40 +1000 Subject: [PATCH 15/31] Finally got around to changing all calls to umbraco.IO to Umbraco.Core.IO - that'll clear up several hundreds of warnings :) --- src/Umbraco.Tests/BusinessLogic/BaseTest.cs | 2 +- .../Routing/UmbracoModuleTests.cs | 2 +- src/Umbraco.Web.UI/install/steps/theend.ascx | 4 +-- src/Umbraco.Web.UI/umbraco/Default.aspx | 2 +- .../umbraco/Search/QuickSearch.ascx | 2 +- .../GenericProperties/GenericProperty.ascx | 4 +-- .../umbraco/controls/ProgressBar.ascx | 2 +- .../umbraco/controls/Tree/TreeControl.ascx | 4 +-- .../umbraco/developer/Xslt/editXslt.aspx | 2 +- .../umbraco/dialogs/ChangeDocType.aspx | 2 +- .../umbraco/plugins/uGoLive/Dashboard.ascx | 2 +- .../umbraco/settings/editTemplate.aspx | 4 +-- src/Umbraco.Web.UI/umbraco/umbraco.aspx | 4 +-- .../FileExtensionIconThumbnailProvider.cs | 2 +- .../ImageThumbnailProvider.cs | 2 +- .../MediaTypeIconThumbnailProvider.cs | 2 +- src/Umbraco.Web/UI/Controls/FolderBrowser.cs | 2 +- src/Umbraco.Web/UmbracoContext.cs | 2 +- .../umbraco.presentation/LegacyClasses.cs | 2 +- .../umbraco.presentation/NotFoundHandlers.cs | 2 +- .../UmbracoServerUtility.cs | 2 +- .../steps/Definitions/LegacyClasses.cs | 12 +++---- .../install/steps/LegacyClasses.cs | 18 +++++------ .../umbraco.presentation/library.cs | 4 +-- .../umbraco.presentation/python.cs | 2 +- .../umbraco.presentation/requestModule.cs | 2 +- .../umbraco.presentation/template.cs | 2 +- .../Controls/LiveEditingToolbar.cs | 2 +- .../Modules/CreateModule/CreateModule.cs | 2 +- .../Modules/DeleteModule/DeleteModule.cs | 2 +- .../Modules/MacroModule/MacroModule.cs | 2 +- .../Modules/SkinModule/ImageUploader.aspx.cs | 11 ++++--- .../Modules/SkinModule/SkinCustomizer.ascx.cs | 4 +-- .../Modules/SkinModule/SkinModule.cs | 2 +- .../UnpublishModule/UnpublishModule.cs | 2 +- .../umbraco/Trees/TreeService.cs | 2 +- .../umbraco/Trees/XmlTree.cs | 2 +- .../umbraco/Trees/loadDLRScripts.cs | 2 +- .../umbraco/Trees/loadPython.cs | 2 +- .../umbraco/Trees/loadScripts.cs | 2 +- .../umbraco/Trees/loadTemplates.cs | 7 +++-- .../umbraco/Trees/loadXslt.cs | 2 +- .../umbraco/actions/preview.aspx.cs | 4 +-- .../umbraco/channels/UmbracoMetaWeblogAPI.cs | 2 +- .../umbraco/channels/config.cs | 2 +- .../umbraco/controls/ContentTypeControl.cs | 2 +- .../GenericProperties/GenericProperty.ascx | 4 +-- .../GenericPropertyWrapper.cs | 2 +- .../Images/ImageViewerUpdater.asmx.cs | 2 +- .../umbraco/controls/ProgressBar.ascx | 2 +- .../umbraco/controls/SaveClickEventArgs.cs | 2 +- .../controls/Tree/CustomTreeControl.cs | 2 +- .../umbraco/controls/Tree/TreeControl.ascx | 4 +-- .../umbraco/controls/macroParameterControl.cs | 2 +- .../umbraco/create/CreatedPackageTasks.cs | 2 +- .../umbraco/create/DLRScripting.ascx.cs | 5 +-- .../umbraco/create/DLRScriptingTasks.cs | 4 +-- .../umbraco/create/DataTypeTasks.cs | 2 +- .../umbraco/create/MediaTypeTasks.cs | 2 +- .../umbraco/create/MemberGroupTasks.cs | 2 +- .../umbraco/create/MemberTypeTasks.cs | 2 +- .../umbraco/create/NewMemberUIEventArgs.cs | 2 +- .../umbraco/create/PythonTasks.cs | 2 +- .../umbraco/create/ScriptTasks.cs | 2 +- .../umbraco/create/StylesheetTasks.cs | 2 +- .../umbraco/create/contentItemTasks.cs | 2 +- .../umbraco/create/contentItemTypeTasks.cs | 2 +- .../umbraco/create/contentTasks.cs | 2 +- .../umbraco/create/dictionaryTasks.cs | 2 +- .../umbraco/create/languageTasks.cs | 2 +- .../umbraco/create/macroTasks.cs | 2 +- .../umbraco/create/mediaTasks.cs | 2 +- .../umbraco/create/memberTasks.cs | 2 +- .../umbraco/create/nodetypeTasks.cs | 2 +- .../umbraco/create/script.ascx.cs | 2 +- .../umbraco/create/stylesheetPropertyTasks.cs | 2 +- .../umbraco/create/templateTasks.cs | 2 +- .../umbraco/create/userTasks.cs | 2 +- .../umbraco/dashboard.aspx.cs | 2 +- .../umbraco/dashboard/FeedProxy.aspx.cs | 2 +- .../umbraco/dashboard/LatestEdits.ascx.cs | 2 +- .../developer/DataTypes/editDatatype.aspx.cs | 2 +- .../Packages/BrowseRepository.aspx.cs | 2 +- .../developer/Packages/editPackage.aspx.cs | 4 +-- .../developer/Xslt/getXsltStatus.asmx.cs | 2 +- .../developer/Xslt/xsltVisualize.aspx.cs | 2 +- .../umbraco/dialogs/imageViewer.aspx.cs | 2 +- .../umbraco/dialogs/uploadImage.aspx.cs | 2 +- .../umbraco/login.aspx.cs | 2 +- .../masterpages/umbracoDialog.Master.cs | 3 +- .../umbraco/plugins/tinymce3/GzipModule.cs | 4 +-- .../settings/EditDictionaryItem.aspx.cs | 2 +- .../umbraco/settings/editTemplate.aspx.cs | 10 +++--- .../settings/scripts/editScript.aspx.cs | 2 +- .../umbraco/templateControls/ItemRenderer.cs | 2 +- .../umbraco/translation/default.aspx.cs | 2 +- .../umbraco/translation/xml.aspx.cs | 2 +- .../umbraco/umbraco.aspx.cs | 4 +-- .../umbraco/users/EditUser.aspx.cs | 2 +- .../umbraco/users/EditUserType.aspx.cs | 2 +- .../umbraco/users/PermissionEditor.aspx.cs | 2 +- .../umbraco/users/PermissionsHandler.asmx.cs | 2 +- .../umbracobase/baseHttpModule.cs | 7 +++-- .../umbracobase/restExtension.cs | 2 +- .../RazorCore/RazorMacroEngine.cs | 2 +- .../BasePages/ClientTools.cs | 2 +- src/umbraco.businesslogic/GlobalSettings.cs | 2 +- src/umbraco.businesslogic/Utils/TypeFinder.cs | 2 +- src/umbraco.businesslogic/xmlHelper.cs | 2 +- src/umbraco.cms/businesslogic/CMSNode.cs | 4 +-- .../businesslogic/CMSPreviewNode.cs | 2 +- .../businesslogic/Packager/Installer.cs | 10 +++--- .../PackageActions/addDashboardSection.cs | 2 +- .../PackageActions/addProxyFeedHost.cs | 2 +- .../PackageActions/addRestExtension.cs | 2 +- .../PackageActions/addXsltExtension.cs | 2 +- .../PackageInstance/CreatedPackage.cs | 6 ++-- .../PackageInstance/InstalledPackage.cs | 2 +- .../Packager/PackageInstance/utill.cs | 2 +- .../Packager/Repositories/Repository.cs | 2 +- .../businesslogic/Packager/Settings.cs | 2 +- .../businesslogic/Packager/data.cs | 13 ++++---- .../businesslogic/skinning/Skin.cs | 31 ++++++++++--------- .../skinning/tasks/AddStyleSheetToTemplate.cs | 10 +++--- .../businesslogic/skinning/tasks/ModifyCss.cs | 8 ++--- .../skinning/tasks/ModifyTemplate.cs | 6 ++-- .../businesslogic/translation/Translation.cs | 2 +- src/umbraco.cms/businesslogic/web/Access.cs | 2 +- .../businesslogic/web/DocumentVersionList.cs | 2 +- .../businesslogic/workflow/Notification.cs | 2 +- src/umbraco.controls/CodeArea.cs | 2 +- src/umbraco.controls/ProgressBar.cs | 3 +- src/umbraco.controls/Splitter.cs | 4 +-- .../TreePicker/BaseTreePicker.cs | 2 +- src/umbraco.controls/TreeUrlGenerator.cs | 6 ++-- .../SelectedItemsTemplate.cs | 2 +- src/umbraco.editorControls/XmlData.cs | 3 +- .../colorpicker/colorPicker.cs | 2 +- .../imagecropper/ImageInfo.cs | 2 +- .../macrocontainer/Editor.cs | 4 +-- .../relatedlinks/RelatedLinksDataEditor.cs | 2 +- .../simpleEditor/simpleEditor.cs | 8 ++--- .../tinyMCE3/TinyMCE.cs | 4 +-- .../tinyMCE3/webcontrol/plugin/GzipModule.cs | 2 +- .../tinymce/tinyMCEConfiguration.cs | 4 +-- .../ultimatePickerDataEditor.cs | 2 +- .../usercontrolPrevalueEditor.cs | 10 +++--- src/umbraco.macroRenderings/content.cs | 2 +- src/umbraco.macroRenderings/media.cs | 1 - 149 files changed, 245 insertions(+), 237 deletions(-) diff --git a/src/Umbraco.Tests/BusinessLogic/BaseTest.cs b/src/Umbraco.Tests/BusinessLogic/BaseTest.cs index 73d51e7816..50e6a43331 100644 --- a/src/Umbraco.Tests/BusinessLogic/BaseTest.cs +++ b/src/Umbraco.Tests/BusinessLogic/BaseTest.cs @@ -7,7 +7,7 @@ using Umbraco.Core; using Umbraco.Tests.TestHelpers; using umbraco.BusinessLogic; using umbraco.DataLayer; -using umbraco.IO; +using Umbraco.Core.IO; using GlobalSettings = umbraco.GlobalSettings; namespace Umbraco.Tests.BusinessLogic diff --git a/src/Umbraco.Tests/Routing/UmbracoModuleTests.cs b/src/Umbraco.Tests/Routing/UmbracoModuleTests.cs index d31e6dbec8..ea62370655 100644 --- a/src/Umbraco.Tests/Routing/UmbracoModuleTests.cs +++ b/src/Umbraco.Tests/Routing/UmbracoModuleTests.cs @@ -10,7 +10,7 @@ using Umbraco.Tests.TestHelpers; using Umbraco.Web; using Umbraco.Web.Routing; using umbraco.BusinessLogic; -using umbraco.IO; +using Umbraco.Core.IO; using umbraco.cms.businesslogic.cache; using umbraco.cms.businesslogic.template; diff --git a/src/Umbraco.Web.UI/install/steps/theend.ascx b/src/Umbraco.Web.UI/install/steps/theend.ascx index b2b4ffe395..ea0d00696c 100644 --- a/src/Umbraco.Web.UI/install/steps/theend.ascx +++ b/src/Umbraco.Web.UI/install/steps/theend.ascx @@ -31,8 +31,8 @@ jQuery(document).ready(function () {
If you installed a starter kit you can start by configuring your new site, just click "Preview your new website" and follow the instructions. Or to start adding content right away click "Set up your new website"

diff --git a/src/Umbraco.Web.UI/umbraco/Default.aspx b/src/Umbraco.Web.UI/umbraco/Default.aspx index 963ced80c2..d3421e3997 100644 --- a/src/Umbraco.Web.UI/umbraco/Default.aspx +++ b/src/Umbraco.Web.UI/umbraco/Default.aspx @@ -12,7 +12,7 @@ } - +