mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
Implementing RssPart
This commit is contained in:
@@ -9,7 +9,6 @@ using Orchard.ContentManagement;
|
||||
using Orchard.Core.Feeds.Models;
|
||||
using Orchard.Mvc.Extensions;
|
||||
using Orchard.Services;
|
||||
using Orchard.Utility.Extensions;
|
||||
|
||||
namespace Orchard.Core.Feeds.StandardBuilders {
|
||||
[UsedImplicitly]
|
||||
@@ -35,9 +34,7 @@ namespace Orchard.Core.Feeds.StandardBuilders {
|
||||
_contentManager.GetItemMetadata(feedItem.Item),
|
||||
_htmlFilters);
|
||||
|
||||
|
||||
// TODO: author
|
||||
|
||||
// author is intentionally left empty as it could result in unwanted spam
|
||||
|
||||
// add to known formats
|
||||
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:
|
||||
Name: Tokens
|
||||
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\Images\tokensPopup.gif" />
|
||||
<Content Include="Web.config" />
|
||||
<Compile Include="Migrations.cs" />
|
||||
<Compile Include="Models\RssPart.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Content Include="Module.txt" />
|
||||
<Content Include="Views\TokenHint.cshtml" />
|
||||
@@ -94,12 +96,15 @@
|
||||
<ItemGroup>
|
||||
<Compile Include="Controllers\AdminController.cs" />
|
||||
<Compile Include="Providers\ContentTokens.cs" />
|
||||
<Compile Include="Providers\RssPartFeedItemBuilder.cs" />
|
||||
<Compile Include="Providers\RequestTokens.cs" />
|
||||
<Compile Include="Providers\DateTokens.cs" />
|
||||
<Compile Include="Providers\ShapeTokens.cs" />
|
||||
<Compile Include="Providers\TextTokens.cs" />
|
||||
<Compile Include="Providers\UserTokens.cs" />
|
||||
<Compile Include="ReplaceOptions.cs" />
|
||||
<Compile Include="RssPartDriver.cs" />
|
||||
<Compile Include="Settings\RssPartSettings.cs" />
|
||||
<Compile Include="TokenDescriptor.cs" />
|
||||
<Compile Include="DescribeContext.cs" />
|
||||
<Compile Include="DescribeFor.cs" />
|
||||
@@ -122,6 +127,9 @@
|
||||
<ItemGroup>
|
||||
<Folder Include="Views\Admin\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Views\DefinitionTemplates\RssPartSettings.cshtml" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
||||
<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