Skip Menu |

This queue is for tickets about the XML-RSS CPAN distribution.

Report information
The Basics
Id: 16191
Status: resolved
Priority: 0/
Queue: XML-RSS

People
Owner: Nobody in particular
Requestors: cpan [...] stupidfool.org
emailpranav [...] gmail.com
ivan.wills [...] gmail.com
rachel [...] nmcfarl.org
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: 1.05
Fixed in: (no value)



Subject: PATCH: Ad-Hoc Module Support for RSS 2.0
This patch adds ad hoc module support for 2.0. I basically copied code from 1.0 and changed it a little to work with 2.0. 1051,1055c1051,1055 < while ( my($url, $prefix) = each %{$self->{modules}} ) { < next if $prefix =~ /^(dc|syn|taxo)$/; < while ( my($el, $value) = each %{$self->{textinput}->{$prefix}} ) { < $output .= "<$prefix:$el>". $self->encode($value) ."</$prefix:$el>\n"; < } --- Show quoted text
> while ( my($url, $prefix) = each %{$self->{modules}} ) { > next if $prefix =~ /^(dc|syn|taxo)$/; > while ( my($el, $value) = each %{$self->{textinput}->{$prefix}} ) { > $output .= "<$prefix:$el>". $self->encode($value) ."</$prefix:$el>\n"; > }
1059c1059 < } --- Show quoted text
> }
1077,1081c1077 < $output .= '<rss version="2.0" xmlns:blogChannel="http://backend.userland.com/blogChannelModule"'; < while (my ($k, $v) = each %{$self->{modules}}) { < $output.=" xmlns:$v=\"$k\"\n"; < } < $output .= ">" . "\n\n"; --- Show quoted text
> $output .= '<rss version="2.0" xmlns:blogChannel="http://backend.userland.com/blogChannelModule">' . "\n\n";
1165,1171c1161 < # Ad-hoc modules < while ( my($url, $prefix) = each %{$self->{modules}} ) { < next if $prefix =~ /^(dc)$/; < while ( my($el, $value) = each %{$self->{channel}->{$prefix}} ) { < $output .= "<$prefix:$el>". $self->encode($value) ."</$prefix:$el>\n"; < } < } --- Show quoted text
>
Subject: add_module does not work for RSS 2.0
Like RSS 1.0, RSS 2.0 supports name spaces but XML::RSS as_rss_2_0 has this hard coded into the function so the add_module method does nothing in RSS 2.0 mode. I have added a quick and dirty patch to get this working with RSS 2.0 this probably needs some extra work as it is adding default name spaces for RSS 1.0 to RSS 2.0 files (probably need to change the way new works).
1077c1077,1089 < $output .= '<rss version="2.0" xmlns:blogChannel="http://backend.userland.com/blogChannelModule">' . "\n\n"; --- > # $output .= '<rss version="2.0" xmlns:blogChannel="http://backend.userland.com/blogChannelModule">' . "\n\n"; > > # RSS namespaces declaration > $output .="<rss\n"; > $output .=' version="2.0"'."\n"; > $output .=' xmlns:blogChannel="http://backend.userland.com/blogChannelModule"'."\n"; > > # print all imported namespaces > while (my($k, $v) = each %{$self->{modules}}) { > $output.=" xmlns:$v=\"$k\"\n"; > } > > $output .=">"."\n\n";
From: ivan.wills [...] gmail.com
[guest - Tue Nov 29 17:42:47 2005]: Show quoted text
> Like RSS 1.0, RSS 2.0 supports name spaces but XML::RSS as_rss_2_0 has > this hard coded into the function so the add_module method does > nothing in RSS 2.0 mode. I have added a quick and dirty patch to > get this working with RSS 2.0 this probably needs some extra work > as it is adding default name spaces for RSS 1.0 to RSS 2.0 files > (probably need to change the way new works).
Added a more sophisticated patch which allows there to be seperate default RSS 1.0 and RSS 2.0 modules
1077c1077,1089 < $output .= '<rss version="2.0" xmlns:blogChannel="http://backend.userland.com/blogChannelModule">' . "\n\n"; --- > # $output .= '<rss version="2.0" xmlns:blogChannel="http://backend.userland.com/blogChannelModule">' . "\n\n"; > > # RSS namespaces declaration > $output .="<rss\n"; > $output .=' version="2.0"'."\n"; > $output .=' xmlns:blogChannel="http://backend.userland.com/blogChannelModule"'."\n"; > > # print all imported namespaces > while (my($k, $v) = each %{$self->{modules}}) { > $output.=" xmlns:$v=\"$k\"\n"; > } > > $output .=">"."\n\n";
From: ivan.wills [...] gmail.com
[guest - Tue Nov 29 17:57:30 2005]: Show quoted text
> [guest - Tue Nov 29 17:42:47 2005]: >
> > Like RSS 1.0, RSS 2.0 supports name spaces but XML::RSS as_rss_2_0
> has
> > this hard coded into the function so the add_module method does > > nothing in RSS 2.0 mode. I have added a quick and dirty patch to > > get this working with RSS 2.0 this probably needs some extra work > > as it is adding default name spaces for RSS 1.0 to RSS 2.0 files > > (probably need to change the way new works).
> > > Added a more sophisticated patch which allows there to be seperate > default RSS 1.0 and RSS 2.0 modules
Another more complete patch that also fixes outputting of the namespace tags (the first two only address getting the namespaces into the rss tag). Note that this is cumulative containing the previous two patches
369a370,376 > }; > > my $modules_2_0 = { > 'http://backend.userland.com/blogChannelModule' => 'blogChannel', > }; > > my $modules_1_0 = { 454c461 < $self->{modules} = $modules; --- > $self->{modules} = { ($hash{version} eq '2.0'? %$modules_2_0: %$modules_1_0), %$modules }; 1077c1084,1095 < $output .= '<rss version="2.0" xmlns:blogChannel="http://backend.userland.com/blogChannelModule">' . "\n\n"; --- > # $output .= '<rss version="2.0" xmlns:blogChannel="http://backend.userland.com/blogChannelModule">' . "\n\n"; > > # RSS namespaces declaration > $output .="<rss\n"; > $output .=' version="2.0"'."\n"; > > # print all imported namespaces > while (my($k, $v) = each %{$self->{modules}}) { > $output.=" xmlns:$v=\"$k\"\n"; > } > > $output .=">"."\n\n"; 1161c1179,1194 < --- > # Ad-hoc modules > while ( my($url, $prefix) = each %{$self->{modules}} ) { > next if $prefix =~ /^(dc|syn|taxo)$/; > while ( my($el, $value) = each %{$self->{channel}->{$prefix}} ) { > if ( exists( $rdf_resource_fields{ $url } ) and > exists( $rdf_resource_fields{ $url }{ $el }) ) > { > $output .= qq!<$prefix:$el rdf:resource="! . > $self->encode($value) . > qq!" />\n!; > } > else { > $output .= "<$prefix:$el>". $self->encode($value) ."</$prefix:$el>\n"; > } > } > } 1192a1226,1241 > # Ad-hoc modules for images > while ( my($url, $prefix) = each %{$self->{modules}} ) { > next if $prefix =~ /^(dc|syn|taxo)$/; > while ( my($el, $value) = each %{$self->{image}->{$prefix}} ) { > if ( exists( $rdf_resource_fields{ $url } ) and > exists( $rdf_resource_fields{ $url }{ $el }) ) > { > $output .= qq!<$prefix:$el rdf:resource="! . > $self->encode($value) . > qq!" />\n!; > } > else { > $output .= "<$prefix:$el>". $self->encode($value) ."</$prefix:$el>\n"; > } > } > } 1243a1293,1308 > # Ad-hoc modules > while ( my($url, $prefix) = each %{$self->{modules}} ) { > next if $prefix =~ /^(dc|syn|taxo)$/; > while ( my($el, $value) = each %{$item->{$prefix}} ) { > if ( exists( $rdf_resource_fields{ $url } ) and > exists( $rdf_resource_fields{ $url }{ $el }) ) > { > $output .= qq!<$prefix:$el rdf:resource="! . > $self->encode($value) . > qq!" />\n!; > } > else { > $output .= "<$prefix:$el>". $self->encode($value) ."</$prefix:$el>\n"; > } > } > } 1257a1323,1339 > > # Ad-hoc modules for images > while ( my($url, $prefix) = each %{$self->{modules}} ) { > next if $prefix =~ /^(dc|syn|taxo)$/; > while ( my($el, $value) = each %{$self->{textinput}->{$prefix}} ) { > if ( exists( $rdf_resource_fields{ $url } ) and > exists( $rdf_resource_fields{ $url }{ $el }) ) > { > $output .= qq!<$prefix:$el rdf:resource="! . > $self->encode($value) . > qq!" />\n!; > } > else { > $output .= "<$prefix:$el>". $self->encode($value) ."</$prefix:$el>\n"; > } > } > } 1266a1349,1365 > > # Ad-hoc modules for skipHours > while ( my($url, $prefix) = each %{$self->{modules}} ) { > next if $prefix =~ /^(dc|syn|taxo)$/; > while ( my($el, $value) = each %{$self->{skipHours}->{$prefix}} ) { > if ( exists( $rdf_resource_fields{ $url } ) and > exists( $rdf_resource_fields{ $url }{ $el }) ) > { > $output .= qq!<$prefix:$el rdf:resource="! . > $self->encode($value) . > qq!" />\n!; > } > else { > $output .= "<$prefix:$el>". $self->encode($value) ."</$prefix:$el>\n"; > } > } > } 1275a1375,1391 > > # Ad-hoc modules for skipDays > while ( my($url, $prefix) = each %{$self->{modules}} ) { > next if $prefix =~ /^(dc|syn|taxo)$/; > while ( my($el, $value) = each %{$self->{skipDays}->{$prefix}} ) { > if ( exists( $rdf_resource_fields{ $url } ) and > exists( $rdf_resource_fields{ $url }{ $el }) ) > { > $output .= qq!<$prefix:$el rdf:resource="! . > $self->encode($value) . > qq!" />\n!; > } > else { > $output .= "<$prefix:$el>". $self->encode($value) ."</$prefix:$el>\n"; > } > } > }
Subject: add_module broken for RSS 2.0 format
I am writing a small utility to provide product feeds to google base and the format google wants it is slightly more than RSS 2.0 (http://base.google.com/base/rss_specs.html). I'm using the vanilla XML::RSS module that you have written to create the RSS file. I wish to add extra (google provided) attributes to my RSS file using google's namespace. Here's an example: <channel xmlns:g="http://base.google.com/ns/1.0"> … <g:image_link>http://www.google.com/images/google_sm.gif </g:image_link> … In order to achieve the above, I am using the add_module functionality to add an external module. But it does not work and these new elements do not get added to my output xml file. Thanks very much.
On Tue Nov 29 21:31:26 2005, guest wrote: Show quoted text
> Another more complete patch that also fixes outputting of the namespace > tags (the first two only address getting the namespaces into the rss tag).
Hi, 1) Test cases please. :-) 2) Diffs with "diff -u" please. - ask
Subject: as_rss_2_0 doesn't serialize content:encoded
Since RSS 2.0 supports namespaces, it should serialize any namespaced elements, even if they're not defined in the base specification. In particular, the content:encoded element (or, well, specifically, http://purl.org/rss/1. 0/modules/content/encoded) isn't serialized in as_rss_2_0. Possibly it should do something like as_rss_1_0 does, where it serializes any elements in namespaces defined in $self->{modules}? A very short test case attached.
Subject: rss-20.pl
#!/usr/bin/perl -w use strict; use Test::More tests => 1; use XML::RSS; my $rss = XML::RSS->new( version => '2.0' ); $rss->add_module( prefix => 'content', uri => 'http://purl.org/rss/1.0/modules/content/' ); $rss->add_item( title => 'title', content => { encoded => 'this is content' }, ); like $rss->as_string, qr/this is content/;
On Tue Apr 25 01:43:17 2006, BTROTT wrote: Show quoted text
> Since RSS 2.0 supports namespaces, it should
serialize any namespaced Show quoted text
> elements, even if > they're not defined in the base specification. > > In particular, the content:encoded element (or,
well, specifically, Show quoted text
> http://purl.org/rss/1. > 0/modules/content/encoded) isn't serialized in
as_rss_2_0. Possibly it Show quoted text
> should do something like > as_rss_1_0 does, where it serializes any
elements in namespaces Show quoted text
> defined in $self->{modules}? > > A very short test case attached.
Hi! This seems like a duplicate of https://rt.cpan.org/Ticket/Display.html?id=16191 . I suggest we merge it there. Regards, Shlomi Fish
RT-Send-CC: BTROTT
On Sat Mar 11 18:02:44 2006, ABH wrote: Show quoted text
> On Tue Nov 29 21:31:26 2005, guest wrote: >
> > Another more complete patch that also fixes outputting of the
namespace Show quoted text
> > tags (the first two only address getting the namespaces into the
rss tag). Show quoted text
> > Hi, > > 1) Test cases please. :-) > > 2) Diffs with "diff -u" please. >
Here is a reworked version of the patch along with BTROTT's testcase from issue #18907. It is in diff -u format. I omitted some places where the modules were rendered in RSS 2.0, but otherwise weren't in RSS 1.0 and 0.91. (And don't seem like it would make sense to render them there.). My svk commit message read: <<<<<<<<< Commited the reworked patch from: https://rt.cpan.org/Ticket/Display.html?id=16191 By ivan.wills@gmail.com along with the 2.0-modules.t from: http://rt.cpan.org/Ticket/Display.html?id=18907 By BTROTT, to add support for modules/namespaces to RSS 2.0. Show quoted text
>>>>>>>>>
Regards, Shlomi Fish Show quoted text
> > > - ask
=== t/2.0-generate.t ================================================================== --- t/2.0-generate.t (revision 444) +++ t/2.0-generate.t (revision 445) @@ -84,9 +84,6 @@ enclosure => { type=>"application/x-bittorrent", url => 'http://127.0.0.1/torrents/The_Passion_of_Dave_Winer.torrent' }, ), "Set one RSS item" ); -my $len = length($rss->as_string()); -ok( $len, "RSS feed has '$len' characters" ); - ok( $rss->add_module( prefix => RSS_MOD_PREFIX, uri => RSS_MOD_URI ), "Added module: " . RSS_MOD_PREFIX ); @@ -97,6 +94,9 @@ is( $rss->{modules}->{$uri}, RSS_MOD_PREFIX, "Namespace URI is " . RSS_MOD_URI); +my $len = length($rss->as_string()); +ok( $len, "RSS feed has '$len' characters" ); + ok( $rss->save(RSS_SAVEAS), "Wrote to disk: " . RSS_SAVEAS ); my $size = -s (RSS_SAVEAS); @@ -163,4 +163,4 @@ http://backend.userland.com/rss2 -=cu \ No newline at end of file +=cu === t/test_manifest ================================================================== --- t/test_manifest (revision 444) +++ t/test_manifest (revision 445) @@ -11,6 +11,7 @@ 1.0-parse.t 1.0-parse-exotic.t 2.0-generate.t +2.0-modules.t 2.0-permalink.t 2.0-parse.t 2.0-wo-title.t === t/2.0-modules.t ================================================================== --- t/2.0-modules.t (revision 444) +++ t/2.0-modules.t (revision 445) @@ -0,0 +1,17 @@ +#!/usr/bin/perl -w +use strict; + +use Test::More tests => 1; +use XML::RSS; + +my $rss = XML::RSS->new( version => '2.0' ); +$rss->add_module( + prefix => 'content', + uri => 'http://purl.org/rss/1.0/modules/content/' + ); +$rss->add_item( + title => 'title', + content => { encoded => 'this is content' }, + ); + +like $rss->as_string, qr/this is content/; === MANIFEST ================================================================== --- MANIFEST (revision 444) +++ MANIFEST (revision 445) @@ -36,6 +36,7 @@ t/1.0-parse.t t/1.0-to-2.0.t t/2.0-generate.t +t/2.0-modules.t t/2.0-parse.t t/2.0-permalink.t t/2.0-wo-title.t === lib/XML/RSS.pm ================================================================== --- lib/XML/RSS.pm (revision 444) +++ lib/XML/RSS.pm (revision 445) @@ -420,6 +420,14 @@ }; } +sub _get_default_rss_2_0_modules +{ + return + { + 'http://backend.userland.com/blogChannelModule' => 'blogChannel', + }; +} + sub new { my $class = shift; @@ -460,18 +468,23 @@ $self->{namespaces} = {}; $self->{rss_namespace} = ''; + #get version info + (exists($hash{version})) + ? ($self->{version} = $hash{version}) + : ($self->{version} = '1.0'); + # modules - $self->{modules} = $self->_get_default_modules(); + $self->{modules} = + (($self->{version} eq "2.0") ? + $self->_get_default_rss_2_0_modules() : + $self->_get_default_modules() + ); # encode output from as_string? (exists($hash{encode_output})) ? ($self->{encode_output} = $hash{encode_output}) : ($self->{encode_output} = 1); - #get version info - (exists($hash{version})) - ? ($self->{version} = $hash{version}) - : ($self->{version} = '1.0'); # set default output (exists($hash{output})) @@ -1274,7 +1287,17 @@ # RSS root element # $output .= '<rss version="0.91">'."\n\n"; - $output .= '<rss version="2.0" xmlns:blogChannel="http://backend.userland.com/blogChannelModule">' . "\n\n"; + + # RSS namespaces declaration + $output .="<rss\n"; + $output .=' version="2.0"'."\n"; + + # print all imported namespaces + while (my($k, $v) = each %{$self->{modules}}) { + $output.=" xmlns:$v=\"$k\"\n"; + } + + $output .=">"."\n\n"; ################### # Channel Element # @@ -1342,8 +1365,23 @@ $output .= '<ttl>'.$self->_encode($self->{channel}->{ttl}).'</ttl>'."\n"; } + # Ad-hoc modules + while ( my($url, $prefix) = each %{$self->{modules}} ) { + next if $prefix =~ /^(dc|syn|taxo)$/; + while ( my($el, $value) = each %{$self->{channel}->{$prefix}} ) { + if ( exists( $rdf_resource_fields{ $url } ) and + exists( $rdf_resource_fields{ $url }{ $el }) ) + { + $output .= "<$prefix:$el rdf:resource=\"" . + $self->_encode($value) . + "\" />\n"; + } + else { + $output .= "<$prefix:$el>". $self->_encode($value) ."</$prefix:$el>\n"; + } + } + } - $output .= "\n"; ################# @@ -1362,6 +1400,23 @@ [qw(link width height description)] ); + # Ad-hoc modules for images + while ( my($url, $prefix) = each %{$self->{modules}} ) { + next if $prefix =~ /^(dc|syn|taxo)$/; + while ( my($el, $value) = each %{$self->{image}->{$prefix}} ) { + if ( exists( $rdf_resource_fields{ $url } ) and + exists( $rdf_resource_fields{ $url }{ $el }) ) + { + $output .= qq{<$prefix:$el rdf:resource="} . + $self->_encode($value) . + qq{" />\n}; + } + else { + $output .= "<$prefix:$el>". $self->_encode($value) ."</$prefix:$el>\n"; + } + } + } + # end image element $output .= '</image>'."\n\n"; } @@ -1403,6 +1458,23 @@ . ' />' . "\n"; } + # Ad-hoc modules + while ( my($url, $prefix) = each %{$self->{modules}} ) { + next if $prefix =~ /^(dc|syn|taxo)$/; + while ( my($el, $value) = each %{$item->{$prefix}} ) { + if ( exists( $rdf_resource_fields{ $url } ) and + exists( $rdf_resource_fields{ $url }{ $el }) ) + { + $output .= "<$prefix:$el rdf:resource=\"" . + $self->_encode($value) . + "\" />\n"; + } + else { + $output .= "<$prefix:$el>". $self->_encode($value) ."</$prefix:$el>\n"; + } + } + } + # end image element $output .= '</item>'."\n\n"; }
Hi Ask! This is a duplicate of: http://rt.cpan.org/Ticket/Display.html?id=16191 I suggest you mark it as such. Regards, Shlomi Fish
Applied, thanks Ben & Ivan. The fix will be in v1.22. - ask (reluctant maintainer of this incredible piece of junk code implementing that absurd messy file format).