mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-07-31 21:32:56 +08:00
Fixing taxonomy navigation
This commit is contained in:
parent
2f45a02a1f
commit
a45d4b29d9
@ -149,7 +149,7 @@ namespace Orchard.Taxonomies.Controllers {
|
||||
var taxonomy = _taxonomyService.GetTaxonomy(taxonomyId);
|
||||
var parentTerm = _taxonomyService.GetTerm(parentTermId);
|
||||
var term = _taxonomyService.NewTerm(taxonomy);
|
||||
|
||||
|
||||
// assign a container to show the full route while editing
|
||||
term.Container = parentTerm == null ? taxonomy : (IContent)parentTerm;
|
||||
|
||||
|
@ -3,6 +3,7 @@ using System.Linq;
|
||||
using System.Web.Mvc;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Drivers;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Taxonomies.Models;
|
||||
using Orchard.Taxonomies.Services;
|
||||
using Orchard.Taxonomies.ViewModels;
|
||||
@ -15,6 +16,8 @@ namespace Orchard.Taxonomies.Drivers {
|
||||
_taxonomyService = taxonomyService;
|
||||
}
|
||||
|
||||
public Localizer T { get; set; }
|
||||
|
||||
protected override string Prefix { get { return "TaxonomyNavigationPart"; } }
|
||||
|
||||
protected override DriverResult Editor(TaxonomyNavigationPart part, dynamic shapeHelper) {
|
||||
@ -30,17 +33,25 @@ namespace Orchard.Taxonomies.Drivers {
|
||||
DisplayContentCount = part.DisplayContentCount,
|
||||
DisplayTopMenuItem = part.DisplayRootTerm,
|
||||
HideEmptyTerms = part.HideEmptyTerms,
|
||||
LevelsToDisplay = part.LevelsToDisplay,
|
||||
};
|
||||
|
||||
if (updater != null) {
|
||||
if (updater.TryUpdateModel(model, Prefix, null, null)) {
|
||||
// taxonomy to render
|
||||
part.TaxonomyId = model.SelectedTaxonomyId;
|
||||
// root term (can be null)
|
||||
part.TermId = model.SelectedTermId;
|
||||
part.DisplayContentCount = model.DisplayContentCount;
|
||||
part.DisplayRootTerm = model.DisplayTopMenuItem;
|
||||
part.HideEmptyTerms = model.HideEmptyTerms;
|
||||
|
||||
if (model.LevelsToDisplay < 0) {
|
||||
updater.AddModelError("LevelsToDisplay", T("The levels to display must be a positive number"));
|
||||
}
|
||||
else {
|
||||
// taxonomy to render
|
||||
part.TaxonomyId = model.SelectedTaxonomyId;
|
||||
// root term (can be null)
|
||||
part.TermId = model.SelectedTermId;
|
||||
part.DisplayContentCount = model.DisplayContentCount;
|
||||
part.DisplayRootTerm = model.DisplayTopMenuItem;
|
||||
part.HideEmptyTerms = model.HideEmptyTerms;
|
||||
part.LevelsToDisplay = model.LevelsToDisplay;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Orchard.Taxonomies.Fields;
|
||||
using Orchard.Taxonomies.Models;
|
||||
@ -59,10 +60,19 @@ namespace Orchard.Taxonomies.Handlers {
|
||||
));
|
||||
}
|
||||
|
||||
// Retrieve the number of associated content items, for the whole hierarchy
|
||||
private static void RecalculateCount(ITaxonomyService taxonomyService, TermsPart part) {
|
||||
foreach (var term in part.Terms) {
|
||||
var termPart = taxonomyService.GetTerm(term.TermRecord.Id);
|
||||
term.TermRecord.Count = (int)taxonomyService.GetContentItemsCount(termPart);
|
||||
while (termPart != null) {
|
||||
termPart.Count = (int)taxonomyService.GetContentItemsCount(termPart);
|
||||
|
||||
// compute count for the hierarchy too
|
||||
if (termPart.Container != null) {
|
||||
var parentTerm = termPart.Container.As<TermPart>();
|
||||
termPart = parentTerm;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Globalization;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.FieldStorage.InfosetStorage;
|
||||
@ -32,6 +33,14 @@ namespace Orchard.Taxonomies.Models {
|
||||
set { this.As<InfosetPart>().Set("TaxonomyNavigationPart", "DisplayRootTerm", null, Convert.ToString(value, CultureInfo.InvariantCulture)); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Number of levels to render. If <value>0</value> all levels are rendered.
|
||||
/// </summary>
|
||||
public int LevelsToDisplay {
|
||||
get { return Convert.ToInt32(this.As<InfosetPart>().Get("TaxonomyNavigationPart", "LevelsToDisplay"), CultureInfo.InvariantCulture); }
|
||||
set { this.As<InfosetPart>().Set("TaxonomyNavigationPart", "LevelsToDisplay", Convert.ToString(value, CultureInfo.InvariantCulture)); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether to display the number of content items
|
||||
/// associated with this term, in the generated menu item text
|
||||
|
@ -1,17 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Taxonomies.Helpers;
|
||||
using Orchard.Taxonomies.Models;
|
||||
using Orchard.Taxonomies.Services;
|
||||
using Orchard.UI.Navigation;
|
||||
using Orchard.Taxonomies.Helpers;
|
||||
|
||||
|
||||
namespace Orchard.Taxonomies.Navigation {
|
||||
/// <summary>
|
||||
/// Dynamically injects query results as menu items on NavigationQueryMenuItem elements
|
||||
/// Dynamically injects taxonomy items as menu items on TaxonomyNavigationMenuItem elements
|
||||
/// </summary>
|
||||
public class TaxonomyNavigationProvider : INavigationFilter {
|
||||
private readonly IContentManager _contentManager;
|
||||
@ -28,60 +28,66 @@ namespace Orchard.Taxonomies.Navigation {
|
||||
|
||||
foreach (var item in items) {
|
||||
if (item.Content != null && item.Content.ContentItem.ContentType == "TaxonomyNavigationMenuItem") {
|
||||
// expand query
|
||||
|
||||
var taxonomyNavigationPart = item.Content.As<TaxonomyNavigationPart>();
|
||||
|
||||
var rootTerm = _taxonomyService.GetTerm(taxonomyNavigationPart.TermId);
|
||||
|
||||
List<int> positionList = new List<int>();
|
||||
TermPart[] allTerms;
|
||||
|
||||
var allTerms = rootTerm != null
|
||||
? _taxonomyService.GetChildren(rootTerm).ToArray()
|
||||
: _taxonomyService.GetTerms(taxonomyNavigationPart.TaxonomyId).ToArray();
|
||||
if (rootTerm != null) {
|
||||
// if DisplayRootTerm is specified add it to the menu items to render
|
||||
allTerms = _taxonomyService.GetChildren(rootTerm, taxonomyNavigationPart.DisplayRootTerm).ToArray();
|
||||
}
|
||||
else {
|
||||
allTerms = _taxonomyService.GetTerms(taxonomyNavigationPart.TaxonomyId).ToArray();
|
||||
}
|
||||
|
||||
var rootlevel = rootTerm == null ? 0 : rootTerm.GetLevels();
|
||||
var rootLevel = rootTerm != null
|
||||
? rootTerm.GetLevels()
|
||||
: 0;
|
||||
|
||||
positionList.Add(0);
|
||||
|
||||
var menuPosition = item.Position;
|
||||
int parentLevel = rootlevel;
|
||||
var rootPath = rootTerm == null || taxonomyNavigationPart.DisplayRootTerm ? "" : rootTerm.FullPath;
|
||||
|
||||
var startLevel = rootLevel + 1;
|
||||
if (rootTerm == null || taxonomyNavigationPart.DisplayRootTerm) {
|
||||
startLevel = rootLevel;
|
||||
}
|
||||
|
||||
var endLevel = Int32.MaxValue;
|
||||
if (taxonomyNavigationPart.LevelsToDisplay > 0) {
|
||||
endLevel = startLevel + taxonomyNavigationPart.LevelsToDisplay - 1;
|
||||
}
|
||||
|
||||
foreach (var contentItem in allTerms) {
|
||||
if (contentItem != null) {
|
||||
var part = contentItem;
|
||||
var level = part.GetLevels();
|
||||
|
||||
if (taxonomyNavigationPart.HideEmptyTerms == true && part.Count == 0) {
|
||||
// filter levels ?
|
||||
if (level < startLevel || level > endLevel) {
|
||||
continue;
|
||||
}
|
||||
string termPosition = "";
|
||||
if (part.GetLevels() - rootlevel > parentLevel) {
|
||||
positionList.Add(0);
|
||||
parentLevel = positionList.Count - 1;
|
||||
}
|
||||
else
|
||||
if ((part.GetLevels() - rootlevel) == parentLevel) {
|
||||
positionList[parentLevel]++;
|
||||
}
|
||||
else {
|
||||
positionList.RemoveRange(1, positionList.Count - 1);
|
||||
parentLevel = positionList.Count - 1;
|
||||
positionList[parentLevel]++;
|
||||
}
|
||||
|
||||
termPosition = positionList.First().ToString();
|
||||
foreach (var position in positionList.Skip(1)) {
|
||||
termPosition = termPosition + "." + position.ToString();
|
||||
// ignore menu item if there are no content items associated to the term
|
||||
if (taxonomyNavigationPart.HideEmptyTerms && part.Count == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
var menuText = _contentManager.GetItemMetadata(part).DisplayText;
|
||||
var routes = _contentManager.GetItemMetadata(part).DisplayRouteValues;
|
||||
|
||||
if (taxonomyNavigationPart.DisplayContentCount) {
|
||||
menuText = String.Format(menuText + " ({0})", part.Count.ToString());
|
||||
menuText += " (" + part.Count + ")";
|
||||
}
|
||||
|
||||
// create
|
||||
var positions = contentItem.FullPath.Substring(rootPath.Length)
|
||||
.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries)
|
||||
.Select(p => Array.FindIndex(allTerms, t => t.Id == Int32.Parse(p)))
|
||||
.ToArray();
|
||||
|
||||
var inserted = new MenuItem {
|
||||
Text = new LocalizedString(menuText),
|
||||
IdHint = item.IdHint,
|
||||
@ -92,7 +98,7 @@ namespace Orchard.Taxonomies.Navigation {
|
||||
RouteValues = routes,
|
||||
LocalNav = item.LocalNav,
|
||||
Items = new MenuItem[0],
|
||||
Position = menuPosition + ":" + termPosition,
|
||||
Position = menuPosition + ":" + String.Join(".", positions.Select(x => x.ToString(CultureInfo.InvariantCulture)).ToArray()),
|
||||
Permissions = item.Permissions,
|
||||
Content = part
|
||||
};
|
||||
|
@ -28,6 +28,7 @@ namespace Orchard.Taxonomies.Services {
|
||||
void UpdateTerms(ContentItem contentItem, IEnumerable<TermPart> terms, string field);
|
||||
IEnumerable<TermPart> GetParents(TermPart term);
|
||||
IEnumerable<TermPart> GetChildren(TermPart term);
|
||||
IEnumerable<TermPart> GetChildren(TermPart term, bool includeParent);
|
||||
IEnumerable<IContent> GetContentItems(TermPart term, int skip = 0, int count = 0, string fieldName = null);
|
||||
long GetContentItemsCount(TermPart term, string fieldName = null);
|
||||
IContentQuery<TermsPart, TermsPartRecord> GetContentItemsQuery(TermPart term, string fieldName = null);
|
||||
|
@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Orchard.Taxonomies.Fields;
|
||||
using Orchard.Taxonomies.Models;
|
||||
using Orchard.Autoroute.Models;
|
||||
using Orchard.ContentManagement;
|
||||
@ -267,12 +266,20 @@ namespace Orchard.Taxonomies.Services {
|
||||
}
|
||||
|
||||
public IEnumerable<TermPart> GetChildren(TermPart term) {
|
||||
return GetChildren(term, false);
|
||||
}
|
||||
|
||||
public IEnumerable<TermPart> GetChildren(TermPart term, bool includeParent) {
|
||||
var rootPath = term.FullPath + "/";
|
||||
|
||||
var result = _contentManager.Query<TermPart, TermPartRecord>()
|
||||
.WithQueryHints(new QueryHints().ExpandRecords<AutoroutePartRecord, TitlePartRecord, CommonPartRecord>())
|
||||
.List()
|
||||
.Where(x => x.Path.StartsWith(rootPath));
|
||||
.Where(x => x.Path.StartsWith(rootPath))
|
||||
.List();
|
||||
|
||||
if (includeParent) {
|
||||
result = result.Concat(new [] {term});
|
||||
}
|
||||
|
||||
return TermPart.Sort(result);
|
||||
}
|
||||
|
@ -12,5 +12,6 @@ namespace Orchard.Taxonomies.ViewModels {
|
||||
public bool DisplayTopMenuItem { get; set; }
|
||||
public bool DisplayContentCount { get; set; }
|
||||
public bool HideEmptyTerms { get; set; }
|
||||
public int LevelsToDisplay { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,13 @@
|
||||
<span class="hint">@T("When checked, the selected term to display will be rendered as a root element in the menu.")</span>
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<label for="@Html.FieldIdFor( m => m.LevelsToDisplay)">@T("Levels to display")</label>
|
||||
@Html.TextBoxFor(m => m.LevelsToDisplay, new { @class = "text small" } )
|
||||
@Html.ValidationMessage("LevelsToDisplay", "*")
|
||||
<span class="hint">@T("The number of levels to display in the hierarchy. 0 to display all levels.")</span>
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
@Html.CheckBoxFor(m => m.HideEmptyTerms)
|
||||
<label for="@Html.FieldIdFor(m => m.HideEmptyTerms)" class="forcheckbox">@T("Hide empty entries")</label>
|
||||
|
Loading…
Reference in New Issue
Block a user