Support namespace addons
This commit is contained in:
parent
0c08823178
commit
b6aab1edb5
@ -15,26 +15,6 @@
|
||||
require "./spec_helper"
|
||||
|
||||
describe RSS do
|
||||
ex_cloud = RSS::Cloud.new(
|
||||
domain: "rpc.sys.com",
|
||||
port: 80,
|
||||
path: "/RPC2",
|
||||
register_procedure: "pingMe",
|
||||
protocol: "soap"
|
||||
)
|
||||
|
||||
ex_enclosure = RSS::Enclosure.new(
|
||||
url: "http://live.curry.com/mp3/celebritySCms.mp3",
|
||||
length: 1069871,
|
||||
type: "audio/mpeg"
|
||||
)
|
||||
|
||||
base_channel = RSS::Channel.new(
|
||||
link: "http://www.goupstate.com/",
|
||||
title: "GoUpstate.com News Headlines",
|
||||
description: "The latest news from GoUpstate.com, a Spartanburg Herald-Journal Web site."
|
||||
)
|
||||
|
||||
it "builds enclosure" do
|
||||
w3 = HEADER + ENCLOSURE_TEST
|
||||
|
||||
@ -85,5 +65,23 @@ describe RSS do
|
||||
chan = base_channel
|
||||
chan.skip_days = [RSS::Day::Monday, RSS::Day::Wednesday]
|
||||
chan.skip_hours = [2, 6, 18, 22]
|
||||
|
||||
chan.to_s.strip.should eq SKIP_DAY_TEST
|
||||
end
|
||||
|
||||
it "adds namespace" do
|
||||
chan = base_channel
|
||||
chan.add_ns(dc: "http://purl.org/dc/elements/1.1")
|
||||
chan.ns("dc") do |dc|
|
||||
dc["rights"] = "Copyright 2002"
|
||||
end
|
||||
|
||||
item = RSS::Item.new(title: "New item")
|
||||
item.ns("dc") do |dc|
|
||||
dc["subject"] = "CSS"
|
||||
end
|
||||
chan << item
|
||||
|
||||
chan.to_s.strip.should eq NAMESPACE_TEST
|
||||
end
|
||||
end
|
||||
|
@ -15,6 +15,32 @@
|
||||
require "spec"
|
||||
require "../src/cryss"
|
||||
|
||||
def ex_cloud
|
||||
RSS::Cloud.new(
|
||||
domain: "rpc.sys.com",
|
||||
port: 80,
|
||||
path: "/RPC2",
|
||||
register_procedure: "pingMe",
|
||||
protocol: "soap"
|
||||
)
|
||||
end
|
||||
|
||||
def ex_enclosure
|
||||
RSS::Enclosure.new(
|
||||
url: "http://live.curry.com/mp3/celebritySCms.mp3",
|
||||
length: 1069871,
|
||||
type: "audio/mpeg"
|
||||
)
|
||||
end
|
||||
|
||||
def base_channel
|
||||
RSS::Channel.new(
|
||||
link: "http://www.goupstate.com/",
|
||||
title: "GoUpstate.com News Headlines",
|
||||
description: "The latest news from GoUpstate.com, a Spartanburg Herald-Journal Web site."
|
||||
)
|
||||
end
|
||||
|
||||
HEADER = "<?xml version=\"1.0\"?>\n"
|
||||
|
||||
CLOUD_TEST = "<cloud domain=\"rpc.sys.com\" port=\"80\" path=\"/RPC2\" registerProcedure=\"pingMe\" protocol=\"soap\"/>"
|
||||
@ -63,6 +89,8 @@ SKIP_DAY_TEST = HEADER + <<-XML
|
||||
<title>GoUpstate.com News Headlines</title>
|
||||
<link>http://www.goupstate.com/</link>
|
||||
<description>The latest news from GoUpstate.com, a Spartanburg Herald-Journal Web site.</description>
|
||||
<docs>https://validator.w3.org/feed/docs/rss2.html</docs>
|
||||
<generator>cryss</generator>
|
||||
<skipHours>
|
||||
<hour>2</hour>
|
||||
<hour>6</hour>
|
||||
@ -76,3 +104,20 @@ SKIP_DAY_TEST = HEADER + <<-XML
|
||||
</channel>
|
||||
</rss>
|
||||
XML
|
||||
|
||||
NAMESPACE_TEST = HEADER + <<-XML
|
||||
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1">
|
||||
<channel>
|
||||
<title>GoUpstate.com News Headlines</title>
|
||||
<link>http://www.goupstate.com/</link>
|
||||
<description>The latest news from GoUpstate.com, a Spartanburg Herald-Journal Web site.</description>
|
||||
<docs>https://validator.w3.org/feed/docs/rss2.html</docs>
|
||||
<generator>cryss</generator>
|
||||
<dc:rights>Copyright 2002</dc:rights>
|
||||
<item>
|
||||
<title>New item</title>
|
||||
<dc:subject>CSS</dc:subject>
|
||||
</item>
|
||||
</channel>
|
||||
</rss>
|
||||
XML
|
||||
|
@ -137,6 +137,8 @@ module RSS
|
||||
# Contained elements of the channel.
|
||||
getter items : Array(Item) = [] of Item
|
||||
|
||||
@namespaces = {} of String => String
|
||||
|
||||
def initialize(link : URI | String, @title : String, @description : String)
|
||||
@link = link.is_a?(URI) ? link : URI.parse link
|
||||
end
|
||||
@ -149,9 +151,21 @@ module RSS
|
||||
push item
|
||||
end
|
||||
|
||||
def add_ns(name : String | Symbol,
|
||||
url : URI | String)
|
||||
@namespaces["xmlns:#{name.to_s}"] = url.to_s
|
||||
end
|
||||
|
||||
def add_ns(**ns)
|
||||
ns.each do |k, v|
|
||||
add_ns(k, v)
|
||||
end
|
||||
end
|
||||
|
||||
# Serialises the channel to the XML builder.
|
||||
def to_xml(xml : XML::Builder)
|
||||
xml.element("rss", version: "2.0") do
|
||||
xml.attributes(@namespaces)
|
||||
xml.element("channel") do
|
||||
emit title
|
||||
emit link
|
||||
@ -197,6 +211,8 @@ module RSS
|
||||
end
|
||||
end
|
||||
|
||||
emit_custom xml
|
||||
|
||||
@items.each do |item|
|
||||
item.to_xml xml
|
||||
end
|
||||
|
@ -16,6 +16,8 @@ require "xml"
|
||||
|
||||
module RSS
|
||||
abstract class Element
|
||||
@custom = {} of String => Hash(String, String)
|
||||
|
||||
def to_s(io : IO)
|
||||
to_xml(io)
|
||||
end
|
||||
@ -27,6 +29,38 @@ module RSS
|
||||
end
|
||||
end
|
||||
|
||||
# Adds a non-standard namespaced element to the component.
|
||||
#
|
||||
# Yields access to a set of namespaced elements and their values.
|
||||
#
|
||||
# Examples taken from [here](http://static.userland.com/gems/backend/rssMarkPilgrimExample.xml).
|
||||
#
|
||||
# ```crystal
|
||||
# channel = RSS::Channel.new(/* ... */)
|
||||
# channel.add_ns(dc: "http://purl.org/dc/elements/1.1")
|
||||
# channel.ns("dc") do |dc|
|
||||
# dc["rights"] = "Copyright 2002"
|
||||
# end
|
||||
#
|
||||
# item = RSS::Item.new(title: "New item")
|
||||
# item.ns("dc") do |dc|
|
||||
# dc["subject"] = "CSS"
|
||||
# end
|
||||
#
|
||||
# channel << item
|
||||
# ```
|
||||
#
|
||||
# If the namespace already exists, it will yield access to the already existing namespace rather
|
||||
# than overwriting it. Duplicate keys inside that namespace will overwrite, however.
|
||||
#
|
||||
# Note that no sanity checking is (currently) done before serializing an element with a custom
|
||||
# namespaced element, as only the top-level element (a `Channel`) has access to specifying the
|
||||
# namespace imports.
|
||||
def ns(name : String, &block)
|
||||
@custom[name] = {} of String => String if @custom[name]?.nil?
|
||||
yield @custom[name]
|
||||
end
|
||||
|
||||
# Writes the generated XML to the provided *xml* builder.
|
||||
abstract def to_xml(xml : XML::Builder)
|
||||
|
||||
@ -37,5 +71,13 @@ module RSS
|
||||
private macro emit(elem, name)
|
||||
xml.element({{name}}) { xml.text @{{elem}}.to_s }
|
||||
end
|
||||
|
||||
private def emit_custom(xml)
|
||||
@custom.each do |ns, content|
|
||||
content.each do |key, val|
|
||||
xml.element("#{ns}:#{key}") { xml.text val }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -71,6 +71,8 @@ module RSS
|
||||
emit width if @width
|
||||
emit height if @height
|
||||
emit description if @description
|
||||
|
||||
emit_custom xml
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -135,6 +135,8 @@ module RSS
|
||||
xml.element("pubDate") { xml.text pub.to_rfc2822 }
|
||||
end
|
||||
xml.element("source", url: @source_url.to_s) { xml.text @source.to_s } if @source
|
||||
|
||||
emit_custom xml
|
||||
end
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user