Changesets can be listed by changeset number.
The Git repository is here.
Changeset 77
Improved news behavior with better handling of specific filter types
for the page part including the news tag.
- Comitted by: adh
- Date: Tuesday August 08 13:22:25 2006 (over 18 years ago)
Affected files:
rool/rails/radiant/trunk/app/behaviors/news_behavior.rb:
prev. | current | |
# before filters run, but there is no way to escape | ||
# text filtered by (say) Textile, instead get rid of | ||
# characters known to be a problem. | ||
18 | # 2006-08-08 (ADH): Now knows about the prevalent part filter during tag | |
19 | # processing and takes steps to escape the generated | |
20 | # content. Markdown doesn't seem to need it but Textile | |
21 | # is escaped; it turns out there is a '<notextile>' tag | |
22 | # which does the job. Generating HTML from a tag is | |
23 | # still conceptually wrong because of filter operations | |
24 | # but for now I still want to keep this behavior very | |
25 | # simple for its users. There is an RSS behavior which | |
26 | # can be used if a more flexible scheme is required at | |
27 | # the expense of more effort and less clean handling of | |
28 | # empty RSS item fields. | |
require 'rss' | ||
... | ... | |
register 'News' | ||
description %{ | ||
27 | | |
28 | | |
29 | | |
30 | | |
31 | | |
32 | | |
33 | | |
34 | | |
35 | | |
36 | | |
38 | This behavior provides a 'news' tag which is supplied with a | |
39 | fully qualified URL pointing to an XML RSS feed. The feed is | |
40 | parsed and the 'latest news' summary generated from it. The URL | |
41 | is given in the mandatory 'feed' attribute within the tag. | |
38 | | |
43 | The 'headlines' attribute is optional; it defines how many entries | |
44 | will be included in the news summary and defaults to '4'. | |
45 | ||
46 | The 'dates' attribute is also optional; it says whether or not | |
47 | article published or modified dates (if found) will be added in | |
48 | small text after each headline. If '0' there are no dates, else | |
49 | dates are shown. The default value is '1', to show dates. Dates are | |
50 | extracted from the feed's "pubDate", "modified" or "dc_date" fields, | |
51 | in that order. | |
52 | ||
53 | Finally, an optional 'escape' attribute, defaulting to '1', ensures | |
54 | that RSS titles or links cannot be accidentally interpreted as | |
55 | Textile data for Textile filtered parts. Setting the attribute to | |
56 | '0' disables escaping to allow headlines marked up in Textile to be | |
57 | passed through to the Textile parser. | |
58 | ||
59 | Note that '<' and '>' characters in RSS item titles will always be | |
60 | escaped to HTML entities for security. Links to articles are run | |
61 | through URI::Escape() processing and have '~' characters changed to | |
62 | '%7E' for similar reasons. | |
63 | ||
64 | Example of use: | |
65 | ||
66 | <r:news feed="http://my.url/news.xml" headlines="4" dates="0" /> | |
} | ||
# We can't cache pages that might change on every fetch. | ||
... | ... | |
false | ||
end | ||
75 | # The <r:news.../> tag generates code that might fall foul of text filters | |
76 | # on the page part. Overriding parse_object lets the behavior extract the | |
77 | # filter ID so that the tag processing code which then gets run can be | |
78 | # evaluated in the context of a particular prevalent filter. | |
79 | ||
80 | def parse_object(object) | |
81 | if (object.respond_to?(:filter_id)) | |
82 | @filter = object.filter_id | |
83 | else | |
84 | @filter = nil | |
85 | end | |
86 | ||
87 | super | |
88 | end | |
89 | ||
# Tag definitions | ||
define_tags do | ||
51 | | |
94 | # <r:news feed="feed_url" [headlines="number"] [dates="0|1"] [escape="0|1"] /> | |
# | ||
53 | | |
54 | | |
55 | | |
56 | | |
57 | | |
58 | | |
59 | | |
96 | # This behavior provides a 'news' tag which is supplied with a | |
97 | # fully qualified URL pointing to an XML RSS feed. The feed is | |
98 | # parsed and the 'latest news' summary generated from it. The URL | |
99 | # is given in the mandatory 'feed' attribute within the tag. | |
# | ||
101 | # The 'headlines' attribute is optional; it defines how many entries | |
102 | # will be included in the news summary and defaults to '4'. | |
103 | # | |
104 | # The 'dates' attribute is also optional; it says whether or not | |
105 | # article published or modified dates (if found) will be added in | |
106 | # small text after each headline. If '0' there are no dates, else | |
107 | # dates are shown. The default value is '1', to show dates. Dates are | |
108 | # extracted from the feed's "pubDate", "modified" or "dc_date" fields, | |
109 | # in that order. | |
110 | # | |
111 | # Finally, an optional 'escape' attribute, defaulting to '1', ensures | |
112 | # that RSS titles or links cannot be accidentally interpreted as | |
113 | # Textile data for Textile filtered partss. Setting the attribute to | |
114 | # '0' disables escaping to allow headlines marked up in Textile to be | |
115 | # passed through to the Textile parser. | |
116 | # | |
117 | # Note that '<' and '>' characters in RSS item titles will always be | |
118 | # escaped to HTML entities for security. Links to articles are run | |
119 | # through URI::Escape() processing and have '~' characters changed to | |
120 | # '%7E' for similar reasons. | |
121 | # | |
122 | # Example of use: | |
123 | # | |
124 | # <r:news feed="http://my.url/news.xml" headlines="4" dates="0" /> | |
125 | # | |
tag 'news' do |tag| | ||
feed = tag.attr['feed'] | ||
dates = (tag.attr['dates'] || '1').to_i | ||
129 | escape = (tag.attr['escape'] || '1').to_i | |
headlines = (tag.attr['headlines'] || '4').to_i | ||
raise TagError.new("No feed URL given in `news' tag") if (feed.nil? or feed.empty?) | ||
... | ... | |
done = 0 | ||
out = "<ul>\n" | ||
140 | # Escape the data for Textile filtered pages if required. | |
141 | ||
142 | if (escape != 0 and @filter == 'Textile') | |
143 | out = '<notextile>' + out | |
144 | end | |
145 | ||
# Loop through all items in the feed. | ||
rss.items.each do |item| | ||
... | ... | |
out << ' <li>' | ||
164 | # Ensure the title string doesn't contain unsafe characters - | |
165 | # RSS feeds can be used maliciously. | |
166 | ||
167 | title = item.title.dup | |
168 | title.gsub!('<', '<') | |
169 | title.gsub!('>', '%gt;') | |
170 | ||
171 | # Markdown doesn't process text here anyway, possibly because | |
172 | # the HTML list markup seems to stop it from doing so. Don't | |
173 | # escape Markdown for now - the code below has been tested and | |
174 | # does work though, so it can be introduced later if need be. | |
175 | # | |
176 | #if (escape != 0 and @filter == 'Markdown') | |
177 | # title.gsub!(/([`*_{}\[\]()#.!])/) { '\\' + $& } | |
178 | #end | |
179 | ||
180 | # Insert link HTML if a link is present, escaping it and | |
181 | # manually converting "~" characters to the "%7E" equivalent. | |
182 | ||
unless (item.link.nil? or item.link.empty?) | ||
93 | | |
184 | link = URI::escape(item.link) | |
link.gsub!(/\~/, '%7E') | ||
95 | | |
186 | out << "<a href=\"#{link}\">#{title}</a>" | |
else | ||
97 | | |
188 | out << "#{title}" | |
end | ||
191 | # Attempt to extract an item publication/modification date. | |
192 | ||
time = nil | ||
if item.respond_to?(:pubDate) | ||
... | ... | |
time = item.dc_date | ||
end | ||
206 | # Add the date if found and if attributes say to do so, then | |
207 | # close the list item. | |
208 | ||
out << time.strftime(' <small>(%d-%b-%Y)</small>') if (time.class == Time and dates != 0) | ||
out << "</li>\n" | ||
end | ||
117 | | |
213 | # Close the list, handle Textile escaping if necessary and | |
214 | # return the final chunk of data. | |
119 | | |
216 | out << "</ul>\n" | |
217 | ||
218 | if (escape != 0 and @filter == 'Textile') | |
219 | out << '</notextile>' | |
220 | end | |
221 | ||
222 | out | |
end | ||
end # From 'define_tags do' |