Rewrote Localizaton controller and driver

This commit is contained in:
Nicholas Mayne
2014-09-11 23:59:04 +01:00
parent a1c7ddc48f
commit fa1de09a4f
8 changed files with 133 additions and 238 deletions

View File

@@ -37,58 +37,32 @@ namespace Orchard.Localization.Controllers {
public IOrchardServices Services { get; set; }
public ActionResult Translate(int id, string to) {
var contentItem = _contentManager.Get(id, VersionOptions.Latest);
if (contentItem == null)
var masterContentItem = _contentManager.Get(id, VersionOptions.Latest);
if (masterContentItem == null)
return HttpNotFound();
var lp = contentItem.As<LocalizationPart>();
if (lp == null)
var masterLocalizationPart = masterContentItem.As<LocalizationPart>();
if (masterLocalizationPart == null)
return HttpNotFound();
string contentItemCulture = _localizationService.GetContentCulture(contentItem);
var localizations = _localizationService.GetLocalizations(lp, VersionOptions.Latest);
// Check is current item stll exists, and redirect.
var existingTranslation = _localizationService.GetLocalizedContentItem(masterContentItem, to);
if (existingTranslation != null) {
var existingTranslationMetadata = _contentManager.GetItemMetadata(existingTranslation);
return RedirectToAction(
Convert.ToString(existingTranslationMetadata.EditorRouteValues["action"]),
existingTranslationMetadata.EditorRouteValues);
}
var contentItemTranslation = _contentManager.New(masterContentItem.ContentType);
var contentItemTranslationPart = contentItemTranslation.As<LocalizationPart>();
contentItemTranslationPart.MasterContentItem = masterContentItem;
var content = _contentManager.BuildEditor(contentItemTranslation);
var siteCultures = _cultureManager.ListCultures();
var missingCultures = siteCultures.Where(s =>
s != contentItemCulture
&& !localizations.Any(l => s == l.Culture.Culture))
.ToList();
string selectedCulture = null;
if (!String.IsNullOrEmpty(to)) {
if (!siteCultures.Any(c => String.Equals(c, to, StringComparison.OrdinalIgnoreCase)))
return HttpNotFound();
var existingLocalization = String.Equals(contentItemCulture, to, StringComparison.OrdinalIgnoreCase)
? lp
: localizations.FirstOrDefault(l => string.Equals(l.Culture.Culture, to, StringComparison.OrdinalIgnoreCase));
if (existingLocalization != null) {
var metadata = _contentManager.GetItemMetadata(existingLocalization);
return RedirectToAction(Convert.ToString(metadata.EditorRouteValues["action"]), metadata.EditorRouteValues);
}
selectedCulture = missingCultures.SingleOrDefault(s => string.Equals(s, to, StringComparison.OrdinalIgnoreCase));
}
if (lp.Culture != null)
lp.Culture.Culture = null;
var model = new AddLocalizationViewModel {
Id = id,
SelectedCulture = selectedCulture,
MissingCultures = missingCultures,
Content = _contentManager.BuildEditor(contentItem)
};
// Cancel transaction so that the LocalizationPart is not modified.
Services.TransactionManager.Cancel();
return View(model);
return View(content);
}
[HttpPost, ActionName("Translate")]
@@ -107,64 +81,47 @@ namespace Orchard.Localization.Controllers {
}
public ActionResult TranslatePOST(int id, Action<ContentItem> conditionallyPublish) {
var contentItem = _contentManager.Get(id, VersionOptions.Latest);
var originalLp = contentItem.As<LocalizationPart>();
if (contentItem == null)
var masterContentItem = _contentManager.Get(id, VersionOptions.Latest);
if (masterContentItem == null)
return HttpNotFound();
var model = new AddLocalizationViewModel();
TryUpdateModel(model);
var masterLocalizationPart = masterContentItem.As<LocalizationPart>();
if (masterLocalizationPart == null)
return HttpNotFound();
ContentItem contentItemTranslation;
var existingTranslation = _localizationService.GetLocalizedContentItem(contentItem, model.SelectedCulture);
var model = new EditLocalizationViewModel();
TryUpdateModel(model, "Localization");
var existingTranslation = _localizationService.GetLocalizedContentItem(masterContentItem, model.SelectedCulture);
if (existingTranslation != null) {
// edit existing
contentItemTranslation = _contentManager.Get(existingTranslation.ContentItem.Id, VersionOptions.DraftRequired);
} else {
// create
contentItemTranslation = _contentManager.New(contentItem.ContentType);
var translationLp = contentItemTranslation.As<LocalizationPart>();
translationLp.MasterContentItem = originalLp.MasterContentItem ?? contentItem;
if (!string.IsNullOrWhiteSpace(model.SelectedCulture))
{
translationLp.Culture = _cultureManager.GetCultureByName(model.SelectedCulture);
}
_contentManager.Create(contentItemTranslation, VersionOptions.Draft);
var existingTranslationMetadata = _contentManager.GetItemMetadata(existingTranslation);
return RedirectToAction(
Convert.ToString(existingTranslationMetadata.EditorRouteValues["action"]),
existingTranslationMetadata.EditorRouteValues);
}
model.Content = _contentManager.UpdateEditor(contentItemTranslation, this);
var contentItemTranslation = _contentManager.New(masterContentItem.ContentType);
var contentItemTranslationPart = contentItemTranslation.As<LocalizationPart>();
contentItemTranslationPart.MasterContentItem = masterContentItem;
_contentManager.Create(contentItemTranslation, VersionOptions.Draft);
var content = _contentManager.UpdateEditor(contentItemTranslation, this);
if (!ModelState.IsValid) {
Services.TransactionManager.Cancel();
model.MissingCultures = _cultureManager.ListCultures().Where(s => s != _localizationService.GetContentCulture(contentItem) && s != _cultureManager.GetSiteCulture());
var culture = originalLp.Culture;
if (culture != null) {
culture.Culture = null;
}
model.Content = _contentManager.BuildEditor(contentItem);
return View(model);
return View(content);
}
if (existingTranslation != null) {
Services.Notifier.Information(T("Edited content item translation."));
}
else {
conditionallyPublish(contentItemTranslation);
conditionallyPublish(contentItemTranslation);
Services.Notifier.Information(T("Created content item translation."));
}
Services.Notifier.Information(T("Created content item translation."));
var metadata = _contentManager.GetItemMetadata(model.Content.ContentItem);
//todo: (heskew) if null, redirect to somewhere better than nowhere
return metadata.EditorRouteValues == null ? null : RedirectToRoute(metadata.EditorRouteValues);
var metadata = _contentManager.GetItemMetadata(contentItemTranslation);
return RedirectToAction(Convert.ToString(metadata.EditorRouteValues["action"]), metadata.EditorRouteValues);
}
bool IUpdateModel.TryUpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, string[] excludeProperties) {

View File

@@ -39,10 +39,33 @@ namespace Orchard.Localization.Drivers {
}
protected override DriverResult Editor(LocalizationPart part, dynamic shapeHelper) {
var localizations = GetEditorLocalizations(part).ToList();
List<LocalizationPart> localizations = GetEditorLocalizations(part).ToList();
var siteCultures = _cultureManager.ListCultures().ToList();
List<string> missingCultures;
if (part.MasterContentItem != null) {
var localizationPart = part.MasterContentItem.As<LocalizationPart>();
missingCultures =
siteCultures.Where(s => GetEditorLocalizations(localizationPart).All(l => l.Culture.Culture != s))
.ToList();
missingCultures.Remove(localizationPart.Culture.Culture);
}
else {
missingCultures =
siteCultures.Where(s => GetEditorLocalizations(part).All(l => l.Culture.Culture != s))
.ToList();
if (part.Culture != null)
missingCultures.Remove(part.Culture.Culture);
}
var model = new EditLocalizationViewModel {
SelectedCulture = GetCulture(part),
SiteCultures = _cultureManager.ListCultures().Where(s => !localizations.Any(l => l.Culture.Culture == s)).ToList(),
SiteCultures = siteCultures,
MissingCultures = missingCultures,
ContentItem = part,
MasterContentItem = part.MasterContentItem,
ContentLocalizations = new ContentLocalizationsViewModel(part) { Localizations = localizations }
@@ -84,7 +107,7 @@ namespace Orchard.Localization.Drivers {
return c;
}).ToList();
}
protected override void Importing(LocalizationPart part, ContentManagement.Handlers.ImportContentContext context) {
var masterContentItem = context.Attribute(part.PartDefinition.Name, "MasterContentItem");
if (masterContentItem != null) {

View File

@@ -98,7 +98,6 @@
<Compile Include="Services\LocalizationService.cs" />
<Compile Include="Services\TransliterationService.cs" />
<Compile Include="Events\TransliterationSlugEventHandler.cs" />
<Compile Include="ViewModels\AddLocalizationViewModel.cs" />
<Compile Include="ViewModels\ContentLocalizationsViewModel.cs" />
<Compile Include="ViewModels\EditLocalizationViewModel.cs" />
<Compile Include="ViewModels\CreateTransliterationViewModel.cs" />
@@ -117,9 +116,6 @@
<ItemGroup>
<Content Include="Views\Admin\Translate.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="Views\CultureSelection.cshtml" />
</ItemGroup>
<ItemGroup>
<Content Include="Views\EditorTemplates\Parts\Localization.ContentTranslations.Edit.cshtml" />
</ItemGroup>

View File

@@ -1,13 +0,0 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using Orchard.ContentManagement;
namespace Orchard.Localization.ViewModels {
public class AddLocalizationViewModel {
public int Id { get; set; }
[Required]
public string SelectedCulture { get; set; }
public IEnumerable<string> MissingCultures { get; set; }
public IContent Content { get; set; }
}
}

View File

@@ -5,6 +5,7 @@ namespace Orchard.Localization.ViewModels {
public class EditLocalizationViewModel {
public string SelectedCulture { get; set; }
public IEnumerable<string> SiteCultures { get; set; }
public IEnumerable<string> MissingCultures { get; set; }
public IContent ContentItem { get; set; }
public IContent MasterContentItem { get; set; }
public ContentLocalizationsViewModel ContentLocalizations { get; set; }

View File

@@ -1,54 +1,8 @@
@model AddLocalizationViewModel
@using Orchard.Localization.ViewModels;
@{
dynamic content = Model.Content;
content.Zones.Content.Add(New.Partial(TemplateName: "CultureSelection", Model: Model), "0");
Layout.Title = T("Translate Content").ToString();
}
@using (Html.BeginFormAntiForgeryPost()) {
@Html.ValidationSummary()
@Display(Model.Content)
}
@using (Script.Foot()) {
<script type="text/javascript">
//<![CDATA[
(function ($) {
"use strict";
// grab the slug input
var slug = $("#Autoroute_CurrentUrl");
if (slug) {
// grab the current culture
var culture = $("#SelectedCulture");
var currentCulture = culture.val();
// when the culture is changed update the slug
culture.change(function () {
var slugValue = slug.val();
var newCulture = $(this).val();
if (slugValue && slugValue.match(currentCulture + "$")) {
slug.val(slugValue.replace(new RegExp(currentCulture + "$", "i"), newCulture));
currentCulture = newCulture;
}
});
}
var culture = $("#SelectedCulture");
culture.change(function () {
var optionDirectionality = $("option:selected", this).attr("data-content-dir");
var contentZone = $(".zone-content");
if (contentZone.hasClass(optionDirectionality))
return;
var oldClass = optionDirectionality === "ltr" ? "rtl" : "";
contentZone.removeClass("content-" + oldClass);
contentZone.addClass("content-" + optionDirectionality);
$(document).trigger("localization.ui.directionalitychanged", optionDirectionality);
});
})(jQuery);
//]]>
</script>
@Display(Model)
}

View File

@@ -1,31 +0,0 @@
@using System.Globalization
@using System.Text
@model Orchard.Localization.ViewModels.AddLocalizationViewModel
@{
Style.Require("LocalizationAdmin");
}
<fieldset class="localization culture-selection">
<label for="SelectedCulture">@T("Content Localization")</label>
<div>
@T("This is the <em>{0}</em> variation of {1}",
BuildSelectedCultureList(Html.FieldIdFor(m => m.SelectedCulture), Html.FieldNameFor(m => m.SelectedCulture), Model.MissingCultures, Model.SelectedCulture),
Html.ItemEditLink(Model.Content))
</div>
</fieldset>
@functions{
private string BuildSelectedCultureList(string id, string name, IEnumerable<string> siteCultures, string culture) {
TagBuilder selectTag = new TagBuilder("select");
selectTag.Attributes["id"] = id;
selectTag.Attributes["name"] = name;
foreach (var siteCulture in siteCultures) {
TagBuilder optionTag = new TagBuilder("option");
optionTag.Attributes["data-content-dir"] = CultureInfo.GetCultureInfo(siteCulture).TextInfo.IsRightToLeft ? "rtl" : "ltr";
optionTag.Attributes["value"] = siteCulture;
optionTag.SetInnerText(siteCulture);
selectTag.InnerHtml += optionTag.ToString();
}
return selectTag.ToString();
}
}

View File

@@ -1,61 +1,66 @@
@model Orchard.Localization.ViewModels.EditLocalizationViewModel
@using System.Globalization
@using System.Linq;
@{
Style.Require("LocalizationAdmin");
var siteCultures = Model.SiteCultures.ToList();
}
<fieldset class="localization culture-selection">
@if (Model.ContentItem.ContentItem.Id == 0 && Model.SelectedCulture == null && Model.ContentLocalizations.Localizations.Count() == 0) {
/* If this is a new item */
<fieldset class="localization culture-selection">
<label for="SelectedCulture">@T("Content Localization")</label>
<div>
<label for="@Html.FieldIdFor(m => m.SelectedCulture)">@T("Content Localization")</label>
<div>
@*Brand new content item*@
@if (Model.ContentItem.ContentItem.Id == 0) {
if (Model.MasterContentItem == null) {
@T("This is the <em>{0}</em> variation of the content",
BuildSelectedCultureList(
Html.FieldIdFor(m => m.SelectedCulture),
Html.FieldNameFor(m => m.SelectedCulture),
siteCultures,
Model.SelectedCulture))
</div>
</fieldset>
}
@if (Model.ContentItem.ContentItem.Id > 0 && Model.SelectedCulture != null && Model.ContentLocalizations.Localizations.Count() == 0) {
<fieldset class="culture-selected">
<label for="SelectedCulture">@T("Content Localization")</label>
<div>
@T("This is the <em>{0}</em> variation of content.",
Html.Encode(Model.SelectedCulture))
</div>
@Html.Hidden("SelectedCulture", Model.SelectedCulture)
</fieldset>
}
@if (Model.ContentItem.ContentItem.Id > 0 && Model.SelectedCulture != null && Model.ContentLocalizations.Localizations.Count() > 0) {
<fieldset class="culture-selected">
<label for="SelectedCulture">@T("Content Localization")</label>
<div>
@T("This is the <em>{0}</em> variation of {1}.",
Html.Encode(Model.SelectedCulture),
Html.ItemEditLink(Model.MasterContentItem ?? Model.ContentItem))
</div>
@Html.Hidden("SelectedCulture", Model.SelectedCulture)
</fieldset>
if (Model.ContentLocalizations.Localizations.Count() > 0) {
<dl class="content-localization">
<dt>@T("Other translations:")</dt>
<dd class="content-localizations">
@Html.UnorderedList(Model.ContentLocalizations.Localizations, (c, i) => Html.ItemEditLink(c.Culture.Culture, c), "localizations")
</dd>
</dl>
BuildSelectedCultureList(
Html.FieldIdFor(m => m.SelectedCulture),
Html.FieldNameFor(m => m.SelectedCulture),
Model.SiteCultures,
Model.SelectedCulture))
}
else {
@T("This is the <em>{0}</em> variation of {1}",
BuildSelectedCultureList(
Html.FieldIdFor(m => m.SelectedCulture),
Html.FieldNameFor(m => m.SelectedCulture),
Model.MissingCultures,
Model.SelectedCulture),
Html.ItemEditLink(Model.MasterContentItem))
}
}
}
@if (Model.SelectedCulture != null && !siteCultures.All(c => c == Model.SelectedCulture || Model.ContentLocalizations.Localizations.Any(l => c == l.Culture.Culture))) {
<div class="add-localization">@Html.ActionLink(T("+ New translation").Text, "Translate", "Admin", new { area = "Orchard.Localization", id = Model.ContentItem.Id }, null)</div>
}
@if (Model.ContentItem.ContentItem.Id > 0) {
//if (Model.MasterContentItem == null) {
@T("This is the <em>{0}</em> variation of the content",
Html.Encode(Model.SelectedCulture))
@*}
else {
@T("This is the <em>{0}</em> variation of {1}",
Html.Encode(Model.SelectedCulture),
Html.ItemEditLink(Model.MasterContentItem))
}*@
if (Model.ContentLocalizations.Localizations.Any()) {
<dl class="content-localization">
<dt>@T("Other translations:")</dt>
<dd class="content-localizations">
@Html.UnorderedList(Model.ContentLocalizations.Localizations, (c, i) =>
Html.ItemEditLink(c.Culture.Culture, c), "localizations")
</dd>
</dl>
}
if (Model.MissingCultures.Any()) {
var contentItemId = Model.MasterContentItem != null ? Model.MasterContentItem.Id : Model.ContentItem.Id;
<div class="add-localization">@Html.ActionLink(T("+ New translation").Text, "Translate", "Admin", new { area = "Orchard.Localization", id = contentItemId }, null)</div>
}
@Html.Hidden(Html.FieldNameFor(m => m.SelectedCulture), Model.SelectedCulture)
}
</div>
</fieldset>
@functions{
private string BuildSelectedCultureList(string id, string name, IEnumerable<string> siteCultures, string culture) {
TagBuilder selectTag = new TagBuilder("select");
@@ -65,7 +70,10 @@
foreach (var siteCulture in siteCultures) {
TagBuilder optionTag = new TagBuilder("option");
optionTag.Attributes["data-content-dir"] = CultureInfo.GetCultureInfo(siteCulture).TextInfo.IsRightToLeft ? "rtl" : "ltr";
//optionTag.Attributes["value"] = siteCulture;
if (siteCulture == culture) {
optionTag.Attributes["selected"] = "selected";
}
optionTag.SetInnerText(siteCulture);
selectTag.InnerHtml += optionTag.ToString();
}