forked from pvencill/slugin
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathindex.js
96 lines (79 loc) · 2.37 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
'use strict';
var
mongoose = require('mongoose'),
_ = require('lodash'),
inflection = require('inflection'),
slugs = require('slugs');
function slugify(model, options) {
var slugParts = _.map(options.source, function(path) {
return _.get(model, path);
});
return slugs(slugParts.join(' '));
}
function getModel(document, options) {
var modelName = options.modelName || inflection.singularize(inflection.camelize(document.collection.name));
return document.collection.conn.model(modelName);
}
function incrementAndSave(document, options, cb) {
var Model = getModel(document, options);
var params = {};
var slugbaseKey = options.slugBase;
var itKey = options.slugIt;
params[slugbaseKey] = document[slugbaseKey];
Model.findOne(params).sort('-'+itKey).exec(function(e, doc) {
if(e) return cb(e);
var it = (doc[itKey] || 0) + Math.ceil(Math.random()*10);
document[itKey] = it;
document[options.slugName] = document[slugbaseKey]+'-'+it;
document.markModified(slugbaseKey);
_.forEach(options.source, function(item) {
document.markModified(item);
});
return document.save(cb);
});
}
function Slugin(schema, options) {
options = _.defaults(options || {}, Slugin.defaultOptions);
if (_.isString(options.source)) options.source = [options.source];
options.slugIt = options.slugName + '_it';
options.slugBase = options.slugName + '_base';
var fields = {};
fields[options.slugName] = {
type : String,
unique: true
};
fields[options.slugBase] = {
type: String,
index:true
};
fields[options.slugIt] = {
type: Number
};
schema.add(fields);
schema.pre('save', function(next){
var self = this;
var slugBase = slugify(self, options);
if (self[options.slugBase] !== slugBase) {
self[options.slugName] = slugBase;
self[options.slugBase] = slugBase;
delete self[options.slugIt];
}
next();
});
schema.methods.save = function(cb){
var self = this;
mongoose.Model.prototype.save.call(self, function(e, model, num) {
if (e && (e.code === 11000 || e.code === 11001) && !!~e.errmsg.indexOf(self[options.slugName])) {
incrementAndSave(self, options, cb);
} else {
cb(e,model,num);
}
});
};
}
Slugin.defaultOptions = {
slugName : 'slug',
source : 'title',
modelName : null
};
module.exports = Slugin;