NAME
    RSSycklr - (beta) Highly configurable recycling of syndication
    (RSS/Atom) feeds into tailored, guaranteed XHTML fragments.
SYNOPSIS
     use strict;
     use warnings;
     use RSSycklr;
     use Encode;
 
     my @feeds = ({ uri => "http://www.xkcd.com/atom.xml",
                    max_display => 1 },
                  { uri => "http://green.yahoo.com/rss/blogs/all" },
                  { uri => "http://www.mnn.com/rss/all-mnn-content" },
                  { uri => "http://feeds.grist.org/rss/gristfeed" },
                  { uri => "http://green.yahoo.com/rss/featured" },
                  { uri => "http://feeds.nationalgeographic.com/ng/NGM/NGM_Magazine" },
                  { uri => "http://feeds.feedburner.com/greenlivingarticles" },
                  { uri => "http://www.ecosherpa.com/feed/" },
                  { uri => "http://www.groovygreen.com/groove/?feed=atom" },
                  { uri => "http://blog.epa.gov/blog/feed/"},
                  { uri => "http://www.unep.org/newscentre/rss/rss.asp?rss-id=pr&l=en" },
                  { uri => "http://feeds.feedburner.com/treehuggersite" },
                  { uri => "http://redgreenandblue.org/feed/" },
                  { uri => "http://green.yahoo.com/rss/news" },
                  { uri => "http://news.cnet.com/8300-11128_3-54.xml" },
                  { uri => "http://news.google.com/news?rls=en-us&oe=UTF-8&um=1&tab=wn&hl=en&q=Environmental&ie=UTF-8&output=atom" },
                  { title_override => "O NOES, IZ TEH DED",
                    uri => "http://rss.news.yahoo.com/rss/obits", });
 
     my $rsklr = RSSycklr->new();
 
     binmode STDOUT, ":encoding(UTF-8)";
     $rsklr->config({ feeds => \@feeds,
                      title_only => 1 });
     # print $rsklr->as_string;
 
     while ( my $feed = $rsklr->next() )
     {
         print $feed->title_override || $feed->title;
         print "\n";
         for my $entry ( $feed->entries )
         {
             print " * ", $entry->title, "\n";
         }
     }
DESCRIPTION
    This is a more of a mini-app engine than a pure module. RSSycklr is a
    package that wraps up the best parts of XML::Feed and HTML::Truncate
    then filters it through XML::LibXML to guarantee valid XHTML and adds a
    side of Template for auto-formatted output of XHTML fragments should you
    so desire.
    This is probably easier to show with examples than explain. This is the
    part where I show, or maybe explain, someday. For now, take a look at
    the "CONFIGURATION" sample below and the source for the tool 'rssycklr'
    that comes with this distribution.
    XHTML validation is currently based on "-//W3C//DTD XHTML 1.0
    Transitional//EN" and errors are not fatal. You will be able to pick
    your DTD eventually and decide if errors are fatals or skip the entry or
    just complain.
METHODS
    new Create an RSSycklr object.
    load_config
        Takes a YAML file name or string. It must conform to the
        configuration format. No validation of input is done at this point.
        More config options will be probably be added soon. As it calls
        "config" underneath, loading configuration options will be add them
        to what's already there, not reset them.
    config
        Set/get hash reference of the configuration and raw feed data.
        Setting config is additive, each new hash reference is merged with
        the current config hash reference.
    add_feeds
        Takes an array ref of hash refs of feed info. "uri" is the only
        required key in the hash ref. Other possible keys are shown in
        "CONFIGURATION" below.
    next
        Iteration through feeds with delayed execution. Feeds are only
        fetched and cleaned-up as they are called. "next" is destructive and
        can be used in a while loop.
            while ( my $feed = $rssycklr->new() ) {
                print "Title: ", $feed->title, "\n";
            }
    feeds
        If you prefer to get your feeds at once in a list or an array ref,
        use "feeds". It iterates on "next" under the hood, therefore "next"
        will be empty after "feeds" has been called though "feeds" may be
        called repeatedly without refetching or parsing. If you "add_feeds"
        to add new feeds, next will able to iterate on those and "feeds"
        will add them to those already parsed and fetched.
        Remember that each feed is a web request and they aren't done in any
        kind of parallel nature so you could expect a list of 20 feeds to
        return slowly, maybe very slowly.
    as_string
        Sort of does this-
         $rssycklr->process($rssycklr->template, { rssycklr => $rssycklr })
               or confess $rssycklr->tt2->error();
        Can also be called for a return value, like so-
         my $output = $rssycklr->as_string;
        In void context, it processes/prints to STDOUT.
         $rssycklr->as_string;
    keep_tags
        The list (stored as a hash ref) of tags which will be kept when
        creating ledes from entry bodies. The default list generally
        comprises the phrasal tags; e.g., "", "", "",
        "", "", et cetera.
         perl -MRSSycklr -MYAML -le '$rsklr = RSSycklr->new; print Dump $rsklr->keep_tags'
        Example: dropping images-
         delete $rsklr->keep_tags->{img};
        Example: drop all tags-
         $rsklr->keep_tags({});
    tt2 The Template object we may create to do output. It's deferred so if
        you never ask for it, and never call its methods, it's never
        created.
    template
        The "template" that will be passed to "process" in Template. It can
        be a string (scalar ref), a file, or a file handle. The default is a
        string ref.
         perl -MRSSycklr -le '$rsklr = RSSycklr->new; print ${$rsklr->template}'
    xml_parser
        The XML::LibXML object.
    html_to_dom
        Passes an HTML fragment through some HTML::TokeParser::Simple sanity
        cleanup and returns an XML::LibXML::Document. This is an
    truncater
        The HTML::Truncate object.
    BUILD
        Internal method. To allow "config" and "load_config" to be passed as
        arguments. "BUILD" runs the methods at initialization if you do.
  DELEGATED METHODS
    As noted above, an RSSycklr object has a collection of objects it
    wrangles. You may call methods on it which get delegated t its objects.
    All the methods below belong to the indicated classes and may be treated
    exactly as the relevant documents show.
    process
        This is "process" in Template.
    parse_html_string
        "parse_html_string" in XML::LibXML. You also have access to
        "recover" in XML::LibXML::Parser and "recover_silently" in
        XML::LibXML::Parser which are set to "1" by default.
    truncate
        "truncate" in HTML::Truncate.
INTERNAL PACKAGES
  RSSycklr::Feed
    Calls from RSSyckler objects to "feeds" and "next" return
    "RSSycklr::Feed" objects. They are based on XML::Feed objects.
  SELECT CONFIGURATION SETTINGS
    More configuration settings are shown in the config example.
    title_override
        For some feeds, like say a search generated feed from Google, you
        might get back a title in the XML which is ridiculous for display;
        e.g., "bingo cards" +tacos site:example.org. In cases likes this it
        would be nice to provide your own title.
  METHODS
    entries
        The processed entries from the feed which passed configuration
        filters.
    count
        The number of entries a feed has. Note, this is not the number of
        entries in the actual XML::Feed, but the number of entries which
        passed your configuration filters.
  DELEGATED METHODS
    The following delegate to the underlying XML::Feed object.
    title
    tagline
    link
    copyright
    author
    generator
    language
  RSSycklr::Feed::Entry
    lede
        The excerpted portion of the feed entry's content.
    feed
        The parent "RSSyckler::Feed" object.
  DELEGATED METHODS
    The following delegate to the underlying XML::Feed::Entry object.
    title
        This will eventually be replaced by a native method.
    link
    content
    category
    id
    author
    issued
    modified
CONFIGURATION
    Configuration is a hash in two levels. The top level contains defaults.
    The key "feeds" contains per feed settings. You can have "max_display =>
    3" in the top, for example, but have "max_display => 1" and "max_display
    => 10" in individual feed data. Leaving "max_display" out of feed data
    would mean a feed would fall back to the top default setting 3.
     ---
     # length of entry excerpt to keep as "lede"
     excerpt_length: 110
     # don't do excerpts, titles, only
     title_only: ~
     # master setting for oldest entry age
     hours_back: 30
     # stop fetching at this point
     max_feeds: 10
     # master setting for entries to keep per feed
     max_display: 3
     # seconds to try a feed fetch before skipping
     timeout: 10
     # ellipsis on truncated ledes/titles
     ellipsis: " "
     # text for "read more" link
     read_more: [more]
     # css class for top 
Oh, Hai!
" is counted as 8 characters, not 15. Default is at 170. title_only If true, don't do excerpts, only pull titles. hours_back Maximum age of feed entries to include. max_display How many entries from a feed to parse and keep. timeout How many seconds to wait for a feed fetch to return before skipping it. ellipsis read_more Text for "read more" link. css_class The CSS class for the top "" wrapper. max_images Maximum images to keep in a "lede". Hardcoded to 1 right now. dtd max_feeds Stop fetching at this point. dtd The DTD to validate feed snippets against. The default is "xhtml1-transitional.dtd". Also available: "xhtml1-frameset.dtd", "xhtml1-strict.dtd", and "xhtml11.dtd". Because we use XML::LibXML to parse our snippets we cannot, and frankly wouldn't want to, support HTML 4 and earlier. title_length Not implemented. excerpt_style Not implemented, dl/dt/dd happens in template now. title_style Not implemented, ul/li happens now. feed_title_tag Settable; "h4" in template now. SAMPLE CSS The image handling is probably the most important part. Feeds might return huge images or several images. .rssycklr { font-family: helvetica, sans-serif; } .rssycklr h4 { border-bottom: 1px solid #ccc; line-height: 100%; } .rssycklr h4 a { color:#039!important; text-decoration:none; } .rssycklr .datetime { color: #445; font-size: 80%; } .rssycklr a.readmore { text-decoration:none; font-size: 90%; } .rssycklr img { float: right; clear: right; width: 60px; margin: -3px 0 0 3px; } AUTHOR Ashley Pond V, "