Makes most special characters be replaced with a dash

closes #4782
- Still achieves the same goal of stripping out reserved characters
- Changes from removal to replacement
- This helps word separators from being removed
- Apostrophes (') are unaffected
This commit is contained in:
Clay Diffrient 2015-01-09 20:31:47 -07:00
parent f56bbc04e6
commit 673293575a
3 changed files with 81 additions and 8 deletions

View File

@ -351,9 +351,6 @@ ghostBookshelf.Model = ghostBookshelf.Model.extend({
slug = utils.safeString(base);
// Remove trailing hyphen
slug = slug.charAt(slug.length - 1) === '-' ? slug.substr(0, slug.length - 1) : slug;
// If it's a user, let's try to cut it down (unless this is a human request)
if (baseName === 'user' && options && options.shortSlug && slugTryCount === 1 && slug !== 'ghost-owner') {
longSlug = slug;

View File

@ -49,20 +49,30 @@ utils = {
return buf.join('');
},
safeString: function (string) {
string = string.trim();
// Handle the £ symbol seperately, since it needs to be removed before
// the unicode conversion.
string = string.replace(/£/g, '-');
// Remove non ascii characters
string = unidecode(string);
// Remove URL reserved chars: `:/?#[]@!$&'()*+,;=` as well as `\%<>|^~£"`
string = string.replace(/[:\/\?#\[\]@!$&'()*+,;=\\%<>\|\^~£"]/g, '')
// Replace dots and spaces with a dash
.replace(/(\s|\.)/g, '-')
// Replace URL reserved chars: `:/?#[]!$&()*+,;=` as well as `\%<>|^~£"`
string = string.replace(/(\s|\.|@|:|\/|\?|#|\[|\]|!|\$|&|\(|\)|\*|\+|,|;|=|\\|%|<|>|\||\^|~|"||—)/g, '-')
// Remove apostrophes
.replace(/'/g, '')
// Convert 2 or more dashes into a single dash
.replace(/-+/g, '-')
// Remove any dashes at the beginning
.replace(/^-/, '')
// Make the whole thing lowercase
.toLowerCase();
// Remove trailing dash if needed
string = string.charAt(string.length - 1) === '-' ? string.substr(0, string.length - 1) : string;
// Handle whitespace at the beginning or end.
string = string.trim();
return string;
},
// The token is encoded URL safe by replcaing '+' with '-', '\' with '_' and removing '='

View File

@ -0,0 +1,66 @@
/*globals describe, it*/
/*jshint expr:true*/
var should = require('should'),
utils = require('../../server/utils');
// To stop jshint complaining
should.equal(true, true);
describe('Safe String', function () {
var safeString = utils.safeString;
it('should remove beginning and ending whitespace', function () {
var result = safeString(' stringwithspace ');
result.should.equal('stringwithspace');
});
it('should remove non ascii characters', function () {
var result = safeString('howtowin✓');
result.should.equal('howtowin');
});
it('should replace spaces with dashes', function () {
var result = safeString('how to win');
result.should.equal('how-to-win');
});
it('should replace most special characters with dashes', function () {
var result = safeString('a:b/c?d#e[f]g!h$i&j(k)l*m+n,o;p=q\\r%s<t>u|v^w~x£y"z@1.2');
result.should.equal('a-b-c-d-e-f-g-h-i-j-k-l-m-n-o-p-q-r-s-t-u-v-w-x-y-z-1-2');
});
it('should remove special characters at the beginning of a string', function () {
var result = safeString('.Not special');
result.should.equal('not-special');
});
it('should remove apostrophes ', function () {
var result = safeString('how we shouldn\'t be');
result.should.equal('how-we-shouldnt-be');
});
it('should convert to lowercase', function () {
var result = safeString('This has Upper Case');
result.should.equal('this-has-upper-case');
});
it('should convert multiple dashes into a single dash', function () {
var result = safeString('This :) means everything');
result.should.equal('this-means-everything');
});
it('should remove trailing dashes from the result', function () {
var result = safeString('This.');
result.should.equal('this');
});
it('should handle pound signs', function () {
var result = safeString('WHOOPS! I spent all my £ again!');
result.should.equal('whoops-i-spent-all-my-again');
});
it('should properly handle unicode punctuation conversion', function () {
var result = safeString('に間違いがないか、再度確認してください。再読み込みしてください。');
result.should.equal('nijian-wei-iganaika-zai-du-que-ren-sitekudasai-zai-du-miip-misitekudasai');
});
});