|
[
Permlink
| « Hide
]
Marius Dumitru Florea added a comment - 25/Feb/08 13:18
I attached a first version of the new FeedPlugin. Any comment is welcome.
(mail from Ludovic)
We should:
This way we would get the RSS feed in 3 lines in the velocity, and customization is still possible Ludovic Sergiu and Vincent, your opinion is most wanted.
I also suggest we add a /feed/ action. It would be very similar to xpage=rdf but would simplify the URL and make it much nicer to read.
/xwiki/bin/feed/Main/WebRss We could also propose some aliases for the standard feeds /xwiki/bin/feed/BlogRss -> all the blogs /xwiki/bin/feed/SpaceName/BlogRss -> the blog in space RSS This could all be based on reserved words.. This is just a suggestion.. We need to find a nice way.. Ludovic, regarding your first proposals:
Currently, getSkinFile method returns relative (internal) URLs. I couldn't find a way to get the external URL for a skin file. Is this something forbidden? I've noticed that we actually compute the full URL but we strip it with urlFactory.getURL(url, context). So what do you think of overloading the getSkinFile method by adding a absoluteURL flag? getSkinFile(String filename, boolean forceSkinAction, boolean absoluteURL, XWikiContext context) Then we could get the logo with: #set($feedLogoAbsoluteURL = $xwiki.getSkinFile($xwiki.getSkinPreference('logo', 'logo.png'), false, true))
Right now we use: #set($feedRights = $xwiki.webCopyright.replaceAll('<', '<html:').replaceAll('<html:/', '</html:')) Why do we need this? I've noticed that in the generated feed the HTML special characters from the copyright are escaped.
I haven't found a library providing this feature. Do you know one? Of course, this is easy to implement using SAX. I could add a method in api.Util but want to be sure I don't reinvent the wheel.
Done.
In progress. I've updated the patch. I'll soon add some tests.
Regarding the API to extract a sub part of a content and make sure it is still valid HTML, I've tested two solutions, but I'm not happy with neither of them:
Solution 1 Solution 2 Recap: the first solution has speed but works only if the input is well-formed (or at least well-formed until it reaches the length limit, i.e. when I want the first 200 characters) and the second solution is slower and takes more memory, but (almost) always provides an acceptable output. Opinions? patch updated with a mix of the above two solutions
I think we should have this patch in 1.4M2. It's not dangerous since these are new APIs.
That would allow to test the code in sample pages before we recode the standard RSS pages using the plugin. I'm not sure about the way DataSources are handled.
AFAICS the query is a searchDocument(), which is logical since documents are our usual unit. Writing a java class for each special type of document we want to manage (like ArticleClass) doesn't seems convenient, I'd prefer to have more flexibility from velocity. This could be done through more arguments, a RSS criterion or a simple map similar to the one used for metadata. I think I'd personnaly choose the 3rd solution. This would lead to something like this for the blog : Velocity : ## Velocity code for XWiki.BlogRssCode #set($cal = $xwiki.calendar.calendar) #set($ok = $cal.add(10, 1)) #set($ok = $response.setDateHeader("Expires", $cal.time.time)) #set($feedMetadata = { "title":"$!title", "description":"$!description", "url":"$!baseurl"}) #set($feedEntryMapping = { "entrytitle":"title", "content":"content"}) #if($list) {pre}$xwiki.feed.getFeedOutput($list, $feedEntryMapping, $feedMetadata, "rss_1.0"){/pre} #else {pre}$xwiki.feed.getFeedOutput($sql, 20, 0, $feedEntryMapping, $feedMetadata, "rss_1.0"){/pre} #end SyndEntrySourceImpl.java String titleProp = feedEntryMapping.get("title"); if (titleProp != null && !"".equals(titleProp)) { String title = doc.display(titleProp); } else { String title = doc.getDisplayTitle(context); } Writing I realize entry contents aren't managed in the last patch you provided, am I wrong ? Is it on purpose ? BTW if we find a solution that statisfies everyone I guess it could be added to the core before 1.4RC1 (since there's no modification on existing code) and then be used in XE1.5M1. Wdyt ?
JV, I'm not sure about your solution too. I admit mine has little flexibility on the Velocity side, but it is flexible on the Java side, plus allowing me to write clean code. In you case, I think we'll end up writing something like:
#set($feedEntryMapping = {
"uri":'$doc.getExternalURL("view", "language=" + $doc.realLanguage())',
"link":'$doc.getExternalURL("view", "language=" + $doc.realLanguage())',
"title":'$doc.display("title", $doc.get("XWiki.ArticleClass"))',
"description":'$?.getHTMLPreview($doc.getRenderedContent($doc.display("content", $doc.get("XWiki.ArticleClass"))), 400)',
"categories":'$doc.display("category", $doc.get("XWiki.ArticleClass")).split(",")',
"publishedDate":'$doc.creationDate',
"updateDate":'$doc.date',
"author":'$xwiki.getUserName($doc.creator, null, false)',
"contributors":'[$xwiki.getUserName($doc.author, null, false)]'
})
which I don't even know if it will work, but for me it's ugly. Plus, because each Velocity string (what about collections?) must be parsed in Java for each feed entry I believe this is time consuming. Also, I don't think that documents are the only feed source. What about a stats feed or an activity event feed? Now FeedPlugin calls searchDocumentsNames, but it can call search instead. I have to change it to do so. I wrote SyndEntryDocumentSource and SyndEntryArticleSource classes to clone the behavior of WebRssCode and BlogRssCode respectively. So I didn't needed the contents field, mostly because I used the description field. Another solution would be to implement the SyndEntrySource in a groovy page.
Not if you write a default behavior for each field, allowing to override only some of them (or even no one) from velocity.
If you call a search instead I think you open a security breach. About other sources like stats or activity stream (which are marginal today) sure we could have other implementations.
Ok, could be a good improvement for XE 1.5 btw (having a diff in the case of a wiki page, the whole content in case of an article). I could implement your solution on top of mine. But I still have some questions.
You say that we can write a default behavior for each field. Right. This is currently happening with SyndEntryDocumentSource and SyndEntryArticleSource. They both provide default values for link, title, description and all the rest of the fields. That's why I added methods like getWebFeedOutput and getBlogFeedOutput in FeedPluginApi. The question is how can the user overwrite these defaults? In my case, I can use the source parameters to complicate the current behavior of SyndEntryDocumentSource and SyndEntryArticleSource. Now they use only two parameters: ContentType and ContentLength. I can add more parameters like: ShowDiff, ContentOffset etc. if needed. This way the user can do some minor customization. The big problem is that he cannot change completely the feed output by only writing velocity code. With Java this is simple. The fix would be to implement a SyndEntrySource that maps each feed entry field to a velocity string which will be evaluated for each feed entry. In your case, you want to map feed entry fields to xwiki class fields (If I understand correctly). For instance, considering XWiki.ArticleClass you say we can map feed entry title to article title and feed entry description to article content. I see this mapping as a particular way of generating feeds. I can write an implementation of SyndEntrySource, which we can call SyndEntryFieldMappingSource, for this particular behavior. In the end the user will have to choose between:
Here's a preview of the new patch. It's almost done. I'll finish it on Monday, when I'll also post some velocity code that relies on it.
JV, I attached the final version of the patch. Here's a velocity snippet:
#set($feedMetadata = {
"title":"My Feed Title",
"description":"My Feed Description",
"url":"http://www.xwiki.org"})
#set($sourceParams = {
"ContentLength":10,
"title":"title",
"description":"XWiki.ArticleClass_content",
"publishedDate":"XWiki.ArticleClass_0_date",
"updatedDate":'{$doc.date.time}',
"categories":'{{pre}[$doc.space,$doc.name,$doc.isNew()]{/pre}}'
})
#set($sql = ", BaseObject as obj where obj.name=doc.fullName and obj.className='XWiki.ArticleClass' and obj.name<>'XWiki.ArticleClassTemplate' order by doc.creationDate desc")
{pre}$xwiki.feed.getDocumentFeedOutput($sql, 20, 0, $sourceParams, $feedMetadata, "atom_0.3"){/pre}
Of course, most of the time you wont care about $sourceParams or at most you'll need simple field mapping. The velocity code from my previous posts is still usable. This is for those who want more customization. Patch updated due to the last changes in core.
Patch re-updated due to the last changes in core.
Patch updated with:
Patch applied.
I wait to see if we add a action mapping for feeds before closing the issue. (see http://tinyurl.com/5ew7np Closing for 1.6M1. If we want actions mappings for feeds, we'll do it in anther JIRA issue.
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||