-
Notifications
You must be signed in to change notification settings - Fork 2
Update ogp.js to support any Open Graph namespace/prefixes. #1
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
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -23,35 +23,43 @@ var jsdom = require('jsdom'), | |
| url = 'http://www.imdb.com/title/tt0068646/' | ||
|
|
||
| jsdom.env({ html: url, done: function(error, window) { | ||
|
|
||
| // 3. pass window as the only argument to ogp.parse method | ||
| var ogData = ogp.parse(window) | ||
|
|
||
| // 5. Profit! | ||
| console.log('Open Graph data', ogData) | ||
| // 3. pass window as the only argument to ogp.parse method | ||
| var ogData = ogp.parse(window) | ||
|
|
||
| // ogp.parse can also parse Open Graph properties for any namespaces desired. | ||
| // | ||
| // To match og and fb namespaces the following could be done: | ||
| // var ogData = ogp.parse(window, 'og fb') | ||
| // or: | ||
| // var ogData = ogp.parse(wondow, ['og', 'fb']) | ||
|
|
||
| // 5. Profit! | ||
| console.log('Open Graph data', ogData) | ||
| }}) | ||
| ``` | ||
|
|
||
| This will put next structure into stdout: | ||
|
|
||
| ```javascript | ||
| { url: 'http://www.imdb.com/title/tt0068646/', | ||
| title: 'The Godfather (1972)', | ||
| type: 'video.movie', | ||
| image: 'http://ia.media-imdb.com/images/M/MV5BMTIyMTIxNjI5NF5BMl5BanBnXkFtZTcwNzQzNDM5MQ@@._V1._SX97_SY140_.jpg', | ||
| site_name: 'IMDb' } | ||
| { 'og:url': 'http://www.imdb.com/title/tt0068646/', | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Updated to show namespaced results. |
||
| 'og:title': 'The Godfather (1972)', | ||
| 'og:type': 'video.movie', | ||
| 'og:image': 'http://ia.media-imdb.com/images/M/MV5BMTIyMTIxNjI5NF5BMl5BanBnXkFtZTcwNzQzNDM5MQ@@._V1._SX97_SY140_.jpg', | ||
| 'og:site_name': 'IMDb' } | ||
| ``` | ||
|
|
||
| In case if some of OpenGraph tags were presented multiple times (few image tags for example, output structure field related to that tag will be converted into array: | ||
|
|
||
| ```javascript | ||
| { image: ['image1.png', 'image2.png']} | ||
| { 'og:image': ['image1.png', 'image2.png']} | ||
| ``` | ||
|
|
||
| ## Credits | ||
|
|
||
| Written and maintained by [Yury Proshchenko](mailto:spect.man@gmail.com). | ||
|
|
||
| Multiple namespace support by [Cody Craven](http://github.com/codycraven). | ||
|
|
||
| ## License | ||
|
|
||
| The MIT License | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,35 +1,44 @@ | ||
| exports.parse = function(window) { | ||
| var ns | ||
| for (var i = 0; i < window.document.documentElement.attributes.length; ++i) { | ||
| var attr = window.document.documentElement.attributes[i] | ||
| if (attr.nodeValue.toLowerCase() !== 'http://opengraphprotocol.org/schema/') continue | ||
|
|
||
| ns = attr.nodeName.substring(6) | ||
| if (ns) break | ||
| } | ||
|
|
||
| if (!ns) return {} | ||
|
|
||
| var result = {}, | ||
| metaTags = window.document.getElementsByTagName('meta') | ||
|
|
||
| for (var i = 0; i < metaTags.length; ++i) { | ||
| var tag = metaTags[i], | ||
| propertyAttr = tag.attributes['property'] | ||
|
|
||
| if (!propertyAttr || propertyAttr.nodeValue.substring(0, ns.length) !== ns) | ||
| continue | ||
|
|
||
| var property = tag.attributes['property'].nodeValue.substring(ns.length+1), | ||
| content = tag.attributes['content'].nodeValue | ||
|
|
||
| if (!result[property]) | ||
| result[property] = content | ||
| else if (result[property].push) | ||
| result[property].push(content) | ||
| else | ||
| result[property] = [result[property], content] | ||
| } | ||
|
|
||
| return result | ||
| exports.parse = function(window, namespaces) { | ||
| var result = {}, | ||
| metaTags = window.document.getElementsByTagName('meta'), | ||
| propertyRegex = /^([a-z]+):/; | ||
|
|
||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This namespace prefix declaration does not match current http://ogp.me/ specifications and as such prevented the script from working on Open Graph valid pages. I removed this requirement all together as I know of at least three different implementations the Open Graph protocol has declared. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. whey don't keep this check and just add conditional for new namespace? |
||
| // If undefined set as "og" namespace (OGP default). | ||
| if (!namespaces) | ||
| namespaces = ['og']; | ||
| // If string convert to an array, accepts comma separated. | ||
| else if (typeof namespaces === 'string') { | ||
| namespaces = namespaces.split(' '); | ||
| } | ||
|
|
||
| for (var i = 0; i < metaTags.length; ++i) { | ||
| var tag = metaTags[i], | ||
| propertyAttr = tag.attributes['property'] | ||
|
|
||
| // All OG meta tags contain property attribute. | ||
| if (!propertyAttr) { | ||
| continue | ||
| } | ||
| else { | ||
| var matches = propertyRegex.exec(propertyAttr.nodeValue); | ||
| // Verify OG property is found in our acceptable namespaces. | ||
| if (!matches[1] || namespaces.indexOf(matches[1]) == -1) | ||
| continue | ||
| } | ||
|
|
||
| var property = tag.attributes['property'].nodeValue, | ||
| content = tag.attributes['content'].nodeValue | ||
|
|
||
| // If the property does not already exist, assign it. | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I kept the results as close to the prior script's results as possible, except og namespaced properties now include "og:' such as 'og:title'. |
||
| if (!result[property]) | ||
| result[property] = content | ||
| // Else if result[property] is already an array then push it. | ||
| else if (result[property].push) | ||
| result[property].push(content) | ||
| // Else convert string to array. | ||
| else | ||
| result[property] = [result[property], content] | ||
| } | ||
|
|
||
| return result | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,10 +1,11 @@ | ||
| { | ||
| "name": "ogp", | ||
| "description": "Parse Open Graph meta tags from jsdom generated DOM", | ||
| "version": "0.0.2", | ||
| "version": "1.0.0", | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Updated major revision since results of parse would break existing implementations due to multiple namespace/prefix support. |
||
| "author": "Yury Proshchenko <spect.man@gmail.com>", | ||
| "contributors": [ | ||
| { "name": "Yury Proshchenko", "email": "spect.man@gmail.com" } | ||
| { "name": "Yury Proshchenko", "email": "spect.man@gmail.com" }, | ||
| { "name": "Cody Craven", "email": "cody@cravencode.com", "url": "https://github.com/codycraven" } | ||
| ], | ||
| "keywords": ["open graph", "opengraph", "ogp"], | ||
| "main": "./lib/ogp.js", | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If namespaces argument omitted then 'og' will be default.