diff --git a/_config/routes.yml b/_config/routes.yml index 77971cd7c..3242d45ee 100644 --- a/_config/routes.yml +++ b/_config/routes.yml @@ -31,4 +31,4 @@ After: --- Director: rules: - 'admin': 'AdminRootController' + 'admin': 'AdminRootController' \ No newline at end of file diff --git a/admin/code/AdminRootController.php b/admin/code/AdminRootController.php index 77a394ce6..25af0dca5 100644 --- a/admin/code/AdminRootController.php +++ b/admin/code/AdminRootController.php @@ -4,15 +4,47 @@ * @package framework * @subpackage admin */ -class AdminRootController extends Controller { +class AdminRootController extends Controller implements TemplateGlobalProvider { /** - * @var string - * @config - * The url base that all LeftAndMain derived panels will live under - * Won't automatically update the base route if you change this - that has to be done seperately + * Convenience function to return the admin route config. + * Looks for the {@link Director::$rules} for the current admin Controller. */ - private static $url_base = 'admin'; + public static function get_admin_route() { + if (Controller::has_curr()) { + $routeParams = Controller::curr()->getRequest()->routeParams(); + $adminControllerClass = isset($routeParams['Controller']) ? $routeParams['Controller'] : get_called_class(); + } + else { + $adminControllerClass = get_called_class(); + } + + $rules = Config::inst()->get('Director', 'rules'); + $adminRoute = array_search($adminControllerClass, $rules); + return $adminRoute ? $adminRoute : ''; + } + + /** + * Returns the root admin URL for the site with trailing slash + * + * @return string + * @uses get_admin_route() + */ + public static function admin_url() { + return self::get_admin_route() . '/'; + } + + /** + * Includes the adminURL JavaScript config in the ss namespace + */ + public static function include_js() { + $js = "(function(root) { + root.ss = root.ss || {}; + root.ss.config = root.ss.config || {}; + root.ss.config.adminURL = '".self::admin_url()."' + }(window));"; + Requirements::customScript($js, 'adminURLConfig'); + } /** * @var string @@ -74,11 +106,10 @@ class AdminRootController extends Controller { public function handleRequest(SS_HTTPRequest $request, DataModel $model) { // If this is the final portion of the request (i.e. the URL is just /admin), direct to the default panel if ($request->allParsed()) { - $base = $this->config()->url_base; $segment = Config::inst()->get($this->config()->default_panel, 'url_segment'); $this->response = new SS_HTTPResponse(); - $this->redirect(Controller::join_links($base, $segment)); + $this->redirect(Controller::join_links(self::admin_url(), $segment)); return $this->response; } @@ -97,4 +128,14 @@ class AdminRootController extends Controller { return $this->httpError(404, 'Not found'); } + + /** + * @return array Returns an array of strings of the method names of methods on the call that should be exposed + * as global variables in the templates. + */ + public static function get_template_global_variables() { + return array( + 'adminURL' => 'admin_url' + ); + } } diff --git a/admin/code/CMSMenu.php b/admin/code/CMSMenu.php index b3f01cd9d..3f48b62ed 100644 --- a/admin/code/CMSMenu.php +++ b/admin/code/CMSMenu.php @@ -57,8 +57,8 @@ class CMSMenu extends Object implements IteratorAggregate, i18nEntityProvider { * Return a CMSMenuItem to add the given controller to the CMSMenu */ protected static function menuitem_for_controller($controllerClass) { - $urlBase = Config::inst()->get($controllerClass, 'url_base', Config::FIRST_SET); - $urlSegment = Config::inst()->get($controllerClass, 'url_segment', Config::FIRST_SET); + $urlBase = AdminRootController::admin_url(); + $urlSegment = Config::inst()->get($controllerClass, 'url_segment', Config::FIRST_SET); $menuPriority = Config::inst()->get($controllerClass, 'menu_priority', Config::FIRST_SET); // Don't add menu items defined the old way diff --git a/admin/code/LeftAndMain.php b/admin/code/LeftAndMain.php index d15c46596..9853765b3 100644 --- a/admin/code/LeftAndMain.php +++ b/admin/code/LeftAndMain.php @@ -11,16 +11,6 @@ */ class LeftAndMain extends Controller implements PermissionProvider { - /** - * The 'base' url for CMS administration areas. - * Note that if this is changed, many javascript - * behaviours need to be updated with the correct url - * - * @config - * @var string $url_base - */ - private static $url_base = "admin"; - /** * The current url segment attached to the LeftAndMain instance * @@ -340,6 +330,7 @@ class LeftAndMain extends Controller implements PermissionProvider { if (Director::isDev()) Requirements::javascript(FRAMEWORK_ADMIN_DIR . '/javascript/leaktools.js'); HTMLEditorField::include_js(); + AdminRootController::include_js(); $leftAndMainIncludes = array_unique(array_merge( array( @@ -527,7 +518,7 @@ class LeftAndMain extends Controller implements PermissionProvider { }; $link = Controller::join_links( - $this->stat('url_base', true), + AdminRootController::admin_url(), $segment, '/', // trailing slash needed if $action is null! "$action" @@ -642,7 +633,7 @@ class LeftAndMain extends Controller implements PermissionProvider { // default menu is the one with a blank {@link url_segment} } else if(singleton($menuItem->controller)->stat('url_segment') == '') { - if($this->Link() == $this->stat('url_base').'/') { + if($this->Link() == AdminRootController::admin_url()) { $linkingmode = "current"; } diff --git a/admin/javascript/LeftAndMain.BatchActions.js b/admin/javascript/LeftAndMain.BatchActions.js index 5e4cb741e..af370a2c6 100644 --- a/admin/javascript/LeftAndMain.BatchActions.js +++ b/admin/javascript/LeftAndMain.BatchActions.js @@ -333,7 +333,7 @@ /** * Publish selected pages action */ - $('#Form_BatchActionsForm').register('admin/batchactions/publish', function(ids) { + $('#Form_BatchActionsForm').register(ss.config.adminURL+'batchactions/publish', function(ids) { var confirmed = confirm( "You have " + ids.length + " pages selected.\n\n" + "Do your really want to publish?" @@ -344,7 +344,7 @@ /** * Unpublish selected pages action */ - $('#Form_BatchActionsForm').register('admin/batchactions/unpublish', function(ids) { + $('#Form_BatchActionsForm').register(ss.config.adminURL+'batchactions/unpublish', function(ids) { var confirmed = confirm( "You have " + ids.length + " pages selected.\n\n" + "Do your really want to unpublish?" @@ -355,7 +355,7 @@ /** * Delete selected pages action */ - $('#Form_BatchActionsForm').register('admin/batchactions/delete', function(ids) { + $('#Form_BatchActionsForm').register(ss.config.adminURL+'batchactions/delete', function(ids) { var confirmed = confirm( "You have " + ids.length + " pages selected.\n\n" + "Do your really want to delete?" @@ -366,7 +366,7 @@ /** * Delete selected pages from live action */ - $('#Form_BatchActionsForm').register('admin/batchactions/deletefromlive', function(ids) { + $('#Form_BatchActionsForm').register(ss.config.adminURL+'batchactions/deletefromlive', function(ids) { var confirmed = confirm( "You have " + ids.length + " pages selected.\n\n" + "Do your really want to delete these pages from live?" diff --git a/admin/templates/Includes/LeftAndMain_Menu.ss b/admin/templates/Includes/LeftAndMain_Menu.ss index 305589e6b..97c36b079 100644 --- a/admin/templates/Includes/LeftAndMain_Menu.ss +++ b/admin/templates/Includes/LeftAndMain_Menu.ss @@ -12,7 +12,7 @@ <% with $CurrentMember %> <% _t('LeftAndMain_Menu_ss.Hello','Hi') %> - + <% if $FirstName && $Surname %>$FirstName $Surname<% else_if $FirstName %>$FirstName<% else %>$Email<% end_if %> diff --git a/control/Director.php b/control/Director.php index 865f52ce4..b8d6a0f5d 100644 --- a/control/Director.php +++ b/control/Director.php @@ -351,12 +351,14 @@ class Director implements TemplateGlobalProvider { if(isset($_REQUEST['debug'])) Debug::show($rules); foreach($rules as $pattern => $controllerOptions) { - if(is_string($controllerOptions)) { + if(is_string($controllerOptions) && $controllerOptions) { if(substr($controllerOptions,0,2) == '->') { $controllerOptions = array('Redirect' => substr($controllerOptions,2)); } else { $controllerOptions = array('Controller' => $controllerOptions); } + } else { + continue; } if(($arguments = $request->match($pattern, true)) !== false) { diff --git a/core/Core.php b/core/Core.php index e55706d86..4868de4e8 100644 --- a/core/Core.php +++ b/core/Core.php @@ -135,7 +135,6 @@ if(Director::isLive()) { */ Debug::loadErrorHandlers(); - /////////////////////////////////////////////////////////////////////////////// // HELPER FUNCTIONS diff --git a/docs/en/02_Developer_Guides/15_Customising_the_Admin_Interface/05_CMS_Architecture.md b/docs/en/02_Developer_Guides/15_Customising_the_Admin_Interface/05_CMS_Architecture.md index 11ac98f58..3bb18a749 100644 --- a/docs/en/02_Developer_Guides/15_Customising_the_Admin_Interface/05_CMS_Architecture.md +++ b/docs/en/02_Developer_Guides/15_Customising_the_Admin_Interface/05_CMS_Architecture.md @@ -15,6 +15,42 @@ with some special conventions. For a more practical-oriented approach to CMS customizations, refer to the [Howto: Extend the CMS Interface](../how_tos/extend_cms_interface) which builds +## The Admin URL + +The CMS interface can be accessed by default through the `admin/` URL. You can change this by setting your own [Director routing rule](director#routing-rules) to the `[api:AdminRootController]` and clear the old rule like in the example below. + + :::yml + --- + Name: myadmin + After: + - '#adminroutes' + --- + Director: + rule: + 'admin': '' + 'newAdmin': 'AdminRootController' + --- + +When extending the CMS or creating modules, you can take advantage of various functions that will return the configured admin URL (by default 'admin/' is returned): + +In PHP you should use: + + :::php + AdminRootController::admin_url() + +When writing templates use: + + :::ss + $AdminURL + +And in JavaScript, this is avaible through the `ss` namespace + + :::js + ss.config.adminURL + +### Multiple Admin URL and overrides + +You can also create your own classes that extend the `[api:AdminRootController]` to create multiple or custom admin areas, with a `Director.rules` for each one. ## Markup and Style Conventions @@ -257,7 +293,7 @@ in a single Ajax request. <% include CMSBreadcrumbs %>