Drupal FeedAPI and FeedAPI mapper notes
Contents |
Configuration
- Install FeedAPI and Feed Element Mapper into the appropriate modules directory.
- Download Simple Pie unzip and place simplepie.inc file into feedapi/parser_simplepie directory (you don't need any of the other files).
- In administer > site building > modules, enable FeedAPI Inherit, FeedAPI Mapper, FeedAPI, FeedAPI Node, SimplePie parser (and if you use Views, FeedAPI Node Views)
Note: The Common syndication parser does not parse enough into the object to be able to get many custom elements. You either need to use SimplePie or write your own parser.
Development Notes
Enclosures
feedapi/parser_simplepie doesn't offer up enclosures separately in a useful way to the feedapi object so that feedapi_mapper can filter the information or so individual mappers can reliably get to the information.
An example (removing all non-enclosure related info) the info about just an image from the first post at the moment in http://bristol.indymedia.org/atomfullposts.xml and http://bristol.indymedia.org/rssfullposts.xml
<pre>
[0] => stdClass Object
(
[options] => stdClass Object
(
[raw] => Array
(
[child] => Array
(
[1] => Array
(
[link] => Array
(
[1] => Array
(
[data] =>
[attribs] => Array
(
[] => Array
(
[rel] => enclosure
[href] => http://www.bristol.indymedia.org/attachments/feb2008/p12491.jpg
[title] => p12491.jpg
[length] => 68603
[type] => image/jpeg
)
)
[xml_base] =>
[xml_base_explicit] =>
[xml_lang] => en
)
)
)
)
[links] => Array
(
[enclosure] => Array
(
[0] => http://www.bristol.indymedia.org/attachments/feb2008/p12491.jpg
[1] => http://www.bristol.indymedia.org/attachments/feb2008/ccac_trade_union_conference1.pdf
)
[2] => Array ( [0] => http://www.bristol.indymedia.org/article/687856 )
[3] => Array ( [0] => http://www.bristol.indymedia.org/attachments/feb2008/p12491.jpg [1] => http://www.bristol.indymedia.org/attachments/feb2008/ccac_trade_union_conference1.pdf )
)
)
)
)
</pre>
<pre>
[0] => stdClass Object
(
[options] => stdClass Object
(
[raw] => Array
(
[child] => Array
(
[] => Array
(
[link] => Array
(
)
[enclosure] => Array
(
[0] => Array
(
[data] =>
[attribs] => Array
(
[] => Array
(
[url] => http://www.bristol.indymedia.org/attachments/feb2008/p12491.jpg
[length] => 68603
[type] => image/jpeg
)
)
[xml_base] =>
[xml_base_explicit] =>
[xml_lang] =>
)
)
)
)
[links] => Array
(
[alternate] => Array
(
[0] => http://www.bristol.indymedia.org/article/687856
)
[4] => Array ( [0] => http://www.bristol.indymedia.org/article/687856 )
)
[date] => Array
(
[raw] => Sun, 03 Feb 2008 21:36:33 +0000
[parsed] => 1202074593
)
)
)
)
</pre>
Adding full details about all possible enclosures at the feedapi parser level would
- repeat work created by simplepie
- but allow for an abstracted common set of methods with future other parsers
- alternatively the simplepie could be the standard till it breaks in 2.0 :)
Passing the simplepie object allows each element mapper to analyse the specific metadata it needs. The parser already passes on the SimplePie author object.
The SimplePie Enclosure object for both of the above looks like
When passing the objects it is better for feedapi_mapper to be able to have the choice to separate by mime type. Present solution a mixture of arrays and objects :-(
But for both above feeds you get:
<pre>
[0] => stdClass Object
(
[options] => stdClass Object
(
[enclosures] => Array
(
[image] => Array
(
[jpeg] => Array
(
[0] => SimplePie_Enclosure Object
(
[bitrate] =>
[captions] =>
[categories] =>
[channels] =>
[copyright] =>
[credits] =>
[description] =>
[duration] =>
[expression] =>
[framerate] =>
[handler] =>
[hashes] =>
[height] =>
[javascript] => js
[keywords] =>
[lang] =>
[length] => 68603
[link] => http://www.bristol.indymedia.org/attachments/feb2008/p12491.jpg
[medium] =>
[player] =>
[ratings] =>
[restrictions] =>
[samplingrate] =>
[thumbnails] =>
[title] =>
[type] => image/jpeg
[width] =>
)
)
)
</pre>
For feedapi_mapper useful to have type as often this will be covered by one field. kid carrier However there will be exceptions - torrents for example and lots of the 'application' types. Messy but a 'all of' or 'all of not assigned' field?
For feedapi_mapper what about defaults for common mime-types not in the feed.
The quick patch to get the enclosures there is
<pre> Index: contributions/modules/feedapi/parser_simplepie/parser_simplepie.module
=======================================================
RCS file: /cvs/drupal-contrib/contributions/modules/feedapi/parser_simplepie/parser_simplepie.module,v retrieving revision 1.6.2.18 diff -u -p -r1.6.2.18 parser_simplepie.module --- contributions/modules/feedapi/parser_simplepie/parser_simplepie.module 23 Jan 2008 19:06:37 -0000 1.6.2.18 +++ contributions/modules/feedapi/parser_simplepie/parser_simplepie.module 3 Feb 2008 23:46:02 -0000 @@ -136,6 +136,15 @@ function _parser_simplepie_feedapi_parse
$curr_item->options->timestamp = $simplepie_item->get_date("U");
$curr_item->options->guid = $simplepie_item->get_id();
$curr_item->options->original_author = $simplepie_item->get_author();
+ // Enclosures + $enclosures = $simplepie_item->get_enclosures(); + foreach ($enclosures as $enclosure) { + $mime = $enclosure->get_real_type(); + if ($mime != ) { + list($type, $subtype) = split('/', $mime); + $curr_item->options->enclosures[$type][$subtype][] = $enclosure; + } + }
// Extract tags related to the item
$simplepie_tags = $simplepie_item->get_categories();
$tags = array();
</pre>
this is now Feature request http://drupal.org/node/217750
FeedAPI_mapper -> Embeded Media Field
Using above. Enabled sending video through to the video_cck field \o/ so video feed enclosure links are automatically correctly embeded \o/
<pre> <?php // $Id$
/**
* Implementation of hook_feedapi_mapper for video_cck part of embedded media CCK. * * @param string $op * @param Drupal node $node * @param string $field_name * @param string, number or array of string or number $feed_element * @param string or number as id $sub_field * */
function video_cck_feedapi_mapper($op, $node, $field_name, $feed_element = array(), $sub_field = ) {
$field = content_fields($field_name);
if ($field['type'] != 'video_cck') {
// if not a video_cck field just return
return;
}
switch ($op) {
case 'describe':
// Describe what we are doing in this mapper. This shows up as help text on the mapping page.
return t('Maps a link to a video to the Embeded Media Video CCK field.');
case 'list':
// just for sub_fields
return TRUE;
case 'map':
// Here is where the actual mapping happens.
$items = $node->$field_name; // $field -> $items
foreach ($feed_element as $element) {
$items[]['embed'] = $element['link'];
}
// validation - missing in original - what happens with a poisoned feed?
video_cck_field('submit', $node, $field, $items, FALSE, FALSE);
$node->$field_name = $items;
return $node;
}
} </pre>