mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2026-02-09 09:16:41 +08:00
Implementing RssPart
This commit is contained in:
@@ -9,7 +9,6 @@ using Orchard.ContentManagement;
|
|||||||
using Orchard.Core.Feeds.Models;
|
using Orchard.Core.Feeds.Models;
|
||||||
using Orchard.Mvc.Extensions;
|
using Orchard.Mvc.Extensions;
|
||||||
using Orchard.Services;
|
using Orchard.Services;
|
||||||
using Orchard.Utility.Extensions;
|
|
||||||
|
|
||||||
namespace Orchard.Core.Feeds.StandardBuilders {
|
namespace Orchard.Core.Feeds.StandardBuilders {
|
||||||
[UsedImplicitly]
|
[UsedImplicitly]
|
||||||
@@ -35,9 +34,7 @@ namespace Orchard.Core.Feeds.StandardBuilders {
|
|||||||
_contentManager.GetItemMetadata(feedItem.Item),
|
_contentManager.GetItemMetadata(feedItem.Item),
|
||||||
_htmlFilters);
|
_htmlFilters);
|
||||||
|
|
||||||
|
// author is intentionally left empty as it could result in unwanted spam
|
||||||
// TODO: author
|
|
||||||
|
|
||||||
|
|
||||||
// add to known formats
|
// add to known formats
|
||||||
if (context.Format == "rss") {
|
if (context.Format == "rss") {
|
||||||
|
|||||||
19
src/Orchard.Web/Modules/Orchard.Tokens/Migrations.cs
Normal file
19
src/Orchard.Web/Modules/Orchard.Tokens/Migrations.cs
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
using Orchard.ContentManagement.MetaData;
|
||||||
|
using Orchard.Core.Contents.Extensions;
|
||||||
|
using Orchard.Data.Migration;
|
||||||
|
|
||||||
|
namespace Orchard.Tokens {
|
||||||
|
public class Migrations : DataMigrationImpl {
|
||||||
|
|
||||||
|
public int Create() {
|
||||||
|
|
||||||
|
ContentDefinitionManager.AlterPartDefinition("RssPart",
|
||||||
|
cfg => cfg
|
||||||
|
.Attachable()
|
||||||
|
.WithDescription("Attach to a content type to provide custom values in RSS feeds.")
|
||||||
|
);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
6
src/Orchard.Web/Modules/Orchard.Tokens/Models/RssPart.cs
Normal file
6
src/Orchard.Web/Modules/Orchard.Tokens/Models/RssPart.cs
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
using Orchard.ContentManagement;
|
||||||
|
|
||||||
|
namespace Orchard.Tokens.Models {
|
||||||
|
public class RssPart : ContentPart {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,4 +9,5 @@ Features:
|
|||||||
Orchard.Tokens:
|
Orchard.Tokens:
|
||||||
Name: Tokens
|
Name: Tokens
|
||||||
Description: Provides a system for performing string replacements with common site values.
|
Description: Provides a system for performing string replacements with common site values.
|
||||||
Category: Content
|
Category: Content
|
||||||
|
Dependencies: Core
|
||||||
@@ -77,6 +77,8 @@
|
|||||||
<Content Include="Styles\orchard-tokens-admin.css" />
|
<Content Include="Styles\orchard-tokens-admin.css" />
|
||||||
<Content Include="Styles\Images\tokensPopup.gif" />
|
<Content Include="Styles\Images\tokensPopup.gif" />
|
||||||
<Content Include="Web.config" />
|
<Content Include="Web.config" />
|
||||||
|
<Compile Include="Migrations.cs" />
|
||||||
|
<Compile Include="Models\RssPart.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Content Include="Module.txt" />
|
<Content Include="Module.txt" />
|
||||||
<Content Include="Views\TokenHint.cshtml" />
|
<Content Include="Views\TokenHint.cshtml" />
|
||||||
@@ -94,12 +96,15 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Controllers\AdminController.cs" />
|
<Compile Include="Controllers\AdminController.cs" />
|
||||||
<Compile Include="Providers\ContentTokens.cs" />
|
<Compile Include="Providers\ContentTokens.cs" />
|
||||||
|
<Compile Include="Providers\RssPartFeedItemBuilder.cs" />
|
||||||
<Compile Include="Providers\RequestTokens.cs" />
|
<Compile Include="Providers\RequestTokens.cs" />
|
||||||
<Compile Include="Providers\DateTokens.cs" />
|
<Compile Include="Providers\DateTokens.cs" />
|
||||||
<Compile Include="Providers\ShapeTokens.cs" />
|
<Compile Include="Providers\ShapeTokens.cs" />
|
||||||
<Compile Include="Providers\TextTokens.cs" />
|
<Compile Include="Providers\TextTokens.cs" />
|
||||||
<Compile Include="Providers\UserTokens.cs" />
|
<Compile Include="Providers\UserTokens.cs" />
|
||||||
<Compile Include="ReplaceOptions.cs" />
|
<Compile Include="ReplaceOptions.cs" />
|
||||||
|
<Compile Include="RssPartDriver.cs" />
|
||||||
|
<Compile Include="Settings\RssPartSettings.cs" />
|
||||||
<Compile Include="TokenDescriptor.cs" />
|
<Compile Include="TokenDescriptor.cs" />
|
||||||
<Compile Include="DescribeContext.cs" />
|
<Compile Include="DescribeContext.cs" />
|
||||||
<Compile Include="DescribeFor.cs" />
|
<Compile Include="DescribeFor.cs" />
|
||||||
@@ -122,6 +127,9 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="Views\Admin\" />
|
<Folder Include="Views\Admin\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="Views\DefinitionTemplates\RssPartSettings.cshtml" />
|
||||||
|
</ItemGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
||||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||||
|
|||||||
@@ -0,0 +1,202 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
using Orchard.ContentManagement;
|
||||||
|
using Orchard.Core.Feeds;
|
||||||
|
using Orchard.Core.Feeds.Models;
|
||||||
|
using Orchard.Tokens.Models;
|
||||||
|
using Orchard.Tokens.Settings;
|
||||||
|
|
||||||
|
namespace Orchard.Tokens.Providers {
|
||||||
|
public class RssPartFeedItemBuilder : IFeedItemBuilder {
|
||||||
|
private readonly ITokenizer _tokenizer;
|
||||||
|
|
||||||
|
public RssPartFeedItemBuilder(
|
||||||
|
ITokenizer tokenizer) {
|
||||||
|
_tokenizer = tokenizer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Populate(FeedContext context) {
|
||||||
|
foreach (var feedItem in context.Response.Items.OfType<FeedItem<ContentItem>>()) {
|
||||||
|
var rssPart = feedItem.Item.As<RssPart>();
|
||||||
|
if (rssPart == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var settings = rssPart.TypePartDefinition.Settings.GetModel<RssPartSettings>();
|
||||||
|
|
||||||
|
// add to known formats
|
||||||
|
if (context.Format == "rss") {
|
||||||
|
|
||||||
|
if (!String.IsNullOrWhiteSpace(settings.Title)) {
|
||||||
|
var title = feedItem.Element.Element("title");
|
||||||
|
|
||||||
|
if (settings.Title == "-") {
|
||||||
|
if (title != null) {
|
||||||
|
title.Remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (title == null) {
|
||||||
|
feedItem.Element.Add(title = new XElement("title"));
|
||||||
|
}
|
||||||
|
|
||||||
|
FeedItem<ContentItem> item = feedItem;
|
||||||
|
context.Response.Contextualize(requestContext => {
|
||||||
|
title.Value = _tokenizer.Replace(settings.Title, new { Content = item.Item, Text = title.Value });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!String.IsNullOrWhiteSpace(settings.Author)) {
|
||||||
|
var author = feedItem.Element.Element("author");
|
||||||
|
|
||||||
|
if (settings.Author == "-") {
|
||||||
|
if (author != null) {
|
||||||
|
author.Remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (author == null) {
|
||||||
|
feedItem.Element.Add(author = new XElement("author"));
|
||||||
|
}
|
||||||
|
|
||||||
|
FeedItem<ContentItem> item = feedItem;
|
||||||
|
context.Response.Contextualize(requestContext => {
|
||||||
|
author.Value = _tokenizer.Replace(settings.Title, new { Content = item.Item, Text = author.Value });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!String.IsNullOrWhiteSpace(settings.Description)) {
|
||||||
|
var description = feedItem.Element.Element("description");
|
||||||
|
|
||||||
|
if (settings.Description == "-") {
|
||||||
|
if (description != null) {
|
||||||
|
description.Remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (description == null) {
|
||||||
|
feedItem.Element.Add(description = new XElement("description"));
|
||||||
|
}
|
||||||
|
|
||||||
|
FeedItem<ContentItem> item = feedItem;
|
||||||
|
context.Response.Contextualize(requestContext => {
|
||||||
|
description.Value = _tokenizer.Replace(settings.Description, new { Content = item.Item, Text = description.Value });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!String.IsNullOrWhiteSpace(settings.Enclosure)) {
|
||||||
|
var enclosure = feedItem.Element.Element("enclosure");
|
||||||
|
|
||||||
|
if (settings.Enclosure == "-") {
|
||||||
|
if (enclosure != null) {
|
||||||
|
enclosure.Remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (enclosure == null) {
|
||||||
|
feedItem.Element.Add(enclosure = new XElement("enclosure"));
|
||||||
|
}
|
||||||
|
|
||||||
|
FeedItem<ContentItem> item = feedItem;
|
||||||
|
context.Response.Contextualize(requestContext => {
|
||||||
|
enclosure.Value = _tokenizer.Replace(settings.Enclosure, new { Content = item.Item, Text = enclosure.Value });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!String.IsNullOrWhiteSpace(settings.Link)) {
|
||||||
|
var link = feedItem.Element.Element("link");
|
||||||
|
|
||||||
|
if (settings.Link == "-") {
|
||||||
|
if (link != null) {
|
||||||
|
link.Remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (link == null) {
|
||||||
|
feedItem.Element.Add(link = new XElement("link"));
|
||||||
|
}
|
||||||
|
|
||||||
|
FeedItem<ContentItem> item = feedItem;
|
||||||
|
context.Response.Contextualize(requestContext => {
|
||||||
|
link.Value = _tokenizer.Replace(settings.Link, new { Content = item.Item, Text = link.Value });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!String.IsNullOrWhiteSpace(settings.PubDate)) {
|
||||||
|
var pubDate = feedItem.Element.Element("pubDate");
|
||||||
|
|
||||||
|
if (settings.PubDate == "-") {
|
||||||
|
if (pubDate != null) {
|
||||||
|
pubDate.Remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (pubDate == null) {
|
||||||
|
feedItem.Element.Add(pubDate = new XElement("pubDate"));
|
||||||
|
}
|
||||||
|
|
||||||
|
FeedItem<ContentItem> item = feedItem;
|
||||||
|
context.Response.Contextualize(requestContext => {
|
||||||
|
pubDate.Value = _tokenizer.Replace(settings.PubDate, new { Content = item.Item, Text = pubDate.Value });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!String.IsNullOrWhiteSpace(settings.Source)) {
|
||||||
|
var source = feedItem.Element.Element("source");
|
||||||
|
|
||||||
|
if (settings.Source == "-") {
|
||||||
|
if (source != null) {
|
||||||
|
source.Remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (source == null) {
|
||||||
|
feedItem.Element.Add(source = new XElement("source"));
|
||||||
|
}
|
||||||
|
|
||||||
|
FeedItem<ContentItem> item = feedItem;
|
||||||
|
context.Response.Contextualize(requestContext => {
|
||||||
|
source.Value = _tokenizer.Replace(settings.Source, new { Content = item.Item, Text = source.Value });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!String.IsNullOrWhiteSpace(settings.Category)) {
|
||||||
|
var categories = feedItem.Element.Elements("category").ToArray();
|
||||||
|
|
||||||
|
var currentValue = String.Join(",", categories.Select(x => x.Value).ToArray());
|
||||||
|
|
||||||
|
if (settings.Category == "-") {
|
||||||
|
foreach (var category in categories) {
|
||||||
|
category.Remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
foreach (var category in categories) {
|
||||||
|
category.Remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
FeedItem<ContentItem> item = feedItem;
|
||||||
|
context.Response.Contextualize(requestContext => {
|
||||||
|
|
||||||
|
var newValue = _tokenizer.Replace(settings.Category, new { Content = item.Item, Text = currentValue });
|
||||||
|
|
||||||
|
foreach (var value in newValue.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) {
|
||||||
|
feedItem.Element.Add(new XElement("category", value));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
7
src/Orchard.Web/Modules/Orchard.Tokens/RssPartDriver.cs
Normal file
7
src/Orchard.Web/Modules/Orchard.Tokens/RssPartDriver.cs
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
using Orchard.ContentManagement.Drivers;
|
||||||
|
using Orchard.Tokens.Models;
|
||||||
|
|
||||||
|
namespace Orchard.Tokens {
|
||||||
|
public class RssPartDriver : ContentPartDriver<RssPart> {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using Orchard.ContentManagement;
|
||||||
|
using Orchard.ContentManagement.MetaData;
|
||||||
|
using Orchard.ContentManagement.MetaData.Builders;
|
||||||
|
using Orchard.ContentManagement.MetaData.Models;
|
||||||
|
using Orchard.ContentManagement.ViewModels;
|
||||||
|
|
||||||
|
namespace Orchard.Tokens.Settings {
|
||||||
|
public class RssPartSettings {
|
||||||
|
|
||||||
|
public string Title { get; set; }
|
||||||
|
public string Link { get; set; }
|
||||||
|
public string Description { get; set; }
|
||||||
|
public string Author { get; set; }
|
||||||
|
public string Category { get; set; }
|
||||||
|
public string Enclosure { get; set; }
|
||||||
|
public string PubDate { get; set; }
|
||||||
|
public string Source { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RssPartSettingsEvents : ContentDefinitionEditorEventsBase {
|
||||||
|
public override IEnumerable<TemplateViewModel> TypePartEditor(ContentTypePartDefinition definition) {
|
||||||
|
if (definition.PartDefinition.Name == "RssPart") {
|
||||||
|
var model = definition.Settings.GetModel<RssPartSettings>();
|
||||||
|
yield return DefinitionTemplate(model);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IEnumerable<TemplateViewModel> TypePartEditorUpdate(ContentTypePartDefinitionBuilder builder, IUpdateModel upOwnerModel) {
|
||||||
|
if (builder.Name == "RssPart") {
|
||||||
|
var model = new RssPartSettings();
|
||||||
|
if (upOwnerModel.TryUpdateModel(model, "RssPartSettings", null, null)) {
|
||||||
|
builder.WithSetting("RssPartSettings.Title", model.Title);
|
||||||
|
builder.WithSetting("RssPartSettings.Link", model.Link);
|
||||||
|
builder.WithSetting("RssPartSettings.Description", model.Description);
|
||||||
|
builder.WithSetting("RssPartSettings.Author", model.Author);
|
||||||
|
builder.WithSetting("RssPartSettings.Category", model.Category);
|
||||||
|
builder.WithSetting("RssPartSettings.Enclosure", model.Enclosure);
|
||||||
|
builder.WithSetting("RssPartSettings.PubDate", model.PubDate);
|
||||||
|
builder.WithSetting("RssPartSettings.Source", model.Source);
|
||||||
|
}
|
||||||
|
|
||||||
|
yield return DefinitionTemplate(model);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
@model Orchard.Tokens.Settings.RssPartSettings
|
||||||
|
|
||||||
|
<fieldset>
|
||||||
|
<span class="hint">@T(" Use '-' to remove the tag, leave empty to keep untouched, or use the 'Text' text token for the current value.")</span>
|
||||||
|
<div>
|
||||||
|
<label for="@Html.FieldIdFor(m => m.Title)">@T("Title")</label>
|
||||||
|
@Html.TextBoxFor(m => m.Title, new { @class = "tokenized text medium" })
|
||||||
|
<span class="hint">@T("The title field of the RSS item.")</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="@Html.FieldIdFor(m => m.Link)">@T("Link")</label>
|
||||||
|
@Html.TextBoxFor(m => m.Link, new { @class = "tokenized text medium" })
|
||||||
|
<span class="hint">@T("The link field of the RSS item")</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="@Html.FieldIdFor(m => m.Description)">@T("Description")</label>
|
||||||
|
@Html.TextBoxFor(m => m.Description, new { @class = "tokenized text medium" })
|
||||||
|
<span class="hint">@T("The description field of the RSS item")</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="@Html.FieldIdFor(m => m.Author)">@T("Author")</label>
|
||||||
|
@Html.TextBoxFor(m => m.Author, new { @class = "tokenized text medium" })
|
||||||
|
<span class="hint">@T("The author field of the RSS item")</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="@Html.FieldIdFor(m => m.Category)">@T("Category")</label>
|
||||||
|
@Html.TextBoxFor(m => m.Category, new { @class = "tokenized text medium" })
|
||||||
|
<span class="hint">@T("The category field of the RSS item")</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="@Html.FieldIdFor(m => m.Enclosure)">@T("Enclosure")</label>
|
||||||
|
@Html.TextBoxFor(m => m.Enclosure, new { @class = "tokenized text medium" })
|
||||||
|
<span class="hint">@T("The enclosure field of the RSS item. This is usually a html tag like <img>")</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="@Html.FieldIdFor(m => m.PubDate)">@T("PubDate")</label>
|
||||||
|
@Html.TextBoxFor(m => m.PubDate, new { @class = "tokenized text medium" })
|
||||||
|
<span class="hint">@T("The pubDate field of the RSS item")</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="@Html.FieldIdFor(m => m.Source)">@T("Source")</label>
|
||||||
|
@Html.TextBoxFor(m => m.Source, new { @class = "tokenized text medium" })
|
||||||
|
<span class="hint">@T("The source field of the RSS item")</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</fieldset>
|
||||||
Reference in New Issue
Block a user