First cut at multiple category/tag support
Simon Wistow [Tue, 9 Dec 2008 23:39:29 +0000 (23:39 +0000)]
12 files changed:
Build.PL
Changes
lib/XML/Feed/Entry.pm
lib/XML/Feed/Format/Atom.pm
lib/XML/Feed/Format/RSS.pm
t/12-multi-categories-atom.t [new file with mode: 0644]
t/12-multi-categories-rss.t [new file with mode: 0644]
t/12-multi-categories.base [new file with mode: 0644]
t/12-multi-subjects-rss.t [new file with mode: 0644]
t/samples/atom-multiple-categories.xml [new file with mode: 0644]
t/samples/rss-multiple-categories.xml [new file with mode: 0644]
t/samples/rss-multiple-subjects.xml [new file with mode: 0644]

index 77a61ab..a920adb 100644 (file)
--- a/Build.PL
+++ b/Build.PL
@@ -17,9 +17,9 @@ my $build = Module::Build
                           'LWP::UserAgent'             => 0,
                           'Module::Pluggable'          => 0,
                           'URI::Fetch'                 => 0,
-                          'XML::Atom'                  => 0.32,
-                          'XML::LibXML'                => 1.66,
-                          'XML::RSS'                   => 1.37,
+                          'XML::Atom'                  => '0.32',
+                          'XML::LibXML'                => '1.66',
+                          'XML::RSS'                   => '1.40',
                           'Test::More'                 => 0,
                         },
          create_makefile_pl => 'traditional',
diff --git a/Changes b/Changes
index 4c43f82..9703122 100644 (file)
--- a/Changes
+++ b/Changes
@@ -2,6 +2,10 @@
 
 Revision history for XML::Feed
 
+0.41
+    - Add handling for multiple categories/tags
+    - Force v1.40 of XML::RSS to get proper multiple category support
+
 0.40 
     - Force v1.37 of XML::RSS to get proper xml:base support
     - Force v0.32 of XML::Atom to fix 
index 7e246cf..78e8da1 100644 (file)
@@ -55,6 +55,7 @@ sub modified;
 sub lat;
 sub long;
 sub format;
+sub tags { shift->category(@_) }
 
 1;
 __END__
@@ -127,6 +128,13 @@ an I<XML::Feed::Content> object with an empty string in the I<body>.
 
 The category in which the entry was posted.
 
+Returns a list of categories if called in array context or the first
+category if called in scalar context.
+
+=head2 $entry->tags([ $tag ])
+
+A synonym for I<category>;
+
 =head2 $entry->author([ $author ])
 
 The name or email address of the person who posted the entry.
index f1179dd..7bd84cd 100644 (file)
@@ -228,10 +228,16 @@ sub category {
     my $entry = shift;
     my $ns = XML::Atom::Namespace->new(dc => 'http://purl.org/dc/elements/1.1/');
     if (@_) {
-        $entry->{entry}->add_category({ term => $_[0] });
+        $entry->{entry}->add_category({ term => $_ }) for @_;
+        return 1
     } else {
-        my $category = $entry->{entry}->category;
-        my @return = $category ? ($category->label || $category->term) : $entry->{entry}->getlist($ns, 'subject');
+
+
+        my @category = ($entry->{entry}->can('categories')) ? $entry->{entry}->categories : $entry->{entry}->category;
+        my @return = @category
+            ? (map { $_->label || $_->term } @category)
+            : $entry->{entry}->getlist($ns, 'subject');
+
         return wantarray? @return : $return[0];
     }
 }
index bb0a7a0..15d6d52 100644 (file)
@@ -245,11 +245,16 @@ sub content {
 }
 
 sub category {
-    my $item = shift->{entry};
+    my $entry = shift;
+    my $item  = $entry->{entry};
     if (@_) {
-        $item->{category} = $item->{dc}{subject} = $_[0];
+        my @tmp = ($entry->category, @_);
+        $item->{category}    = [@tmp];
+        $item->{dc}{subject} = [@tmp];
     } else {
-        $item->{category} || $item->{dc}{subject};
+        my $r = $item->{category} || $item->{dc}{subject};
+        my @r = ref($r)? @$r : ($r);
+        return wantarray? @r : $r[0];
     }
 }
 
diff --git a/t/12-multi-categories-atom.t b/t/12-multi-categories-atom.t
new file mode 100644 (file)
index 0000000..25b0ff9
--- /dev/null
@@ -0,0 +1,6 @@
+#!perl -w
+
+use strict;
+use vars qw($type $field);
+$type = "atom";
+require 't/12-multi-categories.base';
diff --git a/t/12-multi-categories-rss.t b/t/12-multi-categories-rss.t
new file mode 100644 (file)
index 0000000..c467d74
--- /dev/null
@@ -0,0 +1,6 @@
+#!perl -w
+
+use strict;
+use vars qw($type $field);
+$type = "rss";
+require 't/12-multi-categories.base';
diff --git a/t/12-multi-categories.base b/t/12-multi-categories.base
new file mode 100644 (file)
index 0000000..e63b31c
--- /dev/null
@@ -0,0 +1,26 @@
+use strict;
+use Test::More tests => 6;
+use XML::Feed;
+
+$field ||= "categories";
+ok(my $feed = XML::Feed->parse("t/samples/${type}-multiple-${field}.xml"), "Parsed $type file with multiple categories");
+my ($entry) = $feed->entries;
+
+is_deeply(
+        [$entry->category()],
+        ["foo", "bar", "quux", "simon's tags"],        
+"Got all categories");
+
+my $xml = $feed->as_xml;
+ok($feed = XML::Feed->parse(\$xml), "Reparsed $type from string");
+is_deeply(
+        [$entry->category()],
+        ["foo", "bar", "quux", "simon's tags"],        
+"Got all categories again");
+
+ok($entry->category("quirka fleeg"), "Added a category");
+is_deeply(
+        [$entry->category()],
+        ["foo", "bar", "quux", "simon's tags", "quirka fleeg"],        
+"Got new category");
+
diff --git a/t/12-multi-subjects-rss.t b/t/12-multi-subjects-rss.t
new file mode 100644 (file)
index 0000000..c3cd317
--- /dev/null
@@ -0,0 +1,6 @@
+#!perl -w
+
+use vars qw($type $field);
+$type  = "rss";
+$field = "subjects";
+require 't/12-multi-categories.base';
diff --git a/t/samples/atom-multiple-categories.xml b/t/samples/atom-multiple-categories.xml
new file mode 100644 (file)
index 0000000..6010565
--- /dev/null
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
+    <title>Simon Wistow's blog</title>
+    <link rel="self" type="application/atom+xml" title="Simon Wistow.s blog (Atom)" href="http://deflatermouse.vox.com/library/posts/page/1/atom.xml" />
+    <updated>2008-12-09T06:37:07Z</updated> 
+    <id>tag:vox.com,2006:6p00c2252555dbf219/</id> 
+    <subtitle>One Drink Too Many and a Joke Gone Too Far</subtitle>  
+    <entry>
+        <title>Test With Categories</title>   
+        <published>2008-12-08T19:44:50Z</published>
+        <updated>2008-12-09T06:37:07Z</updated>
+        <content>content</content> 
+        <category term="foo"  /> 
+        <category term="bar"  /> 
+        <category term="quux" /> 
+        <category term="simon&#39;s tags" />
+    </entry> 
+</feed>
diff --git a/t/samples/rss-multiple-categories.xml b/t/samples/rss-multiple-categories.xml
new file mode 100644 (file)
index 0000000..4b815b5
--- /dev/null
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<rss version="2.0"
+    xmlns:dc="http://purl.org/dc/elements/1.1/"
+    xmlns:content="http://purl.org/rss/1.0/modules/content/">
+    <channel>
+        <title>Simon Wistow's blog</title>
+        <link>http://deflatermouse.vox.com/library/posts/page/1/</link>
+        <lastBuildDate>Mon, 08 Dec 2008 11:44:50 -0800</lastBuildDate>
+        <item>
+            <title>Test With Categories</title>
+            <pubDate>Mon, 08 Dec 2008 11:44:50 -0800</pubDate>         
+            <description>content</description>
+            <category>foo</category> 
+            <category>bar</category> 
+            <category>quux</category> 
+            <category>simon&#39;s tags</category> 
+        </item> 
+    </channel>
+</rss>
diff --git a/t/samples/rss-multiple-subjects.xml b/t/samples/rss-multiple-subjects.xml
new file mode 100644 (file)
index 0000000..0d2d2d0
--- /dev/null
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<rss version="2.0"
+    xmlns:dc="http://purl.org/dc/elements/1.1/"
+    xmlns:content="http://purl.org/rss/1.0/modules/content/">
+    <channel>
+        <title>Simon Wistow's blog</title>
+        <link>http://deflatermouse.vox.com/library/posts/page/1/</link>
+        <lastBuildDate>Mon, 08 Dec 2008 11:44:50 -0800</lastBuildDate>
+        <item>
+            <title>Test With Categories</title>
+            <pubDate>Mon, 08 Dec 2008 11:44:50 -0800</pubDate>         
+            <description>content</description>
+            <dc:subject>foo</dc:subject> 
+            <dc:subject>bar</dc:subject> 
+            <dc:subject>quux</dc:subject> 
+            <dc:subject>simon&#39;s tags</dc:subject> 
+        </item> 
+    </channel>
+</rss>