mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-09-23 04:43:35 +08:00
#17772: Making creation date editable on blog posts and pages by making it a setting on the common part
--HG-- branch : 1.x
This commit is contained in:
@@ -1,8 +1,12 @@
|
||||
using System.Xml;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Xml;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Drivers;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
using Orchard.Core.Common.Models;
|
||||
using Orchard.Core.Common.Settings;
|
||||
using Orchard.Core.Common.ViewModels;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Security;
|
||||
@@ -16,6 +20,9 @@ namespace Orchard.Core.Common.Drivers {
|
||||
private readonly IMembershipService _membershipService;
|
||||
private readonly IClock _clock;
|
||||
|
||||
private const string DatePattern = "M/d/yyyy";
|
||||
private const string TimePattern = "h:mm tt";
|
||||
|
||||
public CommonPartDriver(
|
||||
IOrchardServices services,
|
||||
IContentManager contentManager,
|
||||
@@ -51,9 +58,7 @@ namespace Orchard.Core.Common.Drivers {
|
||||
}
|
||||
|
||||
protected override DriverResult Editor(CommonPart part, dynamic shapeHelper) {
|
||||
return Combined(
|
||||
OwnerEditor(part, null, shapeHelper),
|
||||
ContainerEditor(part, null, shapeHelper));
|
||||
return BuildEditor(part, null, shapeHelper);
|
||||
}
|
||||
|
||||
protected override DriverResult Editor(CommonPart part, IUpdateModel updater, dynamic shapeHelper) {
|
||||
@@ -61,9 +66,22 @@ namespace Orchard.Core.Common.Drivers {
|
||||
part.ModifiedUtc = _clock.UtcNow;
|
||||
part.VersionModifiedUtc = _clock.UtcNow;
|
||||
|
||||
return Combined(
|
||||
OwnerEditor(part, updater, shapeHelper),
|
||||
ContainerEditor(part, updater, shapeHelper));
|
||||
return BuildEditor(part, updater, shapeHelper);
|
||||
}
|
||||
|
||||
private DriverResult BuildEditor(CommonPart part, IUpdateModel updater, dynamic shapeHelper) {
|
||||
List<DriverResult> parts = new List<DriverResult>();
|
||||
CommonTypePartSettings commonTypePartSettings = GetTypeSettings(part);
|
||||
|
||||
parts.Add(OwnerEditor(part, updater, shapeHelper));
|
||||
|
||||
if (commonTypePartSettings.ShowCreatedUtcEditor) {
|
||||
parts.Add(CreatedUtcEditor(part, updater, shapeHelper));
|
||||
}
|
||||
|
||||
parts.Add(ContainerEditor(part, updater, shapeHelper));
|
||||
|
||||
return Combined(parts.ToArray());
|
||||
}
|
||||
|
||||
DriverResult OwnerEditor(CommonPart part, IUpdateModel updater, dynamic shapeHelper) {
|
||||
@@ -95,6 +113,42 @@ namespace Orchard.Core.Common.Drivers {
|
||||
() => shapeHelper.EditorTemplate(TemplateName: "Parts.Common.Owner", Model: model, Prefix: Prefix));
|
||||
}
|
||||
|
||||
DriverResult CreatedUtcEditor(CommonPart part, IUpdateModel updater, dynamic shapeHelper) {
|
||||
var currentUser = _authenticationService.GetAuthenticatedUser();
|
||||
if (!_authorizationService.TryCheckAccess(StandardPermissions.SiteOwner, currentUser, part)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var model = new CreatedUtcEditorViewModel();
|
||||
if (part.CreatedUtc != null) {
|
||||
model.CreatedDate = part.CreatedUtc.Value.ToLocalTime().ToString(DatePattern, CultureInfo.InvariantCulture);
|
||||
model.CreatedTime = part.CreatedUtc.Value.ToLocalTime().ToString(TimePattern, CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
if (updater != null) {
|
||||
updater.TryUpdateModel(model, Prefix, null, null);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(model.CreatedDate) && !string.IsNullOrWhiteSpace(model.CreatedTime)) {
|
||||
DateTime createdUtc;
|
||||
string parseDateTime = String.Concat(model.CreatedDate, " ", model.CreatedTime);
|
||||
|
||||
// use an english culture as it is the one used by jQuery.datepicker by default
|
||||
if (DateTime.TryParse(parseDateTime, CultureInfo.GetCultureInfo("en-US"), DateTimeStyles.AssumeLocal, out createdUtc)) {
|
||||
part.CreatedUtc = createdUtc;
|
||||
}
|
||||
else {
|
||||
updater.AddModelError(Prefix, T("{0} is an invalid date and time", parseDateTime));
|
||||
}
|
||||
}
|
||||
else {
|
||||
updater.AddModelError(Prefix, T("Both the date and time need to be specified."));
|
||||
}
|
||||
}
|
||||
|
||||
return ContentShape("Parts_Common_CreatedUtc_Edit",
|
||||
() => shapeHelper.EditorTemplate(TemplateName: "Parts.Common.CreatedUtc", Model: model, Prefix: Prefix));
|
||||
}
|
||||
|
||||
DriverResult ContainerEditor(CommonPart part, IUpdateModel updater, dynamic shapeHelper) {
|
||||
var currentUser = _authenticationService.GetAuthenticatedUser();
|
||||
if (!_authorizationService.TryCheckAccess(StandardPermissions.SiteOwner, currentUser, part)) {
|
||||
@@ -124,6 +178,10 @@ namespace Orchard.Core.Common.Drivers {
|
||||
() => shapeHelper.EditorTemplate(TemplateName: "Parts.Common.Container", Model: model, Prefix: Prefix));
|
||||
}
|
||||
|
||||
private static CommonTypePartSettings GetTypeSettings(CommonPart part) {
|
||||
return part.Settings.GetModel<CommonTypePartSettings>();
|
||||
}
|
||||
|
||||
protected override void Importing(CommonPart part, ImportContentContext context) {
|
||||
var owner = context.Attribute(part.PartDefinition.Name, "Owner");
|
||||
if (owner != null) {
|
||||
|
@@ -12,6 +12,7 @@
|
||||
<!-- edit "shape" -->
|
||||
<Place Parts_Common_Body_Edit="Content:2"/>
|
||||
<Place Parts_Common_Owner_Edit="Content:20"/>
|
||||
<Place Parts_Common_CreatedUtc_Edit="Content:18"/>
|
||||
<Place Parts_Common_Container_Edit="Content:20"/>
|
||||
<Place Fields_Common_Text_Edit="Content:2.5"/>
|
||||
<!-- default positioning -->
|
||||
|
9
src/Orchard.Web/Core/Common/ResourceManifest.cs
Normal file
9
src/Orchard.Web/Core/Common/ResourceManifest.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using Orchard.UI.Resources;
|
||||
|
||||
namespace Orchard.Core.Common {
|
||||
public class ResourceManifest : IResourceManifestProvider {
|
||||
public void BuildManifests(ResourceManifestBuilder builder) {
|
||||
builder.Add().DefineStyle("Common_DatePicker").SetUrl("orchard-common-datetime.css");
|
||||
}
|
||||
}
|
||||
}
|
32
src/Orchard.Web/Core/Common/Settings/CommonSettings.cs
Normal file
32
src/Orchard.Web/Core/Common/Settings/CommonSettings.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using System.Collections.Generic;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.MetaData;
|
||||
using Orchard.ContentManagement.MetaData.Builders;
|
||||
using Orchard.ContentManagement.MetaData.Models;
|
||||
using Orchard.ContentManagement.ViewModels;
|
||||
|
||||
namespace Orchard.Core.Common.Settings {
|
||||
public class CommonTypePartSettings {
|
||||
public bool ShowCreatedUtcEditor { get; set; }
|
||||
}
|
||||
|
||||
public class CommonSettingsHooks : ContentDefinitionEditorEventsBase {
|
||||
public override IEnumerable<TemplateViewModel> TypePartEditor(ContentTypePartDefinition definition) {
|
||||
if (definition.PartDefinition.Name != "CommonPart")
|
||||
yield break;
|
||||
|
||||
var model = definition.Settings.GetModel<CommonTypePartSettings>();
|
||||
yield return DefinitionTemplate(model);
|
||||
}
|
||||
|
||||
public override IEnumerable<TemplateViewModel> TypePartEditorUpdate(ContentTypePartDefinitionBuilder builder, IUpdateModel updateModel) {
|
||||
if (builder.Name != "CommonPart")
|
||||
yield break;
|
||||
|
||||
var model = new CommonTypePartSettings();
|
||||
updateModel.TryUpdateModel(model, "CommonTypePartSettings", null, null);
|
||||
builder.WithSetting("CommonTypePartSettings.ShowCreatedUtcEditor", model.ShowCreatedUtcEditor.ToString());
|
||||
yield return DefinitionTemplate(model);
|
||||
}
|
||||
}
|
||||
}
|
21
src/Orchard.Web/Core/Common/Styles/Web.config
Normal file
21
src/Orchard.Web/Core/Common/Styles/Web.config
Normal file
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<appSettings>
|
||||
<add key="webpages:Enabled" value="false" />
|
||||
</appSettings>
|
||||
<system.web>
|
||||
<httpHandlers>
|
||||
<!-- iis6 - for any request in this location, return via managed static file handler -->
|
||||
<add path="*" verb="*" type="System.Web.StaticFileHandler" />
|
||||
</httpHandlers>
|
||||
</system.web>
|
||||
<system.webServer>
|
||||
<handlers accessPolicy="Script,Read">
|
||||
<!--
|
||||
iis7 - for any request to a file exists on disk, return it via native http module.
|
||||
accessPolicy 'Script' is to allow for a managed 404 page.
|
||||
-->
|
||||
<add name="StaticFile" path="*" verb="*" modules="StaticFileModule" preCondition="integratedMode" resourceType="File" requireAccess="Read" />
|
||||
</handlers>
|
||||
</system.webServer>
|
||||
</configuration>
|
@@ -0,0 +1,14 @@
|
||||
fieldset.createdutc-datetime {
|
||||
float:left;
|
||||
clear:none;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
}
|
||||
fieldset.createdutc-datetime legend {
|
||||
display:none;
|
||||
}
|
||||
fieldset.createdutc-datetime input {
|
||||
padding:1px;
|
||||
text-align:center;
|
||||
color:#666;
|
||||
}
|
@@ -0,0 +1,6 @@
|
||||
namespace Orchard.Core.Common.ViewModels {
|
||||
public class CreatedUtcEditorViewModel {
|
||||
public string CreatedDate { get; set; }
|
||||
public string CreatedTime { get; set; }
|
||||
}
|
||||
}
|
@@ -0,0 +1,6 @@
|
||||
@model Orchard.Core.Common.Settings.CommonTypePartSettings
|
||||
<fieldset>
|
||||
@Html.CheckBoxFor(m => m.ShowCreatedUtcEditor)
|
||||
<label class="forcheckbox" for="@Html.FieldIdFor(m => m.ShowCreatedUtcEditor)">@T("Show editor for create date time")</label>
|
||||
@Html.ValidationMessageFor(m => m.ShowCreatedUtcEditor)
|
||||
</fieldset>
|
@@ -0,0 +1,41 @@
|
||||
@model CreatedUtcEditorViewModel
|
||||
@using Orchard.Core.Common.ViewModels;
|
||||
@{
|
||||
Script.Require("jQueryUtils_TimePicker");
|
||||
Script.Require("jQueryUI_DatePicker");
|
||||
Style.Require("Common_DatePicker");
|
||||
Style.Require("jQueryUtils_TimePicker");
|
||||
Style.Require("jQueryUI_DatePicker");
|
||||
}
|
||||
<fieldset class="createdutc-datetime">
|
||||
@Html.LabelFor(m => m.CreatedDate, T("Created On"))
|
||||
<label class="forpicker" for="@ViewData.TemplateInfo.GetFullHtmlFieldId("CreatedDate")">@T("Date")</label>
|
||||
@Html.EditorFor(m => m.CreatedDate)
|
||||
<label class="forpicker" for="@ViewData.TemplateInfo.GetFullHtmlFieldId("CreatedTime")">@T("Time")</label>
|
||||
@Html.EditorFor(m => m.CreatedTime)
|
||||
</fieldset>
|
||||
@using(Script.Foot()) {
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
$(function () {
|
||||
var clearHint = function ($this) { if ($this.val() == $this.data("hint")) { $this.removeClass("hinted").val("") } };
|
||||
var resetHint = function ($this) { setTimeout(function () { if (!$this.val()) { $this.addClass("hinted").val($this.data("hint")) } }, 300) };
|
||||
@* todo: (heskew) make a plugin *@
|
||||
$("label.forpicker").each(function () {
|
||||
var $this = $(this);
|
||||
var pickerInput = $("#" + $this.attr("for"));
|
||||
if (!pickerInput.val()) {
|
||||
pickerInput.data("hint", $this.text());
|
||||
pickerInput.addClass("hinted")
|
||||
.val(pickerInput.data("hint"))
|
||||
.focus(function() {clearHint($(this));})
|
||||
.blur(function() {resetHint($(this));});
|
||||
$this.closest("form").submit(function() {clearHint(pickerInput); pickerInput = 0;});
|
||||
}
|
||||
});
|
||||
$('#@ViewData.TemplateInfo.GetFullHtmlFieldId("CreatedDate")').datepicker({ showAnim: "" }).focus(function () { $('#@ViewData.TemplateInfo.GetFullHtmlFieldId("Command_Created")').attr("checked", "checked") });
|
||||
$('#@ViewData.TemplateInfo.GetFullHtmlFieldId("CreatedTime")').timepickr().focus(function () { $('#@ViewData.TemplateInfo.GetFullHtmlFieldId("Command_Created")').attr("checked", "checked") });
|
||||
})
|
||||
//]]>
|
||||
</script>
|
||||
}
|
@@ -66,7 +66,10 @@
|
||||
<Compile Include="Common\Models\CommonPartVersionRecord.cs" />
|
||||
<Compile Include="Common\Models\IdentityPartRecord.cs" />
|
||||
<Compile Include="Common\Models\IdentityPart.cs" />
|
||||
<Compile Include="Common\ResourceManifest.cs" />
|
||||
<Compile Include="Common\Services\XmlRpcHandler.cs" />
|
||||
<Compile Include="Common\Settings\CommonSettings.cs" />
|
||||
<Compile Include="Common\ViewModels\CreatedUtcEditorViewModel.cs" />
|
||||
<Compile Include="Containers\Controllers\ItemController.cs" />
|
||||
<Compile Include="Containers\Drivers\ContainablePartDriver.cs" />
|
||||
<Compile Include="Containers\Drivers\ContainerPartDriver.cs" />
|
||||
@@ -243,6 +246,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Common\Module.txt" />
|
||||
<Content Include="Common\Styles\orchard-common-datetime.css" />
|
||||
<Content Include="Common\Views\DefinitionTemplates\BodyTypePartSettings.cshtml" />
|
||||
<Content Include="Common\Views\DefinitionTemplates\BodyPartSettings.cshtml" />
|
||||
<Content Include="Common\Views\Fields.Common.Text.cshtml" />
|
||||
@@ -427,6 +431,17 @@
|
||||
<ItemGroup>
|
||||
<Content Include="web.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Common\Views\DefinitionTemplates\CommonTypePartSettings.cshtml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Common\Views\EditorTemplates\Parts.Common.CreatedUtc.cshtml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Common\Styles\Web.config">
|
||||
<SubType>Designer</SubType>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
|
@@ -46,7 +46,8 @@ namespace Orchard.Blogs {
|
||||
ContentDefinitionManager.AlterTypeDefinition("BlogPost",
|
||||
cfg => cfg
|
||||
.WithPart("BlogPostPart")
|
||||
.WithPart("CommonPart")
|
||||
.WithPart("CommonPart", p => p
|
||||
.WithSetting("CommonTypePartSettings.ShowCreatedUtcEditor", "true"))
|
||||
.WithPart("PublishLaterPart")
|
||||
.WithPart("RoutePart")
|
||||
.WithPart("BodyPart")
|
||||
|
@@ -8,23 +8,18 @@ namespace Orchard.Experimental {
|
||||
public class TestingListsMigrations : DataMigrationImpl {
|
||||
public int Create() {
|
||||
ContentDefinitionManager.AlterTypeDefinition("ListItem",
|
||||
cfg => cfg
|
||||
.WithPart("CommonPart")
|
||||
.WithPart("RoutePart")
|
||||
.WithPart("BodyPart")
|
||||
.WithPart("ContainablePart")
|
||||
.Creatable());
|
||||
cfg => cfg
|
||||
.WithPart("CommonPart")
|
||||
.WithPart("RoutePart")
|
||||
.WithPart("BodyPart")
|
||||
.WithPart("ContainablePart")
|
||||
.Creatable()
|
||||
);
|
||||
|
||||
ContentDefinitionManager.AlterTypeDefinition("Page",
|
||||
cfg => cfg
|
||||
.WithPart("ContainablePart"));
|
||||
|
||||
//ContentDefinitionManager.AlterTypeDefinition("ListWidget",
|
||||
// cfg => cfg
|
||||
// .WithPart("CommonPart")
|
||||
// .WithPart("WidgetPart")
|
||||
// .WithPart("ListWidgetPart")
|
||||
// .WithSetting("Stereotype", "Widget"));
|
||||
cfg => cfg
|
||||
.WithPart("ContainablePart")
|
||||
);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@@ -6,8 +6,9 @@ namespace Orchard.Pages {
|
||||
public class Migrations : DataMigrationImpl {
|
||||
public int Create() {
|
||||
ContentDefinitionManager.AlterTypeDefinition("Page",
|
||||
cfg=>cfg
|
||||
.WithPart("CommonPart")
|
||||
cfg => cfg
|
||||
.WithPart("CommonPart", p => p
|
||||
.WithSetting("CommonTypePartSettings.ShowCreatedUtcEditor", "true"))
|
||||
.WithPart("PublishLaterPart")
|
||||
.WithPart("RoutePart")
|
||||
.WithPart("BodyPart")
|
||||
|
Reference in New Issue
Block a user