mongoose-url-slugs
Advanced tools
Comparing version 0.0.3 to 0.0.4
110
index.js
@@ -1,75 +0,93 @@ | ||
var extend = require('extend'), | ||
inspect = require('util').inspect; | ||
var extend = require('extend'); | ||
function defaultURLSlugGeneration(text) { | ||
return text.toLowerCase().replace(/([^a-z0-9\-\_]+)/g, '-').replace(/\-{2,}/g, '-'); | ||
function defaultURLSlugGeneration(text, separator) { | ||
return text.toLowerCase().replace(/([^a-z0-9\-\_]+)/g, separator).replace(new RegExp(separator + '{2,}', 'g'), separator); | ||
} | ||
var defaultOptions = { | ||
key: 'slug', | ||
field: 'slug', | ||
addField: true, | ||
generator: defaultURLSlugGeneration, | ||
index: { | ||
type: String, | ||
trim: true, | ||
index: true, | ||
unique: true, | ||
required: true | ||
} | ||
separator: '-', | ||
update: false, | ||
index: true, | ||
index_type: String, | ||
index_default: '', | ||
index_trim: true, | ||
index_unique: true, | ||
index_required: false | ||
}; | ||
module.exports = function(slugProperty, options) { | ||
module.exports = function(slugFields, options) { | ||
options = extend(true, defaultOptions, options); | ||
if (slugProperty.indexOf(' ') > -1) { | ||
slugProperty = slugProperty.split(' '); | ||
if (slugFields.indexOf(' ') > -1) { | ||
slugFields = slugFields.split(' '); | ||
} | ||
return (function (schema) { | ||
var schemaField = {}; | ||
schemaField[options.key] = {type: options.index.type, trim: options.index.trim, index: options.index.index, unique: options.index.unique, required: options.index.required}; | ||
schema.add(schemaField); | ||
if (options.addField) { | ||
var schemaField = {}; | ||
schemaField[options.field] = {type: options.index_type, default: options.index_default, trim: options.index_trim, index: options.index, unique: options.index_unique, required: options.index_required}; | ||
schema.add(schemaField); | ||
} | ||
schema.methods.ensureUniqueSlug = function (doc, slug, cb) { | ||
if (!options.index.unique) return cb(null, true); | ||
schema.methods.ensureUniqueSlug = function (slug, cb) { | ||
console.log('ensureUniqueSlug Doc:', this); | ||
if (!options.index_unique) return cb(null, true, slug); | ||
var doc = this; | ||
var model = doc.constructor; | ||
var q = {}; | ||
q[options.key] = slug; | ||
model.findOne(q, {_id: 1}).exec(function (e, doc) { | ||
q[options.field] = new RegExp('^' + slug); | ||
q['_id'] = {$ne: doc._id}; | ||
var fields = {}; | ||
fields[options.field] = 1; | ||
model.find(q, fields).exec(function (e, docs) { | ||
if (e) return cb(e); | ||
else if (!doc) cb(null, true); | ||
else cb(null, false); | ||
else if (!docs.length) cb(null, true, slug); | ||
else { | ||
var max = docs.reduce(function (max, doc) { | ||
var count = doc.get(options.field, String).match(new RegExp(options.separator + '([0-9]+)$')); | ||
count = ((count instanceof Array)? parseInt(count[1]) : 0) + 1; | ||
return (count > max)? count : max; | ||
}, 0); | ||
if (max == 1) cb(null, false, slug + options.separator + (max + 1)); // avoid slug-1, rather do slug-2 | ||
else if (max > 0) cb(null, false, slug + options.separator + max); | ||
else cb(null, false, slug); | ||
} | ||
}); | ||
} | ||
}; | ||
schema.statics.findBySlug = function (slug, fields, options, cb) { | ||
var q = {}; | ||
q[options.field] = slug; | ||
return this.findOne(q, fields, options, cb); | ||
}; | ||
schema.pre('validate', function (next) { | ||
var doc = this; | ||
if (doc.get(options.key)) return next(); | ||
if (!doc.isNew && !options.update) return next(); | ||
var slugFieldsModified = doc.isNew? true : false; | ||
var toSlugify = ''; | ||
if (slugProperty instanceof Array) { | ||
for (var i = 0; i < slugProperty.length; i++) { | ||
toSlugify += doc.get(slugProperty[i]) + ' '; | ||
if (slugFields instanceof Array) { | ||
for (var i = 0; i < slugFields.length; i++) { | ||
var slugField = slugFields[i]; | ||
if (doc.isModified(slugField)) slugFieldsModified = true; | ||
var slugPart = doc.get(slugField, String); | ||
if (slugPart) toSlugify += slugPart + ' '; | ||
} | ||
toSlugify = toSlugify.substr(0, toSlugify.length-1); | ||
} else { | ||
toSlugify = doc.get(slugProperty); | ||
if (doc.isModified(slugFields)) slugFieldsModified = true; | ||
toSlugify = doc.get(slugFields, String); | ||
} | ||
function uniqueSlugGeneration(slugCount, cb) { | ||
if (typeof slugCount == 'function') { | ||
cb = slugCount; | ||
slugCount = undefined; | ||
} | ||
slugCount = slugCount || 1; | ||
var tmpSlug = options.generator(toSlugify + ((slugCount > 1)? ' ' + slugCount : '')); | ||
schema.methods.ensureUniqueSlug(doc, tmpSlug, function (e, unique) { | ||
if (e) cb(e); | ||
if (!unique) return uniqueSlugGeneration(++slugCount, cb); | ||
else cb(null, tmpSlug); | ||
}); | ||
} | ||
uniqueSlugGeneration(function (e, finalSlug) { | ||
if (!slugFieldsModified) return next(); | ||
var newSlug = options.generator(toSlugify, options.separator); | ||
doc.ensureUniqueSlug(newSlug, function (e, exists, finalSlug) { | ||
if (e) return next(e); | ||
doc.set(options.key, finalSlug); | ||
doc.set(options.field, finalSlug); | ||
doc.markModified(options.field, finalSlug); // sometimes required :) | ||
next(); | ||
@@ -76,0 +94,0 @@ }); |
@@ -9,3 +9,3 @@ { | ||
"description": "Create URL compatiable slugs on mongoose models, ensuring uniqueness.", | ||
"version": "0.0.3", | ||
"version": "0.0.4", | ||
"keywords": [ | ||
@@ -16,3 +16,4 @@ "mongoose slugs", | ||
"mongodb slugs", | ||
"mongodb url slugs" | ||
"mongodb url slugs", | ||
"mongoose" | ||
], | ||
@@ -19,0 +20,0 @@ "homepage": "http://mindblaze.github.io/mongoose-url-slugs", |
@@ -16,3 +16,3 @@ # Mongoose URL Slugs | ||
### Example 1: Using default options and merging 2 fields for slug generation. | ||
### Example 1: Using default options and using 2 fields for slug generation. | ||
@@ -47,3 +47,3 @@ ```js | ||
// Save slugs to 'myslug' field. | ||
testSchema.plugin(URLSlugs('first_name last_name', {key: 'myslug'})); | ||
testSchema.plugin(URLSlugs('first_name last_name', {field: 'myslug'})); | ||
``` | ||
@@ -54,16 +54,20 @@ | ||
* **key** (Default: 'slug') - Parts that are uploaded simultaneously. | ||
* **generator(text)** (Default: lowercases and then replaces all alphanumeric characters to '-') - Function to generate slug. | ||
* **index** - key schema settings. (see below) | ||
* - **index.type** (Default: String) - Mongoose schema property type. | ||
* - **index.trim** (Default: true) - Mongoose schema property trim. | ||
* - **index.index** (Default: true) - Mongoose schema property index. | ||
* - **index.unique** (Default: true) - Mongoose schema property unique. | ||
* - **index.required** (Default: true) - Mongoose schema property required. | ||
* **field** (Default: 'slug') - Parts that are uploaded simultaneously. | ||
* **addField** (Default: True) - Add slug field to mongoose schema. | ||
* **separator** (Default: '-') - Separator to use for invalid characters. | ||
* **generator(text, separator)** (Default: lowercases and then replaces all alphanumeric characters to separators) - Function to generate slug. | ||
* **update** (Default: false) - Update slug when slug building fields change. | ||
* **index** (Default: true) - Mark slug field as index in mongoose schema. | ||
* **index_type** (Default: String) - Mongoose schema slug index type. | ||
* **index_default** (Default: '') - Mongoose schema slug index default value. | ||
* **index_trim** (Default: True) - Mongoose schema slug index trim value. | ||
* **index_unique** (Default: True) - Mongoose schema slug index unique value. | ||
* **index_required** (Default: True) - Mongoose schema slug index required value. | ||
## History | ||
* v0.0.3 (2014-06-09) -- Initial release. | ||
* v0.0.4 (2014-06-10) -- Initial release. | ||
## License | ||
@@ -70,0 +74,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
8386
85
92