diff --git a/src/Orchard.Core.Tests/Common/Services/RoutableServiceTests.cs b/src/Orchard.Core.Tests/Common/Services/RoutableServiceTests.cs index 51d5af0d7..c33b53dda 100644 --- a/src/Orchard.Core.Tests/Common/Services/RoutableServiceTests.cs +++ b/src/Orchard.Core.Tests/Common/Services/RoutableServiceTests.cs @@ -10,9 +10,10 @@ using Orchard.ContentManagement.Handlers; using Orchard.ContentManagement.MetaData; using Orchard.ContentManagement.Records; 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.Core.Common.Handlers; using System.Web.Mvc; using System.Web.Routing; using Orchard.Tests.Stubs; @@ -37,7 +38,7 @@ namespace Orchard.Core.Tests.Common.Services { builder.RegisterType().As(); builder.RegisterInstance(new UrlHelper(new RequestContext(new StubHttpContext("~/"), new RouteData()))).As(); - builder.RegisterType().As(); + builder.RegisterType().As(); } @@ -48,11 +49,11 @@ namespace Orchard.Core.Tests.Common.Services { var contentManager = _container.Resolve(); var thing = contentManager.Create(ThingDriver.ContentType.Name, t => { - t.As().Record = new RoutableRecord(); + t.As().Record = new RoutableRecord(); t.Title = "Please do not use any of the following characters in your slugs: \":\", \"/\", \"?\", \"#\", \"[\", \"]\", \"@\", \"!\", \"$\", \"&\", \"'\", \"(\", \")\", \"*\", \"+\", \",\", \";\", \"=\""; }); - _routableService.FillSlug(thing.As()); + _routableService.FillSlug(thing.As()); 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"; var thing = contentManager.Create(ThingDriver.ContentType.Name, t => { - t.As().Record = new RoutableRecord(); + t.As().Record = new RoutableRecord(); t.Title = veryVeryLongTitle; }); - _routableService.FillSlug(thing.As()); + _routableService.FillSlug(thing.As()); Assert.That(veryVeryLongTitle.Length, Is.AtLeast(1001)); Assert.That(thing.Slug.Length, Is.EqualTo(1000)); @@ -135,11 +136,11 @@ namespace Orchard.Core.Tests.Common.Services { var contentManager = _container.Resolve(); var thing = contentManager.Create(ThingDriver.ContentType.Name, t => { - t.As().Record = new RoutableRecord(); + t.As().Record = new RoutableRecord(); t.Title = "This Is Some Interesting Title"; }); - _routableService.FillSlug(thing.As()); + _routableService.FillSlug(thing.As()); 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(); var thing1 = contentManager.Create(ThingDriver.ContentType.Name, t => { - t.As().Record = new RoutableRecord(); + t.As().Record = new RoutableRecord(); t.Title = "This Is Some Interesting Title"; }); var thing2 = contentManager.Create(ThingDriver.ContentType.Name, t => { - t.As().Record = new RoutableRecord(); + t.As().Record = new RoutableRecord(); t.Title = "This Is Some Interesting Title"; }); @@ -166,12 +167,12 @@ namespace Orchard.Core.Tests.Common.Services { var contentManager = _container.Resolve(); var thing = contentManager.Create(ThingDriver.ContentType.Name, t => { - t.As().Record = new RoutableRecord(); + t.As().Record = new RoutableRecord(); t.Title = "This Is Some Interesting Title"; }); var stuff = contentManager.Create(StuffDriver.ContentType.Name, s => { - s.As().Record = new RoutableRecord(); + s.As().Record = new RoutableRecord(); s.Title = "This Is Some Interesting Title"; }); @@ -198,7 +199,7 @@ namespace Orchard.Core.Tests.Common.Services { Filters.Add(new ActivatingFilter(ThingDriver.ContentType.Name)); Filters.Add(new ActivatingFilter>(ThingDriver.ContentType.Name)); Filters.Add(new ActivatingFilter(ThingDriver.ContentType.Name)); - Filters.Add(new ActivatingFilter(ThingDriver.ContentType.Name)); + Filters.Add(new ActivatingFilter(ThingDriver.ContentType.Name)); } } @@ -206,13 +207,13 @@ namespace Orchard.Core.Tests.Common.Services { public int Id { get { return ContentItem.Id; } } public string Title { - get { return this.As().Title; } - set { this.As().Title = value; } + get { return this.As().Title; } + set { this.As().Title = value; } } public string Slug { - get { return this.As().Slug; } - set { this.As().Slug = value; } + get { return this.As().Slug; } + set { this.As().Slug = value; } } } @@ -229,7 +230,7 @@ namespace Orchard.Core.Tests.Common.Services { Filters.Add(new ActivatingFilter(StuffDriver.ContentType.Name)); Filters.Add(new ActivatingFilter>(StuffDriver.ContentType.Name)); Filters.Add(new ActivatingFilter(StuffDriver.ContentType.Name)); - Filters.Add(new ActivatingFilter(StuffDriver.ContentType.Name)); + Filters.Add(new ActivatingFilter(StuffDriver.ContentType.Name)); } } @@ -237,13 +238,13 @@ namespace Orchard.Core.Tests.Common.Services { public int Id { get { return ContentItem.Id; } } public string Title { - get { return this.As().Title; } - set { this.As().Title = value; } + get { return this.As().Title; } + set { this.As().Title = value; } } public string Slug { - get { return this.As().Slug; } - set { this.As().Slug = value; } + get { return this.As().Slug; } + set { this.As().Slug = value; } } } diff --git a/src/Orchard.Core.Tests/Feeds/Controllers/FeedControllerTests.cs b/src/Orchard.Core.Tests/Feeds/Controllers/FeedControllerTests.cs index 98504a380..91fe72ea1 100644 --- a/src/Orchard.Core.Tests/Feeds/Controllers/FeedControllerTests.cs +++ b/src/Orchard.Core.Tests/Feeds/Controllers/FeedControllerTests.cs @@ -10,13 +10,13 @@ using NUnit.Framework; using Orchard.ContentManagement; using Orchard.ContentManagement.Handlers; using Orchard.ContentManagement.MetaData.Builders; -using Orchard.ContentManagement.MetaData.Models; using Orchard.Core.Common.Models; using Orchard.Core.Feeds; using Orchard.Core.Feeds.Controllers; using Orchard.Core.Feeds.Models; using Orchard.Core.Feeds.Rss; using Orchard.Core.Feeds.StandardBuilders; +using Orchard.Core.Routable.Models; using Orchard.Mvc.Results; using Orchard.Tests.Modules; using Orchard.Tests.Stubs; @@ -149,16 +149,16 @@ namespace Orchard.Core.Tests.Feeds.Controllers { var clock = new StubClock(); var hello = new ContentItemBuilder(new ContentTypeDefinitionBuilder().Named("hello").Build()) .Weld() - .Weld() + .Weld() .Weld() .Build(); hello.As().Record = new CommonRecord(); - hello.As().Record = new RoutableRecord(); + hello.As().Record = new RoutableRecord(); hello.As().Record = new BodyRecord(); hello.As().PublishedUtc = clock.UtcNow; - hello.As().Title = "alpha"; - hello.As().Slug = "beta"; + hello.As().Title = "alpha"; + hello.As().Slug = "beta"; hello.As().Text = "gamma"; var query = new StubQuery(new[] { diff --git a/src/Orchard.Web/Core/Common/Controllers/RoutableController.cs b/src/Orchard.Web/Core/Common/Controllers/RoutableController.cs deleted file mode 100644 index 339c86002..000000000 --- a/src/Orchard.Web/Core/Common/Controllers/RoutableController.cs +++ /dev/null @@ -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().Container = containerItem; - } - - _contentManager.UpdateEditorModel(contentItem, this); - - return Json(contentItem.As().Slug ?? slug); - } - - bool IUpdateModel.TryUpdateModel(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()); - } - } -} \ No newline at end of file diff --git a/src/Orchard.Web/Core/Common/DataMigrations/CommonDataMigration.cs b/src/Orchard.Web/Core/Common/DataMigrations/CommonDataMigration.cs index cff7a7a9d..52ff185df 100644 --- a/src/Orchard.Web/Core/Common/DataMigrations/CommonDataMigration.cs +++ b/src/Orchard.Web/Core/Common/DataMigrations/CommonDataMigration.cs @@ -29,14 +29,6 @@ namespace Orchard.Core.Common.DataMigrations { .Column("PublishedUtc") .Column("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("Title", column => column.WithLength(1024)) - .Column("Slug") - .Column("Path", column => column.WithLength(2048)) - ); return 0010; } diff --git a/src/Orchard.Web/Core/Common/Drivers/BodyDriver.cs b/src/Orchard.Web/Core/Common/Drivers/BodyDriver.cs index 366d0854d..1c5ef6284 100644 --- a/src/Orchard.Web/Core/Common/Drivers/BodyDriver.cs +++ b/src/Orchard.Web/Core/Common/Drivers/BodyDriver.cs @@ -6,6 +6,7 @@ using Orchard.ContentManagement.Drivers; using Orchard.Core.Common.Models; using Orchard.Core.Common.Settings; using Orchard.Core.Common.ViewModels; +using Orchard.Core.Routable.Models; namespace Orchard.Core.Common.Drivers { [UsedImplicitly] @@ -88,7 +89,7 @@ namespace Orchard.Core.Common.Drivers { if (common == null) return this; - var routable = common.Container.As(); + var routable = common.Container.As(); if (routable == null) return this; @@ -97,7 +98,7 @@ namespace Orchard.Core.Common.Drivers { } public PathBuilder AddSlug() { - var routable = _content.As(); + var routable = _content.As(); if (routable == null) return this; diff --git a/src/Orchard.Web/Core/Common/Drivers/ItemReferenceContentFieldDriver.cs b/src/Orchard.Web/Core/Common/Drivers/ItemReferenceContentFieldDriver.cs deleted file mode 100644 index 2c2b3c8ba..000000000 --- a/src/Orchard.Web/Core/Common/Drivers/ItemReferenceContentFieldDriver.cs +++ /dev/null @@ -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 { - 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) - }; - } - } -} \ No newline at end of file diff --git a/src/Orchard.Web/Core/Common/Drivers/RoutableDriver.cs b/src/Orchard.Web/Core/Common/Drivers/RoutableDriver.cs deleted file mode 100644 index 2b05781cb..000000000 --- a/src/Orchard.Web/Core/Common/Drivers/RoutableDriver.cs +++ /dev/null @@ -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 { - 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"); - } - - } -} \ No newline at end of file diff --git a/src/Orchard.Web/Core/Common/Handlers/RoutableAspectHandler.cs b/src/Orchard.Web/Core/Common/Handlers/RoutableAspectHandler.cs deleted file mode 100644 index 6f5d574a8..000000000 --- a/src/Orchard.Web/Core/Common/Handlers/RoutableAspectHandler.cs +++ /dev/null @@ -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 _contentItemDrivers; - - public RoutableAspectHandler(IRepository repository, IEnumerable contentItemDrivers, IRoutableService routableService, UrlHelper urlHelper) { - _contentItemDrivers = contentItemDrivers; - - Filters.Add(StorageFilter.For(repository)); - - OnGetEditorViewModel((context, routable) => { - var currentDriver = GetDriver(context.ContentItem); - var tempContentItem = context.ContentItem.ContentManager.New(context.ContentItem.ContentType); - tempContentItem.As().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((context, ra) => routableService.ProcessSlug(ra)); - - OnIndexing((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(); - } - } -} \ No newline at end of file diff --git a/src/Orchard.Web/Core/Common/Models/RoutableAspect.cs b/src/Orchard.Web/Core/Common/Models/RoutableAspect.cs deleted file mode 100644 index 45fe93890..000000000 --- a/src/Orchard.Web/Core/Common/Models/RoutableAspect.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Orchard.ContentManagement; -using Orchard.ContentManagement.Aspects; - -namespace Orchard.Core.Common.Models { - public class RoutableAspect : ContentPart, 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; } - } - } -} diff --git a/src/Orchard.Web/Core/Common/Scripts/jquery.slugify.js b/src/Orchard.Web/Core/Common/Scripts/jquery.slugify.js deleted file mode 100644 index 070202125..000000000 --- a/src/Orchard.Web/Core/Common/Scripts/jquery.slugify.js +++ /dev/null @@ -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" - ); - } -}); \ No newline at end of file diff --git a/src/Orchard.Web/Core/Common/Services/IRoutableService.cs b/src/Orchard.Web/Core/Common/Services/IRoutableService.cs deleted file mode 100644 index 0519f07f2..000000000 --- a/src/Orchard.Web/Core/Common/Services/IRoutableService.cs +++ /dev/null @@ -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 model) where TModel : RoutableAspect; - void FillSlug(TModel model, Func generateSlug) where TModel : RoutableAspect; - string GenerateUniqueSlug(string slugCandidate, IEnumerable existingSlugs); - - /// - /// Returns any content item of the specified content type with similar slugs - /// - IEnumerable GetSimilarSlugs(string contentType, string slug); - - /// - /// Validates the given slug - /// - bool IsSlugValid(string slug); - - /// - /// Defines the slug of a RoutableAspect and validate its unicity - /// - /// True if the slug has been created, False if a conflict occured - bool ProcessSlug(RoutableAspect part); - - } -} \ No newline at end of file diff --git a/src/Orchard.Web/Core/Common/Services/RoutableService.cs b/src/Orchard.Web/Core/Common/Services/RoutableService.cs deleted file mode 100644 index 057ccf031..000000000 --- a/src/Orchard.Web/Core/Common/Services/RoutableService.cs +++ /dev/null @@ -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 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 model, Func 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 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 GetSimilarSlugs(string contentType, string slug) - { - return - _contentManager.Query(contentType).Join() - .List() - .Select(i => i.As()) - .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; - } - } -} \ No newline at end of file diff --git a/src/Orchard.Web/Core/Common/ViewModels/RoutableEditorViewModel.cs b/src/Orchard.Web/Core/Common/ViewModels/RoutableEditorViewModel.cs deleted file mode 100644 index 970caa58d..000000000 --- a/src/Orchard.Web/Core/Common/ViewModels/RoutableEditorViewModel.cs +++ /dev/null @@ -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; } - } - } -} \ No newline at end of file diff --git a/src/Orchard.Web/Core/Common/Views/EditorTemplates/Parts/Common.Routable.ascx b/src/Orchard.Web/Core/Common/Views/EditorTemplates/Parts/Common.Routable.ascx deleted file mode 100644 index cda27f412..000000000 --- a/src/Orchard.Web/Core/Common/Views/EditorTemplates/Parts/Common.Routable.ascx +++ /dev/null @@ -1,35 +0,0 @@ -<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl" %> -<%@ 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"); %> -
- <%: Html.LabelFor(m => m.Title) %> - <%: Html.TextBoxFor(m => m.Title, new { @class = "large text" }) %> -
- -<% using (this.Capture("end-of-page-scripts")) { %> - -<% } %> \ No newline at end of file diff --git a/src/Orchard.Web/Core/Contents/Controllers/AdminController.cs b/src/Orchard.Web/Core/Contents/Controllers/AdminController.cs index 5a43930d6..d65ca4880 100644 --- a/src/Orchard.Web/Core/Contents/Controllers/AdminController.cs +++ b/src/Orchard.Web/Core/Contents/Controllers/AdminController.cs @@ -4,6 +4,7 @@ using System.Web.Mvc; using System.Web.Routing; using Orchard.ContentManagement; using Orchard.ContentManagement.MetaData; +using Orchard.Core.Contents.Services; using Orchard.Core.Contents.ViewModels; using Orchard.Data; using Orchard.Localization; @@ -19,18 +20,21 @@ namespace Orchard.Core.Contents.Controllers { private readonly IContentManager _contentManager; private readonly IContentDefinitionManager _contentDefinitionManager; private readonly ITransactionManager _transactionManager; + private readonly IContentsService _contentsService; public AdminController( IOrchardServices orchardServices, INotifier notifier, IContentManager contentManager, IContentDefinitionManager contentDefinitionManager, - ITransactionManager transactionManager) { + ITransactionManager transactionManager, + IContentsService contentsService) { Services = orchardServices; _notifier = notifier; _contentManager = contentManager; _contentDefinitionManager = contentDefinitionManager; _transactionManager = transactionManager; + _contentsService = contentsService; T = NullLocalizer.Instance; Logger = NullLogger.Instance; } @@ -106,7 +110,7 @@ namespace Orchard.Core.Contents.Controllers { [HttpPost] - public ActionResult Create(CreateItemViewModel model) { + public ActionResult Create(CreateItemViewModel model, string command, DateTime? scheduledPublishUtc) { //todo: need to integrate permissions into generic content management var contentItem = _contentManager.New(model.Id); model.Content = _contentManager.UpdateEditorModel(contentItem, this); @@ -114,15 +118,26 @@ namespace Orchard.Core.Contents.Controllers { _contentManager.Create(contentItem, VersionOptions.Draft); model.Content = _contentManager.UpdateEditorModel(contentItem, this); } - if (ModelState.IsValid) { - _contentManager.Publish(contentItem); - } if (!ModelState.IsValid) { _transactionManager.Cancel(); PrepareEditorViewModel(model.Content); 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")); return RedirectToAction("Edit", new RouteValueDictionary { { "Id", contentItem.Id } }); } @@ -138,7 +153,7 @@ namespace Orchard.Core.Contents.Controllers { } [HttpPost] - public ActionResult Edit(EditItemViewModel model) { + public ActionResult Edit(EditItemViewModel model, string command, DateTime? scheduledPublishUtc) { var contentItem = _contentManager.Get(model.Id, VersionOptions.DraftRequired); model.Content = _contentManager.UpdateEditorModel(contentItem, this); if (!ModelState.IsValid) { @@ -146,13 +161,27 @@ namespace Orchard.Core.Contents.Controllers { PrepareEditorViewModel(model.Content); 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 } }); } [HttpPost, ActionName("Remove")] public ActionResult RemovePOST(int id, string returnUrl) { - var contentItem = _contentManager.Get(id); + var contentItem = _contentManager.Get(id, VersionOptions.Latest); if (contentItem != null) _contentManager.Remove(contentItem); diff --git a/src/Orchard.Web/Core/Contents/Services/ContentsService.cs b/src/Orchard.Web/Core/Contents/Services/ContentsService.cs new file mode 100644 index 000000000..84bf88a01 --- /dev/null +++ b/src/Orchard.Web/Core/Contents/Services/ContentsService.cs @@ -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); + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Core/Contents/Services/IContentsService.cs b/src/Orchard.Web/Core/Contents/Services/IContentsService.cs new file mode 100644 index 000000000..b6534b69b --- /dev/null +++ b/src/Orchard.Web/Core/Contents/Services/IContentsService.cs @@ -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); + } +} diff --git a/src/Orchard.Web/Core/Feeds/StandardBuilders/ItemInspector.cs b/src/Orchard.Web/Core/Feeds/StandardBuilders/ItemInspector.cs index e27948924..2d8c0c49c 100644 --- a/src/Orchard.Web/Core/Feeds/StandardBuilders/ItemInspector.cs +++ b/src/Orchard.Web/Core/Feeds/StandardBuilders/ItemInspector.cs @@ -3,20 +3,21 @@ using System.Web.Routing; using Orchard.ContentManagement; using Orchard.ContentManagement.Aspects; using Orchard.Core.Common.Models; +using Orchard.Core.Routable.Models; namespace Orchard.Core.Feeds.StandardBuilders { public class ItemInspector { private readonly IContent _item; private readonly ContentItemMetadata _metadata; private readonly ICommonAspect _common; - private readonly RoutableAspect _routable; + private readonly IsRoutable _routable; private readonly BodyAspect _body; public ItemInspector(IContent item, ContentItemMetadata metadata) { _item = item; _metadata = metadata; _common = item.Get(); - _routable = item.Get(); + _routable = item.Get(); _body = item.Get(); } diff --git a/src/Orchard.Web/Core/Localization/Controllers/AdminController.cs b/src/Orchard.Web/Core/Localization/Controllers/AdminController.cs index 6b8e8693e..a4a270758 100644 --- a/src/Orchard.Web/Core/Localization/Controllers/AdminController.cs +++ b/src/Orchard.Web/Core/Localization/Controllers/AdminController.cs @@ -9,6 +9,7 @@ using Orchard.Localization; using Orchard.Localization.Services; using Orchard.Mvc.Results; using Orchard.Mvc.ViewModels; +using Orchard.UI.Notify; namespace Orchard.Core.Localization.Controllers { [ValidateInput(false)] @@ -21,9 +22,11 @@ namespace Orchard.Core.Localization.Controllers { _contentManager = contentManager; _cultureManager = cultureManager; _localizationService = localizationService; + T = NullLocalizer.Instance; Services = orchardServices; } + public Localizer T { get; set; } public IOrchardServices Services { get; set; } public ActionResult Translate(int id, string to) { @@ -47,8 +50,8 @@ namespace Orchard.Core.Localization.Controllers { } [HttpPost, ActionName("Translate")] - public ActionResult TranslatePOST(int id) { - var contentItem = _contentManager.Get(id, VersionOptions.DraftRequired); + public ActionResult TranslatePOST(int id, string command, DateTime? scheduledPublishUtc) { + var contentItem = _contentManager.Get(id, VersionOptions.Latest); if (contentItem == null) return new NotFoundResult(); @@ -59,7 +62,7 @@ namespace Orchard.Core.Localization.Controllers { ContentItem contentItemTranslation; var existingTranslation = _localizationService.GetLocalizedContentItem(contentItem, viewModel.SelectedCulture); if (existingTranslation != null) { // edit existing - contentItemTranslation = existingTranslation.ContentItem; + contentItemTranslation = _contentManager.Get(existingTranslation.ContentItem.Id, VersionOptions.DraftRequired); } else { // create contentItemTranslation = _contentManager.New(contentItem.ContentType); @@ -79,7 +82,19 @@ namespace Orchard.Core.Localization.Controllers { 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); if (metadata.EditorRouteValues == null) diff --git a/src/Orchard.Web/Core/Localization/Services/ILocalizationService.cs b/src/Orchard.Web/Core/Localization/Services/ILocalizationService.cs index fc007499a..31ecc9795 100644 --- a/src/Orchard.Web/Core/Localization/Services/ILocalizationService.cs +++ b/src/Orchard.Web/Core/Localization/Services/ILocalizationService.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using Orchard.ContentManagement; using Orchard.Core.Localization.Models; @@ -7,5 +8,7 @@ namespace Orchard.Core.Localization.Services { Localized GetLocalizedContentItem(IContent masterContentItem, string culture); string GetContentCulture(IContent contentItem); IEnumerable GetLocalizations(IContent contentItem); + void Publish(ContentItem contentItem); + void Publish(ContentItem contentItem, DateTime scheduledPublishUtc); } } diff --git a/src/Orchard.Web/Core/Localization/Services/LocalizationService.cs b/src/Orchard.Web/Core/Localization/Services/LocalizationService.cs index c45750759..8df960fba 100644 --- a/src/Orchard.Web/Core/Localization/Services/LocalizationService.cs +++ b/src/Orchard.Web/Core/Localization/Services/LocalizationService.cs @@ -4,15 +4,18 @@ using System.Linq; using Orchard.ContentManagement; using Orchard.Core.Localization.Models; using Orchard.Localization.Services; +using Orchard.Tasks.Scheduling; namespace Orchard.Core.Localization.Services { public class LocalizationService : ILocalizationService { private readonly IContentManager _contentManager; private readonly ICultureManager _cultureManager; + private readonly IPublishingTaskManager _publishingTaskManager; - public LocalizationService(IContentManager contentManager, ICultureManager cultureManager) { + public LocalizationService(IContentManager contentManager, ICultureManager cultureManager, IPublishingTaskManager publishingTaskManager) { _contentManager = contentManager; _cultureManager = cultureManager; + _publishingTaskManager = publishingTaskManager; } Localized ILocalizationService.GetLocalizedContentItem(IContent content, string culture) { @@ -43,5 +46,14 @@ namespace Orchard.Core.Localization.Services { .Select(i => i.As()) .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); + } } } \ No newline at end of file diff --git a/src/Orchard.Web/Core/Orchard.Core.csproj b/src/Orchard.Web/Core/Orchard.Core.csproj index 39536e9c0..1679943a3 100644 --- a/src/Orchard.Web/Core/Orchard.Core.csproj +++ b/src/Orchard.Web/Core/Orchard.Core.csproj @@ -64,11 +64,8 @@ - - - @@ -79,6 +76,8 @@ + + @@ -97,6 +96,7 @@ + @@ -104,20 +104,15 @@ - - - - - @@ -165,6 +160,7 @@ + @@ -285,9 +281,7 @@ - - diff --git a/src/Orchard.Web/Core/Routable/DataMigrations/RoutableDataMigration.cs b/src/Orchard.Web/Core/Routable/DataMigrations/RoutableDataMigration.cs new file mode 100644 index 000000000..47544423d --- /dev/null +++ b/src/Orchard.Web/Core/Routable/DataMigrations/RoutableDataMigration.cs @@ -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("Title", column => column.WithLength(1024)) + .Column("Slug") + .Column("Path", column => column.WithLength(2048)) + ); + + return 0010; + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Core/Routable/Drivers/RoutableDriver.cs b/src/Orchard.Web/Core/Routable/Drivers/RoutableDriver.cs index b9b7fdbcc..8db6eb24c 100644 --- a/src/Orchard.Web/Core/Routable/Drivers/RoutableDriver.cs +++ b/src/Orchard.Web/Core/Routable/Drivers/RoutableDriver.cs @@ -1,8 +1,6 @@ -using JetBrains.Annotations; -using Orchard.ContentManagement; +using Orchard.ContentManagement; using Orchard.ContentManagement.Aspects; using Orchard.ContentManagement.Drivers; -using Orchard.Core.Common.Models; using Orchard.Core.Routable.Models; using Orchard.Core.Routable.Services; using Orchard.Core.Routable.ViewModels; diff --git a/src/Orchard.Web/Core/Routable/Handlers/RoutableHandler.cs b/src/Orchard.Web/Core/Routable/Handlers/RoutableHandler.cs index f83864661..3290854c7 100644 --- a/src/Orchard.Web/Core/Routable/Handlers/RoutableHandler.cs +++ b/src/Orchard.Web/Core/Routable/Handlers/RoutableHandler.cs @@ -1,20 +1,11 @@ -using System.Web.Routing; -using Orchard.ContentManagement; -using Orchard.ContentManagement.Handlers; +using Orchard.ContentManagement.Handlers; using Orchard.Core.Routable.Models; +using Orchard.Data; namespace Orchard.Core.Routable.Handlers { - public class RoutableHandler : ContentHandlerBase { - public override void GetContentItemMetadata(GetContentItemMetadataContext context) { - var routable = context.ContentItem.As(); - if (routable != null) { - context.Metadata.DisplayRouteValues = new RouteValueDictionary { - {"Area", "Routable"}, - {"Controller", "Item"}, - {"Action", "Display"}, - {"Path", context.ContentItem.As().Record.Path} - }; - } + public class RoutableHandler : ContentHandler { + public RoutableHandler(IRepository repository) { + Filters.Add(StorageFilter.For(repository)); } } } diff --git a/src/Orchard.Web/Core/Routable/Models/IsRoutable.cs b/src/Orchard.Web/Core/Routable/Models/IsRoutable.cs index bf877799a..29c55134b 100644 --- a/src/Orchard.Web/Core/Routable/Models/IsRoutable.cs +++ b/src/Orchard.Web/Core/Routable/Models/IsRoutable.cs @@ -1,6 +1,5 @@ using Orchard.ContentManagement; using Orchard.ContentManagement.Aspects; -using Orchard.Core.Common.Models; namespace Orchard.Core.Routable.Models { public class IsRoutable : ContentPart, IRoutableAspect { @@ -13,6 +12,5 @@ namespace Orchard.Core.Routable.Models { get { return Record.Slug; } set { Record.Slug = value; } } - } } \ No newline at end of file diff --git a/src/Orchard.Web/Core/Common/Models/RoutableRecord.cs b/src/Orchard.Web/Core/Routable/Models/RoutableRecord.cs similarity index 73% rename from src/Orchard.Web/Core/Common/Models/RoutableRecord.cs rename to src/Orchard.Web/Core/Routable/Models/RoutableRecord.cs index ea142a302..6b6c9030d 100644 --- a/src/Orchard.Web/Core/Common/Models/RoutableRecord.cs +++ b/src/Orchard.Web/Core/Routable/Models/RoutableRecord.cs @@ -1,8 +1,7 @@ -using System; -using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations; using Orchard.ContentManagement.Records; -namespace Orchard.Core.Common.Models { +namespace Orchard.Core.Routable.Models { public class RoutableRecord : ContentPartVersionRecord { [StringLength(1024)] public virtual string Title { get; set; } diff --git a/src/Orchard.Web/Core/Routable/Module.txt b/src/Orchard.Web/Core/Routable/Module.txt index f3305daed..f5a91698b 100644 --- a/src/Orchard.Web/Core/Routable/Module.txt +++ b/src/Orchard.Web/Core/Routable/Module.txt @@ -8,4 +8,4 @@ description: The routable module enables content items to be accessed through a features: Routable: Description: Routable content part. - Category: Core2 + Category: Core diff --git a/src/Orchard.Web/Core/Routable/Services/RoutablePathConstraintUpdator.cs b/src/Orchard.Web/Core/Routable/Services/RoutablePathConstraintUpdator.cs index 5f5a8eb3d..e9fcab916 100644 --- a/src/Orchard.Web/Core/Routable/Services/RoutablePathConstraintUpdator.cs +++ b/src/Orchard.Web/Core/Routable/Services/RoutablePathConstraintUpdator.cs @@ -1,6 +1,6 @@ using System.Linq; using JetBrains.Annotations; -using Orchard.Core.Common.Models; +using Orchard.Core.Routable.Models; using Orchard.Data; using Orchard.Environment; using Orchard.Tasks; diff --git a/src/Orchard.Web/Core/Routable/Services/RoutableService.cs b/src/Orchard.Web/Core/Routable/Services/RoutableService.cs index 4b27b4d1e..3b533b0c7 100644 --- a/src/Orchard.Web/Core/Routable/Services/RoutableService.cs +++ b/src/Orchard.Web/Core/Routable/Services/RoutableService.cs @@ -2,15 +2,11 @@ using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; -using JetBrains.Annotations; using Orchard.ContentManagement; using Orchard.Core.Common.Models; using Orchard.Core.Routable.Models; -using Orchard.Localization; -using Orchard.UI.Notify; namespace Orchard.Core.Routable.Services { - [UsedImplicitly] public class RoutableService : IRoutableService { private readonly IContentManager _contentManager; diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Commands/BlogCommands.cs b/src/Orchard.Web/Modules/Orchard.Blogs/Commands/BlogCommands.cs index e8390950f..2894149fc 100644 --- a/src/Orchard.Web/Modules/Orchard.Blogs/Commands/BlogCommands.cs +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Commands/BlogCommands.cs @@ -2,14 +2,13 @@ using System.Linq; using System.Text.RegularExpressions; using System.Xml.Linq; -using Orchard.Blogs.Models; using Orchard.Commands; using Orchard.ContentManagement; using Orchard.ContentManagement.Aspects; using Orchard.Core.Common.Models; using Orchard.Core.Navigation.Models; +using Orchard.Core.Routable.Models; using Orchard.Security; -using System.IO; using Orchard.Blogs.Services; using Orchard.Core.Navigation.Services; @@ -55,8 +54,8 @@ namespace Orchard.Blogs.Commands { var blog = _contentManager.New("Blog"); blog.As().Owner = admin; - blog.As().Slug = Slug; - blog.As().Title = Title; + blog.As().Slug = Slug; + blog.As().Title = Title; if ( !String.IsNullOrWhiteSpace(MenuText) ) { blog.As().OnMainMenu = true; blog.As().MenuPosition = _menuService.Get().Select(menuPart => menuPart.MenuPosition).Max() + 1 + ".0"; @@ -98,8 +97,8 @@ namespace Orchard.Blogs.Commands { var post = _contentManager.New("BlogPost"); post.As().Owner = admin; post.As().Container = blog; - post.As().Slug = Slugify(postName); - post.As().Title = postName; + post.As().Slug = Slugify(postName); + post.As().Title = postName; post.As().Text = item.Element("description").Value; _contentManager.Create(post); } diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Drivers/BlogDriver.cs b/src/Orchard.Web/Modules/Orchard.Blogs/Drivers/BlogDriver.cs index df4704cae..0bca103ca 100644 --- a/src/Orchard.Web/Modules/Orchard.Blogs/Drivers/BlogDriver.cs +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Drivers/BlogDriver.cs @@ -1,18 +1,13 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; -using System.Text.RegularExpressions; using System.Web.Routing; using JetBrains.Annotations; using Orchard.Blogs.Models; using Orchard.Blogs.Services; using Orchard.ContentManagement; using Orchard.ContentManagement.Drivers; -using Orchard.Core.Common.Models; -using Orchard.Core.Common.Services; using Orchard.Localization; using Orchard.Mvc.ViewModels; -using Orchard.UI.Notify; namespace Orchard.Blogs.Drivers { [UsedImplicitly] diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Drivers/BlogPostDriver.cs b/src/Orchard.Web/Modules/Orchard.Blogs/Drivers/BlogPostDriver.cs index 3435001b7..81148b6bb 100644 --- a/src/Orchard.Web/Modules/Orchard.Blogs/Drivers/BlogPostDriver.cs +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Drivers/BlogPostDriver.cs @@ -5,7 +5,7 @@ using Orchard.Blogs.Models; using Orchard.Blogs.Services; using Orchard.ContentManagement; using Orchard.ContentManagement.Drivers; -using Orchard.Core.Common.Services; +using Orchard.Core.Routable.Services; using Orchard.Localization; namespace Orchard.Blogs.Drivers { diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Handlers/BlogHandler.cs b/src/Orchard.Web/Modules/Orchard.Blogs/Handlers/BlogHandler.cs index 3697e39a3..586b32414 100644 --- a/src/Orchard.Web/Modules/Orchard.Blogs/Handlers/BlogHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Handlers/BlogHandler.cs @@ -3,6 +3,7 @@ using Orchard.Blogs.Drivers; using Orchard.Blogs.Models; using Orchard.ContentManagement.Handlers; using Orchard.Core.Common.Models; +using Orchard.Core.Routable.Models; using Orchard.Data; namespace Orchard.Blogs.Handlers { @@ -11,7 +12,7 @@ namespace Orchard.Blogs.Handlers { public BlogHandler(IRepository repository) { Filters.Add(new ActivatingFilter(BlogDriver.ContentType.Name)); Filters.Add(new ActivatingFilter(BlogDriver.ContentType.Name)); - Filters.Add(new ActivatingFilter(BlogDriver.ContentType.Name)); + Filters.Add(new ActivatingFilter(BlogDriver.ContentType.Name)); Filters.Add(StorageFilter.For(repository)); } } diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Handlers/BlogPostHandler.cs b/src/Orchard.Web/Modules/Orchard.Blogs/Handlers/BlogPostHandler.cs index 0b7ee87a4..dac26c5b4 100644 --- a/src/Orchard.Web/Modules/Orchard.Blogs/Handlers/BlogPostHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Handlers/BlogPostHandler.cs @@ -8,6 +8,7 @@ using Orchard.Blogs.Services; using Orchard.ContentManagement; using Orchard.Core.Common.Models; using Orchard.ContentManagement.Handlers; +using Orchard.Core.Routable.Models; using Orchard.Localization; namespace Orchard.Blogs.Handlers { @@ -24,7 +25,7 @@ namespace Orchard.Blogs.Handlers { Filters.Add(new ActivatingFilter(BlogPostDriver.ContentType.Name)); Filters.Add(new ActivatingFilter(BlogPostDriver.ContentType.Name)); Filters.Add(new ActivatingFilter>(BlogPostDriver.ContentType.Name)); - Filters.Add(new ActivatingFilter(BlogPostDriver.ContentType.Name)); + Filters.Add(new ActivatingFilter(BlogPostDriver.ContentType.Name)); Filters.Add(new ActivatingFilter(BlogPostDriver.ContentType.Name)); OnLoaded((context, p) => p.ScheduledPublishUtc = _blogPostService.GetScheduledPublishUtc(p)); diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Models/Blog.cs b/src/Orchard.Web/Modules/Orchard.Blogs/Models/Blog.cs index 9b80f4001..624380803 100644 --- a/src/Orchard.Web/Modules/Orchard.Blogs/Models/Blog.cs +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Models/Blog.cs @@ -1,6 +1,6 @@ using System.Web.Mvc; -using Orchard.Core.Common.Models; using Orchard.ContentManagement; +using Orchard.Core.Routable.Models; namespace Orchard.Blogs.Models { public class Blog : ContentPart { @@ -8,14 +8,14 @@ namespace Orchard.Blogs.Models { public int Id { get { return ContentItem.Id; } } public string Name { - get { return this.As().Title; } - set { this.As().Title = value; } + get { return this.As().Title; } + set { this.As().Title = value; } } //TODO: (erikpo) Need a data type for slug public string Slug { - get { return this.As().Slug; } - set { this.As().Slug = value; } + get { return this.As().Slug; } + set { this.As().Slug = value; } } public string Description { diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Models/BlogPost.cs b/src/Orchard.Web/Modules/Orchard.Blogs/Models/BlogPost.cs index addb28127..7c3081226 100644 --- a/src/Orchard.Web/Modules/Orchard.Blogs/Models/BlogPost.cs +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Models/BlogPost.cs @@ -3,6 +3,7 @@ using System.Web.Mvc; using Orchard.ContentManagement; using Orchard.ContentManagement.Aspects; using Orchard.Core.Common.Models; +using Orchard.Core.Routable.Models; using Orchard.Security; namespace Orchard.Blogs.Models { @@ -13,13 +14,13 @@ namespace Orchard.Blogs.Models { } public string Title { - get { return this.As().Title; } - set { this.As().Title = value; } + get { return this.As().Title; } + set { this.As().Title = value; } } public string Slug { - get { return this.As().Slug; } - set { this.As().Slug = value; } + get { return this.As().Slug; } + set { this.As().Slug = value; } } public string Text { diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Services/BlogPostService.cs b/src/Orchard.Web/Modules/Orchard.Blogs/Services/BlogPostService.cs index c65d05fce..b3fbd78b9 100644 --- a/src/Orchard.Web/Modules/Orchard.Blogs/Services/BlogPostService.cs +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Services/BlogPostService.cs @@ -6,6 +6,7 @@ using Orchard.Blogs.Drivers; using Orchard.Blogs.Models; using Orchard.Core.Common.Models; using Orchard.ContentManagement; +using Orchard.Core.Routable.Models; using Orchard.Data; using Orchard.Tasks.Scheduling; diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Services/BlogService.cs b/src/Orchard.Web/Modules/Orchard.Blogs/Services/BlogService.cs index 5a67d021c..fd07dcdd5 100644 --- a/src/Orchard.Web/Modules/Orchard.Blogs/Services/BlogService.cs +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Services/BlogService.cs @@ -5,6 +5,7 @@ using Orchard.Blogs.Models; using Orchard.Blogs.Routing; using Orchard.Core.Common.Models; using Orchard.ContentManagement; +using Orchard.Core.Routable.Models; namespace Orchard.Blogs.Services { [UsedImplicitly] diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Views/DisplayTemplates/Items/Blogs.Blog.DetailAdmin.ascx b/src/Orchard.Web/Modules/Orchard.Blogs/Views/DisplayTemplates/Items/Blogs.Blog.DetailAdmin.ascx index 7eeb466f6..f939466ae 100644 --- a/src/Orchard.Web/Modules/Orchard.Blogs/Views/DisplayTemplates/Items/Blogs.Blog.DetailAdmin.ascx +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Views/DisplayTemplates/Items/Blogs.Blog.DetailAdmin.ascx @@ -2,9 +2,7 @@ <%@ Import Namespace="Orchard.Mvc.ViewModels"%> <%@ Import Namespace="Orchard.Blogs.Extensions"%> <%@ Import Namespace="Orchard.Blogs.Models"%> -

<%: Html.TitleForPage(Model.Item.Name) %> - -

+

<%: Html.TitleForPage(Model.Item.Name) %>

<% Html.Zone("manage"); %><%--
diff --git a/src/Orchard.Web/Modules/Orchard.DevTools/Commands/ProfilingCommands.cs b/src/Orchard.Web/Modules/Orchard.DevTools/Commands/ProfilingCommands.cs index 89521e04c..5b441d204 100644 --- a/src/Orchard.Web/Modules/Orchard.DevTools/Commands/ProfilingCommands.cs +++ b/src/Orchard.Web/Modules/Orchard.DevTools/Commands/ProfilingCommands.cs @@ -3,6 +3,7 @@ using Orchard.ContentManagement; using Orchard.ContentManagement.Aspects; using Orchard.Core.Common.Models; using Orchard.Core.Navigation.Models; +using Orchard.Core.Routable.Models; using Orchard.Environment.Extensions; using Orchard.Security; @@ -26,8 +27,8 @@ namespace Orchard.DevTools.Commands { var pageName = "page" + index; var page = _contentManager.Create("Page", VersionOptions.Draft); page.As().Owner = admin; - page.As().Slug = pageName; - page.As().Title = pageName; + page.As().Slug = pageName; + page.As().Title = pageName; page.As().Text = pageName; page.As().OnMainMenu = true; page.As().MenuPosition = "5." + index; @@ -37,8 +38,8 @@ namespace Orchard.DevTools.Commands { var blogName = "blog" + index; var blog = _contentManager.New("Blog"); blog.As().Owner = admin; - blog.As().Slug = blogName; - blog.As().Title = blogName; + blog.As().Slug = blogName; + blog.As().Title = blogName; blog.As().OnMainMenu = true; blog.As().MenuPosition = "6." + index; blog.As().MenuText = blogName; diff --git a/src/Orchard.Web/Modules/Orchard.Pages/Handlers/PageHandler.cs b/src/Orchard.Web/Modules/Orchard.Pages/Handlers/PageHandler.cs index 20137611e..79d1b924a 100644 --- a/src/Orchard.Web/Modules/Orchard.Pages/Handlers/PageHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.Pages/Handlers/PageHandler.cs @@ -1,5 +1,6 @@ using JetBrains.Annotations; using Orchard.ContentManagement; +using Orchard.Core.Routable.Models; using Orchard.Localization; using Orchard.Core.Common.Models; using Orchard.ContentManagement.Handlers; @@ -19,7 +20,7 @@ namespace Orchard.Pages.Handlers { Filters.Add(new ActivatingFilter(PageDriver.ContentType.Name)); Filters.Add(new ActivatingFilter(PageDriver.ContentType.Name)); Filters.Add(new ActivatingFilter>(PageDriver.ContentType.Name)); - Filters.Add(new ActivatingFilter(PageDriver.ContentType.Name)); + Filters.Add(new ActivatingFilter(PageDriver.ContentType.Name)); Filters.Add(new ActivatingFilter(PageDriver.ContentType.Name)); OnLoaded((context, page) => page._scheduledPublishUtc.Loader(value => _pageService.GetScheduledPublishUtc(page))); diff --git a/src/Orchard.Web/Modules/Orchard.Pages/Models/Page.cs b/src/Orchard.Web/Modules/Orchard.Pages/Models/Page.cs index 800747dc0..bd565d33b 100644 --- a/src/Orchard.Web/Modules/Orchard.Pages/Models/Page.cs +++ b/src/Orchard.Web/Modules/Orchard.Pages/Models/Page.cs @@ -3,6 +3,7 @@ using System.Web.Mvc; using Orchard.ContentManagement; using Orchard.ContentManagement.Utilities; using Orchard.Core.Common.Models; +using Orchard.Core.Routable.Models; using Orchard.Security; namespace Orchard.Pages.Models { @@ -11,12 +12,12 @@ namespace Orchard.Pages.Models { public int Id { get { return ContentItem.Id; } } public string Title { - get { return this.As().Title; } + get { return this.As().Title; } } public string Slug { - get { return this.As().Slug; } - set { this.As().Slug = value; } + get { return this.As().Slug; } + set { this.As().Slug = value; } } public IUser Creator { diff --git a/src/Orchard.Web/Modules/Orchard.Pages/Services/PageService.cs b/src/Orchard.Web/Modules/Orchard.Pages/Services/PageService.cs index 15d09e345..84ae3f4c9 100644 --- a/src/Orchard.Web/Modules/Orchard.Pages/Services/PageService.cs +++ b/src/Orchard.Web/Modules/Orchard.Pages/Services/PageService.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.Linq; using JetBrains.Annotations; using Orchard.ContentManagement.Records; -using Orchard.Core.Common.Models; +using Orchard.Core.Routable.Models; using Orchard.Pages.Drivers; using Orchard.Pages.Models; using Orchard.ContentManagement; diff --git a/src/Orchard.Web/Modules/Orchard.Sandbox/Handlers/SandboxContentHandler.cs b/src/Orchard.Web/Modules/Orchard.Sandbox/Handlers/SandboxContentHandler.cs index dfca7dfec..587daed06 100644 --- a/src/Orchard.Web/Modules/Orchard.Sandbox/Handlers/SandboxContentHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.Sandbox/Handlers/SandboxContentHandler.cs @@ -1,5 +1,6 @@ using JetBrains.Annotations; using Orchard.Core.Common.Models; +using Orchard.Core.Routable.Models; using Orchard.Data; using Orchard.ContentManagement; using Orchard.ContentManagement.Handlers; @@ -13,7 +14,7 @@ namespace Orchard.Sandbox.Handlers { // define the "SandboxPage" content type Filters.Add(new ActivatingFilter(SandboxPageDriver.ContentType.Name)); Filters.Add(new ActivatingFilter(SandboxPageDriver.ContentType.Name)); - Filters.Add(new ActivatingFilter(SandboxPageDriver.ContentType.Name)); + Filters.Add(new ActivatingFilter(SandboxPageDriver.ContentType.Name)); Filters.Add(new ActivatingFilter(SandboxPageDriver.ContentType.Name)); Filters.Add(StorageFilter.For(pageRepository) ); diff --git a/src/Orchard.Web/Modules/Orchard.Setup/Services/SetupService.cs b/src/Orchard.Web/Modules/Orchard.Setup/Services/SetupService.cs index a73f48fad..591db0e06 100644 --- a/src/Orchard.Web/Modules/Orchard.Setup/Services/SetupService.cs +++ b/src/Orchard.Web/Modules/Orchard.Setup/Services/SetupService.cs @@ -7,11 +7,10 @@ using Orchard.ContentManagement.MetaData; using Orchard.Core.Common.Models; using Orchard.Core.Common.Settings; using Orchard.Core.Navigation.Models; +using Orchard.Core.Routable.Models; using Orchard.Core.Settings.Models; using Orchard.Data; -using Orchard.Data.Migration.Generator; using Orchard.Data.Migration.Interpreters; -using Orchard.Data.Providers; using Orchard.Data.Migration.Schema; using Orchard.Environment; using Orchard.Environment.Configuration; @@ -76,6 +75,7 @@ namespace Orchard.Setup.Services { "Scheduling", "Indexing", "Localization", + "Routable", "Settings", "XmlRpc", "Orchard.Users", @@ -186,8 +186,8 @@ namespace Orchard.Setup.Services { // create home page as a CMS page var page = contentManager.Create("Page", VersionOptions.Draft); page.As().Text = "

Welcome to Orchard!

Congratulations, you've successfully set-up your Orchard site.

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 Edit to go into edit mode and replace this with whatever you want on your home page to make it your own.

One thing you could do (but you don't have to) is go into Manage Settings (follow the Admin link and then look for it under \"Settings\" in the menu on the left) and check that everything is configured the way you want.

You probably want to make the site your own. One of the ways you can do that is by clicking Manage Themes in the admin menu. A theme is a packaged look and feel that affects the whole site.

Next, you can start playing with the content types that we installed. For example, go ahead and click Add New Page in the admin menu and create an \"about\" page. Then, add it to the navigation menu by going to Manage Menu. You can also click Add New Blog and start posting by clicking \"Add New Post\".

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 Manage Themes and clicking Install a new Theme. Like for themes, modules are created by other users of Orchard just like you so if you feel up to it, please consider participating.

--The Orchard Crew

"; - page.As().Slug = "home"; - page.As().Title = T("Home").ToString(); + page.As().Slug = "home"; + page.As().Title = T("Home").ToString(); page.As().Owner = user; if (page.Has()) { page.As().CommentsShown = false;