Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Trac 6981: Opt-in URL Updating

  • Loading branch information...
commit bd94c6f33634282a74ff8d0b0209e4c30126fe30 1 parent dedb9d0
@ryanwachtl ryanwachtl authored
View
2  code/model/SiteTree.php
@@ -1835,11 +1835,11 @@ function getCMSFields() {
$rootTab = new TabSet("Root",
$tabMain = new Tab('Main',
new TextField("Title", $this->fieldLabel('Title')),
+ $urlsegment,
new TextField("MenuTitle", $this->fieldLabel('MenuTitle')),
$htmlField = new HtmlEditorField("Content", _t('SiteTree.HTMLEDITORTITLE', "Content", 'HTML editor title'))
),
$tabMeta = new Tab('Metadata',
- $urlsegment,
new TextField("MetaTitle", $this->fieldLabel('MetaTitle')),
new TextareaField("MetaKeywords", $this->fieldLabel('MetaKeywords'), 1),
new TextareaField("MetaDescription", $this->fieldLabel('MetaDescription')),
View
49 css/screen.css
@@ -3,42 +3,91 @@
/** ----------------------------- CMS Components ------------------------------ */
/** Style custom to the CMSMain admin interface. CMSMain extends the built in SilverStripe admin section styles. As much as possible we want to use those built in styles. If anything in this file can be implemented in a generic way then it should be include in the admin scss files. @package cms */
/** ------------------------------------------------------------------ Page History Section. ----------------------------------------------------------------- */
+/* line 15, ../scss/_CMSMain.scss */
#cms-page-history-versions tr.loading { color: #999; }
+/* line 20, ../scss/_CMSMain.scss */
#cms-page-history-versions tr.loading td:hover { cursor: none; }
+/* line 27, ../scss/_CMSMain.scss */
#cms-page-history-versions td:hover { cursor: pointer; }
+/* line 34, ../scss/_CMSMain.scss */
.CMSPageHistoryController ins { background-color: #DFD; padding: 2px; text-decoration: none; }
+/* line 40, ../scss/_CMSMain.scss */
.CMSPageHistoryController del { background-color: #FDD; padding: 2px; color: #ff4444; }
/** -------------------------------------------- Tree View (collapsed for sidebar) -------------------------------------------- */
+/* line 51, ../scss/_CMSMain.scss */
#cms-content-treeview .cms-tree-expand-trigger { display: none; }
+/* line 58, ../scss/_CMSMain.scss */
.cms-content-tools #cms-content-treeview .cms-content-toolbar { border-bottom: none; box-shadow: none; margin-bottom: 8px; }
+/* line 62, ../scss/_CMSMain.scss */
.cms-content-tools #cms-content-treeview .cms-content-toolbar .cms-page-add-button { margin-top: 8px; }
+/* line 67, ../scss/_CMSMain.scss */
.cms-content-tools #cms-content-treeview .cms-tree-view-modes, .cms-content-tools #cms-content-treeview .cms-content-batchactions { display: none; }
+/* line 70, ../scss/_CMSMain.scss */
.cms-content-tools #cms-content-treeview .cms-tree-expand-trigger { display: inline-block; margin: 0 0 2px 0; position: absolute; top: 8px; right: 4px; }
+/* line 76, ../scss/_CMSMain.scss */
.cms-content-tools #cms-content-treeview .cms-tree-expand-trigger span.ui-button-text { padding-right: 8px; }
+/* line 83, ../scss/_CMSMain.scss */
.cms-content-tools #cms-content-treeview .cms-tree .badge, .cms-content-tools #cms-content-treeview .cms-tree a > .jstree-icon { display: none; }
+/** ------------------------------------------------------------------ URLSegment field ----------------------------------------------------------------- */
+/* line 94, ../scss/_CMSMain.scss */
+.URLPrefix, .URLSegmentHolder { padding-top: 8px; display: inline-block; }
+
+/* line 99, ../scss/_CMSMain.scss */
+.URLPrefix { color: #777; }
+
+/* line 103, ../scss/_CMSMain.scss */
+#Form_EditForm_URLSegment { margin-left: 7px; }
+/* line 106, ../scss/_CMSMain.scss */
+#Form_EditForm_URLSegment.disabled { color: #444; padding-left: 0px; margin-left: 0px; background: none; border-color: transparent; }
+
+/* line 117, ../scss/_CMSMain.scss */
+#Form_EditForm_URLSegment_Cancel, #Form_EditForm_URLSegment_Update, #Form_EditForm_URLSegment_Edit { margin-left: 7px; }
+
+/* line 2, ../scss/_AssetAdmin.scss */
.cms .AssetAdmin .cms-content-fields { overflow: hidden; }
+/* line 4, ../scss/_AssetAdmin.scss */
.cms .AssetAdmin .cms-content-fields .cms-edit-form.AssetAdmin { overflow-y: auto; }
+/* line 7, ../scss/_AssetAdmin.scss */
.cms .AssetAdmin .cms-content-fields .cms-content-tools .cms-panel-content { overflow: hidden; }
+/* line 9, ../scss/_AssetAdmin.scss */
.cms .AssetAdmin .cms-content-fields .cms-content-tools .cms-panel-content .cms-search-form { height: 100%; }
+/* line 17, ../scss/_AssetAdmin.scss */
.cms .AssetAdmin .cms-content-header-tabs .ui-tabs-nav li a { font-weight: bold; line-height: 16px; padding: 12px 20px 12px; text-indent: -9999em; }
+/* line 23, ../scss/_AssetAdmin.scss */
.cms .AssetAdmin .cms-content-header-tabs .ui-tabs-nav li a.content-treeview { background: url(../images/content-header-tabs-sprite.png) no-repeat 2px 0px; }
+/* line 26, ../scss/_AssetAdmin.scss */
.cms .AssetAdmin .cms-content-header-tabs .ui-tabs-nav li a.content-galleryview { background: url(../images/content-header-tabs-sprite.png) no-repeat -160px 0px; }
+/* line 29, ../scss/_AssetAdmin.scss */
.cms .AssetAdmin .cms-content-header-tabs .ui-tabs-nav li a.content-listview { background: url(../images/content-header-tabs-sprite.png) no-repeat -39px 0px; }
+/* line 37, ../scss/_AssetAdmin.scss */
.cms .AssetAdmin .cms-content-header-tabs .ui-tabs-nav .ui-state-active, .cms .AssetAdmin .cms-content-header-tabs .ui-tabs-nav .ui-widget-content .ui-state-active, .cms .AssetAdmin .cms-content-header-tabs .ui-tabs-nav .ui-widget-header .ui-state-active { border-top: none; }
+/* line 43, ../scss/_AssetAdmin.scss */
.cms .AssetAdmin .cms-content-header-tabs .ui-tabs-nav .ui-state-active a.content-treeview, .cms .AssetAdmin .cms-content-header-tabs .ui-tabs-nav .ui-widget-content .ui-state-active a.content-treeview, .cms .AssetAdmin .cms-content-header-tabs .ui-tabs-nav .ui-widget-header .ui-state-active a.content-treeview { background: url(../images/content-header-tabs-sprite.png) no-repeat 1px -40px; }
+/* line 46, ../scss/_AssetAdmin.scss */
.cms .AssetAdmin .cms-content-header-tabs .ui-tabs-nav .ui-state-active a.content-galleryview, .cms .AssetAdmin .cms-content-header-tabs .ui-tabs-nav .ui-widget-content .ui-state-active a.content-galleryview, .cms .AssetAdmin .cms-content-header-tabs .ui-tabs-nav .ui-widget-header .ui-state-active a.content-galleryview { background: url(../images/content-header-tabs-sprite.png) no-repeat -161px -40px; }
+/* line 49, ../scss/_AssetAdmin.scss */
.cms .AssetAdmin .cms-content-header-tabs .ui-tabs-nav .ui-state-active a.content-listview, .cms .AssetAdmin .cms-content-header-tabs .ui-tabs-nav .ui-widget-content .ui-state-active a.content-listview, .cms .AssetAdmin .cms-content-header-tabs .ui-tabs-nav .ui-widget-header .ui-state-active a.content-listview { background: url(../images/content-header-tabs-sprite.png) no-repeat -38px -40px; }
+/* line 58, ../scss/_AssetAdmin.scss */
.cms .AssetAdmin .cms-content-toolbar .cms-page-add-button { background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #f3f3f3), color-stop(100%, #d9d9d9)); background-image: -webkit-linear-gradient(#f3f3f3, #d9d9d9); background-image: -moz-linear-gradient(#f3f3f3, #d9d9d9); background-image: -o-linear-gradient(#f3f3f3, #d9d9d9); background-image: -ms-linear-gradient(#f3f3f3, #d9d9d9); background-image: linear-gradient(#f3f3f3, #d9d9d9); border-color: #c0c0c2; }
+/* line 61, ../scss/_AssetAdmin.scss */
.cms .AssetAdmin .cms-content-toolbar .cms-page-add-button span.btn-icon-add { height: 17px; }
+/* line 64, ../scss/_AssetAdmin.scss */
.cms .AssetAdmin .cms-content-toolbar .cms-page-add-button span.ui-button-text { color: #393939; text-shadow: white 0 1px 1px; }
+/* line 72, ../scss/_AssetAdmin.scss */
.cms .AssetAdmin #Root_TreeView .cms-tree ul .class-Folder a span.text span.jstree-foldericon { background: url(../images/blue-folder-horizontal.png) no-repeat; width: 16px; height: 16px; float: left; display: block; margin-right: 4px; }
+/* line 83, ../scss/_AssetAdmin.scss */
.cms .AssetAdmin #Form_EditForm_File td { padding-top: 0; padding-bottom: 0; }
+/* line 87, ../scss/_AssetAdmin.scss */
.cms .AssetAdmin #Form_EditForm_File td.bottom-all { padding: 0.7em; }
+/* line 91, ../scss/_AssetAdmin.scss */
.cms .AssetAdmin #Form_EditForm_File td.col-StripThumbnail { padding: 0; width: 32px; height: 32px; display: block; }
+/* line 97, ../scss/_AssetAdmin.scss */
.cms .AssetAdmin #Form_EditForm_File td.col-StripThumbnail img { width: 32px; height: 32px; }
+/* line 103, ../scss/_AssetAdmin.scss */
.cms .AssetAdmin #Form_EditForm_File tr[data-class=Folder] td.col-StripThumbnail { background: transparent url(../images/treeicons/blue-folder-horizontal.png) no-repeat top left; }
+/* line 108, ../scss/_AssetAdmin.scss */
.cms .AssetAdmin #Form_EditForm_File tr[data-class=File] td.col-StripThumbnail { background: transparent url(../images/treeicons/blue-document.png) no-repeat top left; }
View
243 javascript/CMSMain.EditForm.js
@@ -27,30 +27,117 @@
*/
onmatch : function() {
var self = this;
-
- // intercept change event, do our own writing
- this.bind('change', function(e) {
- if(!self.val()) return;
+
+ // add elements and actions for editing
+ self._addActions();
+ // toggle
+ self.edit();
+ // set width of input field
+ self._autoInputWidth();
+
+ this._super();
+ },
+
+ /**
+ * Function: edit
+ *
+ * Toggles the edit state of the field
+ *
+ * Return URLSegemnt val()
+ *
+ * Parameters:
+ * (Bool) external (optional)
+ */
+ edit: function(external) {
+
+ var self = this,
+ holder = $('#URLSegmentHolder'),
+ edit = $('#Form_EditForm_URLSegment_Edit'),
+ update = $('#Form_EditForm_URLSegment_Update'),
+ cancel = $('#Form_EditForm_URLSegment_Cancel');
+
+ // transfer current value to holder
+ holder.text(self.val());
+
+ // toggle elements
+ if (self.is(':visible')) {
+ update.hide();
+ cancel.hide();
+ self.hide();
+ holder.show();
+ edit.show();
+ } else {
+ edit.hide();
+ holder.hide();
+ self.show();
+ update.show();
+ cancel.show();
+ }
+
+ // field updated from another fields value
+ // reset to original state
+ if (external) {
+ self.edit();
+ }
+
+ return self.val();
+ },
+
+ /**
+ * Function: update
+ *
+ * Commits the change of the URLSegment to the field
+ * Optional: pass in another element to use its value
+ * to update the URLSegment (ex. from Title)
+ *
+ * Parameters:
+ * (jQuery Wrapped DOM element) field (optional)
+ */
+ update: function(field) {
+
+ var self = this,
+ holder = $('#URLSegmentHolder'),
+ currentVal = holder.text(),
+ updateVal,
+ external = null;
+
+ if (field && field.val() != "") {
+ updateVal = field.val();
+ external = true;
+ } else {
+ updateVal = self.val();
+ }
+
+ if (currentVal != updateVal) {
- self.addClass('disabled').parents('.field:first').addClass('loading');
- var oldVal = self.val();
- self.suggest(oldVal, function(data) {
- self.removeClass('disabled').parents('.field:first').removeClass('loading');
+ self.suggest(updateVal, function(data) {
var newVal = decodeURIComponent(data.value);
self.val(newVal);
-
- if(oldVal != newVal) {
- var confirmMessage = ss.i18n.sprintf(
- ss.i18n._t('UPDATEURL.CONFIRMURLCHANGED', 'The URL has been changed to\n"%s'),
- data.value
- );
- jQuery.noticeAdd({'text':confirmMessage});
- }
+ self.edit(external);
});
- });
+ } else {
+
+ self.edit();
+ }
+ },
+
+ /**
+ * Function: cancel
+ *
+ * Cancels any changes to the field
+ *
+ * Return URLSegemnt val()
+ *
+ */
+ cancel: function() {
- this._super();
+ var self = this,
+ holder = $('#URLSegmentHolder');
+ self.val(holder.text());
+ self.edit();
+
+ return self.val();
},
/**
@@ -63,13 +150,89 @@
* (Function) callback
*/
suggest: function(val, callback) {
+
$.get(
this.parents('form:first').attr('action') +
- '/field/URLSegment/suggest/?value=' + encodeURIComponent(this.val()),
+ '/field/URLSegment/suggest/?value=' + encodeURIComponent(val),
function(data) {
callback.apply(this, arguments);
}
);
+
+ },
+
+ /**
+ * Function: _addActions
+ *
+ * Utility to add edit buttons and actions
+ *
+ */
+ _addActions: function() {
+
+ var self = this,
+ holder,
+ editAction,
+ updateAction,
+ cancelAction;
+
+ // element to display non-editable text
+ holder = $('<span />', {
+ 'id': 'URLSegmentHolder'
+ });
+
+ // edit button
+ editAction = $('<button />', {
+ 'id': 'Form_EditForm_URLSegment_Edit',
+ 'class': 'ss-ui-button',
+ 'text': 'Edit',
+ 'click': function(e) {
+ e.preventDefault();
+ self.edit();
+ }
+ });
+
+ // update button
+ updateAction = $('<button />', {
+ 'id': 'Form_EditForm_URLSegment_Update',
+ 'text': 'OK',
+ 'click': function(e) {
+ e.preventDefault();
+ self.update();
+ }
+ });
+
+ // cancel button
+ cancelAction = $('<a />', {
+ 'id': 'Form_EditForm_URLSegment_Cancel',
+ 'href': '#',
+ 'text': 'cancel',
+ 'click': function(e) {
+ e.preventDefault();
+ self.cancel();
+ }
+ });
+
+ // insert elements
+ holder.insertAfter('.URLPrefix');
+ editAction.insertAfter(self);
+ cancelAction.insertAfter(self);
+ updateAction.insertAfter(self);
+ },
+
+ /**
+ * Function: _autoInputWidth
+ *
+ * Sets the width of input so it lines up with the other fields
+ *
+ */
+ _autoInputWidth: function() {
+ var self = this,
+ prefix_width,
+ new_width;
+
+ prefix_width = $('.URLPrefix').width();
+ new_width = ((self.width() + 9) - prefix_width);
+ self.width(new_width);
}
});
@@ -82,12 +245,20 @@
// Constructor: onmatch
onmatch : function() {
var self = this;
+
+ var URLSegment = $('.cms-edit-form input[name=URLSegment]');
+ var LiveURLSegment = $('.cms-edit-form input[name=LiveURLSegment]');
this.bind('change', function(e) {
- self.updatePageTitleHeading();
- self.updateURLSegment(jQuery('.cms-edit-form input[name=URLSegment]'));
- // TODO We should really user-confirm these changes
- self.parents('form').find('input[name=MetaTitle], input[name=MenuTitle]').val(self.val());
+ // Criteria for defining a "new" page
+ if ( (URLSegment.val().indexOf("new") == 0) && LiveURLSegment.val() == "" ) {
+ self.updatePageTitleHeading();
+ self.parents('form').find('input[name=MetaTitle], input[name=MenuTitle]').val(self.val());
+ // update the URLSegment
+ URLSegment.update(self);
+ } else {
+ return;
+ }
});
this._super();
@@ -100,32 +271,6 @@
*/
updatePageTitleHeading: function() {
$('#page-title-heading').text(this.val());
- },
-
- /**
- * Function: updateURLSegment
- *
- * Parameters:
- * (DOMElement) field
- */
- updateURLSegment: function(field) {
- if(!field || !field.length) return;
-
- // TODO The new URL value is determined asynchronously,
- // which means we need to come up with an alternative system
- // to ask user permission to change it.
-
- // TODO language/logic coupling
- var isNew = this.val().indexOf("new") == 0;
- var confirmMessage = ss.i18n._t(
- 'UPDATEURL.CONFIRMSIMPLE',
- 'Do you want to update the URL from your new page title?'
- );
-
- // don't ask for replacement if record is considered 'new' as defined by its title
- if(isNew || confirm(confirmMessage)) {
- field.val(this.val()).trigger('change');
- }
}
});
View
31 scss/_CMSMain.scss
@@ -85,4 +85,35 @@
}
}
}
+}
+
+/** ------------------------------------------------------------------
+ * URLSegment field
+ * ----------------------------------------------------------------- */
+.URLPrefix,
+.URLSegmentHolder {
+ padding-top: 8px;
+ display: inline-block;
+}
+
+.URLPrefix {
+ color: #777;
+}
+
+#Form_EditForm_URLSegment {
+ margin-left: 7px;
+
+ &.disabled {
+ color: #444;
+ padding-left: 0px;
+ margin-left: 0px;
+ background: none;
+ border-color: transparent;
+ }
+}
+
+#Form_EditForm_URLSegment_Cancel,
+#Form_EditForm_URLSegment_Update,
+#Form_EditForm_URLSegment_Edit {
+ margin-left: 7px;
}
View
2  templates/forms/SiteTreeURLSegmentField.ss
@@ -1,4 +1,4 @@
-<span>$URLPrefix</span>&nbsp;<input $AttributesHTML />
+<span class="URLPrefix">$URLPrefix</span><input $AttributesHTML />
<% if HelpText %>
<p class="help">$HelpText</p>
<% end_if %>
Please sign in to comment.
Something went wrong with that request. Please try again.