Custom rss in blog with post content

Topics: Feature requests, General, XSLT
Sep 1, 2013 at 12:09 PM
Hello, I'm sure I've seen it before somewhere, but I can't find answer now.

I want to customise blog rss feed to put blog post content inside rss. I don't want users to click on each entity. As far as I understand blog package rss is not customisable because it is in dll. The solutions looks like create custom XSLT or write my own c# handler.

Looks like XSLT is a simpler solution.
As for xslt function I've fount something similar in this discussion
http://compositec1.codeplex.com/discussions/263462
But I'm not sure how to write a query.

If it is not possible I'm comfortable with c# code. But same story - where I can find right datasource.
looking at this example https://c1packages.codeplex.com/SourceControl/changeset/view/8053#129098
I've tried to look into Composite.Community.Blog namespace, but it doesn't like I can get list of my blog entities or I missing something. I'm not very familiar with Composite internal data structure - maybe I'm not looking into right class.

Thank you in advance for any suggestions.
Sep 1, 2013 at 2:48 PM
Edited Sep 1, 2013 at 3:16 PM
Solved solution myself. Here is code:
<%@ WebHandler Language="C#" Class="CustomFullRSSFeed" %>

using System;
using System.Web;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.ServiceModel.Syndication;
using System.Web;
using System.Xml;
using Composite.Data;
using Composite.Data.Types;
using Composite.Community.Blog;


public class CustomFullRSSFeed : IHttpHandler
{
    public const string CacheRSSKeyTemplate = "My_CUstom_BlogRssFeed-{0}-{1}";
    public void ProcessRequest(HttpContext context)
    {
        Guid pageId = Guid.Empty;

        if (context.Request["bid"] != null && Guid.TryParse(context.Request["bid"], out pageId))
        {
            bool isGlobal = Convert.ToBoolean(context.Request["IsGlobal"]);
            string cultureName = context.Request["cultureName"];
            if (string.IsNullOrEmpty(cultureName))
            {
                cultureName = DataLocalizationFacade.DefaultLocalizationCulture.Name;
            }
            string cachedRssKey = string.Format(CacheRSSKeyTemplate, pageId, cultureName);

            ///!!!!!!!!!!!!remove later
            //if (true)
            
            if (context.Cache[cachedRssKey] == null)
            {
                var cultureInfo = new CultureInfo(cultureName);
                context.Response.ContentType = "text/xml";

                using (var conn = new DataConnection(cultureInfo))
                {
                    string pageUrl = BlogFacade.GetPageUrlById(pageId);
                    if (!string.IsNullOrEmpty(pageUrl))
                    {
                        pageUrl = BlogFacade.GetFullPath(pageUrl);
                        string pageTitle =
                            conn.Get<IPage>().Where(p => p.Id == pageId).Select(p => p.Title).Single();
                        var feed = new SyndicationFeed(pageTitle, "", new Uri(pageUrl));
                        var blogItems =
                            conn.Get<Entries>()
                                .Where(b => isGlobal ? b.PageId != null : b.PageId == pageId)
                                .Select(b => new { b.Id, b.Title, b.Date, b.Teaser, b.Tags, b.PageId, b.Content })
                                .OrderByDescending(b => b.Date)
                                .ToList();

                        List<SyndicationItem> items = (from blog in blogItems
                                                       let blogUrl =
                                                           BlogFacade.GetBlogUrl(blog.Date, blog.Title,// blog.PageId,
                                                                                 pageUrl)
                                                       select
                                                           new SyndicationItem(blog.Title, blog.Content.Replace("~/",string.Format("http://{0}/",HttpContext.Current.Request.Url.Host)),
                                                                               new Uri(blogUrl), blog.Id.ToString(),
                                                                               blog.Date)).ToList();

                        feed.Items = items;
                        context.Cache[cachedRssKey] = feed;
                    }
                }
            }

            var syndicationFeed = (SyndicationFeed)context.Cache[cachedRssKey];

            using (XmlWriter writer = XmlWriter.Create(context.Response.OutputStream))
            {
                syndicationFeed.SaveAsRss20(writer);
            }
        }
        else
        {
            context.Response.Write("The required query paramerer 'bid' (blog page GUID) is missing.");
        }
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }

}
Sep 1, 2013 at 3:37 PM
(just a side-note to your code: since there is no instance-member-variables in your class you should let IsReusable return true http://msdn.microsoft.com/en-us/library/system.web.ihttphandler.isreusable.aspx)
Sep 3, 2013 at 9:08 AM
Thank your for pointing that out.