XML data feed import
-
I am developing a WordPress website and want the Post content to be populated by a live XML data feed. We have a local system which will supply a custom XML data feed of records. Each unique XML record will create a post with custom data. The XML feed will be updated regularly and so I imagine we will set up an hourly cron job to do an import of any new records or changes.
I am looking for advice from anyone who has set up something similar for WordPress. Where is the best place to start and are there any plugins worth utilizing or is this going to be a completely custom build job.
-
Also looking for this…anyone?
I too wanted to be able to do this, but couldn’t find anything. So I went to making my own plugin, despite having extremely limited PHP programming skills. Below is what I finally came up with that seems to work. Sorry for the length, I commented it heavily so you could see what I was doing. Like I said, I don’t know much about programming, so I apologize for the likely numerous bad practices – it also has no admin screen functionality so you’re stuck with editing the code itself to get what you want. When you’re done, save it to a php file and stick it in your plugins folder. Upon activation, it should create any posts from the uri you put in, and setup an hourly scheduled event to look for future posts. That’s all! I can’t guarantee it will work for you, and probably can’t help you if it doesn’t lol. But hopefully it will at least start you out.
<?php /* * Plugin Name: XML to WordPress Posts * Description: Creates posts automatically from an XML feed. * Author: Terry Hart * Plugin URI: https://www.freemarconi.com * Version: 1.0 * ======================================================================= */ /* The following code is probably not very pretty or efficient, but it's working * for me so far. I am not a PHP programmer! This took me forever to get going lol. * A lot is taken from the RSS_Import class in the WordPress core, much of the rest * from looking at other plugins and scouring the web for help. * I can't guarantee anything! But hopefully someone can get something out of the * days I spent getting this to work, especially since there doesn't seem to be * any existing plugins that do quite what this does yet. */ require_once(ABSPATH . '/wp-admin/includes/post.php'); require_once(ABSPATH . '/wp-admin/includes/taxonomy.php'); require_once(ABSPATH . '/wp-admin/includes/import.php'); if (!class_exists("xmltowp")) { class xmltowp { var $posts = array (); var $sxml; function xmltowp() { //constructor } function xmltowp_init() { $this->import(); } function get_posts() { global $wpdb; $xmluri = 'https://PUT YOUR FEED ADDRESS HERE'; $sxml = simplexml_load_file($xmluri); $index = 0; /* This next part depends on the schema of your XML * (Sorry if I didn't use those words correctly, I'm * not entirely sure what it means) And the format of the feed * For example, if you look at the XML from a Google * Calendars feed, you'll see xmlns:gd='https://schemas.google.com/g/2005' * at the top, and each entry is enclosed with <entry> tags. * The next two lines would be: * foreach ($sxml->entry as $entry) { * $gd = $entry->children('https://schemas.google.com/g/2005'); * * For my site, and the example below, I pulled an RSS feed, * so the next two lines differ to reflect the structure and schema of * that type of feed. */ foreach ($sxml->channel->item as $item) { $dc = $item->children('https://purl.org/dc/elements/1.1/'); /* Now you have to get all the information you want from the XML * document. The format depends on the XML tags used. * For plain tags - <TAG>, you would use the format * $string = $item->TAG; * (or $entry instead of $item depending on your schema/structure) * Some data is enclosed by <dc:TAG> (or <gd:TAG>) tags, * Those can be parsed by using * $string = $dc->TAG; * Finally, some data is in the tag itself, like * <enclosure url="https://ccmixter.org/content/4nsic/4nsic_-_Super_Heroes_(_Sol_Remix).mp3" length="3958953" type="audio/mpeg"></enclosure> * Parsing that requires something like * $string = $item->TAG->attributes()->ATTRIBUTE; * * For WordPress posts, you'll eventually need the following strings: * $post_author, $post_date, $post_date_gmt, $post_content, $post_title, $post_status, $guid, and $categories * First, let's get everything we want out of the XML itself, then we'll play with it a bit. * This is an example of what I wrote for my own site freemarconi.com. I uploaded vocal tracks * of our music to ccMixter.org. The site has an API that lets you pull an XML document showing * everyone who has remixed my tracks. I wanted to create a post for every remix made * and make it look pretty. Hopefully you get an idea of how this is working to make your * own plugin. */ $post_title = $item->title; //I'm taking the title exactly as it comes. You may want to process your own titles a bit for aesthetic reasons $guid = $item->link; //Also taken straight. I don't know what $guid is for, but I want the link for the post content $pubDate = $item->pubDate; //We'll process this into the two required date fields in a bit $post_content = $item->description; //This starts our post content out, we'll be playing with this later $creator = $dc->creator; //Extra field I want to add into the content $mp3file = $item->enclosure->attributes()->url; //Same //Get the date $post_date_gmt = strtotime($pubDate); $post_date_gmt = gmdate('Y-m-d H:i:s', $post_date_gmt); $post_date = get_date_from_gmt( $post_date_gmt ); /* I had a separate function that generated the category I wanted the post to appear in * which I didn't include here. If you don't have anything for categories it defaults to * uncategorized. If you want every post from the XML going to the same category, just * declare $categories as a string containing your category name. If the category doesn't * exist, WordPress will create it. */ $categories = $source_song; /* This is how I created the actual post content. Remember, I took the <description> from the * XML, which makes the bulk of what I want the post to say. The rest I set below in a number * of strings, which we'll piece together next. */ //Format the post content and add mp3 to Audio Player $post_content_title = '<p><a href="' . $guid . '" target="_blank">' . $post_title . '</a></p>'; $post_content_creator = '<p>By ' . $creator . '</p>'; $post_content_listen = '</p><p> [audio:'. $mp3file . '] </p>'; // Clean up content $post_content = preg_replace_callback('|<(/?[A-Z]+)|', create_function('$match', 'return "<" . strtolower($match[1]);'), $post_content); $post_content = str_replace('<br />', '<br />', $post_content); $post_content = str_replace('<hr>', '<hr />', $post_content); // I put all my content pieces together into $post_content $post_content = $post_content_title . $post_content_creator . $post_content . $post_content_listen; $post_author = 1; //This makes my posts show 'admin' as the author, which is fine for me. You might be able to use a variable or string here instead, I don't know how it works if the user doesn't exist in the WP Database yet though! $post_status = 'publish'; //I don't know the other statuses available, probably something like 'draft' etc. That would be good if you want a chance to review posts before they go live on your site $this->posts[$index] = compact('post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_title', 'post_status', 'guid', 'categories'); //And we have our array that the other functions will put into the posts table $index++; } } //Shouldn't have to change anything in these next two functions function import_posts() { foreach ($this->posts as $post) { extract($post); if ($post_id = post_exists($post_title, $post_content, $post_date)) { return; } else { $post_id = wp_insert_post($post); if ( is_wp_error( $post_id ) ) return $post_id; if (!$post_id) { return; } if (0 != count($categories)) wp_create_categories($categories, $post_id); } } } function import() { $file = $sxml; if ( isset($file['error']) ) { echo $file['error']; return; } $this->file = $file['file']; $this->get_posts(); $result = $this->import_posts(); if ( is_wp_error( $result ) ) return $result; wp_import_cleanup($file['id']); do_action('import_done', 'rss'); } } } if (class_exists("xmltowp")) { $xmltowp_plugin = new xmltowp(); } //Actions and Filters if (isset($xmltowp_plugin)) { //Actions register_activation_hook( __FILE__, array(&$xmltowp_plugin, 'xmltowp_init' )); if (!wp_next_scheduled('xmlschedule_hook')) { wp_schedule_event( time(), 'hourly', 'xmlschedule_hook' ); //Besides 'hourly', you can also schedule 'daily' or 'twicedaily'. } add_action( 'xmlschedule_hook', array(&$xmltowp_plugin, 'xmltowp_init' )); //I don't have a deactivation hook to remove the scheduled event, boh! } ?>
hey freemarconi do you have finally found a way to improve your plug ins ?
The plugin doesn’t seem to be working for my blog.
I have roughly a thousand posts I need to generate from a live XML feed and the tags vary from the wordpress standard. For instance
title = long_name
pubdate = created_at
category = group_typeHow do I make these changes? And does the plugin automatically generate the posts once the .php file is properly in order?
So far I listed the strings like so
$post_title = $item->long_name;
$pubDate = $item->created_at;
$categories = $item->group_type;Is that right?
And if I wanted to add additional fields how would I go about creating those strings properly and have them displayed in the content area?
Any help would be helpful
Hey Free Marconi,
I get the following message when I activate the plugin:
Plugin could not be acivated because it triggered a fatal error:
Fatal error: Call to undefined method xmltowp::import() in E:\websites\home\wp-content\plugins\xmltowp.php on line 33
line 32: function xmltowp_init() {
line 33: $this->import();Any ideas?
Did this ever get fixed ?
Benjamin
- The topic ‘XML data feed import’ is closed to new replies.