Merge branch '1.9.x' into dev

Conflicts:
	src/Orchard.Web/Modules/Orchard.Taxonomies/Views/EditorTemplates/Fields/TaxonomyField.Autocomplete.cshtml
	src/Orchard.Web/Modules/Orchard.Taxonomies/Views/EditorTemplates/Fields/TaxonomyField.cshtml
This commit is contained in:
Sipke Schoorstra
2015-07-17 09:52:23 +01:00
15 changed files with 102 additions and 80 deletions

View File

@@ -1,16 +1,8 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Autofac;
using NUnit.Framework;
using Orchard.Localization.Models;
using Orchard.Localization.Services;
using Orchard.Services;
namespace Orchard.Tests.Localization {
@@ -217,6 +209,17 @@ namespace Orchard.Tests.Localization {
Assert.AreEqual(dateTimeLocal, result);
}
[Test]
[Description("DateTime which is DateTimeKind.Local is converted to DateTimeKind.Utc.")]
public void ConvertFromLocalizedDateStringTest01() {
var container = TestHelpers.InitializeContainer("en-US", "GregorianCalendar", TimeZoneInfo.Utc);
var dateTimeLocal = new DateTime(1998, 1, 15);
var dateTimeLocalString = dateTimeLocal.ToShortDateString();
var target = container.Resolve<IDateLocalizationServices>();
var result = target.ConvertFromLocalizedDateString(dateTimeLocalString);
Assert.AreEqual(DateTimeKind.Utc, result.Value.Kind);
}
[Test]
[Description("Converting to Gregorian calendar yields a DateTimeParts instance equivalent to the original DateTime.")]
public void ConvertToSiteCalendarTest01() {

View File

@@ -59,7 +59,7 @@
<ul class="menu-items-zone">
@foreach (var descriptor in Model.MenuItemDescriptors.OrderBy(x => x.DisplayName)) {
<li>
<div class="menu-item-description"><h2>@T(descriptor.DisplayName.CamelFriendly())</h2>
<div class="menu-item-description"><h2>@T(descriptor.DisplayName)</h2>
@if (!string.IsNullOrWhiteSpace(descriptor.Description)) {
<span class="hint">@T(descriptor.Description)</span>
}

View File

@@ -2,8 +2,8 @@
namespace Orchard.Layouts.Helpers {
public static class MetaDataExtensions {
public static ContentPartDefinitionBuilder Placable(this ContentPartDefinitionBuilder builder, bool placable = true) {
return builder.WithSetting("ContentPartLayoutSettings.Placable", placable.ToString());
public static ContentPartDefinitionBuilder Placeable(this ContentPartDefinitionBuilder builder, bool placeable = true) {
return builder.WithSetting("ContentPartLayoutSettings.Placeable", placeable.ToString());
}
}
}

View File

@@ -45,10 +45,10 @@ namespace Orchard.Layouts {
.WithSetting("Stereotype", "Widget")
.DisplayedAs("Layout Widget"));
ContentDefinitionManager.AlterPartDefinition("BodyPart", part => part.Placable());
ContentDefinitionManager.AlterPartDefinition("TitlePart", part => part.Placable());
ContentDefinitionManager.AlterPartDefinition("CommonPart", part => part.Placable());
ContentDefinitionManager.AlterPartDefinition("TagsPart", part => part.Placable());
ContentDefinitionManager.AlterPartDefinition("BodyPart", part => part.Placeable());
ContentDefinitionManager.AlterPartDefinition("TitlePart", part => part.Placeable());
ContentDefinitionManager.AlterPartDefinition("CommonPart", part => part.Placeable());
ContentDefinitionManager.AlterPartDefinition("TagsPart", part => part.Placeable());
ContentDefinitionManager.AlterPartDefinition("ElementWrapperPart", part => part
.Attachable()

View File

@@ -57,7 +57,7 @@ namespace Orchard.Layouts.Providers {
? contentTypeDefinition.Parts.Select(x => x.PartDefinition)
: _contentDefinitionManager.Value.ListPartDefinitions();
return parts.Where(p => p.Settings.GetModel<ContentPartLayoutSettings>().Placable);
return parts.Where(p => p.Settings.GetModel<ContentPartLayoutSettings>().Placeable);
}
private void Displaying(ElementDisplayingContext context) {

View File

@@ -1,7 +1,7 @@
(function ($) {
var placable = $("input[name=\"ContentPartLayoutSettings.Placable\"]");
var placeable = $("input[name=\"ContentPartLayoutSettings.Placeable\"]");
$(placable).on("change", function (e) {
$(placeable).on("change", function (e) {
syncEnableEditorInput();
});
@@ -11,9 +11,9 @@
var syncEnableEditorInput = function () {
var enableEditorDialog = $("input[name=\"ContentPartLayoutSettings.EnableEditorDialog\"]");
var isPlacable = placable.is(":checked");
var isPlaceable = placeable.is(":checked");
enableEditorDialog.prop("disabled", !isPlacable);
enableEditorDialog.prop("disabled", !isPlaceable);
};
})(jQuery);

View File

@@ -68,7 +68,21 @@ namespace Orchard.Layouts.Services {
}
private IEnumerable<IContentPartDriver> GetPartDrivers(string partName) {
return _contentPartDrivers.Where(x => x.GetType().BaseType.GenericTypeArguments[0].Name == partName);
return _contentPartDrivers.Where(x => GetPartOfDriver(x.GetType().BaseType).Name == partName);
}
private Type GetPartOfDriver(Type type) {
var baseType = type;
while (baseType != null && typeof(IContentPartDriver).IsAssignableFrom(baseType)) {
if (baseType.GenericTypeArguments.Any()) {
return baseType.GenericTypeArguments[0];
}
baseType = baseType.BaseType;
}
return null;
}
}
}

View File

@@ -1,8 +1,8 @@
namespace Orchard.Layouts.Settings {
public class ContentPartLayoutSettings {
/// <summary>
/// This setting is used to configure a part to be placable on a layout.
/// This setting is used to configure a part to be placeable on a layout.
/// </summary>
public bool Placable { get; set; }
public bool Placeable { get; set; }
}
}

View File

@@ -17,7 +17,7 @@ namespace Orchard.Layouts.Settings {
public override IEnumerable<TemplateViewModel> PartEditorUpdate(ContentPartDefinitionBuilder builder, IUpdateModel updateModel) {
var model = new ContentPartLayoutSettings();
updateModel.TryUpdateModel(model, "ContentPartLayoutSettings", null, null);
builder.Placable(model.Placable);
builder.Placeable(model.Placeable);
yield return DefinitionTemplate(model);
}
}

View File

@@ -4,7 +4,7 @@
Script.Include("contentpart-layouts-settings.js");
}
<fieldset>
@Html.CheckBoxFor(m => m.Placable)
<label for="@Html.FieldIdFor(m => m.Placable)" class="forcheckbox">@T("Placable")</label>
<span class="hint">@T("Check to allow this part to be placable on a layout.")</span>
@Html.CheckBoxFor(m => m.Placeable)
<label for="@Html.FieldIdFor(m => m.Placeable)" class="forcheckbox">@T("Placeable")</label>
<span class="hint">@T("Check to allow this part to be placeable on a layout.")</span>
</fieldset>

View File

@@ -30,48 +30,48 @@
var selectedTerms = Newtonsoft.Json.JsonConvert.SerializeObject(Model.Terms.Where(x => x.IsChecked).Select(x => new { label = x.Name, value = x.Id, levels = 0, disabled = true }));
}
<fieldset class="taxonomy-wrapper" data-name-prefix="@Html.FieldNameFor(m => m)" data-id-prefix="@Html.FieldIdFor(m => m)">
<legend @if (Model.Settings.Required) { <text> class="required" </text> }>@Model.DisplayName.CamelFriendly()</legend>
<legend @if(Model.Settings.Required) { <text>class="required"</text> }>@Model.DisplayName</legend>
@if (Model.Settings.Autocomplete) {
<div class="terms-editor" data-all-terms="@allTerms" data-selected-terms="@selectedTerms" data-allow-new-terms="@Model.Settings.AllowCustomTerms.ToString().ToLower()" data-singlechoice="@Model.Settings.SingleChoice.ToString().ToLower()">
<ul></ul>
@if (Model.Settings.SingleChoice) {
<div class="hint">@T("Enter a single term. Hit <i>tab</i> or <i>enter</i> to apply the term.") @if (!Model.Settings.AllowCustomTerms) { <text>@T("This taxonomy does not allow you to create new terms.") </text> }</div>
}
else {
<div class="hint">@T("Enter multiple terms. Hit <i>tab</i>, <i>enter</i> or <i>,</i> to add multiple terms.") @if (!Model.Settings.AllowCustomTerms) { <text>@T("This taxonomy does not allow you to create new terms.") </text> }</div>
}
</div>
<div class="terms-editor" data-all-terms="@allTerms" data-selected-terms="@selectedTerms" data-allow-new-terms="@Model.Settings.AllowCustomTerms.ToString().ToLower()" data-singlechoice="@Model.Settings.SingleChoice.ToString().ToLower()">
<ul></ul>
@if (Model.Settings.SingleChoice) {
<div class="hint">@T("Enter a single term. Hit <i>tab</i> or <i>enter</i> to apply the term.") @if (!Model.Settings.AllowCustomTerms) { <text>@T("This taxonomy does not allow you to create new terms.") </text> }</div>
}
else {
<div class="hint">@T("Enter multiple terms. Hit <i>tab</i>, <i>enter</i> or <i>,</i> to add multiple terms.") @if (!Model.Settings.AllowCustomTerms) { <text>@T("This taxonomy does not allow you to create new terms.") </text> }</div>
}
</div>
}
@if (!String.IsNullOrWhiteSpace(Model.Settings.Hint)) {
<span class="hint">@Model.Settings.Hint</span>
<span class="hint">@Model.Settings.Hint</span>
}
<div class="hidden-taxonomy-state">
<ul class="terms">
@foreach (var entry in Model.Terms) {
var ti = termIndex;
<li>
@{
var disabled = IsTermDisabled(entry);
if (Model.Settings.SingleChoice) {
@foreach (var entry in Model.Terms) {
var ti = termIndex;
<li>
@{
var disabled = IsTermDisabled(entry);
if (Model.Settings.SingleChoice) {
<input @if (disabled) { <text> disabled="disabled" </text> } type="radio" value="@Model.Terms[ti].Id" @if (entry.Id == Model.SingleTermId) { <text> checked="checked" </text> } name="@Html.FieldNameFor(m => m.SingleTermId)" id="@Html.FieldIdFor(m => m.Terms[ti].IsChecked)" data-term="@entry.Name" data-term-identity="@entry.Name.ToLower()" />
}
else {
<input @if (disabled) { <text> disabled="disabled" </text> } type="checkbox" value="true" @if (entry.IsChecked) { <text> checked="checked" </text> } name="@Html.FieldNameFor(m => m.Terms[ti].IsChecked)" id="@Html.FieldIdFor(m => m.Terms[ti].IsChecked)" data-term="@entry.Name" data-term-identity="@entry.Name.ToLower()" />
}
}
<label class="forcheckbox" for="@Html.FieldIdFor(m => m.Terms[ti].IsChecked)">@entry.Name</label>
@Html.HiddenFor(m => m.Terms[ti].Id)
</li>
termIndex++;
}
else {
<input @if (disabled) { <text> disabled="disabled" </text> } type="checkbox" value="true" @if (entry.IsChecked) { <text> checked="checked" </text> } name="@Html.FieldNameFor(m => m.Terms[ti].IsChecked)" id="@Html.FieldIdFor(m => m.Terms[ti].IsChecked)" data-term="@entry.Name" data-term-identity="@entry.Name.ToLower()" />
}
}
<label class="forcheckbox" for="@Html.FieldIdFor(m => m.Terms[ti].IsChecked)">@entry.Name</label>
@Html.HiddenFor(m => m.Terms[ti].Id)
</li>
termIndex++;
}
</ul>
</div>
@if (!Model.Terms.Any()) {
<div class="no-terms">
@T("There are no terms defined for {0} yet.", Model.DisplayName.CamelFriendly())
<a href="@Url.Action("Index", "TermAdmin", new { taxonomyId = Model.TaxonomyId, area = "Orchard.Taxonomies" })">@T("Create some terms")</a>
</div>
<div class="no-terms">
@T("There are no terms defined for {0} yet.", Model.DisplayName)
<a href="@Url.Action("Index", "TermAdmin", new { taxonomyId = Model.TaxonomyId, area = "Orchard.Taxonomies" })">@T("Create some terms")</a>
</div>
}
@Html.HiddenFor(m => m.TaxonomyId)
</fieldset>

View File

@@ -5,7 +5,7 @@
@{
Style.Include("admin-taxonomy.css");
Script.Require("jQuery");
Script.Require("jQuery");
Script.Include("~/Themes/TheAdmin/scripts/admin.js").AtFoot();
Script.Include("admin-taxonomy-expando.js").AtFoot();
@@ -14,39 +14,39 @@
}
<fieldset class="taxonomy-wrapper" data-name-prefix="@Html.FieldNameFor(m => m)" data-id-prefix="@Html.FieldIdFor(m => m)">
<legend @if (settings.Required) { <text> class="required" </text> }>@Model.DisplayName.CamelFriendly()</legend>
<legend @if(settings.Required) { <text>class="required"</text> }>@Model.DisplayName</legend>
<div class="expando">
@if (!String.IsNullOrWhiteSpace(Model.Settings.Hint)) {
<span class="hint">@Model.Settings.Hint</span>
}
<ul class="terms">
@foreach (var entry in Model.Terms) {
var ti = termIndex;
<li>
@* Tabs for levels *@ @for (var i = 1; i <= entry.GetLevels(); i++) { <span class="gap">&nbsp;</span> }
@{
var disabled = !entry.Selectable || (Model.Settings.LeavesOnly && Model.Terms.Any(t => t.Path.Contains(entry.Path + entry.Id)));
if (Model.Settings.SingleChoice) {
var disabled = !entry.Selectable || (Model.Settings.LeavesOnly && Model.Terms.Any(t => t.Path.Contains(entry.Path + entry.Id)));
if (Model.Settings.SingleChoice) {
<input @if (disabled) { <text> disabled="disabled" </text> } type="radio" value="@Model.Terms[ti].Id" @if (entry.Id == Model.SingleTermId) { <text> checked="checked" </text> } name="@Html.FieldNameFor(m => m.SingleTermId)" id="@Html.FieldIdFor(m => m.Terms[ti].IsChecked)" data-term="@entry.Name.ToLower()" />
}
else {
}
else {
<input @if (disabled) { <text> disabled="disabled" </text> } type="checkbox" value="true" @if (entry.IsChecked) { <text> checked="checked" </text> } name="@Html.FieldNameFor(m => m.Terms[ti].IsChecked)" id="@Html.FieldIdFor(m => m.Terms[ti].IsChecked)" data-term="@entry.Name.ToLower()" />
}
}
}
@Html.HiddenFor(m => m.Terms[ti].Id)
<label class="forcheckbox" for="@Html.FieldIdFor(m => m.Terms[ti].IsChecked)">@entry.Name</label>
</li>
termIndex++;
termIndex++;
}
</ul>
@if (!Model.Terms.Any()) {
<div class="no-terms">
@T("There are no terms defined for {0} yet.", Model.DisplayName.CamelFriendly())
@T("There are no terms defined for {0} yet.", Model.DisplayName)
<a href="@Url.Action("Index", "TermAdmin", new { taxonomyId = Model.TaxonomyId, area = "Orchard.Taxonomies" })">@T("Create some terms")</a>
</div>
</div>
}
</div>
@Html.HiddenFor(m => m.TaxonomyId)

View File

@@ -110,10 +110,18 @@ namespace Orchard.DisplayManagement.Descriptors.ShapePlacementStrategy {
private void GetShapeType(PlacementShapeLocation shapeLocation, out string shapeType, out string differentiator) {
differentiator = "";
shapeType = shapeLocation.ShapeType;
var separatorLengh = 2;
var separatorIndex = shapeType.LastIndexOf("__");
var dashIndex = shapeType.LastIndexOf('-');
if (dashIndex > 0 && dashIndex < shapeType.Length - 1) {
differentiator = shapeType.Substring(dashIndex + 1);
shapeType = shapeType.Substring(0, dashIndex);
if (dashIndex > separatorIndex) {
separatorIndex = dashIndex;
separatorLengh = 1;
}
if (separatorIndex > 0 && separatorIndex < shapeType.Length - separatorLengh) {
differentiator = shapeType.Substring(separatorIndex + separatorLengh);
shapeType = shapeType.Substring(0, separatorIndex);
}
}

View File

@@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Orchard.Localization.Models {
public class DateLocalizationOptions {

View File

@@ -1,9 +1,7 @@
using System;
using System.Globalization;
using Orchard.ContentManagement;
using Orchard.Localization.Models;
using Orchard.Services;
using Orchard.Settings;
namespace Orchard.Localization.Services {
@@ -218,6 +216,9 @@ namespace Orchard.Localization.Services {
}
}
if (options.EnableTimeZoneConversion)
dateValue = DateTime.SpecifyKind(dateValue, DateTimeKind.Utc);
return dateValue;
}