Some work on the content localization UI

--HG--
branch : dev
This commit is contained in:
Nathan Heskew
2010-07-20 11:45:44 -07:00
parent 2cf2931745
commit 30fbf7f469
13 changed files with 135 additions and 50 deletions

View File

@@ -9,7 +9,6 @@ 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)]
@@ -32,9 +31,15 @@ namespace Orchard.Core.Localization.Controllers {
public ActionResult Translate(int id, string to) {
var contentItem = _contentManager.Get(id, VersionOptions.Latest);
// only support translations from the site culture, at the moment at least
if (contentItem == null)
return new NotFoundResult();
if (!contentItem.Is<Localized>() || contentItem.As<Localized>().MasterContentItem != null) {
var metadata = _contentManager.GetItemMetadata(contentItem);
return RedirectToAction(Convert.ToString(metadata.EditorRouteValues["action"]), metadata.EditorRouteValues);
}
var siteCultures = _cultureManager.ListCultures().Where(s => s != _localizationService.GetContentCulture(contentItem));
var model = new AddLocalizationViewModel {
Id = id,

View File

@@ -4,40 +4,67 @@ using System.Web;
using JetBrains.Annotations;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Drivers;
using Orchard.Core.Common;
using Orchard.Core.Localization.Models;
using Orchard.Core.Localization.Services;
using Orchard.Core.Localization.ViewModels;
using Orchard.Localization.Services;
using Orchard.Settings;
namespace Orchard.Core.Localization.Drivers {
[UsedImplicitly]
public class LocalizationDriver : ContentPartDriver<Localized> {
private const string TemplatePrefix = "Localization";
private readonly ICultureManager _cultureManager;
private readonly ILocalizationService _localizationService;
public LocalizationDriver(IOrchardServices services, ICultureManager cultureManager, ILocalizationService localizationService) {
public LocalizationDriver(ICultureManager cultureManager, ILocalizationService localizationService) {
_cultureManager = cultureManager;
_localizationService = localizationService;
Services = services;
}
protected virtual ISite CurrentSite { get; private set; }
public IOrchardServices Services { get; set; }
protected override DriverResult Display(Localized part, string displayType) {
var model = new ContentLocalizationsViewModel(part) {
Localizations = _localizationService.GetLocalizations(part.ContentItem)
.Select(c => {
var localized = c.ContentItem.As<Localized>();
if (localized.Culture == null)
localized.Culture = _cultureManager.GetCultureByName(_cultureManager.GetCurrentCulture(new HttpContextWrapper(HttpContext.Current)));
return c;
}).ToList()
Localizations = GetDisplayLocalizations(part)
};
return ContentPartTemplate(model, "Parts/Localization.ContentTranslations").LongestMatch(displayType, "Summary", "SummaryAdmin").Location("primary", "5");
return ContentPartTemplate(model, "Parts/Localization.ContentTranslations", TemplatePrefix).LongestMatch(displayType, "Summary", "SummaryAdmin").Location("primary", "5");
}
protected override DriverResult Editor(Localized part) {
var localizations = GetEditorLocalizations(part).ToList();
var model = new EditLocalizationViewModel {
SelectedCulture = part.Culture != null ? part.Culture.Culture : null,
SiteCultures = _cultureManager.ListCultures().Where(s => s != _cultureManager.GetSiteCulture() && !localizations.Select(l => l.Culture.Culture).Contains(s)),
MasterContentItem = part.MasterContentItem,
ContentLocalizations = new ContentLocalizationsViewModel(part) { Localizations = localizations }
};
return ContentPartTemplate(model, "Parts/Localization.Translation", TemplatePrefix).Location("primary", "1");
}
protected override DriverResult Editor(Localized part, IUpdateModel updater) {
var model = new EditLocalizationViewModel();
if (updater != null && updater.TryUpdateModel(model, TemplatePrefix, null, null)) {
_localizationService.SetContentCulture(part, model.SelectedCulture);
}
return Editor(part);
}
private IEnumerable<Localized> GetDisplayLocalizations(Localized part) {
return _localizationService.GetLocalizations(part.ContentItem)
.Select(c => {
var localized = c.ContentItem.As<Localized>();
if (localized.Culture == null) {
localized.Culture = _cultureManager.GetCultureByName(_cultureManager.GetCurrentCulture(new HttpContextWrapper(HttpContext.Current)));
}
return c;
}).ToList();
}
private IEnumerable<Localized> GetEditorLocalizations(Localized part) {
return _localizationService.GetLocalizations(part.ContentItem)
.Select(c => c.ContentItem.As<Localized>())
.Where(l => l.MasterContentItem != null).ToList();
}
}
}

View File

@@ -22,8 +22,6 @@ namespace Orchard.Core.Localization.Handlers {
OnInitializing<Localized>(InitializePart);
OnLoaded<Localized>(LazyLoadHandlers);
OnIndexed<Localized>((context, localized) => context.DocumentIndex
.Add("culture", CultureInfo.GetCultureInfo(localized.Culture != null ? localized.Culture.Culture : _cultureManager.GetSiteCulture()).LCID)
.Store()
@@ -32,11 +30,6 @@ namespace Orchard.Core.Localization.Handlers {
public Localizer T { get; set; }
void LazyLoadHandlers(LoadContentContext context, Localized localized) {
localized.CultureField.Loader(ctx => _cultureManager.GetCultureById(localized.Record.CultureId));
localized.MasterContentItemField.Loader(ctx => _contentManager.Get(localized.Record.MasterContentItemId));
}
void InitializePart(InitializingContentContext context, Localized localized) {
localized.CultureField.Setter(cultureRecord => {
localized.Record.CultureId = cultureRecord.Id;
@@ -46,6 +39,8 @@ namespace Orchard.Core.Localization.Handlers {
localized.Record.MasterContentItemId = masterContentItem.ContentItem.Id;
return masterContentItem;
});
localized.CultureField.Loader(ctx => _cultureManager.GetCultureById(localized.Record.CultureId));
localized.MasterContentItemField.Loader(ctx => _contentManager.Get(localized.Record.MasterContentItemId));
}
}
}

View File

@@ -6,6 +6,7 @@ namespace Orchard.Core.Localization.Services {
public interface ILocalizationService : IDependency {
Localized GetLocalizedContentItem(IContent masterContentItem, string culture);
string GetContentCulture(IContent contentItem);
void SetContentCulture(IContent contentItem, string culture);
IEnumerable<Localized> GetLocalizations(IContent contentItem);
}
}

View File

@@ -4,7 +4,6 @@ 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 {
@@ -25,11 +24,20 @@ namespace Orchard.Core.Localization.Services {
}
string ILocalizationService.GetContentCulture(IContent content) {
return content.Is<Localized>() && content.As<Localized>().Culture != null
? content.As<Localized>().Culture.Culture
var localized = content.As<Localized>();
return localized != null && localized.Culture != null
? localized.Culture.Culture
: _cultureManager.GetSiteCulture();
}
void ILocalizationService.SetContentCulture(IContent content, string culture) {
var localized = content.As<Localized>();
if (localized == null || localized.MasterContentItem == null)
return;
localized.Culture = _cultureManager.GetCultureByName(culture);
}
IEnumerable<Localized> ILocalizationService.GetLocalizations(IContent content) {
var localized = content.As<Localized>();

View File

@@ -1,25 +1,45 @@
.content-localization {
margin:1.44em 0 0;
}
.content-localization .content-localizations li,
.content-localization .content-localizations li,
.content-localization .add-localization {
font-size:1.4em;
}
.content-localization .culture-selected {
margin-bottom:.5em;
}
.content-localization .content-localizations {
font-size:.9em;
}
.content-localization .content-localizations>* {
display:inline;
}
.content-localization .content-localizations li {
.content-localization .content-localizations .localizations li {
border-bottom:0;
display:inline;
margin-left:.5em;
padding:0;
}
.content-localization .content-localizations li::after {
content:", ";
content:",";
}
.content-localization .content-localizations li:last-child::after {
content:"";
}
.culture-selection fieldset {
padding-top:0;
}
.culture-selection div {
font-size:1.4em;
}
.culture-selection dl {
margin:.2em 0;
}
.culture-selection dt {
color:#4C4C4C;
font-weight:bold;
}
.culture-selection dt, .culture-selection dd, .culture-selection ul {
display:inline;
}
.culture-selection .content-localization .content-localizations {
clear:none;
float:none;
}

View File

@@ -1,14 +1,15 @@
using System.Collections.Generic;
using Orchard.ContentManagement;
using Orchard.Core.Localization.Models;
namespace Orchard.Core.Localization.ViewModels {
public class ContentLocalizationsViewModel {
public ContentLocalizationsViewModel(IContent part) {
Id = part.ContentItem.Id;
public ContentLocalizationsViewModel(Localized part) {
MasterId = part.MasterContentItem != null
? part.MasterContentItem.ContentItem.Id
: part.Id;
}
public int Id { get; private set; }
public int? MasterId { get; private set; }
public IEnumerable<Localized> Localizations { get; set; }
}
}

View File

@@ -0,0 +1,12 @@
using System.Collections.Generic;
using Orchard.ContentManagement;
using Orchard.Mvc.ViewModels;
namespace Orchard.Core.Localization.ViewModels {
public class EditLocalizationViewModel : BaseViewModel {
public string SelectedCulture { get; set; }
public IEnumerable<string> SiteCultures { get; set; }
public IContent MasterContentItem { get; set; }
public ContentLocalizationsViewModel ContentLocalizations { get; set; }
}
}

View File

@@ -1,9 +0,0 @@
using Orchard.Core.Localization.Models;
namespace Orchard.Core.Localization.ViewModels {
public class SelectLocalizationsViewModel {
public SelectLocalizationsViewModel(Localized part) {
}
}
}

View File

@@ -4,7 +4,7 @@
<div class="content-localization"><%
if (Model.Localizations.Count() > 0) { %>
<%--//todo: need this info in the view model--%>
<div class="content-localizations"><h4><%:T("Translations:") %></h4><%:Html.UnorderedList(Model.Localizations, (c, i) => Html.ItemDisplayLink(c.Culture.Culture, c), "localizations") %></div><%
<div class="content-localizations"><h4><%:T("Translations:") %></h4><%:Html.UnorderedList(Model.Localizations, (c, i) => Html.ItemEditLink(c.Culture.Culture, c), "localizations") %></div><%
} %>
<div class="add-localization"><%:Html.ActionLink(T("+ New translation").Text, "translate", "admin", new { area = "Localization", id = Model.Id }, null)%></div>
<div class="add-localization"><%:Html.ActionLink(T("+ New translation").Text, "translate", "admin", new { area = "Localization", id = Model.MasterId }, null)%></div>
</div>

View File

@@ -6,5 +6,5 @@
<%--//todo: need this info in the view model--%>
<div class="content-localizations"><%:Html.UnorderedList(Model.Localizations, (c, i) => Html.ItemDisplayLink(c.Culture.Culture, c), "localizations") %></div><%
} %>
<div class="add-localization"><%:Html.ActionLink(T("+ New translation").Text, "translate", "admin", new { area = "Localization", id = Model.Id }, null)%></div>
<div class="add-localization"><%:Html.ActionLink(T("+ New translation").Text, "translate", "admin", new { area = "Localization", id = Model.MasterId }, null)%></div>
</div>

View File

@@ -0,0 +1,24 @@
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl<Orchard.Core.Localization.ViewModels.EditLocalizationViewModel>" %>
<%
Html.RegisterStyle("admin.css");
Html.RegisterStyle("base.css");
if (Model.ContentLocalizations.MasterId > 0) { %>
<fieldset class="localization culture-selection"><%
if (Model.MasterContentItem != null) { %>
<fieldset class="culture-selected">
<label for="SelectedCulture"><%:T("Content Localization") %></label>
<div><%:T("This is the {0} variation of {1}.",
Html.DropDownList("SelectedCulture", new SelectList(Model.SiteCultures, Model.SelectedCulture)),
Html.ItemEditLink(Model.MasterContentItem)) %></div>
</fieldset><%
}
if (Model.ContentLocalizations.Localizations.Count() > 0) { //todo: find a good place for this info on the content edit page %>
<dl class="content-localization">
<dt><%:Model.MasterContentItem != null ? T("Other translations:") : T("Translations:") %></dt>
<dd class="content-localizations">
<%:Html.UnorderedList(Model.ContentLocalizations.Localizations, (c, i) => Html.ItemEditLink(c.Culture.Culture, c), "localizations") %>
</dd>
</dl><%
} %>
</fieldset><%
} %>

View File

@@ -80,6 +80,7 @@
<Compile Include="Contents\Permissions.cs" />
<Compile Include="Contents\Routes.cs" />
<Compile Include="Contents\ViewModels\PublishContentViewModel.cs" />
<Compile Include="Localization\ViewModels\EditLocalizationViewModel.cs" />
<Compile Include="PublishLater\Drivers\PublishLaterPartDriver.cs" />
<Compile Include="PublishLater\Models\PublishLaterPart.cs" />
<Compile Include="PublishLater\Handlers\PublishLaterPartHandler.cs" />
@@ -93,7 +94,6 @@
<Compile Include="Localization\Services\ILocalizationService.cs" />
<Compile Include="Localization\Services\LocalizationService.cs" />
<Compile Include="Localization\ViewModels\ContentLocalizationsViewModel.cs" />
<Compile Include="Localization\ViewModels\SelectLocalizationsViewModel.cs" />
<Compile Include="Reports\AdminMenu.cs" />
<Compile Include="Reports\Controllers\AdminController.cs" />
<Compile Include="Reports\Routes.cs" />
@@ -233,6 +233,7 @@
<Content Include="Common\Views\DisplayTemplates\Parts\Common.Metadata.SummaryAdmin.ascx" />
<Content Include="Contents\Views\DisplayTemplates\Parts\Contents.Publish.SummaryAdmin.ascx" />
<Content Include="Contents\Views\DisplayTemplates\Parts\Contents.Publish.ascx" />
<Content Include="Localization\Views\EditorTemplates\Parts\Localization.Translation.ascx" />
<Content Include="PublishLater\Views\DisplayTemplates\Parts\PublishLater.Metadata.ascx" />
<Content Include="PublishLater\Views\DisplayTemplates\Parts\PublishLater.Metadata.SummaryAdmin.ascx" />
<Content Include="Common\Views\EditorTemplates\Fields\Common.TextField.ascx" />