-
Notifications
You must be signed in to change notification settings - Fork 303
Writing a plugin
- TODO Plugin structure
- TODO plugin.getLink(s)
- plugin.getMeta
- TODO plugin.getData
- TODO plugin.mixins
- TODO plugin.tests
- TODO Type of plugins
- TODO Generic plugins
- TODO Meta plugins
- TODO Domain plugins
- TODO Custom plugins
- TODO Template plugins
- TODO Generic plugins
- TODO Custom links cases
Terms
- plugin - node.js module.
- plugin method - function in that plugin.
- plugin method requirements - named params of that function.
- URI - page URI on wich iframely search links and meta.
Plugins are node.js modules with attributes and functions defined by iframely engine:
- mixins - list of plugins' to use with domain plugin. Plugins identified by its file name without extension and path.
- re - list or single RegExp for testing page URI.
- getLink - method to generate link.
- getLinks - method to generate links array.
- getMeta - method to create page unified meta.
- getData - this method generates data, which can be used by other plugins and methods (getMeta, getLink(s) and getData).
- tests - array of test urls to test plugin work. This is not used yet.
- lowestPriority - marks plugin's getMeta method with low priority.
- highestPriority - marks plugin's getMeta method with highest priority.
TODO: add links to sections
Main work is done by plugins' methods getMeta, getLink(s) and getData. These methods work similar but returns different kind of objects (hashes). Each method has a number of params, called requirements. For example:
getLink: function(meta, oembed) {
return {
title: oembed.title,
description: meta.description
};
}
getLink
uses meta and oembed params, so they are method's requirements.
Iframely engine know that by parsing module code and provides that parameters when method is called. If some requirements are not available, method will not be called. This means all defined method params ara mandatory requirements. Here is the list of all available default requirements:
- urlMatch - variable got after matching page URI against re RegExpes attribute of plugin. This is available only if domain plugin which has re attribute is used.
- url - page URI itself.
- request - known request module, wrapped with caching (caching not implemented yet). This is useful to call some external APIs' methods.
- meta - parsed paged meta head. You can see how page meta is parsed in debugger, "Plugins context" section.
- oembed - parsed oembed 1.0 (if available for page).
- html - entire page response decoded to UTF-8.
-
$selector - jquery wrapper of page. Useful for fast accessing some page data by element class, e.g.
$selector('.item').text()
. - cb - this is result callback. If method requires cb - it means method is asynchronous. Engine will wait calling of cb. Without cb - method must return object synchronously.
Plugin can provide custom requirements using getData method. See plugin.getData for details.
Here is engine algorithm to work with plugins:
- Extract URI domain (e.g.
example.com
). - Find suitable domain plugins for that URI.
- If domain plugins found:
- Check if domain plugins has re attribute.
- If true:
- Match all RegExp'es against URI and create urlMatch variable.
- Use only plugins with matched res.
- If no matched plugins found - use domain plugins without re.
- If all plugins has re and no matches found - use all generic plugins.
- If false:
- Use all domain plugins.
- If true:
- Check if domain plugins has re attribute.
- If suitable domain plugins not found:
- Use all generic plugins.
- If domain plugins found:
- Find methods of selected plugins to call:
- Iterate all used plugins:
- Itarate all plugin methods:
- If method has only default requirements (see list below) - use it.
- If method has custom requirements (provided by some getData method) - skip it.
- Itarate all plugin methods:
- Iterate all used plugins:
- Load page by URI and get all required variables (meta, oembed, html etc.). If no requirements - page will not be loaded.
- Go through all selected (used) methods. 2. Call method with selected params. 3. Wait for cb called if method is asynchronous or get result immediately. 4. Store received result or error.
- Find methods with custom requirements which can be called with received data (from previous step).
- If methods found - go to step 5.
- Extract all links from saved data:
- Generate info for links with type: "x-safe-html"
- Generate info for links with custom render
- Calculate images sizes and type if not provided.
- Filter links without
href
. - Resolve href to URI (if relative path provided).
- Skip duplicate links (by
href
). - Combine
http://
andhttps://
similar links to one without protocol//
.
- Merge all meta to single object (data from highest priority plugins will override others).
- Return links and meta.
getMeta
function allow plugin to provide some page meta attributes.
Look at all meta plugins at: /plugins/generic/meta.
Names of attributes should be unified. Do not created different forms of one attribute name, like author_url
and author-url
.
See available attributes names to check if similar name exists at /meta-mappings.
Warging! As meta-mappings generated using regexp modules parsing, all attributes should be described in specific form:
- each attribute should be declared in separate line;
- no other functions with
return
are not expected insidegetMeta
function.
See example /generic/meta/video.js:
module.exports = {
getMeta: function(meta) {
// This prevents non useful errors loging with "undefined".
if (!meta.video)
return;
return {
duration: meta.video.duration, // This will extract video duration.
date: meta.video.release_date, // If value is undefined - it will be removed from meta.
author: meta.video.writer,
keywords: meta.video.tag
};
}
};
Some plugins may return same meta attributes. This is possible if one attribute is described using different semantics.
It happens that values of these attributes are different. We know some semantics are better then other.
For example: html <title>
tag often provides page title with site name, which is not really part of content title.
But og:title
usually better and contains only article title without site name.
If you want to mark you plugin as worst source of meta (like html <title>
tag), use lowestPriority: true
:
module.exports = {
lowestPriority: true
}
If you want to mark your plugin as good source of meta (like og:title), use highestPriority: true
:
module.exports = {
highestPriority: true
}
So resulting priority of meta plugins will be following:
- plugins with
highestPriority: true
will override all others plugins meta data. - meta from plugins without priority mark will override only
lowestPriority: true
plugins meta data. - data from plugins with
lowestPriority: true
will be used only if no other plugin provides that meta data.
Example:
tests: [
{
feed: "http://gdata.youtube.com/feeds/api/videos"
},
{
pageWithFeed: "http://www.businessinsider.com/"
},
{
page: "http://500px.com/upcoming",
selector: ".title a",
getUrl: function(url) {
return url.indexOf('ok') > -1 ? url : null;
}
},
{
skipMixins: ["og-title"],
skipMethods: ["getLink"]
},
"http://www.youtube.com/watch?v=etDRmrB9Css"
]
Feeds:
-
feed
- rss/atom feed of links to test. -
pageWithFeed
- "home" page with rss/atom link in page header, feed will be looked for links to test. -
page
andselector
- jquery selector on page to finda
elements withhref
attribute with links to test. -
getUrl
- this function allows to change or mark feed url as not usable by returningnull
.
Testing directives:
-
skipMethods
- array of non mandatory plugin methods. If method will not return data - it will be test warting, not error. Exceptions will raise error as usual. -
skipMixins
- same as previous, but with mixin methods.
If you have test urls but there are no test feeds, specify following to prevent test warnings:
tests: [
{
noFeeds: true
},
"http://www.youtube.com/watch?v=etDRmrB9Css"
]
If there are no any test urls, write:
tests: {
noTest: true
}
Provides unified meta attributes mapping.
You can find current unified meta attributes mapping on http://dev.iframe.ly/meta-mappings.
Here is description of data:
{
"attributes": [ -- List of all supported attributes in alphabetic order.
"author",
"author_url",
...
],
"sources": { -- Object with each attribute source.
"author": [
{
"pluginId": "twitter-author", -- Plugin in which meta attribute is defined.
"source": "meta.twitter.creator" -- Part of that plugin code which returns meta attribute value.
},
...
],
...
}
}
Meta attributes provided by plugins getMeta method.
Endpoint for article rendering scripts.
Method: GET
Params:
-
uri
- page uri to be processed.
Returns: JavaScript widget to render article.
This is behind scenes endpoint. It is not directly used by developer.
Link to endpoint is automatically generated for internal MIME type "text/x-safe-html"
.
See x-safe-html for details.
Endpoint will return JavaScript widget to embed it with <script>
tag.
Embedding will be completed by iframely.js lib.
Endpoint to cusrom rendered widgets.
Method: GET
Params:
-
uri
- page uri to be processed.
Returns: html page with widget.
This is behind scenes endpoint. It is not directly used by developer.
Link to endpoint is automatically generated for internal MIME type "text/html"
with template_context
or template
attributes provided by plugin.
See rendering templates for details.
Result will be embedded with <iframe>
. Embedding and resizing will be completed by iframely.js lib.