Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add querystring to options; add JetBrains project dir to .gitignore; #1

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,5 @@ npm-debug.log
node_modules

build/

.idea/
83 changes: 79 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,14 @@ multiple avatars into named groups!
}
```

Nested objects map directly into the output'ed `gravatar` object, so you can access them by the same
Nested objects map directly into the outputted `gravatar` object, so you can access them by the same
names:

```html
<img src="{{gravatar.authors.stevenschobert}}" />
```

## Options
## Global Options

If you want more control over how the Gravatar URLs are generated, you can specify an `options`
object. If the plugin sees this `options` object, it will expect the avatars you wish to convert to
Expand All @@ -108,15 +108,90 @@ be in a new `avatars` object:
}
```

Below is a list of options that are supported:
## Individual Avatar Options

### protocol
Options can also be given for individual avatars. Any options given for an individual
avatar will override the global version of the same setting. In order to add options
for an individual avatar, set the avatar property to an `object` with an `email`
property:

```json
{
"plugins": {
"metalsmith-gravatar": {
"stevenschobert": {
"email": "spschobert@gmail.com"
}
}
}
}
```

## Valid Options

### protocol (global only)

`String` - `'http' (default)` or `'https'`

Sets the URL prefix for Gravatar images. Useful if you are serving a page via SSL and want to also
load the external images via SSL.

### querystring (global or individual)

`String` or `Object`

Adds a query string to all Gravatar URLs to all for modifications to the requested image, including
image size, default image, and max rating (g, pg, r, x). The query string parameters are detailed
on [Gravatar's website](https://en.gravatar.com/site/implement/images/). Here is the string version:

```json
{
"plugins": {
"metalsmith-gravatar": {
"options": {
"querystring": "s=200&r=pg"
},
"avatars": {
"stevenschobert": "spschobert@gmail.com",
"roadrunner": {
"email": "roadrunnermeepmeep@gmail.com",
"querystring": "s=400&r=g"
},
"authors": { ... }
}
}
}
}
```

Here is the object version:

```json
{
"plugins": {
"metalsmith-gravatar": {
"options": {
"querystring": {
"s": 200,
"r": "pg"
}
},
"avatars": {
"stevenschobert": "spschobert@gmail.com",
"roadrunner": {
"email": "roadrunnermeepmeep@gmail.com",
"querystring": {
"s": 400,
"r": "g"
}
},
"authors": { ... }
}
}
}
}
```

## Credits

Thanks to [Segment.io](http://github.com/segmentio) for creating and open-sourcing
Expand Down
30 changes: 22 additions & 8 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@
'use strict';

var md5 = require('md5'),
qs = require('querystring'),

GRAVATAR_URL = 'www.gravatar.com/avatar',

assembleUrl = function assembleUrl(protocol, hash) {
return protocol + '://' + GRAVATAR_URL + '/' + hash;
assembleUrl = function assembleUrl(protocol, hash, querystring) {
return protocol + '://' + GRAVATAR_URL + '/' + hash + (querystring ? "?" + querystring : '');
},

gravatarForEmail = function gravatarForEmail(protocol, email) {
return assembleUrl(protocol, md5.digest_s(email));
gravatarForEmail = function gravatarForEmail(protocol, email, querystring) {
return assembleUrl(protocol, md5.digest_s(email), querystring);
},

mutateStringsInObject = function mutateStringsInObject(obj, mutator) {
Expand All @@ -22,7 +23,15 @@
if (typeof value === 'string') {
converted[key] = mutator(value);
} else if (typeof value === 'object' && !Array.isArray(value)) {
converted[key] = mutateStringsInObject(value, mutator);
if (value.email) {
if (value.querystring && typeof value.querystring === 'object') {
value.querystring = qs.stringify(value.querystring);
}
converted[key] = mutator(value.email, value.querystring);
} else {
converted[key] = mutateStringsInObject(value, mutator);
}

} else {
converted[key] = value;
}
Expand All @@ -33,7 +42,8 @@

plugin = function plugin(args) {
var options = {
protocol: 'http'
protocol: 'http',
querystring: ''
},
avatars = args || {};

Expand All @@ -47,8 +57,12 @@
return function(files, metalsmith, done) {
var metadata = metalsmith.metadata();

metadata.gravatar = mutateStringsInObject(avatars, function(email) {
return gravatarForEmail(options.protocol, email);
if (options.querystring && typeof options.querystring === 'object') {
options.querystring = qs.stringify(options.querystring);
}

metadata.gravatar = mutateStringsInObject(avatars, function(email, querystring) {
return gravatarForEmail(options.protocol, email, querystring ? querystring : options.querystring);
});

done();
Expand Down
136 changes: 133 additions & 3 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,23 @@
Metalsmith = require('metalsmith'),
gravatar = require('..'),

assembleUrl = function assembleUrl(protocol, url, hash) {
return protocol + '://' + url + '/' + hash;
assembleUrl = function assembleUrl(protocol, url, hash, querystring) {
return protocol + '://' + url + '/' + hash + (querystring ? '?' + querystring : '');
};

describe('the plugin', function() {
var baseUrl = 'www.gravatar.com/avatar',
testEmail = 'spschobert@gmail.com',
testHash = 'bc13eedc2642303b1a2251a4da7f157e',
testEmail2 = 'azurelogic@gmail.com',
testHash2 = '0792a86bd840e2f9e16997e15e6658ea',
defaultProtocol = 'http',
secureProtocol = 'https',
expected = assembleUrl(defaultProtocol, baseUrl, testHash);
testQuerystring = 's=200&r=pg',
testQuerystring2 = 's=400&r=g',
expected = assembleUrl(defaultProtocol, baseUrl, testHash),
expectedWithQuerystring = assembleUrl(defaultProtocol, baseUrl, testHash, testQuerystring),
expectedWithQuerystring2 = assembleUrl(defaultProtocol, baseUrl, testHash2, testQuerystring2);

it('should convert email addresses to urls', function(testDone) {
new Metalsmith(__dirname)
Expand Down Expand Up @@ -63,6 +69,130 @@
})
.build(testDone);
});
it('should append the query string when given a string', function(testDone) {
new Metalsmith(__dirname)
.use(gravatar({
options: {
querystring: 's=200&r=pg'
},
avatars: {
test: testEmail
}
}))
.use(function(files, metalsmith, done) {
assert.equal(metalsmith.metadata().gravatar.options, undefined);
assert.equal(metalsmith.metadata().gravatar.emails, undefined);
assert.equal(metalsmith.metadata().gravatar.test, expectedWithQuerystring);
done();
})
.build(testDone);
});
it('should construct the query string when given an object', function(testDone) {
new Metalsmith(__dirname)
.use(gravatar({
options: {
querystring: {
s: 200,
r: 'pg'
}
},
avatars: {
test: testEmail
}
}))
.use(function(files, metalsmith, done) {
assert.equal(metalsmith.metadata().gravatar.options, undefined);
assert.equal(metalsmith.metadata().gravatar.emails, undefined);
assert.equal(metalsmith.metadata().gravatar.test, expectedWithQuerystring);
done();
})
.build(testDone);
});
});

describe('with individual user configurations', function() {
it('should convert a user object with email to url', function(testDone) {
new Metalsmith(__dirname)
.use(gravatar({
test: {
email: testEmail
}
}))
.use(function(files, metalsmith, done) {
assert.equal(metalsmith.metadata().gravatar.options, undefined);
assert.equal(metalsmith.metadata().gravatar.emails, undefined);
assert.equal(metalsmith.metadata().gravatar.test, expected);
done();
})
.build(testDone);
});

it('should convert a user object with email and query string to url with query string', function(testDone) {
new Metalsmith(__dirname)
.use(gravatar({
test: {
email: testEmail,
querystring: testQuerystring
}
}))
.use(function(files, metalsmith, done) {
assert.equal(metalsmith.metadata().gravatar.options, undefined);
assert.equal(metalsmith.metadata().gravatar.emails, undefined);
assert.equal(metalsmith.metadata().gravatar.test, expectedWithQuerystring);
done();
})
.build(testDone);
});

it('should convert a user object with email and query string object to url with query string', function(testDone) {
new Metalsmith(__dirname)
.use(gravatar({
test: {
email: testEmail,
querystring: {
s: 200,
r: 'pg'
}
}
}))
.use(function(files, metalsmith, done) {
assert.equal(metalsmith.metadata().gravatar.options, undefined);
assert.equal(metalsmith.metadata().gravatar.emails, undefined);
assert.equal(metalsmith.metadata().gravatar.test, expectedWithQuerystring);
done();
})
.build(testDone);
});

it('should take individual query string settings over general ones', function(testDone) {
new Metalsmith(__dirname)
.use(gravatar({
options: {
querystring: {
s: 200,
r: 'pg'
}
},
avatars: {
test: testEmail,
test2: {
email: testEmail2,
querystring: {
s: 400,
r: 'g'
}
}
}
}))
.use(function(files, metalsmith, done) {
assert.equal(metalsmith.metadata().gravatar.options, undefined);
assert.equal(metalsmith.metadata().gravatar.emails, undefined);
assert.equal(metalsmith.metadata().gravatar.test, expectedWithQuerystring);
assert.equal(metalsmith.metadata().gravatar.test2, expectedWithQuerystring2);
done();
})
.build(testDone);
});
});

describe('the protocol option', function() {
Expand Down