Skip to content

Commit a1f64d2

Browse files
committed
Extending halfdan’s work for UX settings improvements
#1351 - prevent a new post (not saved on server) from updating its slug/date to the server - fix jshint - add back creation of a posts slug upon a post creation - update for rebasing - hide ability to ‘delete this post’ from post settings menu when a post hasn’t yet been saved to the server
1 parent 11c8d23 commit a1f64d2

File tree

8 files changed

+102
-21
lines changed

8 files changed

+102
-21
lines changed

core/client/assets/sass/layouts/editor.scss

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -634,6 +634,20 @@ body.zen {
634634
position: relative;
635635
padding: 0;
636636
z-index: 1;
637+
638+
&.unsaved {
639+
.post-settings-menu {
640+
padding-bottom: 0;
641+
642+
.post-setting:nth-child(3) td {
643+
border-bottom: none;
644+
}
645+
646+
.delete {
647+
display: none;
648+
}
649+
}
650+
}
637651
}
638652

639653
#entry-actions {

core/client/views/post-settings.js

Lines changed: 72 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,10 @@
2828
render: function () {
2929
var slug = this.model ? this.model.get('slug') : '',
3030
pubDate = this.model ? this.model.get('published_at') : 'Not Published',
31-
$pubDateEl = this.$('.post-setting-date');
31+
$pubDateEl = this.$('.post-setting-date'),
32+
$postSettingSlugEl = this.$('.post-setting-slug');
3233

33-
$('.post-setting-slug').val(slug);
34+
$postSettingSlugEl.val(slug);
3435

3536
// Update page status test if already a page.
3637
if (this.model && this.model.get('page')) {
@@ -47,20 +48,40 @@
4748
this.$('.delete').removeClass('hidden');
4849
}
4950

51+
// Apply different style for model's that aren't
52+
// yet persisted to the server.
53+
// Mostly we're hiding the delete post UI
54+
if (this.model.id === undefined) {
55+
this.$el.addClass('unsaved');
56+
} else {
57+
this.$el.removeClass('unsaved');
58+
}
59+
5060
$pubDateEl.val(pubDate);
5161
},
5262

5363
// Requests a new slug when the title was changed
5464
updateSlugPlaceholder: function () {
55-
var title = this.model.get('title');
56-
57-
$.ajax({
58-
url: Ghost.paths.apiRoot + '/posts/getSlug/' + encodeURIComponent(title),
59-
success: function (result){
60-
// ToDo: Find better selector
61-
$('.post-setting-slug')[0].placeholder = result;
62-
}
63-
});
65+
var title = this.model.get('title'),
66+
$postSettingSlugEl = this.$('.post-setting-slug');
67+
68+
// If there's a title present we want to
69+
// validate it against existing slugs in the db
70+
// and then update the placeholder value.
71+
if (title) {
72+
$.ajax({
73+
url: Ghost.paths.apiRoot + '/posts/getSlug/' + encodeURIComponent(title) + '/',
74+
success: function (result) {
75+
$postSettingSlugEl.attr('placeholder', result);
76+
}
77+
});
78+
} else {
79+
// If there's no title set placeholder to blank
80+
// and don't make an ajax request to server
81+
// for a proper slug (as there won't be any).
82+
$postSettingSlugEl.attr('placeholder', '');
83+
return;
84+
}
6485
},
6586

6687
selectSlug: function (e) {
@@ -74,6 +95,16 @@
7495
slugEl = e.currentTarget,
7596
newSlug = slugEl.value;
7697

98+
// If the model doesn't currently
99+
// exist on the server (aka has no id)
100+
// then just update the model's value
101+
if (self.model.id === undefined) {
102+
this.model.set({
103+
slug: newSlug
104+
});
105+
return;
106+
}
107+
77108
// Ignore unchanged slugs
78109
if (slug === newSlug) {
79110
slugEl.value = slug === undefined ? '' : slug;
@@ -116,6 +147,11 @@
116147
pubDateMoment,
117148
newPubDateMoment;
118149

150+
// if there is no new pub date do nothing
151+
if (!newPubDate) {
152+
return;
153+
}
154+
119155
// Check for missing time stamp on new data
120156
// If no time specified, add a 12:00
121157
if (newPubDate && !newPubDate.slice(-5).match(/\d+:\d\d/)) {
@@ -164,6 +200,16 @@
164200
return;
165201
}
166202

203+
// If the model doesn't currently
204+
// exist on the server (aka has no id)
205+
// then just update the model's value
206+
if (self.model.id === undefined) {
207+
this.model.set({
208+
published_at: newPubDateMoment.toDate()
209+
});
210+
return;
211+
}
212+
167213
// Save new 'Published' date
168214
this.model.save({
169215
published_at: newPubDateMoment.toDate()
@@ -192,6 +238,16 @@
192238
var pageEl = $(e.currentTarget),
193239
page = pageEl.prop('checked');
194240

241+
// Don't try to save
242+
// if the model doesn't currently
243+
// exist on the server
244+
if (this.model.id === undefined) {
245+
this.model.set({
246+
page: page
247+
});
248+
return;
249+
}
250+
195251
this.model.save({
196252
page: page
197253
}, {
@@ -218,6 +274,11 @@
218274
deletePost: function (e) {
219275
e.preventDefault();
220276
var self = this;
277+
// You can't delete a post
278+
// that hasn't yet been saved
279+
if (this.model.id === undefined) {
280+
return;
281+
}
221282
this.addSubview(new Ghost.Views.Modal({
222283
model: {
223284
options: {

core/server/api/posts.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ posts = {
5353
return slug;
5454
}
5555
return when.reject({errorCode: 500, message: 'Could not generate slug'});
56-
})
56+
});
5757
},
5858

5959
// #### Edit

core/server/models/base.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ ghostBookshelf.Model = ghostBookshelf.Model.extend({
182182
generateSlug: function (Model, base, readOptions) {
183183
var slug,
184184
slugTryCount = 1,
185-
// Look for a post with a matching slug, append an incrementing number if so
185+
// Look for a post with a matching slug, append an incrementing number if so
186186
checkIfSlugExists = function (slugToFind) {
187187
var args = {slug: slugToFind};
188188
//status is needed for posts

core/server/models/post.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,16 @@ Post = ghostBookshelf.Model.extend({
8484
}
8585

8686
ghostBookshelf.Model.prototype.creating.call(this);
87+
88+
// We require a slug be set when creating a new post
89+
// as the database doesn't allow null slug values.
90+
if (!this.get('slug')) {
91+
// Generating a slug requires a db call to look for conflicting slugs
92+
return ghostBookshelf.Model.generateSlug(Post, this.get('title'), {status: 'all', transacting: options.transacting})
93+
.then(function (slug) {
94+
self.set({slug: slug});
95+
});
96+
}
8797
},
8898

8999
updateTags: function (newTags, attr, options) {
@@ -389,11 +399,7 @@ Post = ghostBookshelf.Model.extend({
389399

390400
return post.destroy(options);
391401
});
392-
},
393-
getSlug: function(options) {
394-
395402
}
396-
397403
});
398404

399405
Posts = ghostBookshelf.Collection.extend({

core/server/models/tag.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ Tag = ghostBookshelf.Model.extend({
2424

2525
if (!this.get('slug')) {
2626
// Generating a slug requires a db call to look for conflicting slugs
27-
return this.generateSlug(Tag, this.get('name'))
27+
return ghostBookshelf.Model.generateSlug(Tag, this.get('name'))
2828
.then(function (slug) {
2929
self.set({slug: slug});
3030
});

core/server/models/user.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ User = ghostBookshelf.Model.extend({
5858

5959
if (!this.get('slug')) {
6060
// Generating a slug requires a db call to look for conflicting slugs
61-
return this.generateSlug(User, this.get('name'))
61+
return ghostBookshelf.Model.generateSlug(User, this.get('name'))
6262
.then(function (slug) {
6363
self.set({slug: slug});
6464
});

core/server/views/editor.hbs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
<ul class="suggestions overlay"></ul>
4141
</section>
4242
<div class="right">
43-
43+
4444
<section id="entry-controls">
4545
<a class="post-settings" href="#" data-toggle=".post-settings-menu" title="Post Settings"><span class="hidden">Post Settings</span></a>
4646
<div class="post-settings-menu menu-right overlay">
@@ -51,7 +51,7 @@
5151
<label for="url">URL</label>
5252
</td>
5353
<td class="post-setting-field">
54-
<input id="url" class="post-setting-slug" type="text" placeholder="your-post-title" value="" />
54+
<input id="url" class="post-setting-slug" type="text" placeholder="" value="" />
5555
</td>
5656
</tr>
5757
<tr class="post-setting">

0 commit comments

Comments
 (0)