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
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();
