* Make OPAC URLs absolute (needs refinement to respect locale/skin)
* Push datetime creation down to the feed and item level
* Atom:
* Merge summary fields into a single element
* RSS2:
* Generate a channel/description field
* Merge item/description fields into a single element
* Use RFC-822 dates (adds DateTime::Format::Mail as a prerequisite)
* Set guid isPermaLink attribute false as we're using tag: URIs
* Place alternate link elements in the xhtml namespace
* Generate a link element with no attributes
git-svn-id: svn://svn.open-ils.org/ILS/trunk@9950
dcc99617-32d9-48b4-a31d-
7c20da2025e4
libclass-dbi-abstractsearch-perl\
libtemplate-perl\
libtext-aspell-perl\
+ libdatetime-format-mail-perl\
libdatetime-timezone-perl\
libdatetime-perl\
libunix-syslog-perl\
$feed->root($root);
$feed->creator($host);
- $feed->update_ts(gmtime_ISO8601());
+ $feed->update_ts();
$feed->link( unapi => $base) if ($flesh_feed);
print "Content-type: ". $feed->type ."; charset=utf-8\n\n";
$feed->root($root);
$feed->creator($host);
- $feed->update_ts(gmtime_ISO8601());
+
+ $feed->update_ts();
+
$feed->link( unapi => $base) if ($flesh_feed);
print "Content-type: ". $feed->type ."; charset=utf-8\n\n";
$feed->title("Items in Book Bag [".$bucket->name."]");
$feed->creator($host);
- $feed->update_ts(gmtime_ISO8601());
+ $feed->update_ts();
$feed->link(alternate => $base . "/rss2-full/$id" => 'application/rss+xml');
$feed->link(atom => $base . "/atom-full/$id" => 'application/atom+xml');
$feed->link(
OPAC =>
- '/opac/en-US/skin/default/xml/rresult.xml?rt=list&' .
+ $host . '/opac/en-US/skin/default/xml/rresult.xml?rt=list&' .
join('&', map { 'rl=' . $_->target_biblio_record_entry } @{$bucket->items} ),
'text/html'
);
}
$feed->creator($host);
- $feed->update_ts(gmtime_ISO8601());
+ $feed->update_ts();
$feed->link(alternate => $base . "/rss2-full/$rtype/$axis/$limit/$date" => 'application/rss+xml');
$feed->link(atom => $base . "/atom-full/$rtype/$axis/$limit/$date" => 'application/atom+xml');
$feed->link(
OPAC =>
- '/opac/en-US/skin/default/xml/rresult.xml?rt=list&' .
+ $host . '/opac/en-US/skin/default/xml/rresult.xml?rt=list&' .
join('&', map { 'rl=' . $_} @$list ),
'text/html'
);
$feed->title("Search results for [$terms] at ".$org_unit->[0]->name);
$feed->creator($host);
- $feed->update_ts(gmtime_ISO8601());
+ $feed->update_ts();
$feed->_create_node(
$feed->{item_xpath},
use XML::LibXSLT;
use OpenSRF::Utils::SettingsClient;
use CGI;
+use DateTime;
+use DateTime::Format::Mail;
+
sub exists {
my $class = shift;
package OpenILS::WWW::SuperCat::Feed::atom;
use base 'OpenILS::WWW::SuperCat::Feed';
+use OpenSRF::Utils qw/:datetime/;
sub new {
my $class = shift;
sub update_ts {
my $self = shift;
- my $text = shift;
+ # ATOM demands RFC-3339 compliant datetime formats
+ my $text = shift || gmtime_ISO8601();
$self->_create_node($self->{item_xpath},'http://www.w3.org/2005/Atom','updated', $text);
}
my $self = shift;
my $text = shift;
$self->_create_node('/rss/channel',undef,'title', $text);
+ # RSS2 demands a /channel/description element; just dupe title until we give
+ # users the ability to provide a description for their bookbags
+ $self->_create_node('/rss/channel',undef,'description', $text);
}
sub update_ts {
my $self = shift;
- my $text = shift;
+ # RSS2 demands RFC-822 compliant datetime formats
+ my $text = shift || DateTime::Format::Mail->format_datetime(DateTime->now());
$self->_create_node($self->{item_xpath},undef,'lastBuildDate', $text);
}
my $id = shift;
my $mime = shift || "application/x-$type+xml";
- $type = 'self' if ($type eq 'rss2');
-
- $self->_create_node(
- $self->{item_xpath},
- undef,
- 'link',
- $id,
- { rel => $type,
- type => $mime,
- }
- );
+ if ($type eq 'rss2' or $type eq 'alternate') {
+ # Just link to ourself using standard RSS2 link element
+ $self->_create_node(
+ $self->{item_xpath},
+ undef,
+ 'link',
+ $id,
+ undef
+ );
+ } else {
+ # Alternate link: use XHTML link element
+ $self->_create_node(
+ $self->{item_xpath},
+ 'http://www.w3.org/1999/xhtml',
+ 'xhtml:link',
+ $id,
+ { rel => $type,
+ type => $mime,
+ }
+ );
+ }
}
sub id {
sub update_ts {
my $self = shift;
+ # RSS2 demands RFC-822 compliant datetime formats
my $text = shift;
+ if (!$text) {
+ # No date passed in, default to now
+ $text = DateTime::Format::Mail->format_datetime(DateTime->now());
+ } elsif ($text =~ m/^\s*(\d{4})\.?\s*$/o) {
+ # Publication date is just a year, convert accordingly
+ my $year = DateTime->new(year=>$1);
+ $text = DateTime::Format::Mail->format_datetime($year);
+ }
$self->_create_node($self->{item_xpath},undef,'pubDate', $text);
}
+sub id {
+ my $self = shift;
+ my $id = shift;
+ $self->_create_node(
+ $self->{item_xpath},
+ undef,
+ 'guid',
+ $id,
+ {
+ isPermaLink=>"false"
+ }
+ );
+}
#----------------------------------------------------------
</id>
</xsl:for-each>
+ <!-- Spec wants RFC 3339 format - fix it outside of XSL? -->
<xsl:for-each select="marc:controlfield[@tag=005]">
<updated>
<xsl:value-of select="."/>
</rights>
</xsl:for-each>
+ <!-- Spec wants RFC 3339 format - fix it outside of XSL? -->
<xsl:for-each select="marc:datafield[@tag=260]/marc:subfield[@code='c']">
<published>
<xsl:value-of select="."/>
</published>
</xsl:for-each>
- <xsl:for-each select="marc:datafield[500<@tag][@tag<=599][not(@tag=506 or @tag=530 or @tag=540 or @tag=546)]">
- <summary>
- <xsl:value-of select="marc:subfield[@code='a']"/>
- </summary>
- </xsl:for-each>
+ <!--
+ Spec wants zero or one summary elements per item; best option
+ would be to test for one of these elements and only create
+ if one exists, but for now we simply merge all candidates
+ -->
+ <summary>
+ <xsl:for-each select="marc:datafield[500<@tag][@tag<=599][not(@tag=506 or @tag=530 or @tag=540 or @tag=546)]">
+ <xsl:value-of select="marc:subfield[@code='a']"/>
+ </xsl:for-each>
+ </summary>
<xsl:for-each select="marc:datafield[@tag=600 or @tag=610 or @tag=611 or @tag=630 or @tag=650 or @tag=653]">
<category>
</dc:publisher>
</xsl:for-each>
+ <!-- this is supposed to be RFC-822 compliant -->
<xsl:for-each select="marc:datafield[@tag=260]/marc:subfield[@code='c']">
<pubDate>
<xsl:value-of select="."/>
</dc:format>
</xsl:for-each>
- <xsl:for-each select="marc:datafield[500<@tag][@tag<=599][not(@tag=506 or @tag=530 or @tag=540 or @tag=546)]">
- <description>
- <xsl:value-of select="marc:subfield[@code='a']"/>
- </description>
- </xsl:for-each>
+ <!-- specification only allows one description element per item -->
+ <description>
+ <xsl:for-each select="marc:datafield[500<@tag][@tag<=599][not(@tag=506 or @tag=530 or @tag=540 or @tag=546)]">
+ <xsl:value-of select="marc:subfield[@code='a']"/>
+ </xsl:for-each>
+ </description>
<xsl:for-each select="marc:datafield[@tag=600]">
<dc:subject>