c# - Sitecore 自定义 RSS 提要
问题描述
我正在尝试为我的项目创建自定义 RSS 提要。我对使用 RSS Feed 进行更改还很陌生。所以我正在阅读 John West 的文章,以及如何通过创建新模板并在我的新 rss 模板中添加我的命名空间、扩展名下的程序集来覆盖我的 RSS。但我无法取得太大进展。我需要一个类似于下面的视图,并且开箱即用的 sitecore rss 不会这样做。我是否必须重写 PublicFeed 类和“FeedDeliveryLayout.aspx”布局才能实现这一点?任何人都有我可以查看的任何示例,或者任何信息都会非常有帮助。另外,我如何让文章的类别显示在 RSS 中并按类别标题显示?
谢谢
<rss xmlns:content="purl.org/.../" xmlns:dc="purl.org/.../" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="purl.org/.../" version="2.0">
<channel>
<title>Blog</title>
<atom:link href="http://mysite/blog/rss" rel="self" type="application/rss+xml"/>
<link>mysite/.../link>
<description>Article Descript</description>
<language>en-US</language>
<sy:updatePeriod>hourly</sy:updatePeriod>
<sy:updateFrequency>1</sy:updateFrequency>
<item>
<title>Article Title</title>
<link>
mysite/.../link>
<category>Sales</category>
<category>Management</category>
<category>Professional</category>
<category>Marketing</category>
<category>Dynamics</category>
<guid isPermaLink="false">mysite/.../guid>
<description>
<p>Article Summary</p> <p> </p>
</description>
<dc:creator>John Smith</dc:creator>
<pubDate>Wed, 10 Jan 2018 12:00:00 -0400</pubDate>
<content:encoded>
<div class="row"><div><p>BODY OF ARTICLE</p></div>
</content:encoded>
</item>
---Ans-- 修改sitecore/shell/applications/feeds中可以找到的feeddeliverylayout.aspx
/// <summary>
/// Parse PublicFeed response (string) convert it into XML document
/// add/remove/update Node(s) as per requiremnt
/// </summary>
/// <param name="html"></param>
/// <returns>modified Feeds</returns>
private string ModifyRss(string html)
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(html);
XmlNodeList items = doc.SelectNodes("//item");
foreach (XmlNode item in items)
{
XmlNode idNode = item.ChildNodes[0];
XmlNode linkNode = item.ChildNodes[1];
XmlNode titleNode = item.ChildNodes[2];
XmlNode descNode = item.ChildNodes[3];
XmlNode pubDateNode = item.ChildNodes[4];
item.InsertBefore(titleNode, idNode);
item.InsertBefore(linkNode, idNode);
string id = idNode.InnerText;
Sitecore.Data.Items.Item contextItem = Sitecore.Context.Database.Items[new Sitecore.Data.ID(id)];
if (contextItem != null)
{
// render categories
var categoriesValue = contextItem[BlogSyndicationRSS.BlogsCategories];
if (!string.IsNullOrEmpty(categoriesValue))
{
MultilistField refMultilistField = contextItem.Fields[BlogSyndicationRSS.BlogsCategories];
if (refMultilistField != null)
{
Item[] categories = refMultilistField.GetItems();
List<Item> check = categories.Where(x => x != null && x.Versions.Count > 0).ToList();
if (check != null && check.Count > 0)
{
Boolean firstCategory = true;
foreach (var category in categories)
{
XmlElement cateogryField = doc.CreateElement("category");
cateogryField.InnerText = !string.IsNullOrEmpty(category["TITLE"]) ? category["TITLE"] : category.Name;
if (firstCategory)
item.InsertAfter(cateogryField, linkNode);
else
item.AppendChild(cateogryField);
}
}
}
}
// render creator aka author name
var createdBy = contextItem[BlogSyndicationRSS.Author];
if (!string.IsNullOrEmpty(createdBy))
{
XmlElement createdByField = doc.CreateElement("dc", "creator", "urn:abc");
createdByField.InnerText = createdBy;
item.InsertAfter(createdByField, descNode);
}
// render content aka body of blog article
var body = contextItem[BlogSyndicationRSS.Content];
if (!string.IsNullOrEmpty(body))
{
XmlElement bodyField = doc.CreateElement("content", "encoded", "urn:abc");
bodyField.InnerText = body + GetContentFooter(contextItem);
item.InsertAfter(bodyField, pubDateNode);
}
}
var options = LinkManager.GetDefaultUrlOptions();
options.AlwaysIncludeServerUrl = true;
idNode.InnerText = LinkManager.GetItemUrl(contextItem, options);
}
ProcessXML(doc);
//remove invalid attributes from xml tags
var invalidAttributes = "xmlns:atom=\"urn:abc\", xmlns:sy=\"urn:abc\", xmlns:dc=\"urn:abc\", xmlns:content=\"urn:abc\"";
var outerXML = doc.OuterXml;
foreach (var invalidAttr in invalidAttributes.Split(','))
{
outerXML = outerXML.Replace(invalidAttr, string.Empty);
}
return outerXML;
}
/// <summary>
/// Process XMLDocument //rss node to remove existing elements and add new elements
/// </summary>
/// <param name="doc"></param>
private void ProcessXML(XmlDocument doc)
{
if (doc != null)
{
XmlNode Node = doc.SelectSingleNode("//rss");
Node.Attributes.RemoveAll();
AddRemoveAttributes(doc, Node, "xmlns:content", "http://purl.org/rss/1.0/modules/content/");
AddRemoveAttributes(doc, Node, "xmlns:dc", "http://purl.org/dc/elements/1.1/");
AddRemoveAttributes(doc, Node, "xmlns:atom", "http://www.w3.org/2005/Atom");
AddRemoveAttributes(doc, Node, "xmlns:sy", "http://purl.org/rss/1.0/modules/syndication/");
AddRemoveAttributes(doc, Node, "version", "2.0");
var updateFrequencyValue = updateFrequency();
AddElements(doc, "sy:updateFrequency", updateFrequencyValue, "language");
var updatePeriodValue = updatePeriod();
AddElements(doc, "sy:updatePeriod", updatePeriodValue, "language");
var atomLink = AddElements(doc, "atom:link", string.Empty, "title");
if (atomLink != null)
{
atomLink.Attributes.RemoveAll();
var contextItem = Sitecore.Context.Item.Parent;
AddRemoveAttributes(doc, atomLink, "href", LinkManager.GetItemUrl(contextItem, new UrlOptions { AlwaysIncludeServerUrl = true }));
AddRemoveAttributes(doc, atomLink, "rel", "self");
AddRemoveAttributes(doc, atomLink, "type", "application/rss+xml");
}
}
}
/// <summary>
/// Add remove attributs from node
/// </summary>
/// <param name="doc">XmlDocument</param>
/// <param name="Node">Xml Node</param>
/// <param name="type">type of Attribute</param>
/// <param name="value">value of Attribute</param>
private void AddRemoveAttributes(XmlDocument doc, XmlNode Node, string type, string value)
{
if (Node != null)
{
XmlAttribute typeAttr = doc.CreateAttribute(type);
typeAttr.Value = value;
Node.Attributes.Append(typeAttr);
}
}
/// <summary>
/// Add element to XMLDocument
/// </summary>
/// <param name="doc">xml document</param>
/// <param name="name">element name</param>
/// <param name="value">elemnent value</param>
/// <param name="insertAfter">existing node name the new element will be inserted after</param>
/// <returns></returns>
private XmlNode AddElements(XmlDocument doc, string name, string value, string insertAfter)
{
XmlNode Node = doc.SelectSingleNode("//channel");
XmlNode newElement = doc.CreateNode(XmlNodeType.Element, name, "urn:abc");
newElement.InnerText = value;
Node.InsertAfter(newElement, doc.SelectSingleNode("//" + insertAfter));
return newElement;
}
解决方案
你只需要做两件事:
- 覆盖方法
RenderItem
来自Sitecore.Syndication.PublicFeed
这是一个非常简单的示例,但在覆盖方法中,您可以插入自定义 XML 命名空间和任何您想要的内容:
using Sitecore.Data.Items;
using Sitecore.Syndication;
using System.ServiceModel.Syndication;
using System.Xml.Linq;
namespace MyWebsite.Foundation.RssFeeds.Services
{
public class CustomRssFeed : PublicFeed
{
protected override SyndicationItem RenderItem(Item item)
{
SyndicationItem syndicationItem = base.RenderItem(item);
syndicationItem.ElementExtensions.Add(new XElement("addedNode", "addedContent"));
return syndicationItem;
}
}
}
- 在 中填写您的自定义公共提要类
Sitecore
。执行此操作的位置在您的 RSS Feed 项中 - 它应该是从模板“/sitecore/templates/System/Feeds/RSS Feed”创建的。在“类型”字段中输入您的类和程序集的全名(在“可扩展性”部分下)。
示例:“MyWebsite.Foundation.RssFeeds.Services.CustomRssFeed, MyWebsite.Foundation.RssFeeds”
推荐阅读
- amazon-web-services - 尝试从不同区域链接 EB 和 EFS 时出现“未知主机”错误
- scala - 在 DataFrame 中使用 UDF
- c - 在 Switch 语句代码停止工作并且我无法输入后,我需要修改 Files 中的详细信息
- excel - Excel VBA - 将来自不同工作表的所有访问和用户汇总到新工作表中
- java - java.lang.IllegalStateException:片段未附加到上下文
- c# - ASP.NET Core 中的 ConfigureServices() 和 Configure() 有什么区别?
- javascript - Javascript排序数组连接两个id
- javascript - Primeng Turbo 表在 Angular 5 中未按预期呈现
- python - 预计稠密具有形状但得到具有形状的阵列
- angular - 是否可以在经典网站中嵌入 Angular5 应用程序?