mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-09-19 18:27:55 +08:00
Swapped out Orchard.Core's Common Routable for the work in progress replacement, Orchard.Core's Routable (seperate core module now)
--HG-- branch : dev
This commit is contained in:
@@ -10,9 +10,10 @@ using Orchard.ContentManagement.Handlers;
|
|||||||
using Orchard.ContentManagement.MetaData;
|
using Orchard.ContentManagement.MetaData;
|
||||||
using Orchard.ContentManagement.Records;
|
using Orchard.ContentManagement.Records;
|
||||||
using Orchard.Core.Common.Models;
|
using Orchard.Core.Common.Models;
|
||||||
using Orchard.Core.Common.Services;
|
using Orchard.Core.Routable.Handlers;
|
||||||
|
using Orchard.Core.Routable.Models;
|
||||||
|
using Orchard.Core.Routable.Services;
|
||||||
using Orchard.Tests.Modules;
|
using Orchard.Tests.Modules;
|
||||||
using Orchard.Core.Common.Handlers;
|
|
||||||
using System.Web.Mvc;
|
using System.Web.Mvc;
|
||||||
using System.Web.Routing;
|
using System.Web.Routing;
|
||||||
using Orchard.Tests.Stubs;
|
using Orchard.Tests.Stubs;
|
||||||
@@ -37,7 +38,7 @@ namespace Orchard.Core.Tests.Common.Services {
|
|||||||
|
|
||||||
builder.RegisterType<DefaultContentQuery>().As<IContentQuery>();
|
builder.RegisterType<DefaultContentQuery>().As<IContentQuery>();
|
||||||
builder.RegisterInstance(new UrlHelper(new RequestContext(new StubHttpContext("~/"), new RouteData()))).As<UrlHelper>();
|
builder.RegisterInstance(new UrlHelper(new RequestContext(new StubHttpContext("~/"), new RouteData()))).As<UrlHelper>();
|
||||||
builder.RegisterType<RoutableAspectHandler>().As<IContentHandler>();
|
builder.RegisterType<RoutableHandler>().As<IContentHandler>();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,11 +49,11 @@ namespace Orchard.Core.Tests.Common.Services {
|
|||||||
var contentManager = _container.Resolve<IContentManager>();
|
var contentManager = _container.Resolve<IContentManager>();
|
||||||
|
|
||||||
var thing = contentManager.Create<Thing>(ThingDriver.ContentType.Name, t => {
|
var thing = contentManager.Create<Thing>(ThingDriver.ContentType.Name, t => {
|
||||||
t.As<RoutableAspect>().Record = new RoutableRecord();
|
t.As<IsRoutable>().Record = new RoutableRecord();
|
||||||
t.Title = "Please do not use any of the following characters in your slugs: \":\", \"/\", \"?\", \"#\", \"[\", \"]\", \"@\", \"!\", \"$\", \"&\", \"'\", \"(\", \")\", \"*\", \"+\", \",\", \";\", \"=\"";
|
t.Title = "Please do not use any of the following characters in your slugs: \":\", \"/\", \"?\", \"#\", \"[\", \"]\", \"@\", \"!\", \"$\", \"&\", \"'\", \"(\", \")\", \"*\", \"+\", \",\", \";\", \"=\"";
|
||||||
});
|
});
|
||||||
|
|
||||||
_routableService.FillSlug(thing.As<RoutableAspect>());
|
_routableService.FillSlug(thing.As<IsRoutable>());
|
||||||
|
|
||||||
Assert.That(thing.Slug, Is.EqualTo("please-do-not-use-any-of-the-following-characters-in-your-slugs-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\""));
|
Assert.That(thing.Slug, Is.EqualTo("please-do-not-use-any-of-the-following-characters-in-your-slugs-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\"-\""));
|
||||||
}
|
}
|
||||||
@@ -84,11 +85,11 @@ namespace Orchard.Core.Tests.Common.Services {
|
|||||||
veryVeryLongTitle += "aaaaaaaaaa";
|
veryVeryLongTitle += "aaaaaaaaaa";
|
||||||
|
|
||||||
var thing = contentManager.Create<Thing>(ThingDriver.ContentType.Name, t => {
|
var thing = contentManager.Create<Thing>(ThingDriver.ContentType.Name, t => {
|
||||||
t.As<RoutableAspect>().Record = new RoutableRecord();
|
t.As<IsRoutable>().Record = new RoutableRecord();
|
||||||
t.Title = veryVeryLongTitle;
|
t.Title = veryVeryLongTitle;
|
||||||
});
|
});
|
||||||
|
|
||||||
_routableService.FillSlug(thing.As<RoutableAspect>());
|
_routableService.FillSlug(thing.As<IsRoutable>());
|
||||||
|
|
||||||
Assert.That(veryVeryLongTitle.Length, Is.AtLeast(1001));
|
Assert.That(veryVeryLongTitle.Length, Is.AtLeast(1001));
|
||||||
Assert.That(thing.Slug.Length, Is.EqualTo(1000));
|
Assert.That(thing.Slug.Length, Is.EqualTo(1000));
|
||||||
@@ -135,11 +136,11 @@ namespace Orchard.Core.Tests.Common.Services {
|
|||||||
var contentManager = _container.Resolve<IContentManager>();
|
var contentManager = _container.Resolve<IContentManager>();
|
||||||
|
|
||||||
var thing = contentManager.Create<Thing>(ThingDriver.ContentType.Name, t => {
|
var thing = contentManager.Create<Thing>(ThingDriver.ContentType.Name, t => {
|
||||||
t.As<RoutableAspect>().Record = new RoutableRecord();
|
t.As<IsRoutable>().Record = new RoutableRecord();
|
||||||
t.Title = "This Is Some Interesting Title";
|
t.Title = "This Is Some Interesting Title";
|
||||||
});
|
});
|
||||||
|
|
||||||
_routableService.FillSlug(thing.As<RoutableAspect>());
|
_routableService.FillSlug(thing.As<IsRoutable>());
|
||||||
|
|
||||||
Assert.That(thing.Slug, Is.EqualTo("this-is-some-interesting-title"));
|
Assert.That(thing.Slug, Is.EqualTo("this-is-some-interesting-title"));
|
||||||
}
|
}
|
||||||
@@ -149,12 +150,12 @@ namespace Orchard.Core.Tests.Common.Services {
|
|||||||
var contentManager = _container.Resolve<IContentManager>();
|
var contentManager = _container.Resolve<IContentManager>();
|
||||||
|
|
||||||
var thing1 = contentManager.Create<Thing>(ThingDriver.ContentType.Name, t => {
|
var thing1 = contentManager.Create<Thing>(ThingDriver.ContentType.Name, t => {
|
||||||
t.As<RoutableAspect>().Record = new RoutableRecord();
|
t.As<IsRoutable>().Record = new RoutableRecord();
|
||||||
t.Title = "This Is Some Interesting Title";
|
t.Title = "This Is Some Interesting Title";
|
||||||
});
|
});
|
||||||
|
|
||||||
var thing2 = contentManager.Create<Thing>(ThingDriver.ContentType.Name, t => {
|
var thing2 = contentManager.Create<Thing>(ThingDriver.ContentType.Name, t => {
|
||||||
t.As<RoutableAspect>().Record = new RoutableRecord();
|
t.As<IsRoutable>().Record = new RoutableRecord();
|
||||||
t.Title = "This Is Some Interesting Title";
|
t.Title = "This Is Some Interesting Title";
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -166,12 +167,12 @@ namespace Orchard.Core.Tests.Common.Services {
|
|||||||
var contentManager = _container.Resolve<IContentManager>();
|
var contentManager = _container.Resolve<IContentManager>();
|
||||||
|
|
||||||
var thing = contentManager.Create<Thing>(ThingDriver.ContentType.Name, t => {
|
var thing = contentManager.Create<Thing>(ThingDriver.ContentType.Name, t => {
|
||||||
t.As<RoutableAspect>().Record = new RoutableRecord();
|
t.As<IsRoutable>().Record = new RoutableRecord();
|
||||||
t.Title = "This Is Some Interesting Title";
|
t.Title = "This Is Some Interesting Title";
|
||||||
});
|
});
|
||||||
|
|
||||||
var stuff = contentManager.Create<Stuff>(StuffDriver.ContentType.Name, s => {
|
var stuff = contentManager.Create<Stuff>(StuffDriver.ContentType.Name, s => {
|
||||||
s.As<RoutableAspect>().Record = new RoutableRecord();
|
s.As<IsRoutable>().Record = new RoutableRecord();
|
||||||
s.Title = "This Is Some Interesting Title";
|
s.Title = "This Is Some Interesting Title";
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -198,7 +199,7 @@ namespace Orchard.Core.Tests.Common.Services {
|
|||||||
Filters.Add(new ActivatingFilter<Thing>(ThingDriver.ContentType.Name));
|
Filters.Add(new ActivatingFilter<Thing>(ThingDriver.ContentType.Name));
|
||||||
Filters.Add(new ActivatingFilter<ContentPart<CommonVersionRecord>>(ThingDriver.ContentType.Name));
|
Filters.Add(new ActivatingFilter<ContentPart<CommonVersionRecord>>(ThingDriver.ContentType.Name));
|
||||||
Filters.Add(new ActivatingFilter<CommonAspect>(ThingDriver.ContentType.Name));
|
Filters.Add(new ActivatingFilter<CommonAspect>(ThingDriver.ContentType.Name));
|
||||||
Filters.Add(new ActivatingFilter<RoutableAspect>(ThingDriver.ContentType.Name));
|
Filters.Add(new ActivatingFilter<IsRoutable>(ThingDriver.ContentType.Name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,13 +207,13 @@ namespace Orchard.Core.Tests.Common.Services {
|
|||||||
public int Id { get { return ContentItem.Id; } }
|
public int Id { get { return ContentItem.Id; } }
|
||||||
|
|
||||||
public string Title {
|
public string Title {
|
||||||
get { return this.As<RoutableAspect>().Title; }
|
get { return this.As<IsRoutable>().Title; }
|
||||||
set { this.As<RoutableAspect>().Title = value; }
|
set { this.As<IsRoutable>().Title = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Slug {
|
public string Slug {
|
||||||
get { return this.As<RoutableAspect>().Slug; }
|
get { return this.As<IsRoutable>().Slug; }
|
||||||
set { this.As<RoutableAspect>().Slug = value; }
|
set { this.As<IsRoutable>().Slug = value; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -229,7 +230,7 @@ namespace Orchard.Core.Tests.Common.Services {
|
|||||||
Filters.Add(new ActivatingFilter<Stuff>(StuffDriver.ContentType.Name));
|
Filters.Add(new ActivatingFilter<Stuff>(StuffDriver.ContentType.Name));
|
||||||
Filters.Add(new ActivatingFilter<ContentPart<CommonVersionRecord>>(StuffDriver.ContentType.Name));
|
Filters.Add(new ActivatingFilter<ContentPart<CommonVersionRecord>>(StuffDriver.ContentType.Name));
|
||||||
Filters.Add(new ActivatingFilter<CommonAspect>(StuffDriver.ContentType.Name));
|
Filters.Add(new ActivatingFilter<CommonAspect>(StuffDriver.ContentType.Name));
|
||||||
Filters.Add(new ActivatingFilter<RoutableAspect>(StuffDriver.ContentType.Name));
|
Filters.Add(new ActivatingFilter<IsRoutable>(StuffDriver.ContentType.Name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -237,13 +238,13 @@ namespace Orchard.Core.Tests.Common.Services {
|
|||||||
public int Id { get { return ContentItem.Id; } }
|
public int Id { get { return ContentItem.Id; } }
|
||||||
|
|
||||||
public string Title {
|
public string Title {
|
||||||
get { return this.As<RoutableAspect>().Title; }
|
get { return this.As<IsRoutable>().Title; }
|
||||||
set { this.As<RoutableAspect>().Title = value; }
|
set { this.As<IsRoutable>().Title = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Slug {
|
public string Slug {
|
||||||
get { return this.As<RoutableAspect>().Slug; }
|
get { return this.As<IsRoutable>().Slug; }
|
||||||
set { this.As<RoutableAspect>().Slug = value; }
|
set { this.As<IsRoutable>().Slug = value; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -10,13 +10,13 @@ using NUnit.Framework;
|
|||||||
using Orchard.ContentManagement;
|
using Orchard.ContentManagement;
|
||||||
using Orchard.ContentManagement.Handlers;
|
using Orchard.ContentManagement.Handlers;
|
||||||
using Orchard.ContentManagement.MetaData.Builders;
|
using Orchard.ContentManagement.MetaData.Builders;
|
||||||
using Orchard.ContentManagement.MetaData.Models;
|
|
||||||
using Orchard.Core.Common.Models;
|
using Orchard.Core.Common.Models;
|
||||||
using Orchard.Core.Feeds;
|
using Orchard.Core.Feeds;
|
||||||
using Orchard.Core.Feeds.Controllers;
|
using Orchard.Core.Feeds.Controllers;
|
||||||
using Orchard.Core.Feeds.Models;
|
using Orchard.Core.Feeds.Models;
|
||||||
using Orchard.Core.Feeds.Rss;
|
using Orchard.Core.Feeds.Rss;
|
||||||
using Orchard.Core.Feeds.StandardBuilders;
|
using Orchard.Core.Feeds.StandardBuilders;
|
||||||
|
using Orchard.Core.Routable.Models;
|
||||||
using Orchard.Mvc.Results;
|
using Orchard.Mvc.Results;
|
||||||
using Orchard.Tests.Modules;
|
using Orchard.Tests.Modules;
|
||||||
using Orchard.Tests.Stubs;
|
using Orchard.Tests.Stubs;
|
||||||
@@ -149,16 +149,16 @@ namespace Orchard.Core.Tests.Feeds.Controllers {
|
|||||||
var clock = new StubClock();
|
var clock = new StubClock();
|
||||||
var hello = new ContentItemBuilder(new ContentTypeDefinitionBuilder().Named("hello").Build())
|
var hello = new ContentItemBuilder(new ContentTypeDefinitionBuilder().Named("hello").Build())
|
||||||
.Weld<CommonAspect>()
|
.Weld<CommonAspect>()
|
||||||
.Weld<RoutableAspect>()
|
.Weld<IsRoutable>()
|
||||||
.Weld<BodyAspect>()
|
.Weld<BodyAspect>()
|
||||||
.Build();
|
.Build();
|
||||||
hello.As<CommonAspect>().Record = new CommonRecord();
|
hello.As<CommonAspect>().Record = new CommonRecord();
|
||||||
hello.As<RoutableAspect>().Record = new RoutableRecord();
|
hello.As<IsRoutable>().Record = new RoutableRecord();
|
||||||
hello.As<BodyAspect>().Record = new BodyRecord();
|
hello.As<BodyAspect>().Record = new BodyRecord();
|
||||||
|
|
||||||
hello.As<CommonAspect>().PublishedUtc = clock.UtcNow;
|
hello.As<CommonAspect>().PublishedUtc = clock.UtcNow;
|
||||||
hello.As<RoutableAspect>().Title = "alpha";
|
hello.As<IsRoutable>().Title = "alpha";
|
||||||
hello.As<RoutableAspect>().Slug = "beta";
|
hello.As<IsRoutable>().Slug = "beta";
|
||||||
hello.As<BodyAspect>().Text = "gamma";
|
hello.As<BodyAspect>().Text = "gamma";
|
||||||
|
|
||||||
var query = new StubQuery(new[] {
|
var query = new StubQuery(new[] {
|
||||||
|
@@ -1,47 +0,0 @@
|
|||||||
using System.Web.Mvc;
|
|
||||||
using Orchard.ContentManagement;
|
|
||||||
using Orchard.ContentManagement.Aspects;
|
|
||||||
using Orchard.Core.Common.Models;
|
|
||||||
using Orchard.Localization;
|
|
||||||
|
|
||||||
namespace Orchard.Core.Common.Controllers {
|
|
||||||
public class RoutableController : Controller, IUpdateModel {
|
|
||||||
private readonly IContentManager _contentManager;
|
|
||||||
|
|
||||||
public RoutableController(IContentManager contentManager) {
|
|
||||||
_contentManager = contentManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpPost]
|
|
||||||
public ActionResult Slugify(string contentType, int? id, int? containerId) {
|
|
||||||
const string slug = "";
|
|
||||||
ContentItem contentItem = null;
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(contentType))
|
|
||||||
return Json(slug);
|
|
||||||
|
|
||||||
if (id != null)
|
|
||||||
contentItem = _contentManager.Get((int) id);
|
|
||||||
|
|
||||||
if (contentItem == null)
|
|
||||||
contentItem = _contentManager.New(contentType);
|
|
||||||
|
|
||||||
if (containerId != null) {
|
|
||||||
var containerItem = _contentManager.Get((int)containerId);
|
|
||||||
contentItem.As<ICommonAspect>().Container = containerItem;
|
|
||||||
}
|
|
||||||
|
|
||||||
_contentManager.UpdateEditorModel(contentItem, this);
|
|
||||||
|
|
||||||
return Json(contentItem.As<RoutableAspect>().Slug ?? slug);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IUpdateModel.TryUpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, string[] excludeProperties) {
|
|
||||||
return TryUpdateModel(model, prefix, includeProperties, excludeProperties);
|
|
||||||
}
|
|
||||||
|
|
||||||
void IUpdateModel.AddModelError(string key, LocalizedString errorMessage) {
|
|
||||||
ModelState.AddModelError(key, errorMessage.ToString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -29,14 +29,6 @@ namespace Orchard.Core.Common.DataMigrations {
|
|||||||
.Column<DateTime>("PublishedUtc")
|
.Column<DateTime>("PublishedUtc")
|
||||||
.Column<DateTime>("ModifiedUtc")
|
.Column<DateTime>("ModifiedUtc")
|
||||||
);
|
);
|
||||||
|
|
||||||
//CREATE TABLE Common_RoutableRecord (Id INTEGER not null, Title TEXT, Slug TEXT, Path TEXT, ContentItemRecord_id INTEGER, primary key (Id));
|
|
||||||
SchemaBuilder.CreateTable("RoutableRecord", table => table
|
|
||||||
.ContentPartVersionRecord()
|
|
||||||
.Column<string>("Title", column => column.WithLength(1024))
|
|
||||||
.Column<string>("Slug")
|
|
||||||
.Column<string>("Path", column => column.WithLength(2048))
|
|
||||||
);
|
|
||||||
|
|
||||||
return 0010;
|
return 0010;
|
||||||
}
|
}
|
||||||
|
@@ -6,6 +6,7 @@ using Orchard.ContentManagement.Drivers;
|
|||||||
using Orchard.Core.Common.Models;
|
using Orchard.Core.Common.Models;
|
||||||
using Orchard.Core.Common.Settings;
|
using Orchard.Core.Common.Settings;
|
||||||
using Orchard.Core.Common.ViewModels;
|
using Orchard.Core.Common.ViewModels;
|
||||||
|
using Orchard.Core.Routable.Models;
|
||||||
|
|
||||||
namespace Orchard.Core.Common.Drivers {
|
namespace Orchard.Core.Common.Drivers {
|
||||||
[UsedImplicitly]
|
[UsedImplicitly]
|
||||||
@@ -88,7 +89,7 @@ namespace Orchard.Core.Common.Drivers {
|
|||||||
if (common == null)
|
if (common == null)
|
||||||
return this;
|
return this;
|
||||||
|
|
||||||
var routable = common.Container.As<RoutableAspect>();
|
var routable = common.Container.As<IsRoutable>();
|
||||||
if (routable == null)
|
if (routable == null)
|
||||||
return this;
|
return this;
|
||||||
|
|
||||||
@@ -97,7 +98,7 @@ namespace Orchard.Core.Common.Drivers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public PathBuilder AddSlug() {
|
public PathBuilder AddSlug() {
|
||||||
var routable = _content.As<RoutableAspect>();
|
var routable = _content.As<IsRoutable>();
|
||||||
if (routable == null)
|
if (routable == null)
|
||||||
return this;
|
return this;
|
||||||
|
|
||||||
|
@@ -1,46 +0,0 @@
|
|||||||
using JetBrains.Annotations;
|
|
||||||
using Orchard.ContentManagement;
|
|
||||||
using Orchard.ContentManagement.Drivers;
|
|
||||||
using Orchard.Core.Common.Fields;
|
|
||||||
using Orchard.Core.Common.ViewModels;
|
|
||||||
|
|
||||||
namespace Orchard.Core.Common.Drivers {
|
|
||||||
[UsedImplicitly]
|
|
||||||
public class ItemReferenceContentFieldDriver : ContentFieldDriver<ItemReferenceContentField> {
|
|
||||||
public IOrchardServices Services { get; set; }
|
|
||||||
private const string TemplateName = "Fields/Common.ItemReferenceContentField";
|
|
||||||
|
|
||||||
public ItemReferenceContentFieldDriver(IOrchardServices services) {
|
|
||||||
Services = services;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override string Prefix {
|
|
||||||
get { return "ItemReferenceContentField"; }
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override DriverResult Display(ItemReferenceContentField field, string displayType) {
|
|
||||||
var model = new ItemReferenceContentFieldDisplayViewModel {
|
|
||||||
Item = Services.ContentManager.Get(field.ContentItemReference.Id)
|
|
||||||
};
|
|
||||||
|
|
||||||
return ContentFieldTemplate(model, TemplateName, Prefix);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override DriverResult Editor(ItemReferenceContentField field) {
|
|
||||||
var model = BuildEditorViewModel(field);
|
|
||||||
return ContentFieldTemplate(model, TemplateName, Prefix).Location("primary", "6");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override DriverResult Editor(ItemReferenceContentField field, IUpdateModel updater) {
|
|
||||||
var model = BuildEditorViewModel(field);
|
|
||||||
updater.TryUpdateModel(model, Prefix, null, null);
|
|
||||||
return ContentFieldTemplate(model, TemplateName, Prefix).Location("primary", "6");
|
|
||||||
}
|
|
||||||
|
|
||||||
private ItemReferenceContentFieldEditorViewModel BuildEditorViewModel(ItemReferenceContentField field) {
|
|
||||||
return new ItemReferenceContentFieldEditorViewModel {
|
|
||||||
Item = Services.ContentManager.Get(field.ContentItemReference.Id)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,54 +0,0 @@
|
|||||||
using JetBrains.Annotations;
|
|
||||||
using Orchard.ContentManagement;
|
|
||||||
using Orchard.ContentManagement.Drivers;
|
|
||||||
using Orchard.Core.Common.Models;
|
|
||||||
using Orchard.Core.Common.ViewModels;
|
|
||||||
using Orchard.Core.Common.Services;
|
|
||||||
using Orchard.Localization;
|
|
||||||
using Orchard.UI.Notify;
|
|
||||||
|
|
||||||
namespace Orchard.Core.Common.Drivers {
|
|
||||||
[UsedImplicitly]
|
|
||||||
public class Routable : ContentPartDriver<RoutableAspect> {
|
|
||||||
private const string TemplateName = "Parts/Common.Routable";
|
|
||||||
|
|
||||||
private readonly IOrchardServices _services;
|
|
||||||
private readonly IRoutableService _routableService;
|
|
||||||
public Localizer T { get; set; }
|
|
||||||
|
|
||||||
protected override string Prefix {
|
|
||||||
get { return "Routable"; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public Routable(IOrchardServices services, IRoutableService routableService)
|
|
||||||
{
|
|
||||||
_services = services;
|
|
||||||
_routableService = routableService;
|
|
||||||
|
|
||||||
T = NullLocalizer.Instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override DriverResult Editor(RoutableAspect part) {
|
|
||||||
var model = new RoutableEditorViewModel { Prefix = Prefix, RoutableAspect = part };
|
|
||||||
return ContentPartTemplate(model, TemplateName, Prefix).Location("primary", "before.5");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override DriverResult Editor(RoutableAspect part, IUpdateModel updater) {
|
|
||||||
var model = new RoutableEditorViewModel { Prefix = Prefix, RoutableAspect = part };
|
|
||||||
updater.TryUpdateModel(model, Prefix, null, null);
|
|
||||||
|
|
||||||
if (!_routableService.IsSlugValid(part.Slug)){
|
|
||||||
updater.AddModelError("Routable.Slug", T("Please do not use any of the following characters in your slugs: \"/\", \":\", \"?\", \"#\", \"[\", \"]\", \"@\", \"!\", \"$\", \"&\", \"'\", \"(\", \")\", \"*\", \"+\", \",\", \";\", \"=\". No spaces are allowed (please use dashes or underscores instead)."));
|
|
||||||
}
|
|
||||||
|
|
||||||
string originalSlug = part.Slug;
|
|
||||||
if(!_routableService.ProcessSlug(part)) {
|
|
||||||
_services.Notifier.Warning(T("Slugs in conflict. \"{0}\" is already set for a previously created {2} so now it has the slug \"{1}\"",
|
|
||||||
originalSlug, part.Slug, part.ContentItem.ContentType));
|
|
||||||
}
|
|
||||||
|
|
||||||
return ContentPartTemplate(model, TemplateName, Prefix).Location("primary", "before.5");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,65 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Web.Mvc;
|
|
||||||
using System.Web.Routing;
|
|
||||||
using JetBrains.Annotations;
|
|
||||||
using Orchard.ContentManagement;
|
|
||||||
using Orchard.ContentManagement.Drivers;
|
|
||||||
using Orchard.ContentManagement.Handlers;
|
|
||||||
using Orchard.Core.Common.Models;
|
|
||||||
using Orchard.Core.Common.Services;
|
|
||||||
using Orchard.Data;
|
|
||||||
|
|
||||||
namespace Orchard.Core.Common.Handlers {
|
|
||||||
[UsedImplicitly]
|
|
||||||
public class RoutableAspectHandler : ContentHandler {
|
|
||||||
private readonly IEnumerable<IContentItemDriver> _contentItemDrivers;
|
|
||||||
|
|
||||||
public RoutableAspectHandler(IRepository<RoutableRecord> repository, IEnumerable<IContentItemDriver> contentItemDrivers, IRoutableService routableService, UrlHelper urlHelper) {
|
|
||||||
_contentItemDrivers = contentItemDrivers;
|
|
||||||
|
|
||||||
Filters.Add(StorageFilter.For(repository));
|
|
||||||
|
|
||||||
OnGetEditorViewModel<RoutableAspect>((context, routable) => {
|
|
||||||
var currentDriver = GetDriver(context.ContentItem);
|
|
||||||
var tempContentItem = context.ContentItem.ContentManager.New(context.ContentItem.ContentType);
|
|
||||||
tempContentItem.As<RoutableAspect>().Slug = "ABCDEFG";
|
|
||||||
|
|
||||||
var routeValues = GetRouteValues(currentDriver, tempContentItem);
|
|
||||||
var url = urlHelper.RouteUrl(routeValues).Replace("/ABCDEFG", "");
|
|
||||||
|
|
||||||
if (url.StartsWith("/"))
|
|
||||||
url = url.Substring(1);
|
|
||||||
|
|
||||||
routable.ContentItemBasePath = url;
|
|
||||||
});
|
|
||||||
|
|
||||||
OnCreated<RoutableAspect>((context, ra) => routableService.ProcessSlug(ra));
|
|
||||||
|
|
||||||
OnIndexing<RoutableAspect>((context, part) => context.DocumentIndex
|
|
||||||
.Add("slug", part.Slug).Analyze().Store()
|
|
||||||
.Add("title", part.Title).Analyze()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static RouteValueDictionary GetRouteValues(IContentItemDriver driver, ContentItem contentItem) {
|
|
||||||
//TODO: (erikpo) Need to rearrange ContentItemDriver so reflection isn't needed here
|
|
||||||
var driverType = driver.GetType();
|
|
||||||
var method = driverType.GetMethod("GetDisplayRouteValues");
|
|
||||||
|
|
||||||
if (method != null) {
|
|
||||||
return (RouteValueDictionary)method.Invoke(driver, new object[] {contentItem.Get(driverType.BaseType.GetGenericArguments()[0])});
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private IContentItemDriver GetDriver(ContentItem contentItem) {
|
|
||||||
return
|
|
||||||
_contentItemDrivers
|
|
||||||
.Where(cid => cid.GetContentTypes().Any(ct => string.Compare(ct.Name, contentItem.ContentType, true) == 0))
|
|
||||||
//TODO: (erikpo) SingleOrDefault should be called here, but for some reason, the amount of drivers registered is doubled sometimes.
|
|
||||||
.FirstOrDefault();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,18 +0,0 @@
|
|||||||
using Orchard.ContentManagement;
|
|
||||||
using Orchard.ContentManagement.Aspects;
|
|
||||||
|
|
||||||
namespace Orchard.Core.Common.Models {
|
|
||||||
public class RoutableAspect : ContentPart<RoutableRecord>, IRoutableAspect {
|
|
||||||
public string ContentItemBasePath { get; set; }
|
|
||||||
|
|
||||||
public string Title {
|
|
||||||
get { return Record.Title; }
|
|
||||||
set { Record.Title = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Slug {
|
|
||||||
get { return Record.Slug; }
|
|
||||||
set { Record.Slug = value; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,24 +0,0 @@
|
|||||||
jQuery.fn.extend({
|
|
||||||
slugify: function(options) {
|
|
||||||
//todo: (heskew) need messaging system
|
|
||||||
if (!options.target || !options.url)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var args = {
|
|
||||||
"contentType": options.contentType,
|
|
||||||
"id": options.id,
|
|
||||||
"containerId": options.containerId,
|
|
||||||
__RequestVerificationToken: $("input[name=__RequestVerificationToken]").val()
|
|
||||||
};
|
|
||||||
args[$(this).attr("name")] = $(this).val();
|
|
||||||
|
|
||||||
jQuery.post(
|
|
||||||
options.url,
|
|
||||||
args,
|
|
||||||
function(data) {
|
|
||||||
options.target.val(data);
|
|
||||||
},
|
|
||||||
"json"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
@@ -1,28 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Orchard.Core.Common.Models;
|
|
||||||
|
|
||||||
namespace Orchard.Core.Common.Services {
|
|
||||||
public interface IRoutableService : IDependency {
|
|
||||||
void FillSlug<TModel>(TModel model) where TModel : RoutableAspect;
|
|
||||||
void FillSlug<TModel>(TModel model, Func<string, string> generateSlug) where TModel : RoutableAspect;
|
|
||||||
string GenerateUniqueSlug(string slugCandidate, IEnumerable<string> existingSlugs);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns any content item of the specified content type with similar slugs
|
|
||||||
/// </summary>
|
|
||||||
IEnumerable<RoutableAspect> GetSimilarSlugs(string contentType, string slug);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Validates the given slug
|
|
||||||
/// </summary>
|
|
||||||
bool IsSlugValid(string slug);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Defines the slug of a RoutableAspect and validate its unicity
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>True if the slug has been created, False if a conflict occured</returns>
|
|
||||||
bool ProcessSlug(RoutableAspect part);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,112 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using JetBrains.Annotations;
|
|
||||||
using Orchard.Core.Common.Models;
|
|
||||||
using Orchard.ContentManagement;
|
|
||||||
using Orchard.Localization;
|
|
||||||
using Orchard.UI.Notify;
|
|
||||||
|
|
||||||
namespace Orchard.Core.Common.Services {
|
|
||||||
[UsedImplicitly]
|
|
||||||
public class RoutableService : IRoutableService {
|
|
||||||
private readonly IContentManager _contentManager;
|
|
||||||
|
|
||||||
public RoutableService(IContentManager contentManager) {
|
|
||||||
_contentManager = contentManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void FillSlug<TModel>(TModel model) where TModel : RoutableAspect {
|
|
||||||
if (!string.IsNullOrEmpty(model.Slug) || string.IsNullOrEmpty(model.Title))
|
|
||||||
return;
|
|
||||||
|
|
||||||
var slug = model.Title;
|
|
||||||
var dissallowed = new Regex(@"[/:?#\[\]@!$&'()*+,;=\s]+");
|
|
||||||
|
|
||||||
slug = dissallowed.Replace(slug, "-");
|
|
||||||
slug = slug.Trim('-');
|
|
||||||
|
|
||||||
if (slug.Length > 1000)
|
|
||||||
slug = slug.Substring(0, 1000);
|
|
||||||
|
|
||||||
model.Slug = slug.ToLowerInvariant();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void FillSlug<TModel>(TModel model, Func<string, string> generateSlug) where TModel : RoutableAspect {
|
|
||||||
if (!string.IsNullOrEmpty(model.Slug) || string.IsNullOrEmpty(model.Title))
|
|
||||||
return;
|
|
||||||
|
|
||||||
model.Slug = generateSlug(model.Title).ToLowerInvariant();
|
|
||||||
}
|
|
||||||
|
|
||||||
public string GenerateUniqueSlug(string slugCandidate, IEnumerable<string> existingSlugs) {
|
|
||||||
if (existingSlugs == null || !existingSlugs.Contains(slugCandidate))
|
|
||||||
return slugCandidate;
|
|
||||||
|
|
||||||
int? version = existingSlugs.Select(s => GetSlugVersion(slugCandidate, s)).OrderBy(i => i).LastOrDefault();
|
|
||||||
|
|
||||||
return version != null
|
|
||||||
? string.Format("{0}-{1}", slugCandidate, version)
|
|
||||||
: slugCandidate;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int? GetSlugVersion(string slugCandidate, string slug) {
|
|
||||||
int v;
|
|
||||||
string[] slugParts = slug.Split(new []{slugCandidate}, StringSplitOptions.RemoveEmptyEntries);
|
|
||||||
|
|
||||||
if (slugParts.Length == 0)
|
|
||||||
return 2;
|
|
||||||
|
|
||||||
return int.TryParse(slugParts[0].TrimStart('-'), out v)
|
|
||||||
? (int?)++v
|
|
||||||
: null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<RoutableAspect> GetSimilarSlugs(string contentType, string slug)
|
|
||||||
{
|
|
||||||
return
|
|
||||||
_contentManager.Query(contentType).Join<RoutableRecord>()
|
|
||||||
.List()
|
|
||||||
.Select(i => i.As<RoutableAspect>())
|
|
||||||
.Where(routable => routable.Slug.StartsWith(slug, StringComparison.OrdinalIgnoreCase)) // todo: for some reason the filter doesn't work within the query, even without StringComparison or StartsWith
|
|
||||||
.ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsSlugValid(string slug) {
|
|
||||||
// see http://tools.ietf.org/html/rfc3987 for prohibited chars
|
|
||||||
return slug == null || String.IsNullOrEmpty(slug.Trim()) || Regex.IsMatch(slug, @"^[^/:?#\[\]@!$&'()*+,;=\s]+$");
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool ProcessSlug(RoutableAspect part)
|
|
||||||
{
|
|
||||||
FillSlug(part);
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(part.Slug))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
var slugsLikeThis = GetSimilarSlugs(part.ContentItem.ContentType, part.Slug);
|
|
||||||
|
|
||||||
// If the part is already a valid content item, don't include it in the list
|
|
||||||
// of slug to consider for conflict detection
|
|
||||||
if (part.ContentItem.Id != 0)
|
|
||||||
slugsLikeThis = slugsLikeThis.Where(p => p.ContentItem.Id != part.ContentItem.Id);
|
|
||||||
|
|
||||||
//todo: (heskew) need better messages
|
|
||||||
if (slugsLikeThis.Count() > 0)
|
|
||||||
{
|
|
||||||
var originalSlug = part.Slug;
|
|
||||||
//todo: (heskew) make auto-uniqueness optional
|
|
||||||
part.Slug = GenerateUniqueSlug(part.Slug, slugsLikeThis.Select(p => p.Slug));
|
|
||||||
|
|
||||||
if (originalSlug != part.Slug) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,20 +0,0 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
using Orchard.Core.Common.Models;
|
|
||||||
|
|
||||||
namespace Orchard.Core.Common.ViewModels {
|
|
||||||
public class RoutableEditorViewModel {
|
|
||||||
public string Prefix { get; set; }
|
|
||||||
public RoutableAspect RoutableAspect { get; set; }
|
|
||||||
|
|
||||||
[Required]
|
|
||||||
public string Title {
|
|
||||||
get { return RoutableAspect.Record.Title; }
|
|
||||||
set { RoutableAspect.Record.Title = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Slug {
|
|
||||||
get { return RoutableAspect.Record.Slug; }
|
|
||||||
set { RoutableAspect.Record.Slug = value; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,35 +0,0 @@
|
|||||||
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl<RoutableEditorViewModel>" %>
|
|
||||||
<%@ Import Namespace="Orchard.Utility.Extensions"%>
|
|
||||||
<%@ Import Namespace="Orchard.ContentManagement.Extenstions"%>
|
|
||||||
<%@ Import Namespace="Orchard.ContentManagement"%>
|
|
||||||
<%@ Import Namespace="Orchard.ContentManagement.Aspects"%>
|
|
||||||
<%@ Import Namespace="Orchard.Core.Common.ViewModels"%>
|
|
||||||
<% Html.RegisterFootScript("jquery.slugify.js"); %>
|
|
||||||
<fieldset>
|
|
||||||
<%: Html.LabelFor(m => m.Title) %>
|
|
||||||
<%: Html.TextBoxFor(m => m.Title, new { @class = "large text" }) %>
|
|
||||||
</fieldset>
|
|
||||||
<fieldset class="permalink">
|
|
||||||
<label class="sub" for="Slug"><%: T("Permalink")%><br /><span><%: Request.ToRootUrlString() %>/<%: Model.RoutableAspect.ContentItemBasePath %></span></label>
|
|
||||||
<span><%: Html.TextBoxFor(m => m.Slug, new { @class = "text" })%></span>
|
|
||||||
</fieldset>
|
|
||||||
<% using (this.Capture("end-of-page-scripts")) { %>
|
|
||||||
<script type="text/javascript">
|
|
||||||
$(function(){
|
|
||||||
//pull slug input from tab order
|
|
||||||
$("<%=String.Format("input#{0}Slug", !string.IsNullOrEmpty(Model.Prefix) ? Model.Prefix + "_" : "") %>").attr("tabindex",-1);
|
|
||||||
$("<%=String.Format("input#{0}Title", !string.IsNullOrEmpty(Model.Prefix) ? Model.Prefix + "_" : "") %>").blur(function(){
|
|
||||||
$(this).slugify({
|
|
||||||
target:$("<%=String.Format("input#{0}Slug", !string.IsNullOrEmpty(Model.Prefix) ? Model.Prefix + "_" : "") %>"),
|
|
||||||
url:"<%: Url.Slugify() %>",
|
|
||||||
contentType:"<%=Model.RoutableAspect.ContentItem.ContentType %>",
|
|
||||||
id:"<%=Model.RoutableAspect.ContentItem.Id %>"<%
|
|
||||||
var commonAspect = Model.RoutableAspect.ContentItem.As<ICommonAspect>();
|
|
||||||
var container = commonAspect != null ? commonAspect.Container : null;
|
|
||||||
if (container != null) { %>,
|
|
||||||
containerId:<%=container.ContentItem.Id %><%
|
|
||||||
} %>
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})</script>
|
|
||||||
<% } %>
|
|
@@ -4,6 +4,7 @@ using System.Web.Mvc;
|
|||||||
using System.Web.Routing;
|
using System.Web.Routing;
|
||||||
using Orchard.ContentManagement;
|
using Orchard.ContentManagement;
|
||||||
using Orchard.ContentManagement.MetaData;
|
using Orchard.ContentManagement.MetaData;
|
||||||
|
using Orchard.Core.Contents.Services;
|
||||||
using Orchard.Core.Contents.ViewModels;
|
using Orchard.Core.Contents.ViewModels;
|
||||||
using Orchard.Data;
|
using Orchard.Data;
|
||||||
using Orchard.Localization;
|
using Orchard.Localization;
|
||||||
@@ -19,18 +20,21 @@ namespace Orchard.Core.Contents.Controllers {
|
|||||||
private readonly IContentManager _contentManager;
|
private readonly IContentManager _contentManager;
|
||||||
private readonly IContentDefinitionManager _contentDefinitionManager;
|
private readonly IContentDefinitionManager _contentDefinitionManager;
|
||||||
private readonly ITransactionManager _transactionManager;
|
private readonly ITransactionManager _transactionManager;
|
||||||
|
private readonly IContentsService _contentsService;
|
||||||
|
|
||||||
public AdminController(
|
public AdminController(
|
||||||
IOrchardServices orchardServices,
|
IOrchardServices orchardServices,
|
||||||
INotifier notifier,
|
INotifier notifier,
|
||||||
IContentManager contentManager,
|
IContentManager contentManager,
|
||||||
IContentDefinitionManager contentDefinitionManager,
|
IContentDefinitionManager contentDefinitionManager,
|
||||||
ITransactionManager transactionManager) {
|
ITransactionManager transactionManager,
|
||||||
|
IContentsService contentsService) {
|
||||||
Services = orchardServices;
|
Services = orchardServices;
|
||||||
_notifier = notifier;
|
_notifier = notifier;
|
||||||
_contentManager = contentManager;
|
_contentManager = contentManager;
|
||||||
_contentDefinitionManager = contentDefinitionManager;
|
_contentDefinitionManager = contentDefinitionManager;
|
||||||
_transactionManager = transactionManager;
|
_transactionManager = transactionManager;
|
||||||
|
_contentsService = contentsService;
|
||||||
T = NullLocalizer.Instance;
|
T = NullLocalizer.Instance;
|
||||||
Logger = NullLogger.Instance;
|
Logger = NullLogger.Instance;
|
||||||
}
|
}
|
||||||
@@ -106,7 +110,7 @@ namespace Orchard.Core.Contents.Controllers {
|
|||||||
|
|
||||||
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
public ActionResult Create(CreateItemViewModel model) {
|
public ActionResult Create(CreateItemViewModel model, string command, DateTime? scheduledPublishUtc) {
|
||||||
//todo: need to integrate permissions into generic content management
|
//todo: need to integrate permissions into generic content management
|
||||||
var contentItem = _contentManager.New(model.Id);
|
var contentItem = _contentManager.New(model.Id);
|
||||||
model.Content = _contentManager.UpdateEditorModel(contentItem, this);
|
model.Content = _contentManager.UpdateEditorModel(contentItem, this);
|
||||||
@@ -114,15 +118,26 @@ namespace Orchard.Core.Contents.Controllers {
|
|||||||
_contentManager.Create(contentItem, VersionOptions.Draft);
|
_contentManager.Create(contentItem, VersionOptions.Draft);
|
||||||
model.Content = _contentManager.UpdateEditorModel(contentItem, this);
|
model.Content = _contentManager.UpdateEditorModel(contentItem, this);
|
||||||
}
|
}
|
||||||
if (ModelState.IsValid) {
|
|
||||||
_contentManager.Publish(contentItem);
|
|
||||||
}
|
|
||||||
if (!ModelState.IsValid) {
|
if (!ModelState.IsValid) {
|
||||||
_transactionManager.Cancel();
|
_transactionManager.Cancel();
|
||||||
PrepareEditorViewModel(model.Content);
|
PrepareEditorViewModel(model.Content);
|
||||||
return View("Create", model);
|
return View("Create", model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (command) {
|
||||||
|
case "PublishNow":
|
||||||
|
_contentsService.Publish(model.Content.Item);
|
||||||
|
Services.Notifier.Information(T("{0} has been published", contentItem.TypeDefinition.DisplayName));
|
||||||
|
break;
|
||||||
|
case "PublishLater":
|
||||||
|
_contentsService.Publish(model.Content.Item, scheduledPublishUtc.HasValue ? scheduledPublishUtc.Value : DateTime.MaxValue);
|
||||||
|
Services.Notifier.Information(T("{0} has been scheduled for publishing", contentItem.TypeDefinition.DisplayName));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Services.Notifier.Information(T("{0} draft has been saved", contentItem.TypeDefinition.DisplayName));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
_notifier.Information(T("Created content item"));
|
_notifier.Information(T("Created content item"));
|
||||||
return RedirectToAction("Edit", new RouteValueDictionary { { "Id", contentItem.Id } });
|
return RedirectToAction("Edit", new RouteValueDictionary { { "Id", contentItem.Id } });
|
||||||
}
|
}
|
||||||
@@ -138,7 +153,7 @@ namespace Orchard.Core.Contents.Controllers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
public ActionResult Edit(EditItemViewModel model) {
|
public ActionResult Edit(EditItemViewModel model, string command, DateTime? scheduledPublishUtc) {
|
||||||
var contentItem = _contentManager.Get(model.Id, VersionOptions.DraftRequired);
|
var contentItem = _contentManager.Get(model.Id, VersionOptions.DraftRequired);
|
||||||
model.Content = _contentManager.UpdateEditorModel(contentItem, this);
|
model.Content = _contentManager.UpdateEditorModel(contentItem, this);
|
||||||
if (!ModelState.IsValid) {
|
if (!ModelState.IsValid) {
|
||||||
@@ -146,13 +161,27 @@ namespace Orchard.Core.Contents.Controllers {
|
|||||||
PrepareEditorViewModel(model.Content);
|
PrepareEditorViewModel(model.Content);
|
||||||
return View("Edit", model);
|
return View("Edit", model);
|
||||||
}
|
}
|
||||||
_contentManager.Publish(contentItem);
|
|
||||||
|
switch (command) {
|
||||||
|
case "PublishNow":
|
||||||
|
_contentsService.Publish(model.Content.Item);
|
||||||
|
Services.Notifier.Information(T("{0} has been published", contentItem.TypeDefinition.DisplayName));
|
||||||
|
break;
|
||||||
|
case "PublishLater":
|
||||||
|
_contentsService.Publish(model.Content.Item, scheduledPublishUtc.HasValue ? scheduledPublishUtc.Value : DateTime.MaxValue);
|
||||||
|
Services.Notifier.Information(T("{0} has been scheduled for publishing", contentItem.TypeDefinition.DisplayName));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Services.Notifier.Information(T("{0} draft has been saved", contentItem.TypeDefinition.DisplayName));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return RedirectToAction("Edit", new RouteValueDictionary { { "Id", contentItem.Id } });
|
return RedirectToAction("Edit", new RouteValueDictionary { { "Id", contentItem.Id } });
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost, ActionName("Remove")]
|
[HttpPost, ActionName("Remove")]
|
||||||
public ActionResult RemovePOST(int id, string returnUrl) {
|
public ActionResult RemovePOST(int id, string returnUrl) {
|
||||||
var contentItem = _contentManager.Get(id);
|
var contentItem = _contentManager.Get(id, VersionOptions.Latest);
|
||||||
if (contentItem != null)
|
if (contentItem != null)
|
||||||
_contentManager.Remove(contentItem);
|
_contentManager.Remove(contentItem);
|
||||||
|
|
||||||
|
26
src/Orchard.Web/Core/Contents/Services/ContentsService.cs
Normal file
26
src/Orchard.Web/Core/Contents/Services/ContentsService.cs
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Orchard.ContentManagement;
|
||||||
|
using Orchard.Tasks.Scheduling;
|
||||||
|
|
||||||
|
namespace Orchard.Core.Contents.Services {
|
||||||
|
public class ContentsService : IContentsService {
|
||||||
|
private readonly IContentManager _contentManager;
|
||||||
|
private readonly IPublishingTaskManager _publishingTaskManager;
|
||||||
|
|
||||||
|
public ContentsService(IContentManager contentManager, IPublishingTaskManager publishingTaskManager) {
|
||||||
|
_contentManager = contentManager;
|
||||||
|
_publishingTaskManager = publishingTaskManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IContentsService.Publish(ContentItem contentItem) {
|
||||||
|
_publishingTaskManager.DeleteTasks(contentItem);
|
||||||
|
_contentManager.Publish(contentItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IContentsService.Publish(ContentItem contentItem, DateTime scheduledPublishUtc) {
|
||||||
|
_publishingTaskManager.Publish(contentItem, scheduledPublishUtc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,9 @@
|
|||||||
|
using System;
|
||||||
|
using Orchard.ContentManagement;
|
||||||
|
|
||||||
|
namespace Orchard.Core.Contents.Services {
|
||||||
|
public interface IContentsService : IDependency {
|
||||||
|
void Publish(ContentItem contentItem);
|
||||||
|
void Publish(ContentItem contentItem, DateTime scheduledPublishUtc);
|
||||||
|
}
|
||||||
|
}
|
@@ -3,20 +3,21 @@ using System.Web.Routing;
|
|||||||
using Orchard.ContentManagement;
|
using Orchard.ContentManagement;
|
||||||
using Orchard.ContentManagement.Aspects;
|
using Orchard.ContentManagement.Aspects;
|
||||||
using Orchard.Core.Common.Models;
|
using Orchard.Core.Common.Models;
|
||||||
|
using Orchard.Core.Routable.Models;
|
||||||
|
|
||||||
namespace Orchard.Core.Feeds.StandardBuilders {
|
namespace Orchard.Core.Feeds.StandardBuilders {
|
||||||
public class ItemInspector {
|
public class ItemInspector {
|
||||||
private readonly IContent _item;
|
private readonly IContent _item;
|
||||||
private readonly ContentItemMetadata _metadata;
|
private readonly ContentItemMetadata _metadata;
|
||||||
private readonly ICommonAspect _common;
|
private readonly ICommonAspect _common;
|
||||||
private readonly RoutableAspect _routable;
|
private readonly IsRoutable _routable;
|
||||||
private readonly BodyAspect _body;
|
private readonly BodyAspect _body;
|
||||||
|
|
||||||
public ItemInspector(IContent item, ContentItemMetadata metadata) {
|
public ItemInspector(IContent item, ContentItemMetadata metadata) {
|
||||||
_item = item;
|
_item = item;
|
||||||
_metadata = metadata;
|
_metadata = metadata;
|
||||||
_common = item.Get<ICommonAspect>();
|
_common = item.Get<ICommonAspect>();
|
||||||
_routable = item.Get<RoutableAspect>();
|
_routable = item.Get<IsRoutable>();
|
||||||
_body = item.Get<BodyAspect>();
|
_body = item.Get<BodyAspect>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -9,6 +9,7 @@ using Orchard.Localization;
|
|||||||
using Orchard.Localization.Services;
|
using Orchard.Localization.Services;
|
||||||
using Orchard.Mvc.Results;
|
using Orchard.Mvc.Results;
|
||||||
using Orchard.Mvc.ViewModels;
|
using Orchard.Mvc.ViewModels;
|
||||||
|
using Orchard.UI.Notify;
|
||||||
|
|
||||||
namespace Orchard.Core.Localization.Controllers {
|
namespace Orchard.Core.Localization.Controllers {
|
||||||
[ValidateInput(false)]
|
[ValidateInput(false)]
|
||||||
@@ -21,9 +22,11 @@ namespace Orchard.Core.Localization.Controllers {
|
|||||||
_contentManager = contentManager;
|
_contentManager = contentManager;
|
||||||
_cultureManager = cultureManager;
|
_cultureManager = cultureManager;
|
||||||
_localizationService = localizationService;
|
_localizationService = localizationService;
|
||||||
|
T = NullLocalizer.Instance;
|
||||||
Services = orchardServices;
|
Services = orchardServices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Localizer T { get; set; }
|
||||||
public IOrchardServices Services { get; set; }
|
public IOrchardServices Services { get; set; }
|
||||||
|
|
||||||
public ActionResult Translate(int id, string to) {
|
public ActionResult Translate(int id, string to) {
|
||||||
@@ -47,8 +50,8 @@ namespace Orchard.Core.Localization.Controllers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost, ActionName("Translate")]
|
[HttpPost, ActionName("Translate")]
|
||||||
public ActionResult TranslatePOST(int id) {
|
public ActionResult TranslatePOST(int id, string command, DateTime? scheduledPublishUtc) {
|
||||||
var contentItem = _contentManager.Get(id, VersionOptions.DraftRequired);
|
var contentItem = _contentManager.Get(id, VersionOptions.Latest);
|
||||||
|
|
||||||
if (contentItem == null)
|
if (contentItem == null)
|
||||||
return new NotFoundResult();
|
return new NotFoundResult();
|
||||||
@@ -59,7 +62,7 @@ namespace Orchard.Core.Localization.Controllers {
|
|||||||
ContentItem contentItemTranslation;
|
ContentItem contentItemTranslation;
|
||||||
var existingTranslation = _localizationService.GetLocalizedContentItem(contentItem, viewModel.SelectedCulture);
|
var existingTranslation = _localizationService.GetLocalizedContentItem(contentItem, viewModel.SelectedCulture);
|
||||||
if (existingTranslation != null) { // edit existing
|
if (existingTranslation != null) { // edit existing
|
||||||
contentItemTranslation = existingTranslation.ContentItem;
|
contentItemTranslation = _contentManager.Get(existingTranslation.ContentItem.Id, VersionOptions.DraftRequired);
|
||||||
}
|
}
|
||||||
else { // create
|
else { // create
|
||||||
contentItemTranslation = _contentManager.New(contentItem.ContentType);
|
contentItemTranslation = _contentManager.New(contentItem.ContentType);
|
||||||
@@ -79,7 +82,19 @@ namespace Orchard.Core.Localization.Controllers {
|
|||||||
return View(viewModel);
|
return View(viewModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
_contentManager.Publish(contentItemTranslation);
|
switch (command) {
|
||||||
|
case "PublishNow":
|
||||||
|
_localizationService.Publish(contentItemTranslation);
|
||||||
|
Services.Notifier.Information(T("{0} has been published", contentItem.TypeDefinition.DisplayName));
|
||||||
|
break;
|
||||||
|
case "PublishLater":
|
||||||
|
_localizationService.Publish(contentItemTranslation, scheduledPublishUtc.HasValue ? scheduledPublishUtc.Value : DateTime.MaxValue);
|
||||||
|
Services.Notifier.Information(T("{0} has been scheduled for publishing", contentItem.TypeDefinition.DisplayName));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Services.Notifier.Information(T("{0} draft has been saved", contentItem.TypeDefinition.DisplayName));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
var metadata = _contentManager.GetItemMetadata(viewModel.Content.Item);
|
var metadata = _contentManager.GetItemMetadata(viewModel.Content.Item);
|
||||||
if (metadata.EditorRouteValues == null)
|
if (metadata.EditorRouteValues == null)
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using Orchard.ContentManagement;
|
using Orchard.ContentManagement;
|
||||||
using Orchard.Core.Localization.Models;
|
using Orchard.Core.Localization.Models;
|
||||||
|
|
||||||
@@ -7,5 +8,7 @@ namespace Orchard.Core.Localization.Services {
|
|||||||
Localized GetLocalizedContentItem(IContent masterContentItem, string culture);
|
Localized GetLocalizedContentItem(IContent masterContentItem, string culture);
|
||||||
string GetContentCulture(IContent contentItem);
|
string GetContentCulture(IContent contentItem);
|
||||||
IEnumerable<IContent> GetLocalizations(IContent contentItem);
|
IEnumerable<IContent> GetLocalizations(IContent contentItem);
|
||||||
|
void Publish(ContentItem contentItem);
|
||||||
|
void Publish(ContentItem contentItem, DateTime scheduledPublishUtc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -4,15 +4,18 @@ using System.Linq;
|
|||||||
using Orchard.ContentManagement;
|
using Orchard.ContentManagement;
|
||||||
using Orchard.Core.Localization.Models;
|
using Orchard.Core.Localization.Models;
|
||||||
using Orchard.Localization.Services;
|
using Orchard.Localization.Services;
|
||||||
|
using Orchard.Tasks.Scheduling;
|
||||||
|
|
||||||
namespace Orchard.Core.Localization.Services {
|
namespace Orchard.Core.Localization.Services {
|
||||||
public class LocalizationService : ILocalizationService {
|
public class LocalizationService : ILocalizationService {
|
||||||
private readonly IContentManager _contentManager;
|
private readonly IContentManager _contentManager;
|
||||||
private readonly ICultureManager _cultureManager;
|
private readonly ICultureManager _cultureManager;
|
||||||
|
private readonly IPublishingTaskManager _publishingTaskManager;
|
||||||
|
|
||||||
public LocalizationService(IContentManager contentManager, ICultureManager cultureManager) {
|
public LocalizationService(IContentManager contentManager, ICultureManager cultureManager, IPublishingTaskManager publishingTaskManager) {
|
||||||
_contentManager = contentManager;
|
_contentManager = contentManager;
|
||||||
_cultureManager = cultureManager;
|
_cultureManager = cultureManager;
|
||||||
|
_publishingTaskManager = publishingTaskManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
Localized ILocalizationService.GetLocalizedContentItem(IContent content, string culture) {
|
Localized ILocalizationService.GetLocalizedContentItem(IContent content, string culture) {
|
||||||
@@ -43,5 +46,14 @@ namespace Orchard.Core.Localization.Services {
|
|||||||
.Select(i => i.As<Localized>())
|
.Select(i => i.As<Localized>())
|
||||||
.Where(l => l.MasterContentItem != null && l.MasterContentItem.ContentItem.Id == content.ContentItem.Id);
|
.Where(l => l.MasterContentItem != null && l.MasterContentItem.ContentItem.Id == content.ContentItem.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ILocalizationService.Publish(ContentItem contentItem) {
|
||||||
|
_publishingTaskManager.DeleteTasks(contentItem);
|
||||||
|
_contentManager.Publish(contentItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ILocalizationService.Publish(ContentItem contentItem, DateTime scheduledPublishUtc) {
|
||||||
|
_publishingTaskManager.Publish(contentItem, scheduledPublishUtc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -64,11 +64,8 @@
|
|||||||
<Compile Include="Common\DataMigrations\CommonDataMigration.cs" />
|
<Compile Include="Common\DataMigrations\CommonDataMigration.cs" />
|
||||||
<Compile Include="Common\Drivers\BodyDriver.cs" />
|
<Compile Include="Common\Drivers\BodyDriver.cs" />
|
||||||
<Compile Include="Common\Drivers\CommonDriver.cs" />
|
<Compile Include="Common\Drivers\CommonDriver.cs" />
|
||||||
<Compile Include="Common\Drivers\RoutableDriver.cs" />
|
|
||||||
<Compile Include="Common\Controllers\RoutableController.cs" />
|
|
||||||
<Compile Include="Common\Drivers\TextFieldDriver.cs" />
|
<Compile Include="Common\Drivers\TextFieldDriver.cs" />
|
||||||
<Compile Include="Common\Fields\TextField.cs" />
|
<Compile Include="Common\Fields\TextField.cs" />
|
||||||
<Compile Include="Common\Handlers\RoutableAspectHandler.cs" />
|
|
||||||
<Compile Include="Common\Services\ICommonService.cs" />
|
<Compile Include="Common\Services\ICommonService.cs" />
|
||||||
<Compile Include="Common\Services\CommonService.cs" />
|
<Compile Include="Common\Services\CommonService.cs" />
|
||||||
<Compile Include="Common\Settings\BodySettings.cs" />
|
<Compile Include="Common\Settings\BodySettings.cs" />
|
||||||
@@ -79,6 +76,8 @@
|
|||||||
<Compile Include="Contents\Controllers\ItemController.cs" />
|
<Compile Include="Contents\Controllers\ItemController.cs" />
|
||||||
<Compile Include="Contents\Drivers\ContentsDriver.cs" />
|
<Compile Include="Contents\Drivers\ContentsDriver.cs" />
|
||||||
<Compile Include="Contents\Handlers\ContentsHandler.cs" />
|
<Compile Include="Contents\Handlers\ContentsHandler.cs" />
|
||||||
|
<Compile Include="Contents\Services\IContentsService.cs" />
|
||||||
|
<Compile Include="Contents\Services\ContentsService.cs" />
|
||||||
<Compile Include="Contents\ViewModels\EditItemViewModel.cs" />
|
<Compile Include="Contents\ViewModels\EditItemViewModel.cs" />
|
||||||
<Compile Include="Contents\ViewModels\ListContentsViewModel.cs" />
|
<Compile Include="Contents\ViewModels\ListContentsViewModel.cs" />
|
||||||
<Compile Include="Contents\ViewModels\ListContentTypesViewModel.cs" />
|
<Compile Include="Contents\ViewModels\ListContentTypesViewModel.cs" />
|
||||||
@@ -97,6 +96,7 @@
|
|||||||
<Compile Include="Reports\ViewModels\DisplayReportViewModel.cs" />
|
<Compile Include="Reports\ViewModels\DisplayReportViewModel.cs" />
|
||||||
<Compile Include="Reports\ViewModels\ReportsAdminIndexViewModel.cs" />
|
<Compile Include="Reports\ViewModels\ReportsAdminIndexViewModel.cs" />
|
||||||
<Compile Include="Routable\Controllers\ItemController.cs" />
|
<Compile Include="Routable\Controllers\ItemController.cs" />
|
||||||
|
<Compile Include="Routable\DataMigrations\RoutableDataMigration.cs" />
|
||||||
<Compile Include="Routable\Drivers\RoutableDriver.cs" />
|
<Compile Include="Routable\Drivers\RoutableDriver.cs" />
|
||||||
<Compile Include="Routable\Handlers\RoutableHandler.cs" />
|
<Compile Include="Routable\Handlers\RoutableHandler.cs" />
|
||||||
<Compile Include="Routable\IRoutablePathConstraint.cs" />
|
<Compile Include="Routable\IRoutablePathConstraint.cs" />
|
||||||
@@ -104,20 +104,15 @@
|
|||||||
<Compile Include="Common\Permissions.cs" />
|
<Compile Include="Common\Permissions.cs" />
|
||||||
<Compile Include="Common\Models\CommonVersionRecord.cs" />
|
<Compile Include="Common\Models\CommonVersionRecord.cs" />
|
||||||
<Compile Include="Common\Routes.cs" />
|
<Compile Include="Common\Routes.cs" />
|
||||||
<Compile Include="Common\Services\IRoutableService.cs" />
|
|
||||||
<Compile Include="Common\Services\RoutableService.cs" />
|
|
||||||
<Compile Include="Common\Utilities\LazyField.cs" />
|
<Compile Include="Common\Utilities\LazyField.cs" />
|
||||||
<Compile Include="Common\Handlers\CommonAspectHandler.cs" />
|
<Compile Include="Common\Handlers\CommonAspectHandler.cs" />
|
||||||
<Compile Include="Common\Models\CommonAspect.cs" />
|
<Compile Include="Common\Models\CommonAspect.cs" />
|
||||||
<Compile Include="Common\Handlers\BodyAspectHandler.cs" />
|
<Compile Include="Common\Handlers\BodyAspectHandler.cs" />
|
||||||
<Compile Include="Common\Models\BodyAspect.cs" />
|
<Compile Include="Common\Models\BodyAspect.cs" />
|
||||||
<Compile Include="Common\Models\RoutableAspect.cs" />
|
|
||||||
<Compile Include="Common\Models\BodyRecord.cs" />
|
<Compile Include="Common\Models\BodyRecord.cs" />
|
||||||
<Compile Include="Common\Models\CommonRecord.cs" />
|
<Compile Include="Common\Models\CommonRecord.cs" />
|
||||||
<Compile Include="Common\Models\RoutableRecord.cs" />
|
|
||||||
<Compile Include="Common\ViewModels\BodyDisplayViewModel.cs" />
|
<Compile Include="Common\ViewModels\BodyDisplayViewModel.cs" />
|
||||||
<Compile Include="Common\ViewModels\BodyEditorViewModel.cs" />
|
<Compile Include="Common\ViewModels\BodyEditorViewModel.cs" />
|
||||||
<Compile Include="Common\ViewModels\RoutableEditorViewModel.cs" />
|
|
||||||
<Compile Include="Common\ViewModels\OwnerEditorViewModel.cs" />
|
<Compile Include="Common\ViewModels\OwnerEditorViewModel.cs" />
|
||||||
<Compile Include="Contents\AdminMenu.cs" />
|
<Compile Include="Contents\AdminMenu.cs" />
|
||||||
<Compile Include="Contents\Controllers\AdminController.cs" />
|
<Compile Include="Contents\Controllers\AdminController.cs" />
|
||||||
@@ -165,6 +160,7 @@
|
|||||||
<Compile Include="Navigation\ViewModels\MenuItemEntry.cs" />
|
<Compile Include="Navigation\ViewModels\MenuItemEntry.cs" />
|
||||||
<Compile Include="Navigation\ViewModels\NavigationManagementViewModel.cs" />
|
<Compile Include="Navigation\ViewModels\NavigationManagementViewModel.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<Compile Include="Routable\Models\RoutableRecord.cs" />
|
||||||
<Compile Include="Routable\Routes.cs" />
|
<Compile Include="Routable\Routes.cs" />
|
||||||
<Compile Include="Routable\Services\IRoutableService.cs" />
|
<Compile Include="Routable\Services\IRoutableService.cs" />
|
||||||
<Compile Include="Routable\Services\RoutablePathConstraint.cs" />
|
<Compile Include="Routable\Services\RoutablePathConstraint.cs" />
|
||||||
@@ -285,9 +281,7 @@
|
|||||||
<Content Include="Common\Views\Web.config" />
|
<Content Include="Common\Views\Web.config" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="Common\Scripts\jquery.slugify.js" />
|
|
||||||
<Content Include="Common\Views\DisplayTemplates\Parts\Common.Body.ascx" />
|
<Content Include="Common\Views\DisplayTemplates\Parts\Common.Body.ascx" />
|
||||||
<Content Include="Common\Views\EditorTemplates\Parts\Common.Routable.ascx" />
|
|
||||||
<Content Include="Common\Views\EditorTemplates\Parts\Common.Body.ascx" />
|
<Content Include="Common\Views\EditorTemplates\Parts\Common.Body.ascx" />
|
||||||
<Content Include="Common\Views\EditorTemplates\Parts\Common.Owner.ascx" />
|
<Content Include="Common\Views\EditorTemplates\Parts\Common.Owner.ascx" />
|
||||||
<Content Include="Feeds\Module.txt" />
|
<Content Include="Feeds\Module.txt" />
|
||||||
|
@@ -0,0 +1,18 @@
|
|||||||
|
using Orchard.Data.Migration;
|
||||||
|
|
||||||
|
namespace Orchard.Core.Routable.DataMigrations {
|
||||||
|
public class RoutableDataMigration : DataMigrationImpl {
|
||||||
|
|
||||||
|
public int Create() {
|
||||||
|
//CREATE TABLE Routable_RoutableRecord (Id INTEGER not null, Title TEXT, Slug TEXT, Path TEXT, ContentItemRecord_id INTEGER, primary key (Id));
|
||||||
|
SchemaBuilder.CreateTable("RoutableRecord", table => table
|
||||||
|
.ContentPartVersionRecord()
|
||||||
|
.Column<string>("Title", column => column.WithLength(1024))
|
||||||
|
.Column<string>("Slug")
|
||||||
|
.Column<string>("Path", column => column.WithLength(2048))
|
||||||
|
);
|
||||||
|
|
||||||
|
return 0010;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -1,8 +1,6 @@
|
|||||||
using JetBrains.Annotations;
|
using Orchard.ContentManagement;
|
||||||
using Orchard.ContentManagement;
|
|
||||||
using Orchard.ContentManagement.Aspects;
|
using Orchard.ContentManagement.Aspects;
|
||||||
using Orchard.ContentManagement.Drivers;
|
using Orchard.ContentManagement.Drivers;
|
||||||
using Orchard.Core.Common.Models;
|
|
||||||
using Orchard.Core.Routable.Models;
|
using Orchard.Core.Routable.Models;
|
||||||
using Orchard.Core.Routable.Services;
|
using Orchard.Core.Routable.Services;
|
||||||
using Orchard.Core.Routable.ViewModels;
|
using Orchard.Core.Routable.ViewModels;
|
||||||
|
@@ -1,20 +1,11 @@
|
|||||||
using System.Web.Routing;
|
using Orchard.ContentManagement.Handlers;
|
||||||
using Orchard.ContentManagement;
|
|
||||||
using Orchard.ContentManagement.Handlers;
|
|
||||||
using Orchard.Core.Routable.Models;
|
using Orchard.Core.Routable.Models;
|
||||||
|
using Orchard.Data;
|
||||||
|
|
||||||
namespace Orchard.Core.Routable.Handlers {
|
namespace Orchard.Core.Routable.Handlers {
|
||||||
public class RoutableHandler : ContentHandlerBase {
|
public class RoutableHandler : ContentHandler {
|
||||||
public override void GetContentItemMetadata(GetContentItemMetadataContext context) {
|
public RoutableHandler(IRepository<RoutableRecord> repository) {
|
||||||
var routable = context.ContentItem.As<IsRoutable>();
|
Filters.Add(StorageFilter.For(repository));
|
||||||
if (routable != null) {
|
|
||||||
context.Metadata.DisplayRouteValues = new RouteValueDictionary {
|
|
||||||
{"Area", "Routable"},
|
|
||||||
{"Controller", "Item"},
|
|
||||||
{"Action", "Display"},
|
|
||||||
{"Path", context.ContentItem.As<IsRoutable>().Record.Path}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
using Orchard.ContentManagement;
|
using Orchard.ContentManagement;
|
||||||
using Orchard.ContentManagement.Aspects;
|
using Orchard.ContentManagement.Aspects;
|
||||||
using Orchard.Core.Common.Models;
|
|
||||||
|
|
||||||
namespace Orchard.Core.Routable.Models {
|
namespace Orchard.Core.Routable.Models {
|
||||||
public class IsRoutable : ContentPart<RoutableRecord>, IRoutableAspect {
|
public class IsRoutable : ContentPart<RoutableRecord>, IRoutableAspect {
|
||||||
@@ -13,6 +12,5 @@ namespace Orchard.Core.Routable.Models {
|
|||||||
get { return Record.Slug; }
|
get { return Record.Slug; }
|
||||||
set { Record.Slug = value; }
|
set { Record.Slug = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -1,8 +1,7 @@
|
|||||||
using System;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
using Orchard.ContentManagement.Records;
|
using Orchard.ContentManagement.Records;
|
||||||
|
|
||||||
namespace Orchard.Core.Common.Models {
|
namespace Orchard.Core.Routable.Models {
|
||||||
public class RoutableRecord : ContentPartVersionRecord {
|
public class RoutableRecord : ContentPartVersionRecord {
|
||||||
[StringLength(1024)]
|
[StringLength(1024)]
|
||||||
public virtual string Title { get; set; }
|
public virtual string Title { get; set; }
|
@@ -8,4 +8,4 @@ description: The routable module enables content items to be accessed through a
|
|||||||
features:
|
features:
|
||||||
Routable:
|
Routable:
|
||||||
Description: Routable content part.
|
Description: Routable content part.
|
||||||
Category: Core2
|
Category: Core
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Orchard.Core.Common.Models;
|
using Orchard.Core.Routable.Models;
|
||||||
using Orchard.Data;
|
using Orchard.Data;
|
||||||
using Orchard.Environment;
|
using Orchard.Environment;
|
||||||
using Orchard.Tasks;
|
using Orchard.Tasks;
|
||||||
|
@@ -2,15 +2,11 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using JetBrains.Annotations;
|
|
||||||
using Orchard.ContentManagement;
|
using Orchard.ContentManagement;
|
||||||
using Orchard.Core.Common.Models;
|
using Orchard.Core.Common.Models;
|
||||||
using Orchard.Core.Routable.Models;
|
using Orchard.Core.Routable.Models;
|
||||||
using Orchard.Localization;
|
|
||||||
using Orchard.UI.Notify;
|
|
||||||
|
|
||||||
namespace Orchard.Core.Routable.Services {
|
namespace Orchard.Core.Routable.Services {
|
||||||
[UsedImplicitly]
|
|
||||||
public class RoutableService : IRoutableService {
|
public class RoutableService : IRoutableService {
|
||||||
private readonly IContentManager _contentManager;
|
private readonly IContentManager _contentManager;
|
||||||
|
|
||||||
|
@@ -2,14 +2,13 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
using Orchard.Blogs.Models;
|
|
||||||
using Orchard.Commands;
|
using Orchard.Commands;
|
||||||
using Orchard.ContentManagement;
|
using Orchard.ContentManagement;
|
||||||
using Orchard.ContentManagement.Aspects;
|
using Orchard.ContentManagement.Aspects;
|
||||||
using Orchard.Core.Common.Models;
|
using Orchard.Core.Common.Models;
|
||||||
using Orchard.Core.Navigation.Models;
|
using Orchard.Core.Navigation.Models;
|
||||||
|
using Orchard.Core.Routable.Models;
|
||||||
using Orchard.Security;
|
using Orchard.Security;
|
||||||
using System.IO;
|
|
||||||
using Orchard.Blogs.Services;
|
using Orchard.Blogs.Services;
|
||||||
using Orchard.Core.Navigation.Services;
|
using Orchard.Core.Navigation.Services;
|
||||||
|
|
||||||
@@ -55,8 +54,8 @@ namespace Orchard.Blogs.Commands {
|
|||||||
|
|
||||||
var blog = _contentManager.New("Blog");
|
var blog = _contentManager.New("Blog");
|
||||||
blog.As<ICommonAspect>().Owner = admin;
|
blog.As<ICommonAspect>().Owner = admin;
|
||||||
blog.As<RoutableAspect>().Slug = Slug;
|
blog.As<IsRoutable>().Slug = Slug;
|
||||||
blog.As<RoutableAspect>().Title = Title;
|
blog.As<IsRoutable>().Title = Title;
|
||||||
if ( !String.IsNullOrWhiteSpace(MenuText) ) {
|
if ( !String.IsNullOrWhiteSpace(MenuText) ) {
|
||||||
blog.As<MenuPart>().OnMainMenu = true;
|
blog.As<MenuPart>().OnMainMenu = true;
|
||||||
blog.As<MenuPart>().MenuPosition = _menuService.Get().Select(menuPart => menuPart.MenuPosition).Max() + 1 + ".0";
|
blog.As<MenuPart>().MenuPosition = _menuService.Get().Select(menuPart => menuPart.MenuPosition).Max() + 1 + ".0";
|
||||||
@@ -98,8 +97,8 @@ namespace Orchard.Blogs.Commands {
|
|||||||
var post = _contentManager.New("BlogPost");
|
var post = _contentManager.New("BlogPost");
|
||||||
post.As<ICommonAspect>().Owner = admin;
|
post.As<ICommonAspect>().Owner = admin;
|
||||||
post.As<ICommonAspect>().Container = blog;
|
post.As<ICommonAspect>().Container = blog;
|
||||||
post.As<RoutableAspect>().Slug = Slugify(postName);
|
post.As<IsRoutable>().Slug = Slugify(postName);
|
||||||
post.As<RoutableAspect>().Title = postName;
|
post.As<IsRoutable>().Title = postName;
|
||||||
post.As<BodyAspect>().Text = item.Element("description").Value;
|
post.As<BodyAspect>().Text = item.Element("description").Value;
|
||||||
_contentManager.Create(post);
|
_contentManager.Create(post);
|
||||||
}
|
}
|
||||||
|
@@ -1,18 +1,13 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using System.Web.Routing;
|
using System.Web.Routing;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Orchard.Blogs.Models;
|
using Orchard.Blogs.Models;
|
||||||
using Orchard.Blogs.Services;
|
using Orchard.Blogs.Services;
|
||||||
using Orchard.ContentManagement;
|
using Orchard.ContentManagement;
|
||||||
using Orchard.ContentManagement.Drivers;
|
using Orchard.ContentManagement.Drivers;
|
||||||
using Orchard.Core.Common.Models;
|
|
||||||
using Orchard.Core.Common.Services;
|
|
||||||
using Orchard.Localization;
|
using Orchard.Localization;
|
||||||
using Orchard.Mvc.ViewModels;
|
using Orchard.Mvc.ViewModels;
|
||||||
using Orchard.UI.Notify;
|
|
||||||
|
|
||||||
namespace Orchard.Blogs.Drivers {
|
namespace Orchard.Blogs.Drivers {
|
||||||
[UsedImplicitly]
|
[UsedImplicitly]
|
||||||
|
@@ -5,7 +5,7 @@ using Orchard.Blogs.Models;
|
|||||||
using Orchard.Blogs.Services;
|
using Orchard.Blogs.Services;
|
||||||
using Orchard.ContentManagement;
|
using Orchard.ContentManagement;
|
||||||
using Orchard.ContentManagement.Drivers;
|
using Orchard.ContentManagement.Drivers;
|
||||||
using Orchard.Core.Common.Services;
|
using Orchard.Core.Routable.Services;
|
||||||
using Orchard.Localization;
|
using Orchard.Localization;
|
||||||
|
|
||||||
namespace Orchard.Blogs.Drivers {
|
namespace Orchard.Blogs.Drivers {
|
||||||
|
@@ -3,6 +3,7 @@ using Orchard.Blogs.Drivers;
|
|||||||
using Orchard.Blogs.Models;
|
using Orchard.Blogs.Models;
|
||||||
using Orchard.ContentManagement.Handlers;
|
using Orchard.ContentManagement.Handlers;
|
||||||
using Orchard.Core.Common.Models;
|
using Orchard.Core.Common.Models;
|
||||||
|
using Orchard.Core.Routable.Models;
|
||||||
using Orchard.Data;
|
using Orchard.Data;
|
||||||
|
|
||||||
namespace Orchard.Blogs.Handlers {
|
namespace Orchard.Blogs.Handlers {
|
||||||
@@ -11,7 +12,7 @@ namespace Orchard.Blogs.Handlers {
|
|||||||
public BlogHandler(IRepository<BlogRecord> repository) {
|
public BlogHandler(IRepository<BlogRecord> repository) {
|
||||||
Filters.Add(new ActivatingFilter<Blog>(BlogDriver.ContentType.Name));
|
Filters.Add(new ActivatingFilter<Blog>(BlogDriver.ContentType.Name));
|
||||||
Filters.Add(new ActivatingFilter<CommonAspect>(BlogDriver.ContentType.Name));
|
Filters.Add(new ActivatingFilter<CommonAspect>(BlogDriver.ContentType.Name));
|
||||||
Filters.Add(new ActivatingFilter<RoutableAspect>(BlogDriver.ContentType.Name));
|
Filters.Add(new ActivatingFilter<IsRoutable>(BlogDriver.ContentType.Name));
|
||||||
Filters.Add(StorageFilter.For(repository));
|
Filters.Add(StorageFilter.For(repository));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -8,6 +8,7 @@ using Orchard.Blogs.Services;
|
|||||||
using Orchard.ContentManagement;
|
using Orchard.ContentManagement;
|
||||||
using Orchard.Core.Common.Models;
|
using Orchard.Core.Common.Models;
|
||||||
using Orchard.ContentManagement.Handlers;
|
using Orchard.ContentManagement.Handlers;
|
||||||
|
using Orchard.Core.Routable.Models;
|
||||||
using Orchard.Localization;
|
using Orchard.Localization;
|
||||||
|
|
||||||
namespace Orchard.Blogs.Handlers {
|
namespace Orchard.Blogs.Handlers {
|
||||||
@@ -24,7 +25,7 @@ namespace Orchard.Blogs.Handlers {
|
|||||||
Filters.Add(new ActivatingFilter<BlogPost>(BlogPostDriver.ContentType.Name));
|
Filters.Add(new ActivatingFilter<BlogPost>(BlogPostDriver.ContentType.Name));
|
||||||
Filters.Add(new ActivatingFilter<CommonAspect>(BlogPostDriver.ContentType.Name));
|
Filters.Add(new ActivatingFilter<CommonAspect>(BlogPostDriver.ContentType.Name));
|
||||||
Filters.Add(new ActivatingFilter<ContentPart<CommonVersionRecord>>(BlogPostDriver.ContentType.Name));
|
Filters.Add(new ActivatingFilter<ContentPart<CommonVersionRecord>>(BlogPostDriver.ContentType.Name));
|
||||||
Filters.Add(new ActivatingFilter<RoutableAspect>(BlogPostDriver.ContentType.Name));
|
Filters.Add(new ActivatingFilter<IsRoutable>(BlogPostDriver.ContentType.Name));
|
||||||
Filters.Add(new ActivatingFilter<BodyAspect>(BlogPostDriver.ContentType.Name));
|
Filters.Add(new ActivatingFilter<BodyAspect>(BlogPostDriver.ContentType.Name));
|
||||||
|
|
||||||
OnLoaded<BlogPost>((context, p) => p.ScheduledPublishUtc = _blogPostService.GetScheduledPublishUtc(p));
|
OnLoaded<BlogPost>((context, p) => p.ScheduledPublishUtc = _blogPostService.GetScheduledPublishUtc(p));
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
using System.Web.Mvc;
|
using System.Web.Mvc;
|
||||||
using Orchard.Core.Common.Models;
|
|
||||||
using Orchard.ContentManagement;
|
using Orchard.ContentManagement;
|
||||||
|
using Orchard.Core.Routable.Models;
|
||||||
|
|
||||||
namespace Orchard.Blogs.Models {
|
namespace Orchard.Blogs.Models {
|
||||||
public class Blog : ContentPart<BlogRecord> {
|
public class Blog : ContentPart<BlogRecord> {
|
||||||
@@ -8,14 +8,14 @@ namespace Orchard.Blogs.Models {
|
|||||||
public int Id { get { return ContentItem.Id; } }
|
public int Id { get { return ContentItem.Id; } }
|
||||||
|
|
||||||
public string Name {
|
public string Name {
|
||||||
get { return this.As<RoutableAspect>().Title; }
|
get { return this.As<IsRoutable>().Title; }
|
||||||
set { this.As<RoutableAspect>().Title = value; }
|
set { this.As<IsRoutable>().Title = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: (erikpo) Need a data type for slug
|
//TODO: (erikpo) Need a data type for slug
|
||||||
public string Slug {
|
public string Slug {
|
||||||
get { return this.As<RoutableAspect>().Slug; }
|
get { return this.As<IsRoutable>().Slug; }
|
||||||
set { this.As<RoutableAspect>().Slug = value; }
|
set { this.As<IsRoutable>().Slug = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Description {
|
public string Description {
|
||||||
|
@@ -3,6 +3,7 @@ using System.Web.Mvc;
|
|||||||
using Orchard.ContentManagement;
|
using Orchard.ContentManagement;
|
||||||
using Orchard.ContentManagement.Aspects;
|
using Orchard.ContentManagement.Aspects;
|
||||||
using Orchard.Core.Common.Models;
|
using Orchard.Core.Common.Models;
|
||||||
|
using Orchard.Core.Routable.Models;
|
||||||
using Orchard.Security;
|
using Orchard.Security;
|
||||||
|
|
||||||
namespace Orchard.Blogs.Models {
|
namespace Orchard.Blogs.Models {
|
||||||
@@ -13,13 +14,13 @@ namespace Orchard.Blogs.Models {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public string Title {
|
public string Title {
|
||||||
get { return this.As<RoutableAspect>().Title; }
|
get { return this.As<IsRoutable>().Title; }
|
||||||
set { this.As<RoutableAspect>().Title = value; }
|
set { this.As<IsRoutable>().Title = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Slug {
|
public string Slug {
|
||||||
get { return this.As<RoutableAspect>().Slug; }
|
get { return this.As<IsRoutable>().Slug; }
|
||||||
set { this.As<RoutableAspect>().Slug = value; }
|
set { this.As<IsRoutable>().Slug = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Text {
|
public string Text {
|
||||||
|
@@ -6,6 +6,7 @@ using Orchard.Blogs.Drivers;
|
|||||||
using Orchard.Blogs.Models;
|
using Orchard.Blogs.Models;
|
||||||
using Orchard.Core.Common.Models;
|
using Orchard.Core.Common.Models;
|
||||||
using Orchard.ContentManagement;
|
using Orchard.ContentManagement;
|
||||||
|
using Orchard.Core.Routable.Models;
|
||||||
using Orchard.Data;
|
using Orchard.Data;
|
||||||
using Orchard.Tasks.Scheduling;
|
using Orchard.Tasks.Scheduling;
|
||||||
|
|
||||||
|
@@ -5,6 +5,7 @@ using Orchard.Blogs.Models;
|
|||||||
using Orchard.Blogs.Routing;
|
using Orchard.Blogs.Routing;
|
||||||
using Orchard.Core.Common.Models;
|
using Orchard.Core.Common.Models;
|
||||||
using Orchard.ContentManagement;
|
using Orchard.ContentManagement;
|
||||||
|
using Orchard.Core.Routable.Models;
|
||||||
|
|
||||||
namespace Orchard.Blogs.Services {
|
namespace Orchard.Blogs.Services {
|
||||||
[UsedImplicitly]
|
[UsedImplicitly]
|
||||||
|
@@ -2,9 +2,7 @@
|
|||||||
<%@ Import Namespace="Orchard.Mvc.ViewModels"%>
|
<%@ Import Namespace="Orchard.Mvc.ViewModels"%>
|
||||||
<%@ Import Namespace="Orchard.Blogs.Extensions"%>
|
<%@ Import Namespace="Orchard.Blogs.Extensions"%>
|
||||||
<%@ Import Namespace="Orchard.Blogs.Models"%>
|
<%@ Import Namespace="Orchard.Blogs.Models"%>
|
||||||
<h1><a href="<%: Url.BlogForAdmin(Model.Item.Slug) %>"><%: Html.TitleForPage(Model.Item.Name) %></a>
|
<h1><a href="<%: Url.BlogForAdmin(Model.Item.Slug) %>"><%: Html.TitleForPage(Model.Item.Name) %></a></h1>
|
||||||
|
|
||||||
</h1>
|
|
||||||
<% Html.Zone("manage"); %><%--
|
<% Html.Zone("manage"); %><%--
|
||||||
<form>
|
<form>
|
||||||
<div class="actions bulk">
|
<div class="actions bulk">
|
||||||
|
@@ -3,6 +3,7 @@ using Orchard.ContentManagement;
|
|||||||
using Orchard.ContentManagement.Aspects;
|
using Orchard.ContentManagement.Aspects;
|
||||||
using Orchard.Core.Common.Models;
|
using Orchard.Core.Common.Models;
|
||||||
using Orchard.Core.Navigation.Models;
|
using Orchard.Core.Navigation.Models;
|
||||||
|
using Orchard.Core.Routable.Models;
|
||||||
using Orchard.Environment.Extensions;
|
using Orchard.Environment.Extensions;
|
||||||
using Orchard.Security;
|
using Orchard.Security;
|
||||||
|
|
||||||
@@ -26,8 +27,8 @@ namespace Orchard.DevTools.Commands {
|
|||||||
var pageName = "page" + index;
|
var pageName = "page" + index;
|
||||||
var page = _contentManager.Create("Page", VersionOptions.Draft);
|
var page = _contentManager.Create("Page", VersionOptions.Draft);
|
||||||
page.As<ICommonAspect>().Owner = admin;
|
page.As<ICommonAspect>().Owner = admin;
|
||||||
page.As<RoutableAspect>().Slug = pageName;
|
page.As<IsRoutable>().Slug = pageName;
|
||||||
page.As<RoutableAspect>().Title = pageName;
|
page.As<IsRoutable>().Title = pageName;
|
||||||
page.As<BodyAspect>().Text = pageName;
|
page.As<BodyAspect>().Text = pageName;
|
||||||
page.As<MenuPart>().OnMainMenu = true;
|
page.As<MenuPart>().OnMainMenu = true;
|
||||||
page.As<MenuPart>().MenuPosition = "5." + index;
|
page.As<MenuPart>().MenuPosition = "5." + index;
|
||||||
@@ -37,8 +38,8 @@ namespace Orchard.DevTools.Commands {
|
|||||||
var blogName = "blog" + index;
|
var blogName = "blog" + index;
|
||||||
var blog = _contentManager.New("Blog");
|
var blog = _contentManager.New("Blog");
|
||||||
blog.As<ICommonAspect>().Owner = admin;
|
blog.As<ICommonAspect>().Owner = admin;
|
||||||
blog.As<RoutableAspect>().Slug = blogName;
|
blog.As<IsRoutable>().Slug = blogName;
|
||||||
blog.As<RoutableAspect>().Title = blogName;
|
blog.As<IsRoutable>().Title = blogName;
|
||||||
blog.As<MenuPart>().OnMainMenu = true;
|
blog.As<MenuPart>().OnMainMenu = true;
|
||||||
blog.As<MenuPart>().MenuPosition = "6." + index;
|
blog.As<MenuPart>().MenuPosition = "6." + index;
|
||||||
blog.As<MenuPart>().MenuText = blogName;
|
blog.As<MenuPart>().MenuText = blogName;
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Orchard.ContentManagement;
|
using Orchard.ContentManagement;
|
||||||
|
using Orchard.Core.Routable.Models;
|
||||||
using Orchard.Localization;
|
using Orchard.Localization;
|
||||||
using Orchard.Core.Common.Models;
|
using Orchard.Core.Common.Models;
|
||||||
using Orchard.ContentManagement.Handlers;
|
using Orchard.ContentManagement.Handlers;
|
||||||
@@ -19,7 +20,7 @@ namespace Orchard.Pages.Handlers {
|
|||||||
Filters.Add(new ActivatingFilter<Page>(PageDriver.ContentType.Name));
|
Filters.Add(new ActivatingFilter<Page>(PageDriver.ContentType.Name));
|
||||||
Filters.Add(new ActivatingFilter<CommonAspect>(PageDriver.ContentType.Name));
|
Filters.Add(new ActivatingFilter<CommonAspect>(PageDriver.ContentType.Name));
|
||||||
Filters.Add(new ActivatingFilter<ContentPart<CommonVersionRecord>>(PageDriver.ContentType.Name));
|
Filters.Add(new ActivatingFilter<ContentPart<CommonVersionRecord>>(PageDriver.ContentType.Name));
|
||||||
Filters.Add(new ActivatingFilter<RoutableAspect>(PageDriver.ContentType.Name));
|
Filters.Add(new ActivatingFilter<IsRoutable>(PageDriver.ContentType.Name));
|
||||||
Filters.Add(new ActivatingFilter<BodyAspect>(PageDriver.ContentType.Name));
|
Filters.Add(new ActivatingFilter<BodyAspect>(PageDriver.ContentType.Name));
|
||||||
|
|
||||||
OnLoaded<Page>((context, page) => page._scheduledPublishUtc.Loader(value => _pageService.GetScheduledPublishUtc(page)));
|
OnLoaded<Page>((context, page) => page._scheduledPublishUtc.Loader(value => _pageService.GetScheduledPublishUtc(page)));
|
||||||
|
@@ -3,6 +3,7 @@ using System.Web.Mvc;
|
|||||||
using Orchard.ContentManagement;
|
using Orchard.ContentManagement;
|
||||||
using Orchard.ContentManagement.Utilities;
|
using Orchard.ContentManagement.Utilities;
|
||||||
using Orchard.Core.Common.Models;
|
using Orchard.Core.Common.Models;
|
||||||
|
using Orchard.Core.Routable.Models;
|
||||||
using Orchard.Security;
|
using Orchard.Security;
|
||||||
|
|
||||||
namespace Orchard.Pages.Models {
|
namespace Orchard.Pages.Models {
|
||||||
@@ -11,12 +12,12 @@ namespace Orchard.Pages.Models {
|
|||||||
public int Id { get { return ContentItem.Id; } }
|
public int Id { get { return ContentItem.Id; } }
|
||||||
|
|
||||||
public string Title {
|
public string Title {
|
||||||
get { return this.As<RoutableAspect>().Title; }
|
get { return this.As<IsRoutable>().Title; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Slug {
|
public string Slug {
|
||||||
get { return this.As<RoutableAspect>().Slug; }
|
get { return this.As<IsRoutable>().Slug; }
|
||||||
set { this.As<RoutableAspect>().Slug = value; }
|
set { this.As<IsRoutable>().Slug = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public IUser Creator {
|
public IUser Creator {
|
||||||
|
@@ -3,7 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Orchard.ContentManagement.Records;
|
using Orchard.ContentManagement.Records;
|
||||||
using Orchard.Core.Common.Models;
|
using Orchard.Core.Routable.Models;
|
||||||
using Orchard.Pages.Drivers;
|
using Orchard.Pages.Drivers;
|
||||||
using Orchard.Pages.Models;
|
using Orchard.Pages.Models;
|
||||||
using Orchard.ContentManagement;
|
using Orchard.ContentManagement;
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Orchard.Core.Common.Models;
|
using Orchard.Core.Common.Models;
|
||||||
|
using Orchard.Core.Routable.Models;
|
||||||
using Orchard.Data;
|
using Orchard.Data;
|
||||||
using Orchard.ContentManagement;
|
using Orchard.ContentManagement;
|
||||||
using Orchard.ContentManagement.Handlers;
|
using Orchard.ContentManagement.Handlers;
|
||||||
@@ -13,7 +14,7 @@ namespace Orchard.Sandbox.Handlers {
|
|||||||
// define the "SandboxPage" content type
|
// define the "SandboxPage" content type
|
||||||
Filters.Add(new ActivatingFilter<SandboxPage>(SandboxPageDriver.ContentType.Name));
|
Filters.Add(new ActivatingFilter<SandboxPage>(SandboxPageDriver.ContentType.Name));
|
||||||
Filters.Add(new ActivatingFilter<CommonAspect>(SandboxPageDriver.ContentType.Name));
|
Filters.Add(new ActivatingFilter<CommonAspect>(SandboxPageDriver.ContentType.Name));
|
||||||
Filters.Add(new ActivatingFilter<RoutableAspect>(SandboxPageDriver.ContentType.Name));
|
Filters.Add(new ActivatingFilter<IsRoutable>(SandboxPageDriver.ContentType.Name));
|
||||||
Filters.Add(new ActivatingFilter<BodyAspect>(SandboxPageDriver.ContentType.Name));
|
Filters.Add(new ActivatingFilter<BodyAspect>(SandboxPageDriver.ContentType.Name));
|
||||||
Filters.Add(StorageFilter.For(pageRepository) );
|
Filters.Add(StorageFilter.For(pageRepository) );
|
||||||
|
|
||||||
|
@@ -7,11 +7,10 @@ using Orchard.ContentManagement.MetaData;
|
|||||||
using Orchard.Core.Common.Models;
|
using Orchard.Core.Common.Models;
|
||||||
using Orchard.Core.Common.Settings;
|
using Orchard.Core.Common.Settings;
|
||||||
using Orchard.Core.Navigation.Models;
|
using Orchard.Core.Navigation.Models;
|
||||||
|
using Orchard.Core.Routable.Models;
|
||||||
using Orchard.Core.Settings.Models;
|
using Orchard.Core.Settings.Models;
|
||||||
using Orchard.Data;
|
using Orchard.Data;
|
||||||
using Orchard.Data.Migration.Generator;
|
|
||||||
using Orchard.Data.Migration.Interpreters;
|
using Orchard.Data.Migration.Interpreters;
|
||||||
using Orchard.Data.Providers;
|
|
||||||
using Orchard.Data.Migration.Schema;
|
using Orchard.Data.Migration.Schema;
|
||||||
using Orchard.Environment;
|
using Orchard.Environment;
|
||||||
using Orchard.Environment.Configuration;
|
using Orchard.Environment.Configuration;
|
||||||
@@ -76,6 +75,7 @@ namespace Orchard.Setup.Services {
|
|||||||
"Scheduling",
|
"Scheduling",
|
||||||
"Indexing",
|
"Indexing",
|
||||||
"Localization",
|
"Localization",
|
||||||
|
"Routable",
|
||||||
"Settings",
|
"Settings",
|
||||||
"XmlRpc",
|
"XmlRpc",
|
||||||
"Orchard.Users",
|
"Orchard.Users",
|
||||||
@@ -186,8 +186,8 @@ namespace Orchard.Setup.Services {
|
|||||||
// create home page as a CMS page
|
// create home page as a CMS page
|
||||||
var page = contentManager.Create("Page", VersionOptions.Draft);
|
var page = contentManager.Create("Page", VersionOptions.Draft);
|
||||||
page.As<BodyAspect>().Text = "<p>Welcome to Orchard!</p><p>Congratulations, you've successfully set-up your Orchard site.</p><p>This is the home page of your new site. We've taken the liberty to write here about a few things you could look at next in order to get familiar with the application. Once you feel confident you don't need this anymore, just click <a href=\"Admin/Pages/Edit/3\">Edit</a> to go into edit mode and replace this with whatever you want on your home page to make it your own.</p><p>One thing you could do (but you don't have to) is go into <a href=\"Admin/Settings\">Manage Settings</a> (follow the <a href=\"Admin\">Admin</a> link and then look for it under \"Settings\" in the menu on the left) and check that everything is configured the way you want.</p><p>You probably want to make the site your own. One of the ways you can do that is by clicking <a href=\"Admin/Themes\">Manage Themes</a> in the admin menu. A theme is a packaged look and feel that affects the whole site.</p><p>Next, you can start playing with the content types that we installed. For example, go ahead and click <a href=\"Admin/Pages/Create\">Add New Page</a> in the admin menu and create an \"about\" page. Then, add it to the navigation menu by going to <a href=\"Admin/Navigation\">Manage Menu</a>. You can also click <a href=\"Admin/Blogs/Create\">Add New Blog</a> and start posting by clicking \"Add New Post\".</p><p>Finally, Orchard has been designed to be extended. It comes with a few built-in modules such as pages and blogs or themes. You can install new themes by going to <a href=\"Admin/Themes\">Manage Themes</a> and clicking <a href=\"Admin/Themes/Install\">Install a new Theme</a>. Like for themes, modules are created by other users of Orchard just like you so if you feel up to it, please <a href=\"http://www.orchardproject.net/\">consider participating</a>.</p><p>--The Orchard Crew</p>";
|
page.As<BodyAspect>().Text = "<p>Welcome to Orchard!</p><p>Congratulations, you've successfully set-up your Orchard site.</p><p>This is the home page of your new site. We've taken the liberty to write here about a few things you could look at next in order to get familiar with the application. Once you feel confident you don't need this anymore, just click <a href=\"Admin/Pages/Edit/3\">Edit</a> to go into edit mode and replace this with whatever you want on your home page to make it your own.</p><p>One thing you could do (but you don't have to) is go into <a href=\"Admin/Settings\">Manage Settings</a> (follow the <a href=\"Admin\">Admin</a> link and then look for it under \"Settings\" in the menu on the left) and check that everything is configured the way you want.</p><p>You probably want to make the site your own. One of the ways you can do that is by clicking <a href=\"Admin/Themes\">Manage Themes</a> in the admin menu. A theme is a packaged look and feel that affects the whole site.</p><p>Next, you can start playing with the content types that we installed. For example, go ahead and click <a href=\"Admin/Pages/Create\">Add New Page</a> in the admin menu and create an \"about\" page. Then, add it to the navigation menu by going to <a href=\"Admin/Navigation\">Manage Menu</a>. You can also click <a href=\"Admin/Blogs/Create\">Add New Blog</a> and start posting by clicking \"Add New Post\".</p><p>Finally, Orchard has been designed to be extended. It comes with a few built-in modules such as pages and blogs or themes. You can install new themes by going to <a href=\"Admin/Themes\">Manage Themes</a> and clicking <a href=\"Admin/Themes/Install\">Install a new Theme</a>. Like for themes, modules are created by other users of Orchard just like you so if you feel up to it, please <a href=\"http://www.orchardproject.net/\">consider participating</a>.</p><p>--The Orchard Crew</p>";
|
||||||
page.As<RoutableAspect>().Slug = "home";
|
page.As<IsRoutable>().Slug = "home";
|
||||||
page.As<RoutableAspect>().Title = T("Home").ToString();
|
page.As<IsRoutable>().Title = T("Home").ToString();
|
||||||
page.As<CommonAspect>().Owner = user;
|
page.As<CommonAspect>().Owner = user;
|
||||||
if (page.Has<HasComments>()) {
|
if (page.Has<HasComments>()) {
|
||||||
page.As<HasComments>().CommentsShown = false;
|
page.As<HasComments>().CommentsShown = false;
|
||||||
|
Reference in New Issue
Block a user