mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-24 03:14:03 +03:00
New Post UX behaviour.
refs #1351 - Make generateSlug a static method on base model - Change client behaviour (unfinished) - Add new getSlug API method
This commit is contained in:
parent
80eac65e9b
commit
11c8d234f7
@ -396,6 +396,9 @@
|
||||
if (rawTitle !== trimmedTitle) {
|
||||
$title.val(trimmedTitle);
|
||||
}
|
||||
|
||||
// Trigger title change for post-settings.js
|
||||
this.model.set('title', trimmedTitle);
|
||||
},
|
||||
|
||||
renderTitle: function () {
|
||||
|
@ -21,6 +21,7 @@
|
||||
this.listenTo(this.model, 'change:status', this.render);
|
||||
this.listenTo(this.model, 'change:published_at', this.render);
|
||||
this.listenTo(this.model, 'change:page', this.render);
|
||||
this.listenTo(this.model, 'change:title', this.updateSlugPlaceholder);
|
||||
}
|
||||
},
|
||||
|
||||
@ -49,6 +50,19 @@
|
||||
$pubDateEl.val(pubDate);
|
||||
},
|
||||
|
||||
// Requests a new slug when the title was changed
|
||||
updateSlugPlaceholder: function () {
|
||||
var title = this.model.get('title');
|
||||
|
||||
$.ajax({
|
||||
url: Ghost.paths.apiRoot + '/posts/getSlug/' + encodeURIComponent(title),
|
||||
success: function (result){
|
||||
// ToDo: Find better selector
|
||||
$('.post-setting-slug')[0].placeholder = result;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
selectSlug: function (e) {
|
||||
e.currentTarget.select();
|
||||
},
|
||||
@ -60,8 +74,8 @@
|
||||
slugEl = e.currentTarget,
|
||||
newSlug = slugEl.value;
|
||||
|
||||
// Ignore empty or unchanged slugs
|
||||
if (newSlug.length === 0 || slug === newSlug) {
|
||||
// Ignore unchanged slugs
|
||||
if (slug === newSlug) {
|
||||
slugEl.value = slug === undefined ? '' : slug;
|
||||
return;
|
||||
}
|
||||
@ -102,11 +116,6 @@
|
||||
pubDateMoment,
|
||||
newPubDateMoment;
|
||||
|
||||
// Ignore empty or unchanged dates
|
||||
if (!newPubDate) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for missing time stamp on new data
|
||||
// If no time specified, add a 12:00
|
||||
if (newPubDate && !newPubDate.slice(-5).match(/\d+:\d\d/)) {
|
||||
|
@ -47,6 +47,15 @@ posts = {
|
||||
});
|
||||
},
|
||||
|
||||
getSlug: function getSlug(args) {
|
||||
return dataProvider.Base.Model.generateSlug(dataProvider.Post, args.title, {status: 'all'}).then(function (slug) {
|
||||
if (slug) {
|
||||
return slug;
|
||||
}
|
||||
return when.reject({errorCode: 500, message: 'Could not generate slug'});
|
||||
})
|
||||
},
|
||||
|
||||
// #### Edit
|
||||
|
||||
// **takes:** a json object with all the properties which should be updated
|
||||
|
@ -93,67 +93,6 @@ ghostBookshelf.Model = ghostBookshelf.Model.extend({
|
||||
|
||||
sanitize: function (attr) {
|
||||
return sanitize(this.get(attr)).xss();
|
||||
},
|
||||
|
||||
// #### generateSlug
|
||||
// Create a string act as the permalink for an object.
|
||||
generateSlug: function (Model, base, readOptions) {
|
||||
var slug,
|
||||
slugTryCount = 1,
|
||||
// Look for a post with a matching slug, append an incrementing number if so
|
||||
checkIfSlugExists = function (slugToFind) {
|
||||
var args = {slug: slugToFind};
|
||||
//status is needed for posts
|
||||
if (readOptions && readOptions.status) {
|
||||
args.status = readOptions.status;
|
||||
}
|
||||
return Model.findOne(args, readOptions).then(function (found) {
|
||||
var trimSpace;
|
||||
|
||||
if (!found) {
|
||||
return when.resolve(slugToFind);
|
||||
}
|
||||
|
||||
slugTryCount += 1;
|
||||
|
||||
// If this is the first time through, add the hyphen
|
||||
if (slugTryCount === 2) {
|
||||
slugToFind += '-';
|
||||
} else {
|
||||
// Otherwise, trim the number off the end
|
||||
trimSpace = -(String(slugTryCount - 1).length);
|
||||
slugToFind = slugToFind.slice(0, trimSpace);
|
||||
}
|
||||
|
||||
slugToFind += slugTryCount;
|
||||
|
||||
return checkIfSlugExists(slugToFind);
|
||||
});
|
||||
};
|
||||
|
||||
// Remove URL reserved chars: `:/?#[]@!$&'()*+,;=` as well as `\%<>|^~£"`
|
||||
slug = base.trim().replace(/[:\/\?#\[\]@!$&'()*+,;=\\%<>\|\^~£"]/g, '')
|
||||
// Replace dots and spaces with a dash
|
||||
.replace(/(\s|\.)/g, '-')
|
||||
// Convert 2 or more dashes into a single dash
|
||||
.replace(/-+/g, '-')
|
||||
// Make the whole thing lowercase
|
||||
.toLowerCase();
|
||||
|
||||
// Remove trailing hyphen
|
||||
slug = slug.charAt(slug.length - 1) === '-' ? slug.substr(0, slug.length - 1) : slug;
|
||||
// Remove non ascii characters
|
||||
slug = unidecode(slug);
|
||||
// Check the filtered slug doesn't match any of the reserved keywords
|
||||
slug = /^(ghost|ghost\-admin|admin|wp\-admin|wp\-login|dashboard|logout|login|signin|signup|signout|register|archive|archives|category|categories|tag|tags|page|pages|post|posts|user|users)$/g
|
||||
.test(slug) ? slug + '-post' : slug;
|
||||
|
||||
//if slug is empty after trimming use "post"
|
||||
if (!slug) {
|
||||
slug = 'post';
|
||||
}
|
||||
// Test for duplicate slugs.
|
||||
return checkIfSlugExists(slug);
|
||||
}
|
||||
|
||||
}, {
|
||||
@ -236,6 +175,67 @@ ghostBookshelf.Model = ghostBookshelf.Model.extend({
|
||||
|
||||
'delete': function () {
|
||||
return this.destroy.apply(this, arguments);
|
||||
},
|
||||
|
||||
// #### generateSlug
|
||||
// Create a string act as the permalink for an object.
|
||||
generateSlug: function (Model, base, readOptions) {
|
||||
var slug,
|
||||
slugTryCount = 1,
|
||||
// Look for a post with a matching slug, append an incrementing number if so
|
||||
checkIfSlugExists = function (slugToFind) {
|
||||
var args = {slug: slugToFind};
|
||||
//status is needed for posts
|
||||
if (readOptions && readOptions.status) {
|
||||
args.status = readOptions.status;
|
||||
}
|
||||
return Model.findOne(args, readOptions).then(function (found) {
|
||||
var trimSpace;
|
||||
|
||||
if (!found) {
|
||||
return when.resolve(slugToFind);
|
||||
}
|
||||
|
||||
slugTryCount += 1;
|
||||
|
||||
// If this is the first time through, add the hyphen
|
||||
if (slugTryCount === 2) {
|
||||
slugToFind += '-';
|
||||
} else {
|
||||
// Otherwise, trim the number off the end
|
||||
trimSpace = -(String(slugTryCount - 1).length);
|
||||
slugToFind = slugToFind.slice(0, trimSpace);
|
||||
}
|
||||
|
||||
slugToFind += slugTryCount;
|
||||
|
||||
return checkIfSlugExists(slugToFind);
|
||||
});
|
||||
};
|
||||
|
||||
// Remove URL reserved chars: `:/?#[]@!$&'()*+,;=` as well as `\%<>|^~£"`
|
||||
slug = base.trim().replace(/[:\/\?#\[\]@!$&'()*+,;=\\%<>\|\^~£"]/g, '')
|
||||
// Replace dots and spaces with a dash
|
||||
.replace(/(\s|\.)/g, '-')
|
||||
// Convert 2 or more dashes into a single dash
|
||||
.replace(/-+/g, '-')
|
||||
// Make the whole thing lowercase
|
||||
.toLowerCase();
|
||||
|
||||
// Remove trailing hyphen
|
||||
slug = slug.charAt(slug.length - 1) === '-' ? slug.substr(0, slug.length - 1) : slug;
|
||||
// Remove non ascii characters
|
||||
slug = unidecode(slug);
|
||||
// Check the filtered slug doesn't match any of the reserved keywords
|
||||
slug = /^(ghost|ghost\-admin|admin|wp\-admin|wp\-login|dashboard|logout|login|signin|signup|signout|register|archive|archives|category|categories|tag|tags|page|pages|post|posts|user|users)$/g
|
||||
.test(slug) ? slug + '-post' : slug;
|
||||
|
||||
//if slug is empty after trimming use "post"
|
||||
if (!slug) {
|
||||
slug = 'post';
|
||||
}
|
||||
// Test for duplicate slugs.
|
||||
return checkIfSlugExists(slug);
|
||||
}
|
||||
|
||||
});
|
||||
|
@ -67,7 +67,7 @@ Post = ghostBookshelf.Model.extend({
|
||||
|
||||
if (this.hasChanged('slug')) {
|
||||
// Pass the new slug through the generator to strip illegal characters, detect duplicates
|
||||
return this.generateSlug(Post, this.get('slug'), {status: 'all', transacting: options.transacting})
|
||||
return ghostBookshelf.Model.generateSlug(Post, this.get('slug'), {status: 'all', transacting: options.transacting})
|
||||
.then(function (slug) {
|
||||
self.set({slug: slug});
|
||||
});
|
||||
@ -84,14 +84,6 @@ Post = ghostBookshelf.Model.extend({
|
||||
}
|
||||
|
||||
ghostBookshelf.Model.prototype.creating.call(this);
|
||||
|
||||
if (!this.get('slug')) {
|
||||
// Generating a slug requires a db call to look for conflicting slugs
|
||||
return this.generateSlug(Post, this.get('title'), {status: 'all', transacting: options.transacting})
|
||||
.then(function (slug) {
|
||||
self.set({slug: slug});
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
updateTags: function (newTags, attr, options) {
|
||||
@ -397,6 +389,9 @@ Post = ghostBookshelf.Model.extend({
|
||||
|
||||
return post.destroy(options);
|
||||
});
|
||||
},
|
||||
getSlug: function(options) {
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
@ -10,6 +10,7 @@ module.exports = function (server) {
|
||||
server.get('/ghost/api/v0.1/posts/:id', middleware.authAPI, api.requestHandler(api.posts.read));
|
||||
server.put('/ghost/api/v0.1/posts/:id', middleware.authAPI, api.requestHandler(api.posts.edit));
|
||||
server.del('/ghost/api/v0.1/posts/:id', middleware.authAPI, api.requestHandler(api.posts.destroy));
|
||||
server.get('/ghost/api/v0.1/posts/getSlug/:title', middleware.authAPI, api.requestHandler(api.posts.getSlug));
|
||||
// #### Settings
|
||||
server.get('/ghost/api/v0.1/settings/', middleware.authAPI, api.requestHandler(api.settings.browse));
|
||||
server.get('/ghost/api/v0.1/settings/:key/', middleware.authAPI, api.requestHandler(api.settings.read));
|
||||
|
@ -51,7 +51,7 @@
|
||||
<label for="url">URL</label>
|
||||
</td>
|
||||
<td class="post-setting-field">
|
||||
<input id="url" class="post-setting-slug" type="text" value="" />
|
||||
<input id="url" class="post-setting-slug" type="text" placeholder="your-post-title" value="" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="post-setting">
|
||||
@ -59,7 +59,7 @@
|
||||
<label for="pub-date">Pub Date</label>
|
||||
</td>
|
||||
<td class="post-setting-field">
|
||||
<input id="pub-date" class="post-setting-date" type="text" value=""><!--<span class="post-setting-calendar"></span>-->
|
||||
<input id="pub-date" class="post-setting-date" type="text" placeholder="Now" value=""><!--<span class="post-setting-calendar"></span>-->
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="post-setting">
|
||||
|
Loading…
Reference in New Issue
Block a user