diff --git a/client/dist/styles/bundle.css b/client/dist/styles/bundle.css index bccd6614..f8f01a7d 100644 --- a/client/dist/styles/bundle.css +++ b/client/dist/styles/bundle.css @@ -1 +1 @@ -#cms-page-history-versions tr.loading{color:#999}#cms-page-history-versions tr.loading td:hover{cursor:none}#cms-page-history-versions td:hover{cursor:pointer}.CMSPageHistoryController{overflow:hidden}.CMSPageHistoryController ins{background-color:#dfd;padding:2px;text-decoration:none}.CMSPageHistoryController del{background-color:#fdd;padding:2px;color:#f44}.CMSPageHistoryController .htmleditorfield.readonly img{max-width:100%;height:auto}.CMSPageHistoryController .cms-content-tools.collapsed{overflow:hidden}#cms-content-listview .cms-tree-expand-trigger,#cms-content-treeview .cms-tree-expand-trigger{display:none}.cms-content-tools #cms-content-treeview .cms-content-toolbar{border-bottom:none;-webkit-box-shadow:none;box-shadow:none;margin-bottom:0}.cms-content-tools #cms-content-treeview .cms-tree-expand-trigger{display:block;float:left;margin:0 0 2px}.cms-content-tools #cms-content-treeview .cms-tree-expand-trigger span.ui-button-text{padding-right:8px}.cms-content-tools #cms-content-treeview .cms-tree .badge{display:none}.cms-content-tools #cms-content-treeview .cms-tree .jstree-clicked>.text>.badge,.cms-content-tools #cms-content-treeview .cms-tree a:hover>.text>.badge{display:inline-block}.cms-list .cms-list__item-breadcrumbs{margin-left:21px;margin-bottom:0;font-size:.9em;word-break:break-word}.cms-content-toolbar .view-controls{margin-top:0}.cms-content-toolbar .view-controls .page-view-link{display:none;margin-right:-5px}.cms-content-toolbar .view-controls.view-controls--listview .font-icon-tree,.cms-content-toolbar .view-controls.view-controls--treeview .font-icon-list{display:inline-block}.field.urlsegment.loading .form__field-label{background-image:url(data:image/gif;base64,R0lGODlhEAAQAPQAAP///wpakvj6+z9+qYivyg9dlC5yotfk7KvG2R9om3umxGubveXt8py80sjZ5k+IsFyRtgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCgAAACwAAAAAEAAQAAAFUCAgjmRpnqUwFGwhKoRgqq2YFMaRGjWA8AbZiIBbjQQ8AmmFUJEQhQGJhaKOrCksgEla+KIkYvC6SJKQOISoNSYdeIk1ayA8ExTyeR3F749CACH5BAkKAAAALAAAAAAQABAAAAVoICCKR9KMaCoaxeCoqEAkRX3AwMHWxQIIjJSAZWgUEgzBwCBAEQpMwIDwY1FHgwJCtOW2UDWYIDyqNVVkUbYr6CK+o2eUMKgWrqKhj0FrEM8jQQALPFA3MAc8CQSAMA5ZBjgqDQmHIyEAIfkECQoAAAAsAAAAABAAEAAABWAgII4j85Ao2hRIKgrEUBQJLaSHMe8zgQo6Q8sxS7RIhILhBkgumCTZsXkACBC+0cwF2GoLLoFXREDcDlkAojBICRaFLDCOQtQKjmsQSubtDFU/NXcDBHwkaw1cKQ8MiyEAIfkECQoAAAAsAAAAABAAEAAABVIgII5kaZ6AIJQCMRTFQKiDQx4GrBfGa4uCnAEhQuRgPwCBtwK+kCNFgjh6QlFYgGO7baJ2CxIioSDpwqNggWCGDVVGphly3BkOpXDrKfNm/4AhACH5BAkKAAAALAAAAAAQABAAAAVgICCOZGmeqEAMRTEQwskYbV0Yx7kYSIzQhtgoBxCKBDQCIOcoLBimRiFhSABYU5gIgW01pLUBYkRItAYAqrlhYiwKjiWAcDMWY8QjsCf4DewiBzQ2N1AmKlgvgCiMjSQhACH5BAkKAAAALAAAAAAQABAAAAVfICCOZGmeqEgUxUAIpkA0AMKyxkEiSZEIsJqhYAg+boUFSTAkiBiNHks3sg1ILAfBiS10gyqCg0UaFBCkwy3RYKiIYMAC+RAxiQgYsJdAjw5DN2gILzEEZgVcKYuMJiEAOwAAAAAAAAAAAA==);background-repeat:no-repeat;background-position:100%;padding-right:20px}.field.urlsegment .URL-link{padding-top:8px;display:inline-block}.field.urlsegment input.text{width:250px;float:left}.field.urlsegment .cancel,.field.urlsegment .edit,.field.urlsegment .update,.field.urlsegment input.text{margin-right:8px}.field.urlsegment .help{margin-left:0}.field.urlsegment .edit-holder{display:none}.field.urlsegment .edit-holder .form__field-description{clear:both}.form__field-update-url{position:absolute;top:4px;right:20px;background:#fff;z-index:3}@media (max-width:992px){.form__field-update-url{right:0}}#Form_EditForm #Title .update{margin-left:7px} \ No newline at end of file +#cms-page-history-versions tr.loading{color:#999}#cms-page-history-versions tr.loading td:hover{cursor:none}#cms-page-history-versions td:hover{cursor:pointer}.CMSPageHistoryController{overflow:hidden}.CMSPageHistoryController ins{background-color:#dfd;padding:2px;text-decoration:none}.CMSPageHistoryController del{background-color:#fdd;padding:2px;color:#f44}.CMSPageHistoryController .htmleditorfield.readonly img{max-width:100%;height:auto}.CMSPageHistoryController .cms-content-tools.collapsed{overflow:hidden}#cms-content-listview .cms-tree-expand-trigger,#cms-content-treeview .cms-tree-expand-trigger{display:none}.cms-content-tools #cms-content-treeview .cms-content-toolbar{border-bottom:none;-webkit-box-shadow:none;box-shadow:none;margin-bottom:0}.cms-content-tools #cms-content-treeview .cms-tree-expand-trigger{display:block;float:left;margin:0 0 2px}.cms-content-tools #cms-content-treeview .cms-tree-expand-trigger span.ui-button-text{padding-right:8px}.cms-content-tools #cms-content-treeview .cms-tree .badge{display:none}.cms-content-tools #cms-content-treeview .cms-tree .jstree-clicked>.text>.badge,.cms-content-tools #cms-content-treeview .cms-tree a:hover>.text>.badge{display:inline-block}.cms-list .cms-list__item-breadcrumbs{margin-left:21px;margin-bottom:0;font-size:.9em;word-break:break-word}.cms-content-toolbar .view-controls{margin-top:0}.cms-content-toolbar .view-controls .page-view-link{display:inline-block;margin-right:-5px}.cms-content-toolbar .view-controls.view-controls--listview .font-icon-list,.cms-content-toolbar .view-controls.view-controls--treeview .font-icon-tree{display:none}.field.urlsegment.loading .form__field-label{background-image:url(data:image/gif;base64,R0lGODlhEAAQAPQAAP///wpakvj6+z9+qYivyg9dlC5yotfk7KvG2R9om3umxGubveXt8py80sjZ5k+IsFyRtgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCgAAACwAAAAAEAAQAAAFUCAgjmRpnqUwFGwhKoRgqq2YFMaRGjWA8AbZiIBbjQQ8AmmFUJEQhQGJhaKOrCksgEla+KIkYvC6SJKQOISoNSYdeIk1ayA8ExTyeR3F749CACH5BAkKAAAALAAAAAAQABAAAAVoICCKR9KMaCoaxeCoqEAkRX3AwMHWxQIIjJSAZWgUEgzBwCBAEQpMwIDwY1FHgwJCtOW2UDWYIDyqNVVkUbYr6CK+o2eUMKgWrqKhj0FrEM8jQQALPFA3MAc8CQSAMA5ZBjgqDQmHIyEAIfkECQoAAAAsAAAAABAAEAAABWAgII4j85Ao2hRIKgrEUBQJLaSHMe8zgQo6Q8sxS7RIhILhBkgumCTZsXkACBC+0cwF2GoLLoFXREDcDlkAojBICRaFLDCOQtQKjmsQSubtDFU/NXcDBHwkaw1cKQ8MiyEAIfkECQoAAAAsAAAAABAAEAAABVIgII5kaZ6AIJQCMRTFQKiDQx4GrBfGa4uCnAEhQuRgPwCBtwK+kCNFgjh6QlFYgGO7baJ2CxIioSDpwqNggWCGDVVGphly3BkOpXDrKfNm/4AhACH5BAkKAAAALAAAAAAQABAAAAVgICCOZGmeqEAMRTEQwskYbV0Yx7kYSIzQhtgoBxCKBDQCIOcoLBimRiFhSABYU5gIgW01pLUBYkRItAYAqrlhYiwKjiWAcDMWY8QjsCf4DewiBzQ2N1AmKlgvgCiMjSQhACH5BAkKAAAALAAAAAAQABAAAAVfICCOZGmeqEgUxUAIpkA0AMKyxkEiSZEIsJqhYAg+boUFSTAkiBiNHks3sg1ILAfBiS10gyqCg0UaFBCkwy3RYKiIYMAC+RAxiQgYsJdAjw5DN2gILzEEZgVcKYuMJiEAOwAAAAAAAAAAAA==);background-repeat:no-repeat;background-position:100%;padding-right:20px}.field.urlsegment .URL-link{padding-top:8px;display:inline-block}.field.urlsegment input.text{width:250px;float:left}.field.urlsegment .cancel,.field.urlsegment .edit,.field.urlsegment .update,.field.urlsegment input.text{margin-right:8px}.field.urlsegment .help{margin-left:0}.field.urlsegment .edit-holder{display:none}.field.urlsegment .edit-holder .form__field-description{clear:both}.form__field-update-url{position:absolute;top:4px;right:20px;background:#fff;z-index:3}@media (max-width:992px){.form__field-update-url{right:0}}#Form_EditForm #Title .update{margin-left:7px} \ No newline at end of file diff --git a/client/src/styles/legacy/_CMSMain.scss b/client/src/styles/legacy/_CMSMain.scss index 02834d5f..6877f2b6 100644 --- a/client/src/styles/legacy/_CMSMain.scss +++ b/client/src/styles/legacy/_CMSMain.scss @@ -122,18 +122,15 @@ .view-controls { margin-top: 0; - .page-view-link { - display: none; - margin-right: -5px; - } + .page-view-link { + display: inline-block; + margin-right: -5px; + } - &.view-controls--treeview .font-icon-list { - display: inline-block; - } - - &.view-controls--listview .font-icon-tree { - display: inline-block; - } + &.view-controls--treeview .font-icon-tree, + &.view-controls--listview .font-icon-list { + display: none; + } } } diff --git a/code/Controllers/CMSMain.php b/code/Controllers/CMSMain.php index 6ff07e63..6a99f745 100644 --- a/code/Controllers/CMSMain.php +++ b/code/Controllers/CMSMain.php @@ -24,6 +24,7 @@ use SilverStripe\Control\HTTPResponse_Exception; use SilverStripe\Core\Convert; use SilverStripe\Core\Environment; use SilverStripe\Core\Injector\Injector; +use SilverStripe\Core\Manifest\ModuleResource; use SilverStripe\Core\Manifest\ModuleResourceLoader; use SilverStripe\Forms\DateField; use SilverStripe\Forms\DropdownField; @@ -1056,20 +1057,17 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr } // skip this type if it is restricted - if ($instance->config()->get('need_permission') && !$this->can(singleton($class)->config()->get('need_permission'))) { + $needPermissions = $instance->config()->get('need_permission'); + if ($needPermissions && !$this->can($needPermissions)) { continue; } - $singularName = $instance->i18n_singular_name(); - $description = $instance->i18n_classDescription(); - $result->push(new ArrayData(array( 'ClassName' => $class, - 'AddAction' => $singularName, - 'Description' => $description, - // TODO Sprite support - 'IconURL' => ModuleResourceLoader::resourceURL($instance->config()->get('icon')), - 'Title' => $singularName, + 'AddAction' => $instance->i18n_singular_name(), + 'Description' => $instance->i18n_classDescription(), + 'IconURL' => $instance->getPageIconURL(), + 'Title' => $instance->i18n_singular_name(), ))); } diff --git a/code/Controllers/LeftAndMainPageIconsExtension.php b/code/Controllers/LeftAndMainPageIconsExtension.php index aa95dc61..9ea68f60 100644 --- a/code/Controllers/LeftAndMainPageIconsExtension.php +++ b/code/Controllers/LeftAndMainPageIconsExtension.php @@ -3,11 +3,11 @@ namespace SilverStripe\CMS\Controllers; use SilverStripe\CMS\Model\SiteTree; -use SilverStripe\Core\Convert; -use SilverStripe\View\Requirements; use SilverStripe\Core\ClassInfo; -use SilverStripe\Control\Director; +use SilverStripe\Core\Config\Config; +use SilverStripe\Core\Convert; use SilverStripe\Core\Extension; +use SilverStripe\View\Requirements; /** * Extension to include custom page icons @@ -32,28 +32,16 @@ class LeftAndMainPageIconsExtension extends Extension $classes = ClassInfo::subclassesFor(SiteTree::class); foreach ($classes as $class) { - $obj = singleton($class); - $iconSpec = $obj->config()->get('icon'); - - if (!$iconSpec) { + $icon = Config::inst()->get($class, 'icon'); + if (!$icon) { continue; } - // Legacy support: We no longer need separate icon definitions for folders etc. - $iconFile = (is_array($iconSpec)) ? $iconSpec[0] : $iconSpec; - - // Legacy support: Add file extension if none exists - if (!pathinfo($iconFile, PATHINFO_EXTENSION)) { - $iconFile .= '-file.gif'; - } - - $class = Convert::raw2htmlid($class); - $selector = ".page-icon.class-$class, li.class-$class > a .jstree-pageicon"; - if (Director::fileExists($iconFile)) { - $css .= "$selector { background: transparent url('$iconFile') 0 0 no-repeat; }\n"; - } else { - // Support for more sophisticated rules, e.g. sprited icons - $css .= "$selector { $iconFile }\n"; + $cssClass = Convert::raw2htmlid($class); + $selector = ".page-icon.class-$cssClass, li.class-$cssClass > a .jstree-pageicon"; + $iconURL = SiteTree::singleton($class)->getPageIconURL(); + if ($iconURL) { + $css .= "$selector { background: transparent url('$iconURL') 0 0 no-repeat; }\n"; } } diff --git a/code/Model/SiteTree.php b/code/Model/SiteTree.php index 66a907a1..3f69002e 100755 --- a/code/Model/SiteTree.php +++ b/code/Model/SiteTree.php @@ -17,6 +17,8 @@ use SilverStripe\Core\ClassInfo; use SilverStripe\Core\Config\Config; use SilverStripe\Core\Convert; use SilverStripe\Core\Injector\Injector; +use SilverStripe\Core\Manifest\ModuleResource; +use SilverStripe\Core\Manifest\ModuleResourceLoader; use SilverStripe\Core\Resettable; use SilverStripe\Dev\Deprecation; use SilverStripe\Forms\CheckboxField; @@ -248,7 +250,7 @@ class SiteTree extends DataObject implements PermissionProvider, i18nEntityProvi * Icon to use in the CMS page tree. This should be the full filename, relative to the webroot. * Also supports custom CSS rule contents (applied to the correct selector for the tree UI implementation). * - * @see CMSMain::generateTreeStylingCSS() + * @see LeftAndMainPageIconsExtension::generatePageIconsCss() * @config * @var string */ @@ -1486,7 +1488,7 @@ class SiteTree extends DataObject implements PermissionProvider, i18nEntityProvi parent::onBeforeDelete(); // If deleting this page, delete all its children. - if (SiteTree::config()->enforce_strict_hierarchy && $children = $this->AllChildren()) { + if ($this->isInDB() && SiteTree::config()->enforce_strict_hierarchy && $children = $this->AllChildren()) { foreach ($children as $child) { /** @var SiteTree $child */ $child->delete(); @@ -2857,6 +2859,33 @@ class SiteTree extends DataObject implements PermissionProvider, i18nEntityProvi return parent::plural_name(); } + /** + * Generate link to this page's icon + * + * @return string + */ + public function getPageIconURL() + { + $icon = $this->config()->get('icon'); + if (!$icon) { + return null; + } + + // Icon is relative resource + $iconResource = ModuleResourceLoader::singleton()->resolveResource($icon); + if ($iconResource instanceof ModuleResource) { + return $iconResource->getURL(); + } + + // Full path to file + if (Director::fileExists($icon)) { + return ModuleResourceLoader::resourceURL($icon); + } + + // Skip invalid files + return null; + } + /** * Get description for this page type * diff --git a/templates/SilverStripe/CMS/Controllers/Includes/CMSMain_Content.ss b/templates/SilverStripe/CMS/Controllers/Includes/CMSMain_Content.ss index 2e247ba7..63b3fae1 100644 --- a/templates/SilverStripe/CMS/Controllers/Includes/CMSMain_Content.ss +++ b/templates/SilverStripe/CMS/Controllers/Includes/CMSMain_Content.ss @@ -1,40 +1,36 @@