diff --git a/.gitignore b/.gitignore index 339279d0f5..38d41211d5 100644 --- a/.gitignore +++ b/.gitignore @@ -23,11 +23,11 @@ _NCrunch_*/ umbraco.config *.vs10x App_Data/TEMP/* -umbraco/presentation/umbraco/plugins/* -umbraco/presentation/usercontrols/* -umbraco/presentation/scripts/* -umbraco/presentation/fonts/* -umbraco/presentation/css/* +[Uu]mbraco/[Pp]resentation/[Uu]mbraco/[Pp]lugins/* +[Uu]mbraco/[Pp]resentation/[Uu]ser[Cc]ontrols/* +[Uu]mbraco/[Pp]resentation/[Ss]cripts/* +[Uu]mbraco/[Pp]resentation/[Ff]onts/* +[Uu]mbraco/[Pp]resentation/[Cc]ss/* src/Umbraco.Web.UI/[Cc]ss/* src/Umbraco.Web.UI/App_Code/* @@ -44,7 +44,6 @@ src/Umbraco.Web.UI/Web.*.config.transformed umbraco/presentation/umbraco/plugins/uComponents/uComponentsInstaller.ascx umbraco/presentation/packages/uComponents/MultiNodePicker/CustomTreeService.asmx _BuildOutput/* -*.ncrunchsolution build/UmbracoCms.AllBinaries*zip build/UmbracoCms.WebPI*zip build/UmbracoCms*zip @@ -54,14 +53,28 @@ src/Umbraco.Tests/config/trees.config src/Umbraco.Web.UI/web.config *.orig src/Umbraco.Tests/config/404handlers.config -src/Umbraco.Web.UI/Views/*.cshtml -src/Umbraco.Web.UI/Views/*.vbhtml -src/Umbraco.Tests/config/umbracoSettings.config -src/Umbraco.Web.UI/App_Plugins/* -src/Umbraco.Web.UI/Views/* +src/Umbraco.Web.UI/[Vv]iews/*.cshtml +src/Umbraco.Web.UI/[Vv]iews/*.vbhtml +src/Umbraco.Tests/[Cc]onfig/umbracoSettings.config +src/Umbraco.Web.UI/[Vv]iews/* src/packages/ src/packages/repositories.config -src/Umbraco.Web.UI/[W]eb.config +src/Umbraco.Web.UI/[Ww]eb.config *.transformed -webpihash.txt \ No newline at end of file +webpihash.txt + +node_modules +src/Umbraco.Web.UI/[Uu]mbraco/[Ll]ib/* +src/Umbraco.Web.UI/[Uu]mbraco/[Jj]s/umbraco.* +src/Umbraco.Web.UI/[Uu]mbraco/[Jj]s/routes.js +src/Umbraco.Web.UI/[Uu]mbraco/[Jj]s/main.js +src/Umbraco.Web.UI/[Uu]mbraco/[Jj]s/app.js +src/Umbraco.Web.UI/[Uu]mbraco/[Vv]iews/**/*.js +src/Umbraco.Web.UI/[Uu]mbraco/[Vv]iews/**/*.css +src/Umbraco.Web.UI/[Uu]mbraco/[Vv]iews/**/*.html +src/Umbraco.Web.UI/[Uu]mbraco/[Aa]ssets/* +src/Umbraco.Web.UI.Client/[Bb]uild/* +src/Umbraco.Web.UI.Client/[Bb]uild/[Bb]elle/ +src/Umbraco.Web.UI/[Uu]ser[Cc]ontrols/ +build/_BuildOutput/ diff --git a/src/Umbraco.Web.UI/umbraco_client/FolderBrowser/Js/folderbrowser.js b/src/Umbraco.Web.UI/umbraco_client/FolderBrowser/Js/folderbrowser.js index a8132ae7c7..438a04344a 100644 --- a/src/Umbraco.Web.UI/umbraco_client/FolderBrowser/Js/folderbrowser.js +++ b/src/Umbraco.Web.UI/umbraco_client/FolderBrowser/Js/folderbrowser.js @@ -178,7 +178,7 @@ Umbraco.Sys.registerNamespace("Umbraco.Controls"); var overlay = $("
" + "
" + instructions + - "
" + + "" + "" + "" + "" + diff --git a/src/Umbraco.Web.UI/web.Template.config b/src/Umbraco.Web.UI/web.Template.config index c0e24992f3..e7a036fc40 100644 --- a/src/Umbraco.Web.UI/web.Template.config +++ b/src/Umbraco.Web.UI/web.Template.config @@ -167,13 +167,6 @@ - - - - - - - @@ -290,4 +283,4 @@ - \ No newline at end of file + diff --git a/src/Umbraco.Web/Mvc/AreaRegistrationExtensions.cs b/src/Umbraco.Web/Mvc/AreaRegistrationExtensions.cs index c867a0823d..d61257b760 100644 --- a/src/Umbraco.Web/Mvc/AreaRegistrationExtensions.cs +++ b/src/Umbraco.Web/Mvc/AreaRegistrationExtensions.cs @@ -7,7 +7,7 @@ using Umbraco.Core.Configuration; namespace Umbraco.Web.Mvc { - internal static class AreaRegistrationExtensions + internal static class AreaRegistrationExtensions { /// /// Creates a custom individual route for the specified controller plugin. Individual routes @@ -31,7 +31,7 @@ namespace Umbraco.Web.Mvc string umbracoTokenValue = "backoffice") { Mandate.ParameterNotNullOrEmpty(controllerName, "controllerName"); - Mandate.ParameterNotNullOrEmpty(controllerSuffixName, "controllerSuffixName"); + Mandate.ParameterNotNull(controllerSuffixName, "controllerSuffixName"); Mandate.ParameterNotNullOrEmpty(defaultAction, "defaultAction"); Mandate.ParameterNotNull(controllerType, "controllerType"); Mandate.ParameterNotNull(routes, "routes"); @@ -60,13 +60,18 @@ namespace Umbraco.Web.Mvc { "id", defaultId } }); - //constraints: only match controllers ending with 'controllerSuffixName' and only match this controller's ID for this route - controllerPluginRoute.Constraints = new RouteValueDictionary( - new Dictionary + //Don't look anywhere else except this namespace! + controllerPluginRoute.DataTokens.Add("UseNamespaceFallback", false); + + //constraints: only match controllers ending with 'controllerSuffixName' and only match this controller's ID for this route + if (controllerSuffixName.IsNullOrWhiteSpace() == false) + { + controllerPluginRoute.Constraints = new RouteValueDictionary( + new Dictionary { { "controller", @"(\w+)" + controllerSuffixName } - }); - + }); + } //match this area controllerPluginRoute.DataTokens.Add("area", area.AreaName); diff --git a/src/Umbraco.Web/Mvc/BackOfficeArea.cs b/src/Umbraco.Web/Mvc/BackOfficeArea.cs new file mode 100644 index 0000000000..5393996d78 --- /dev/null +++ b/src/Umbraco.Web/Mvc/BackOfficeArea.cs @@ -0,0 +1,44 @@ +using System.Web.Mvc; +using Umbraco.Core.Configuration; +using Umbraco.Web.Install; + +namespace Umbraco.Web.Mvc +{ + /// + /// An area registration for back office components + /// + internal class BackOfficeArea : AreaRegistration + { + + /// + /// Create the routes for the area + /// + /// + /// + /// By using the context to register the routes it means that the area is already applied to them all + /// and that the namespaces searched for the controllers are ONLY the ones specified. + /// + public override void RegisterArea(AreaRegistrationContext context) + { + //Create the install routes + context.MapRoute( + "Umbraco_install_packages", + "Install/PackageInstaller/{action}/{id}", + new {controller = "InstallPackage", action = "Index", id = UrlParameter.Optional}, + new[] {typeof (InstallPackageController).Namespace}); + + //Create the REST/web/script service routes + context.MapRoute( + "Umbraco_web_services", + GlobalSettings.UmbracoMvcArea + "/RestServices/{controller}/{action}/{id}", + new {controller = "SaveFileController", action = "Index", id = UrlParameter.Optional}, + //look in this namespace for controllers + new[] {"Umbraco.Web.WebServices"}); + } + + public override string AreaName + { + get { return GlobalSettings.UmbracoMvcArea; } + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/Mvc/PluginControllerArea.cs b/src/Umbraco.Web/Mvc/PluginControllerArea.cs index 591d53480a..a8b6725534 100644 --- a/src/Umbraco.Web/Mvc/PluginControllerArea.cs +++ b/src/Umbraco.Web/Mvc/PluginControllerArea.cs @@ -67,7 +67,7 @@ namespace Umbraco.Web.Mvc { foreach (var s in surfaceControllers) { - this.RouteControllerPlugin(s.ControllerName, s.ControllerType, routes, "Surface", "Index", UrlParameter.Optional, "surface"); + this.RouteControllerPlugin(s.ControllerName, s.ControllerType, routes, "", "Index", UrlParameter.Optional, "surface"); } } } diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 21fa2d97bb..ea1c65c1bb 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -278,6 +278,7 @@ + @@ -420,9 +421,9 @@ ASPXCodeBehind - - ASPXCodeBehind - + + ASPXCodeBehind + ASPXCodeBehind @@ -1941,7 +1942,7 @@ ASPXCodeBehind - + ASPXCodeBehind diff --git a/src/Umbraco.Web/WebBootManager.cs b/src/Umbraco.Web/WebBootManager.cs index c112fcf1d1..d2e604055b 100644 --- a/src/Umbraco.Web/WebBootManager.cs +++ b/src/Umbraco.Web/WebBootManager.cs @@ -30,10 +30,10 @@ namespace Umbraco.Web { private readonly bool _isForTesting; - public WebBootManager(UmbracoApplicationBase umbracoApplication) + public WebBootManager(UmbracoApplicationBase umbracoApplication) : this(umbracoApplication, false) { - + } /// @@ -41,10 +41,10 @@ namespace Umbraco.Web /// /// /// - internal WebBootManager(UmbracoApplicationBase umbracoApplication, bool isForTesting) + internal WebBootManager(UmbracoApplicationBase umbracoApplication, bool isForTesting) : base(umbracoApplication) { - _isForTesting = isForTesting; + _isForTesting = isForTesting; } /// @@ -52,7 +52,7 @@ namespace Umbraco.Web /// /// public override IBootManager Initialize() - { + { base.Initialize(); // Backwards compatibility - set the path and URL type for ClientDependency 1.5.1 [LK] @@ -130,43 +130,36 @@ namespace Umbraco.Web ); defaultRoute.RouteHandler = new RenderRouteHandler(ControllerBuilder.Current.GetControllerFactory()); - //Create the install routes - var installPackageRoute = RouteTable.Routes.MapRoute( - "Umbraco_install_packages", - "Install/PackageInstaller/{action}/{id}", - new { controller = "InstallPackage", action = "Index", id = UrlParameter.Optional } - ); - installPackageRoute.DataTokens.Add("area", umbracoPath); + //register all back office routes + RouteBackOfficeControllers(); - //Create the REST/web/script service routes - var webServiceRoutes = RouteTable.Routes.MapRoute( - "Umbraco_web_services", - umbracoPath + "/RestServices/{controller}/{action}/{id}", - new {controller = "SaveFileController", action = "Index", id = UrlParameter.Optional}, - //VERY IMPORTANT! for this route, only match controllers in this namespace! - new string[] { "Umbraco.Web.WebServices" } - ); - webServiceRoutes.DataTokens.Add("area", umbracoPath); + //plugin controllers must come first because the next route will catch many things + RoutePluginControllers(); + } - //we need to find the surface controllers and route them - var surfaceControllers = SurfaceControllerResolver.Current.RegisteredSurfaceControllers.ToArray(); + private void RouteBackOfficeControllers() + { + var backOfficeArea = new BackOfficeArea(); + RouteTable.Routes.RegisterArea(backOfficeArea); + } - //local surface controllers do not contain the attribute - var localSurfaceControlleres = surfaceControllers.Where(x => PluginController.GetMetadata(x).AreaName.IsNullOrWhiteSpace()); - foreach (var s in localSurfaceControlleres) + private void RoutePluginControllers() + { + var umbracoPath = GlobalSettings.UmbracoMvcArea; + + //we need to find the plugin controllers and route them + var pluginControllers = + SurfaceControllerResolver.Current.RegisteredSurfaceControllers.ToArray(); + + //local controllers do not contain the attribute + var localControllers = pluginControllers.Where(x => PluginController.GetMetadata(x).AreaName.IsNullOrWhiteSpace()); + foreach (var s in localControllers) { - var meta = PluginController.GetMetadata(s); - var route = RouteTable.Routes.MapRoute( - string.Format("umbraco-{0}-{1}", "surface", meta.ControllerName), - umbracoPath + "/Surface/" + meta.ControllerName + "/{action}/{id}",//url to match - new { controller = meta.ControllerName, action = "Index", id = UrlParameter.Optional }, - new[] { meta.ControllerNamespace }); //only match this namespace - route.DataTokens.Add("umbraco", "surface"); //ensure the umbraco token is set + RouteLocalSurfaceController(s, umbracoPath); } //need to get the plugin controllers that are unique to each area (group by) - //TODO: One day when we have more plugin controllers, we will need to do a group by on ALL of them to pass into the ctor of PluginControllerArea - var pluginSurfaceControlleres = surfaceControllers.Where(x => !PluginController.GetMetadata(x).AreaName.IsNullOrWhiteSpace()); + var pluginSurfaceControlleres = pluginControllers.Where(x => !PluginController.GetMetadata(x).AreaName.IsNullOrWhiteSpace()); var groupedAreas = pluginSurfaceControlleres.GroupBy(controller => PluginController.GetMetadata(controller).AreaName); //loop through each area defined amongst the controllers foreach (var g in groupedAreas) @@ -178,7 +171,17 @@ namespace Umbraco.Web } } - + private void RouteLocalSurfaceController(Type controller, string umbracoPath) + { + var meta = PluginController.GetMetadata(controller); + var route = RouteTable.Routes.MapRoute( + string.Format("umbraco-{0}-{1}", "surface", meta.ControllerName), + umbracoPath + "/Surface/" + meta.ControllerName + "/{action}/{id}",//url to match + new { controller = meta.ControllerName, action = "Index", id = UrlParameter.Optional }, + new[] { meta.ControllerNamespace }); //look in this namespace to create the controller + route.DataTokens.Add("umbraco", "surface"); //ensure the umbraco token is set + route.DataTokens.Add("UseNamespaceFallback", false); //Don't look anywhere else except this namespace! + } /// /// Initializes all web based and core resolves @@ -212,7 +215,7 @@ namespace Umbraco.Web // the legacy 404 will run from within LookupByNotFoundHandlers below // so for the time being there is no last chance lookup - LastChanceLookupResolver.Current = new LastChanceLookupResolver(); + LastChanceLookupResolver.Current = new LastChanceLookupResolver(); DocumentLookupsResolver.Current = new DocumentLookupsResolver( //add all known resolvers in the correct order, devs can then modify this list on application startup either by binding to events