README
slugz
Turn a string into a url-safe slug.
Basic Usage
var slugz = require('slugz')();
slugz('Developing Hybrid iPhone Apps'); // => 'developing-hybrid-iphone-apps'
slugz("It's Johnny!"); // => 'its-johnny'
Cleaners
You can customize the way handles are generated by using cleaners. Cleaners are added using the chainable use
method.
use(function)
Any function passed to the use
method will be called with a cleaned handle that has underscores seperating words, and is expected to return a modified handle.
For example, the following could be used to replace "yipee" with "yahoo":
var slugz = require('slugz')().use(function(text) {
return text.replace(/(^|_)yipee(_|$)/g, '_yahoo_');
});
slugz('Things That Make Me Say "Yipee!"'); // => 'things-that-make-me-say-yahoo'
use(object)
If you need more granularity then you can pass an object to use
that can have any combination of beforeClean
, clean
, and afterClean
methods.
beforeClean
is called before the original text has been modified in any wayclean
is called after basic cleaning has occurred and the text will be underscore delimitedafterClean
is called just before the final handle is returned
For example, if you want to expand some contractions:
var slugz = require('slugz')().use({
beforeClean: function(text) {
return text.replace(/\b(that|what)'s\b/gi, '$1 is');
}
});
slugz("That's All Folks"); // => 'that-is-all-folks'
slugz("Peyton Manning: What's the Big Deal?"); // => 'peyton-manning-what-is-the-big-deal'
If you only need clean
then consider just passing that function to use
rather than using an object.
use(string, [params...])
There are several predefined cleaners in the "cleaners" folder that can be be added by name and configured by adding addtional arguments to the use
call.
Parenthesis
Strip parenthetical text from handles.
var slugz = require('slugz')().use('parenthesis');
slugz('Save Money on Over-the-Counter (OTC) Medications'); // => 'save-money-on-over-the-counter-medications'
How-To
Remove the words "how to" from handles.
var slugz = require('slugz')().use('how-to');
slugz('How to Build a Hover Car'); // => 'build-a-hover-car'
slugz('HowTo: Dance Like You Mean It'); // => 'dance-like-you-mean-it'
slugz('Healthcare Headlines: How-to Deal with High Blood Pressure'); // => 'healthcare-headlines-deal-with-high-blood-pressure'
Max Chars
Limit the character length of the handle, truncating on word boundaries.
var slugz = require('slugz')().use('max-chars', 20);
slugz("Your Dog's Pain Medications and Muscle Relaxants: Dangerous to Humans"); // => 'your-dogs-pain'
Max Words
Limit the number of words in the handle.
var slugz = require('slugz')().use('max-words', 5);
slugz('Natural Ways to Control High Blood Pressure'); // => 'natural-ways-to-control-high'
Common Words
Remove words that would not be considered "keywords". First and last words will not be touched as well as hyphenated words.
var slugz = require('slugz')().use('common-words');
slugz('Worst NFL Off-Seasons of 2013'); // => 'worst-nfl-off-seasons-2013'
slugz('The Best of Both Worlds'); // => 'the-best-both-worlds'
slugz("Your Dog's Pain Medications and Muscle Relaxants: Dangerous to Humans"); // => 'your-dogs-pain-medications-muscle-relaxants-dangerous-humans'
You can optionally pass your own "common words" list:
var slugz = require('slugz')().use('common-words', {
remove: ['best', 'hot', 'humans?', 'its', 'the', 'worst', 'your'],
preserve: ['hot[_\\-]+momma', 'your_+dogs?']
});
slugz('Treating Your Dog With Human Medications'); // => 'treating-your-dog-with-medications'
slugz("Staying Cool When It's Hot Outside"); // => 'staying-cool-when-outside'
slugz('How Your Dog Percieves Humans In Groups'); // => 'how-your-dog-percieves-in-groups'
How we use it:
This is basically the logic that we want to use to generate article handles:
var Handleify = require('slugz'),
async = require('async');
var MAX_CHARS = 100;
// Handle generators, in our prefered order
var handleifiers = [
Handleify(),
Handleify().use('parenthesis'),
Handleify().use('parenthesis').use('how-to'),
Handleify().use('common-words'),
Handleify().use('parenthesis').use('common-words'),
Handleify().use('how-to').use('common-words'),
Handleify().use('parenthesis').use('how-to').use('common-words')
];
// Handle generators to fall back to if the corresponding one above is too long
var shortenedHandleifiers = [
Handleify().use('max-chars', MAX_CHARS),
Handleify().use('parenthesis').use('max-chars', MAX_CHARS),
Handleify().use('parenthesis').use('how-to').use('max-chars', MAX_CHARS),
Handleify().use('common-words').use('max-chars', MAX_CHARS),
Handleify().use('parenthesis').use('common-words').use('max-chars', MAX_CHARS),
Handleify().use('how-to').use('common-words').use('max-chars', MAX_CHARS),
Handleify().use('parenthesis').use('how-to').use('common-words').use('max-chars', MAX_CHARS)
];
function getHandle(headline, done) {
var results = [],
shortenedResults = [];
// Get 7 possible handles to test for uniqueness
for(var handle, i = 0; i++; i < handleifiers.length) {
handle = handleifiers[i](headline);
if(headline.length <= MAX_CHARS)
results.push(handle);
else
shortenedResults.push(shortenedHandleifiers[i](headline));
}
// Build the list and remove duplicates
results = results.concat(shortenedResults.reverse());
//results = results.unique();
// Find the first handle that isn't already taken
async.detect(results, function(handle, cb) {
mysql.recordExists(handle, function(err, exists) {
if(err) cb(false);
else cb(!exists);
});
}, done);
}