wiki:UsingFeedsInCode

Having identified which feed to use, it is then very easy to make use of this feed data in your applications.

Below, we hope to present example code for using OpenGuides RSS feeds in a number of common web application programming languages.

Examples

  1. PHP
  2. Ruby On Rails
  3. ColdFusion
  4. Django (Python)
  5. JavaScript

PHP

An example for outputting the title and summary from the recent changes list follows.

<?php
$want_array = array(
   "TITLE"    => "Title",
   "SUMMARY"  => "Summary"
);
$feed = "http://cotswolds.openguides.org/wiki/wiki.cgi?action=rc;format=atom";

$tag_text = "";
function startElement($parser, $name, $attrs)
{
}

function endElement($parser, $name)
{
   global $want_array;
   global $tag_text;
   if (isset($want_array[$name])) {
       echo "<b>$want_array[$name]:</b> $tag_text<br />";
   }
}

function characterData($parser, $data)
{
   global $tag_text;
   $tag_text = $data;
}

// Grab feed
$curl = curl_init($feed);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$data = curl_exec($curl);

// Run parser
$xml_parser = xml_parser_create();
xml_set_element_handler($xml_parser, "startElement", "endElement");
xml_set_character_data_handler($xml_parser, "characterData");

if (!xml_parse($xml_parser, $data)) {
  die(sprintf("XML error: %s at line %d",
                           xml_error_string(xml_get_error_code($xml_parser)),
                           xml_get_current_line_number($xml_parser)));
}
xml_parser_free($xml_parser);
?>

Ruby On Rails

An example for grabbing the nodes in a Locale, and outputting the nodes titles and links follows.

require 'rexml/document'
require 'open-uri'
include REXML

class LocalIndexController < ApplicationController

def showindex
    feed_url = 'http://cotswolds.openguides.org/wiki/wiki.cgi?action=index;index_type=locale;index_value=Charlbury;format=rss'
    output = "<h1>My RSS Reader</h1>" 
    open(feed_url) do |http|
        response = http.read
        doc = Document.new(response)

        title = doc.root.elements["//title"].text
        puts title

        output += "<h2>Title: #{title}</h2><div>" 

        i = 0
        doc.each_element("//item") do |node|
            node_title = node.elements["title"].text
            node_link = node.elements["link"].text

            output += "#{i+1}. <a href='#{node_link}'>#{node_title}</a><br />"
            i = i + 1
        end

        output += "</div>"
    end
    render_text output
end
end

This should be added to routes.rb something like:

   map.connect '/nodesInLocale', :controller => "localeIndex", :action => 'showindex'

ColdFusion

An example for grabbing the RDF of a node, and outputting the node's title and OS x and y co-ordinates follows.

<cfsilent>
    <!--- Grab the RDF of a given Node --->
    <!--- Then, parse it, and pull out interesting things --->

    <!--- The URL of the RDF to fetch --->
    <cfset rdf_url = "http://cotswolds.openguides.org/wiki/wiki.cgi?id=The_Royal_Oak%2C_Ramsden;format=rdf">

    <!--- Grab our RDF, and load it into the XML parser --->
    <cfhttp url="#rdf_url#" method="get">
    <cfif left(cfhttp.statusCode,3) EQ "200" OR left(cfhttp.statusCode,3) EQ "304">
        <cfset raw_xml = cfhttp.fileContent>
        <cfset xml = XmlParse(raw_xml).xmlRoot>

        <!--- Grab the rdf:Description and geo:SpatialThing tags --->
        <cfset rdf = "">
        <cfset geo_spatial = "">
        <cfscript>
            for(i = 1; i LTE ArrayLen(xml.XmlChildren); i = i+1) {
                if(xml.XmlChildren[i].XmlName EQ "rdf:description") {
                    rdf = xml.XmlChildren[i];
                }
                if(xml.XmlChildren[i].XmlName EQ "geo:SpatialThing") {
                    geo_spatial = xml.XmlChildren[i];
                }
            }
        </cfscript>

        <!--- Now pull out the title, and OS co-ordinates --->
        <!--- For that, we want dc:title and os:x / os:y --->
        <cfset dc_title = "">
        <cfif rdf NEQ "">
            <cfscript>
                for(i = 1; i LTE ArrayLen(rdf.XmlChildren); i = i+1) {
                    if(rdf.XmlChildren[i].XmlName EQ "dc:title") {
                        dc_title = rdf.XmlChildren[i].xmlText;
                    }
                }
            </cfscript>
        </cfif>

        <cfset os_x = "">
        <cfset os_y = "">
        <cfif geo_spatial NEQ "">
            <cfscript>
                for(i = 1; i LTE ArrayLen(geo_spatial.XmlChildren); i = i+1) {
                    if(geo_spatial.XmlChildren[i].XmlName EQ "os:x") {
                        os_x = geo_spatial.XmlChildren[i].xmlText;
                    }
                    if(geo_spatial.XmlChildren[i].XmlName EQ "os:y") {
                        os_y = geo_spatial.XmlChildren[i].xmlText;
                    }
                }
            </cfscript>
        </cfif>
    </cfif>
</cfsilent>

<!--- Now make use of these --->
<cfoutput><p>#dc_title# is at OS #os_x#:#os_y#</p></cfoutput>

Django (Python)

An example for grabbing the nodes in a Category, and outputting the nodes titles, links and lat+long follows.

Note: this assumes an app called og has been set up

in og/models/og.py, have this:

from django.core import meta

# Class to return the Atom stuff
class ogatom(meta.Model):
    def __repr__(self): return "An OpenGuides Atom parser"

    # Test method
    def _module_hello():
        return "hello"
    def _module_get_entries():
        from xml.dom import minidom
        from xml.dom import EMPTY_NAMESPACE
        import urllib

        # Grab the feed
        url = "http://cotswolds.openguides.org/wiki/wiki.cgi?action=index;index_type=category;index_value=Pubs;format=atom"
        contents = urllib.urlopen(url)

        # XML Parse
        doc = minidom.parse(contents)
        doc.normalize()

        # Grab out interesting bits
        main_title = doc.getElementsByTagName(u"title")[0].firstChild.data
        entries_xml = doc.getElementsByTagName(u"entry")

        # We want title, link, and geo
        entries = []
        for entry in entries_xml:
            title = entry.getElementsByTagName(u"title")[0].firstChild.data
            link_tag = entry.getElementsByTagName(u"link")[0]
            link = link_tag.getAttribute(u"href")
            e = { 'title': title, 'link':link }

            lat_tags = entry.getElementsByTagName("geo:lat")
            long_tags = entry.getElementsByTagName("geo:long")
            if len(lat_tags) > 0:
                e['lat'] = lat_tags[0].firstChild.data
            if len(long_tags) > 0:
                e['long'] = long_tags[0].firstChild.data
            entries.append(e)

        return entries

and in og/views.py have this:

# Pre 0.90
from django.utils.httpwrappers import HttpResponse
# 0.90 onwards
#from django.http import HttpResponse

from django.models import og

def index(request):
    entries = og.ogatoms.get_entries()
    content = "<h1>Entries from feed:</h1>\n"
    for entry in entries:
        content += "<div>\n"
        content += "<b><a href='%s'>%s</a></b>\n" % (entry['link'],entry['title'])
        if entry.has_key("lat"):
            content += "<br /><span style='margin-left: 20px'>Latitude: %s</span
" % entry['lat']
        if entry.has_key("long"):
            content += "<br /><span style='margin-left: 20px'>Longitude: %s</span" % entry['long']
        content += "</div>\n"
    return HttpResponse(content)

Finally wire up in urls.py

JavaScript

Note that the JavaScript will either need to come from the same server as the feed, or be running with the browser granting it extra security rights, otherwise you'll get a security exception when you try to request something off another server.

An example for pulling out titles and modified dates from the recent changes RSS feed, and chucking them into a paragraph with the id "data" follows.

// This will fetch the Recent Changes RSS from an OpenGuide on the
//  same server as the script. 
// It will then output the node title and modified date, into a
//  paragraph on the page with id "data"
// You will need to ensure that there is:
//      <p id="data" />
// Already on the page before calling this
var feed_url = "/og-wiki/wiki.cgi?action=rc;format=rss";

function go() {
    // Get a XMLHttpRequest Object
    var xmlhttp = false;
    if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
        xmlhttp = new XMLHttpRequest();
    } else {
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }

    // Use it
    if(xmlhttp) {
        xmlhttp.open("GET", feed_url, false);
        xmlhttp.send(null);

        var status = xmlhttp.status;
        var p = document.getElementById("data");

        if(status == 200 || status == 304 || status == 0 || status == null) {
            // Bingo, we have the feed
            var feed = xmlhttp.responseXML;

            // Go find the individual item entries
            var items = feed.getElementsByTagName("item");

            // Loop over the items, getting the titles and dates out
            for(var i=0; i<items.length; i++) {
                var item = items[i];
                var ic = item.childNodes;

                var title;
                var date;
                for(var j=0; j<ic.length; j++) {
                    var tag = ic[j];
                    if(tag.nodeType == Node.ELEMENT_NODE) {
                        if(tag.tagName == "title") {
                            title = tag;
                        }
                        if(tag.tagName == "dc:date") {
                            date = tag;
                        }
                    }
                }

                // Add a div with the title and date
                var sub_div = document.createElement("div");
                sub_div.appendChild(document.createTextNode(
                    title.firstChild.nodeValue + " - modified " + date.firstChild.nodeValue
                ));
                p.appendChild(sub_div);
            }
        } else {
            var text = "Error code " + status;
            p.appendChild(document.createTextNode(text));
        }
    }
}
go();
Last modified 11 years ago Last modified on Jul 20, 2006, 5:59:46 PM