<?xml version="1.0"?>

<% 
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
%>

<%    
   var queryManager = currentNode.getSession().getWorkspace().getQueryManager();  
   var query = queryManager.createQuery("/jcr:root/content/espblog/posts/element(*, nt:unstructured) order by @created descending", "xpath");
   var result = query.execute().getNodes();
   
%>

<rss version="2.0">
   <channel>
      <title>My Sling Blog</title>
      <link><%=request.getRequestURL()%></link>
      <description>RSS 2.0 feed of my Sling blog</description>
      
      <%
      	df = new java.text.SimpleDateFormat( "EEE', 'dd' 'MMM' 'yyyy' 'HH:mm:ss' 'Z", Packages.java.util.Locale.US);
	var counter = 0;
	while(result.hasNext() && counter < 10) {
		counter++;
		post = result.nextNode()
      %>
      
      <item>
         <title><%=post.title%></title>
         <link>http://<%=request.getServerName()%>:<%=request.getServerPort()%><%=post%>.html</link>
         <description><%=post.posttext%></description>
         <pubDate><%=df.format(post.created.getTime())%></pubDate>
      </item>
      
      <%
      }
      %>
     
   </channel>
</rss>