Search code examples
rubyrsscdata

Encode content as CDATA in generated RSS feed


I'm generating an RSS feed using Ruby's built-in RSS library, which seems to escape HTML when generating feeds. For certain elements I'd prefer that it preserve the original HTML by wrapping it in a CDATA block.

A minimal working example:

require 'rss/2.0'

feed = RSS::Rss.new("2.0")
feed.channel = RSS::Rss::Channel.new

feed.channel.title = "Title & Show"
feed.channel.link = "http://foo.net"
feed.channel.description = "<strong>Description</strong>"

item = RSS::Rss::Channel::Item.new
item.title = "Foo & Bar"
item.description = "<strong>About</strong>"

feed.channel.items << item

puts feed

...which generates the following RSS:

<?xml version="1.0"?>
<rss version="2.0">
  <channel>
    <title>Title &amp; Show</title>
    <link>http://foo.net</link>
    <description>&lt;strong&gt;Description&lt;/strong&gt;</description>
    <item>
      <title>Foo &amp; Bar</title>
      <description>&lt;strong&gt;About&lt;/strong&gt;</description>
    </item>
  </channel>
</rss>

Instead of HTML-encoding the channel and item descriptions, I'd like to keep the original HTML and wrap them in CDATA blocks, e.g.:

<description><![CDATA[<strong>Description</strong>]]></description>

Solution

  • monkey-patching the element-generating method works for me:

    require 'rss/2.0'
    
    class RSS::Rss::Channel
      def description_element need_convert, indent
        markup = "#{indent}<description>"
        markup << "<![CDATA[#{@description}]]>"
        markup << "</description>"
        markup
      end
    end
    
    # ...
    

    this prevents the call to Utils.html_escape which escapes a few special entities.