mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-06-28 15:34:39 +08:00
Merge branch 'dev' into issue/8773
This commit is contained in:
commit
832a0c8515
@ -64,7 +64,8 @@ namespace Orchard.Blogs.BlogsLocalizationExtensions.Handlers {
|
||||
var blogids = new HashSet<int> { blog.As<BlogPart>().ContentItem.Id };
|
||||
|
||||
//seek for same culture blog
|
||||
var realBlog = _localizationService.GetLocalizations(blog).SingleOrDefault(w => w.As<LocalizationPart>().Culture == blogPostCulture);
|
||||
var realBlog = _localizationService.GetLocalizations(blog)
|
||||
.SingleOrDefault(w => w.Culture?.Culture == blogPostCulture.Culture);
|
||||
if (realBlog.Has<LocalizationPart>() && realBlog.As<LocalizationPart>().Culture.Id == blogPostCulture.Id) {
|
||||
blogPost.As<ICommonPart>().Container = realBlog;
|
||||
if (blogPost.Has<AutoroutePart>()) {
|
||||
|
@ -0,0 +1,34 @@
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Routing;
|
||||
using Orchard.ContentManagement.MetaData;
|
||||
using Orchard.Environment.Extensions;
|
||||
using Orchard.Localization.Services;
|
||||
using Orchard.Taxonomies.Services;
|
||||
using Orchard.UI.Admin;
|
||||
|
||||
namespace Orchard.Taxonomies.Controllers {
|
||||
[OrchardFeature("Orchard.Taxonomies.LocalizationExtensions")]
|
||||
public class AdminLocalizedTaxonomyController : LocalizedTaxonomyController {
|
||||
private readonly RequestContext _requestContext;
|
||||
|
||||
public AdminLocalizedTaxonomyController(IContentDefinitionManager contentDefinitionManager,
|
||||
ILocalizationService localizationService,
|
||||
ITaxonomyService taxonomyService,
|
||||
ITaxonomyExtensionsService
|
||||
taxonomyExtensionsService,
|
||||
RequestContext requestContext) : base(contentDefinitionManager,
|
||||
localizationService,
|
||||
taxonomyService,
|
||||
taxonomyExtensionsService) {
|
||||
|
||||
_requestContext = requestContext;
|
||||
}
|
||||
|
||||
[OutputCache(NoStore = true, Duration = 0)]
|
||||
public new ActionResult GetTaxonomy(string contentTypeName, string taxonomyFieldName, int contentId, string culture, string selectedValues) {
|
||||
AdminFilter.Apply(_requestContext);
|
||||
|
||||
return GetTaxonomyInternal(contentTypeName, taxonomyFieldName, contentId, culture, selectedValues);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,13 +1,12 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.UI.WebControls;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.MetaData;
|
||||
using Orchard.Environment.Extensions;
|
||||
using Orchard.Localization.Models;
|
||||
using Orchard.Localization.Services;
|
||||
using Orchard.Taxonomies.Drivers;
|
||||
using Orchard.Taxonomies.Fields;
|
||||
using Orchard.Taxonomies.Helpers;
|
||||
using Orchard.Taxonomies.Models;
|
||||
using Orchard.Taxonomies.Services;
|
||||
@ -28,6 +27,7 @@ namespace Orchard.Taxonomies.Controllers {
|
||||
ILocalizationService localizationService,
|
||||
ITaxonomyService taxonomyService,
|
||||
ITaxonomyExtensionsService taxonomyExtensionsService) {
|
||||
|
||||
_taxonomyService = taxonomyService;
|
||||
_taxonomyExtensionsService = taxonomyExtensionsService;
|
||||
_contentDefinitionManager = contentDefinitionManager;
|
||||
@ -35,14 +35,19 @@ namespace Orchard.Taxonomies.Controllers {
|
||||
}
|
||||
|
||||
[OutputCache(NoStore = true, Duration = 0)]
|
||||
public ActionResult GetTaxonomy(string contentTypeName, string taxonomyFieldName, int contentId, string culture) {
|
||||
public ActionResult GetTaxonomy(string contentTypeName, string taxonomyFieldName, int contentId, string culture, string selectedValues) {
|
||||
return GetTaxonomyInternal(contentTypeName, taxonomyFieldName, contentId, culture, selectedValues);
|
||||
}
|
||||
|
||||
protected ActionResult GetTaxonomyInternal (string contentTypeName, string taxonomyFieldName, int contentId, string culture, string selectedValues) {
|
||||
var viewModel = new TaxonomyFieldViewModel();
|
||||
bool autocomplete = false;
|
||||
var contentDefinition = _contentDefinitionManager.GetTypeDefinition(contentTypeName);
|
||||
if (contentDefinition != null) {
|
||||
var taxonomyField = contentDefinition.Parts.SelectMany(p => p.PartDefinition.Fields).Where(x => x.FieldDefinition.Name == "TaxonomyField" && x.Name == taxonomyFieldName).FirstOrDefault();
|
||||
var contentTypePartDefinition = contentDefinition.Parts.Where(x => x.PartDefinition.Fields.Any(a => a.FieldDefinition.Name == "TaxonomyField" && a.Name == taxonomyFieldName)).FirstOrDefault();
|
||||
ViewData.TemplateInfo.HtmlFieldPrefix = contentTypePartDefinition.PartDefinition.Name + "." + taxonomyField.Name;
|
||||
var fieldPrefix = contentTypePartDefinition.PartDefinition.Name + "." + taxonomyField.Name;
|
||||
ViewData.TemplateInfo.HtmlFieldPrefix = fieldPrefix;
|
||||
if (taxonomyField != null) {
|
||||
var taxonomySettings = taxonomyField.Settings.GetModel<TaxonomyFieldSettings>();
|
||||
// Getting the translated taxonomy and its terms
|
||||
@ -60,7 +65,33 @@ namespace Orchard.Taxonomies.Controllers {
|
||||
List<TermPart> appliedTerms = new List<TermPart>();
|
||||
int firstTermIdForCulture = 0;
|
||||
if (contentId > 0) {
|
||||
appliedTerms = _taxonomyService.GetTermsForContentItem(contentId, taxonomyFieldName, VersionOptions.Published).Distinct(new TermPartComparer()).ToList();
|
||||
var selectedIds = selectedValues.Split(',');
|
||||
var destinationTaxonomyCulture = taxonomy.As<LocalizationPart>()?.Culture?.Culture;
|
||||
foreach (var id in selectedIds) {
|
||||
if (!string.IsNullOrWhiteSpace(id)) {
|
||||
var intId = 0;
|
||||
int.TryParse(id, out intId);
|
||||
var originalTerm = _taxonomyService.GetTerm(intId);
|
||||
|
||||
// The original term has to be added to applied terms in the following scenarios:
|
||||
// When the original term has no LocalizationPart, which means that, when creating the taxonomy, terms have been set to be culture neutral.
|
||||
// When the culture of the original term matches the culture of the taxonomy.
|
||||
// In any other scenario, get the localized term and add it to the applied terms list.
|
||||
// If no localization is found, nothing is added to the list for the current id.
|
||||
var otCulture = originalTerm.As<LocalizationPart>()?.Culture?.Culture;
|
||||
if (!originalTerm.Has<LocalizationPart>() || string.Equals(destinationTaxonomyCulture, otCulture)) {
|
||||
appliedTerms.Add(originalTerm);
|
||||
} else {
|
||||
// Get the localized term. If no localized term is found, no term should be added to applied terms list.
|
||||
var t = _localizationService.GetLocalizedContentItem(originalTerm, culture);
|
||||
if (t != null) {
|
||||
// Localized term has been found
|
||||
appliedTerms.Add(t.As<TermPart>());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// It takes the first term localized with the culture in order to set correctly the TaxonomyFieldViewModel.SingleTermId
|
||||
var firstTermForCulture = appliedTerms.FirstOrDefault(x => x.As<LocalizationPart>() != null && x.As<LocalizationPart>().Culture != null && x.As<LocalizationPart>().Culture.Culture == culture);
|
||||
@ -86,16 +117,13 @@ namespace Orchard.Taxonomies.Controllers {
|
||||
TaxonomyId = taxonomy != null ? taxonomy.Id : 0,
|
||||
HasTerms = taxonomy != null && _taxonomyService.GetTermsCount(taxonomy.Id) > 0
|
||||
};
|
||||
if (taxonomySettings.Autocomplete)
|
||||
if (taxonomySettings.Autocomplete) {
|
||||
autocomplete = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
var templateName = autocomplete ? "../EditorTemplates/Fields/TaxonomyField.Autocomplete" : "../EditorTemplates/Fields/TaxonomyField";
|
||||
return View(templateName, viewModel);
|
||||
}
|
||||
private IEnumerable<TermPart> GetAppliedTerms(ContentPart part, TaxonomyField field = null, VersionOptions versionOptions = null) {
|
||||
string fieldName = field != null ? field.Name : string.Empty;
|
||||
return _taxonomyService.GetTermsForContentItem(part.ContentItem.Id, fieldName, versionOptions ?? VersionOptions.Published).Distinct(new TermPartComparer());
|
||||
return PartialView(templateName, viewModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ namespace Orchard.Taxonomies.Drivers {
|
||||
if (localizedParentTerm != null && localizedParentTerm != parentTerm)
|
||||
_notifier.Add(NotifyType.Information, T("The parent term has been changed to its localized version associated to the culture {0}.", localizedParentTerm.As<LocalizationPart>().Culture.Culture));
|
||||
}
|
||||
else if (termCulture != taxonomyCulture && taxonomyCulture != null && _localizationService.GetLocalizations(parentTaxonomy).Count() > 0) {
|
||||
else if (taxonomyCulture != null && termCulture.Culture != taxonomyCulture.Culture && _localizationService.GetLocalizations(parentTaxonomy).Count() > 0) {
|
||||
//I can associate to a taxonomy a term of a different culture only if the taxonomy is unlocalized or has no translations
|
||||
updater.AddModelError("WrongTaxonomyLocalization", T("A localization of the taxonomy in the specified language does not exist. Please create it first."));
|
||||
}
|
||||
|
@ -126,6 +126,7 @@
|
||||
<ItemGroup>
|
||||
<Compile Include="AdminMenu.cs" />
|
||||
<Compile Include="Controllers\AdminController.cs" />
|
||||
<Compile Include="Controllers\AdminLocalizedTaxonomyController.cs" />
|
||||
<Compile Include="Controllers\LocalizedTaxonomyController.cs" />
|
||||
<Compile Include="Drivers\LocalizedTaxonomyFieldDriver.cs" />
|
||||
<Compile Include="Drivers\LocalizedTaxonomyPartDriver.cs" />
|
||||
|
@ -32,6 +32,9 @@ namespace Orchard.Taxonomies.Services {
|
||||
|
||||
private readonly HashSet<int> _processedTermPartIds = new HashSet<int>();
|
||||
|
||||
private Dictionary<string, TaxonomyPart> _taxonomiesByName;
|
||||
private Dictionary<string, TaxonomyPart> _taxonomiesBySlug;
|
||||
|
||||
public TaxonomyService(
|
||||
IRepository<TermContentItem> termContentItemRepository,
|
||||
IContentManager contentManager,
|
||||
@ -54,13 +57,21 @@ namespace Orchard.Taxonomies.Services {
|
||||
|
||||
Logger = NullLogger.Instance;
|
||||
T = NullLocalizer.Instance;
|
||||
|
||||
// initialize memorization structures
|
||||
_taxonomiesByName = new Dictionary<string, TaxonomyPart>();
|
||||
_taxonomiesBySlug = new Dictionary<string, TaxonomyPart>();
|
||||
}
|
||||
|
||||
public ILogger Logger { get; set; }
|
||||
public Localizer T { get; set; }
|
||||
|
||||
private IEnumerable<TaxonomyPart> _taxonomies;
|
||||
public IEnumerable<TaxonomyPart> GetTaxonomies() {
|
||||
return GetTaxonomiesQuery().List();
|
||||
if (_taxonomies == null) {
|
||||
_taxonomies = GetTaxonomiesQuery().List();
|
||||
}
|
||||
return _taxonomies;
|
||||
}
|
||||
|
||||
public virtual TaxonomyPart GetTaxonomy(int id) {
|
||||
@ -71,26 +82,32 @@ namespace Orchard.Taxonomies.Services {
|
||||
if (string.IsNullOrWhiteSpace(name)) {
|
||||
throw new ArgumentNullException("name");
|
||||
}
|
||||
|
||||
if (!_taxonomiesByName.ContainsKey(name)) {
|
||||
// include the record in the query to optimize the query plan
|
||||
return GetTaxonomiesQuery()
|
||||
var t = GetTaxonomiesQuery()
|
||||
.Join<TitlePartRecord>()
|
||||
.Where(r => r.Title == name)
|
||||
.List()
|
||||
.FirstOrDefault();
|
||||
_taxonomiesByName.Add(name, t);
|
||||
}
|
||||
return _taxonomiesByName[name];
|
||||
}
|
||||
|
||||
public TaxonomyPart GetTaxonomyBySlug(string slug) {
|
||||
if (string.IsNullOrWhiteSpace(slug)) {
|
||||
throw new ArgumentNullException("slug");
|
||||
}
|
||||
|
||||
return GetTaxonomiesQuery()
|
||||
if (!_taxonomiesBySlug.ContainsKey(slug)) {
|
||||
var t = GetTaxonomiesQuery()
|
||||
.Join<TitlePartRecord>()
|
||||
.Join<AutoroutePartRecord>()
|
||||
.Where(r => r.DisplayAlias == slug)
|
||||
.List()
|
||||
.FirstOrDefault();
|
||||
_taxonomiesBySlug.Add(slug, t);
|
||||
}
|
||||
return _taxonomiesBySlug[slug];
|
||||
}
|
||||
|
||||
public void CreateTermContentType(TaxonomyPart taxonomy) {
|
||||
|
@ -1,4 +1,5 @@
|
||||
@using Orchard.Utility.Extensions;
|
||||
@using Orchard.UI.Admin;
|
||||
@model Orchard.Taxonomies.ViewModels.LocalizedTaxonomiesViewModel
|
||||
|
||||
@{
|
||||
@ -8,21 +9,63 @@
|
||||
var partField = Model.PartName + "_" + Model.FieldName;
|
||||
var functionName = "filterTaxonomyCulture_" + partField;
|
||||
|
||||
var isAdmin = AdminFilter.IsApplied(Request.RequestContext);
|
||||
|
||||
var controllerUrl = Url.Action("GetTaxonomy", "LocalizedTaxonomy", new { area = "Orchard.Taxonomies" });
|
||||
if (isAdmin) {
|
||||
controllerUrl = Url.Action("GetTaxonomy", "AdminLocalizedTaxonomy", new { area = "Orchard.Taxonomies" });
|
||||
}
|
||||
|
||||
|
||||
using (Script.Foot()) {
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
$(document).ready(function () {
|
||||
var pageurl = '@Url.Action("GetTaxonomy", "LocalizedTaxonomy", new { area = "Orchard.Taxonomies" })';
|
||||
var pageurl = '@controllerUrl';
|
||||
|
||||
function @(functionName)(culture) {
|
||||
// Read currently selected values
|
||||
var checkedTerms = $("input[type!='hidden']:checked", $(".taxonomy-wrapper[data-id-prefix='@Taxonomyprefix']"));
|
||||
var selectedValues = "";
|
||||
$(checkedTerms).each(function () {
|
||||
var sel = $("input[type=hidden]", $(this).parent()).attr("value");
|
||||
if (sel) {
|
||||
selectedValues = selectedValues + "," + sel;
|
||||
}
|
||||
});
|
||||
$.ajax({
|
||||
url: pageurl,
|
||||
data: { contentTypeName: '@Model.ContentType', taxonomyFieldName: '@Model.FieldName', contentId: @Model.Id, culture: culture },
|
||||
data: {
|
||||
contentTypeName: '@Model.ContentType',
|
||||
taxonomyFieldName: '@Model.FieldName',
|
||||
contentId: @Model.Id,
|
||||
culture: culture,
|
||||
selectedValues: selectedValues,
|
||||
success: function (html) {
|
||||
var container = $(".taxonomy-wrapper[data-id-prefix='@Taxonomyprefix']");
|
||||
|
||||
// Take the terms previously checked
|
||||
var checkedTerms = $("input[checked='checked']", container);
|
||||
|
||||
$(".taxonomy-wrapper[data-id-prefix='@Taxonomyprefix']").replaceWith(html);
|
||||
|
||||
$(".taxonomy-wrapper[data-id-prefix='@Taxonomyprefix'] legend").expandoControl(function (controller) { return controller.nextAll(".expando"); }, { collapse: true, remember: false });
|
||||
// try to init expando controls until we manage to
|
||||
var interval = setInterval(InitExpando, 10);
|
||||
function InitExpando() {
|
||||
// the script to initialize expando controls requires them to have a rendered size on screen.
|
||||
// That is not the case when they are in a different tab, because in that case they are basically
|
||||
// set to display=none. By retrying here until they get on screen we get around that issue.
|
||||
$(".taxonomy-wrapper[data-id-prefix='@Taxonomyprefix'] legend")
|
||||
.expandoControl(function (controller) {
|
||||
return controller.nextAll(".expando");
|
||||
}, { collapse: true, remember: false });
|
||||
|
||||
var glyph = $(".taxonomy-wrapper[data-id-prefix='@Taxonomyprefix'] legend .expando-glyph-container");
|
||||
if (glyph && glyph.length) {
|
||||
clearInterval(interval);
|
||||
}
|
||||
}
|
||||
|
||||
@if (Model.Setting.Autocomplete) {
|
||||
<text>
|
||||
var createTermCheckbox = function($wrapper, tag, checked) {
|
||||
@ -137,20 +180,27 @@
|
||||
</text>
|
||||
}
|
||||
|
||||
///////////////////////////
|
||||
}
|
||||
}).fail(function () {
|
||||
alert("@T("Loading taxonomy fail, Retry")");
|
||||
});
|
||||
}
|
||||
$("#Localization_SelectedCulture").on('change', function (p) {
|
||||
var optionSelected = $("option:selected", this);
|
||||
|
||||
$("#Localization_SelectedCulture").on('change', function (ev, pf) {
|
||||
//ev: jquery event
|
||||
//pf: Orchard's field differentiator
|
||||
var refreshTerms = false;
|
||||
if (p != undefined) {
|
||||
if (p == "@(partField)") {
|
||||
if (pf != undefined) {
|
||||
// refresh of terms invoked from a field
|
||||
if (pf == "@(partField)") {
|
||||
// refresh of terms invoked from this field
|
||||
refreshTerms = true;
|
||||
}
|
||||
} else {
|
||||
// refresh of terms invoked by changing the content's culture
|
||||
refreshTerms = true;
|
||||
}
|
||||
|
||||
if (refreshTerms) {
|
||||
@(functionName)($("#Localization_SelectedCulture").val());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user