Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Autoroute container routing #5665

Merged
merged 22 commits into from
Apr 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
9b21a8f
wip. stil resolving issues with absolute routing and path verification
deanmarcussen Mar 1, 2020
5d71d5e
wip. add setting to autoroute so it knows when it is contained, and c…
deanmarcussen Mar 2, 2020
9d2066e
tweaks
deanmarcussen Mar 3, 2020
abc414d
Autohide some ui when it is not required
deanmarcussen Mar 3, 2020
eaeffd6
Merge branch 'dev' into deanmarcussen/autoroute-container
deanmarcussen Mar 4, 2020
ad59ad7
add home route options, update hints
deanmarcussen Mar 7, 2020
f446bc3
add autoroutepart in migrations. remove unused shapes. update settings.
deanmarcussen Mar 15, 2020
bb4d164
move to content manager
deanmarcussen Mar 15, 2020
3814a54
Merge branch 'dev' into deanmarcussen/autoroute-container
deanmarcussen Mar 24, 2020
ce04b88
wip. term shapes and routing implementation for the blog theme.
deanmarcussen Mar 29, 2020
e6c9b4b
Merge branch 'dev' into deanmarcussen/autoroute-container
deanmarcussen Apr 1, 2020
52053c2
Remove tagbuilder from TermItem. Tidy up
deanmarcussen Apr 3, 2020
31fcf33
typos
deanmarcussen Apr 3, 2020
596b5a9
add docs for autoroute
deanmarcussen Apr 8, 2020
134a1ea
Merge branch 'dev' into deanmarcussen/autoroute-container
deanmarcussen Apr 8, 2020
bb09b1e
Feedback
deanmarcussen Apr 8, 2020
b4de45b
Respond to feedback
deanmarcussen Apr 8, 2020
7da60c2
Update term shape alternates
deanmarcussen Apr 11, 2020
37a0ab3
minor change
deanmarcussen Apr 11, 2020
056d683
term shape docs
deanmarcussen Apr 11, 2020
c6fad89
Merge branch 'dev' into deanmarcussen/autoroute-container
deanmarcussen Apr 11, 2020
38d1263
fix spelling
deanmarcussen Apr 11, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
Expand Down Expand Up @@ -53,16 +54,28 @@ public override IDisplayResult Edit(AutoroutePart autoroutePart, BuildPartEditor
{
model.Path = autoroutePart.Path;
model.AutoroutePart = autoroutePart;
model.ContentItem = autoroutePart.ContentItem;
model.SetHomepage = false;

var siteSettings = await _siteService.GetSiteSettingsAsync();
var homeRoute = siteSettings.HomeRoute;

if (autoroutePart.ContentItem.ContentItemId == homeRoute?[_options.ContentItemIdKey]?.ToString())
if (homeRoute != null && homeRoute.TryGetValue(_options.ContainedContentItemIdKey, out var containedContentItemId))
{
if (string.Equals(autoroutePart.ContentItem.ContentItemId, containedContentItemId.ToString(), StringComparison.OrdinalIgnoreCase))
{
model.IsHomepage = true;
}
}
else if (string.Equals(autoroutePart.ContentItem.ContentItemId, homeRoute?[_options.ContentItemIdKey]?.ToString(), StringComparison.OrdinalIgnoreCase))
{
model.IsHomepage = true;
}

model.Disabled = autoroutePart.Disabled;
model.Absolute = autoroutePart.Absolute;
model.RouteContainedItems = autoroutePart.RouteContainedItems;

model.Settings = context.TypePartDefinition.GetSettings<AutoroutePartSettings>();
});
}
Expand All @@ -71,34 +84,42 @@ public override async Task<IDisplayResult> UpdateAsync(AutoroutePart model, IUpd
{
var viewModel = new AutoroutePartViewModel();

await updater.TryUpdateModelAsync(viewModel, Prefix, t => t.Path, t => t.UpdatePath);
await updater.TryUpdateModelAsync(viewModel, Prefix, t => t.Path, t => t.UpdatePath, t => t.RouteContainedItems, t => t.Absolute, t => t.Disabled);

var settings = context.TypePartDefinition.GetSettings<AutoroutePartSettings>();

if (settings.AllowCustomPath)
{
model.Path = viewModel.Path;
}
model.Disabled = viewModel.Disabled;
model.Absolute = viewModel.Absolute;
model.RouteContainedItems = viewModel.RouteContainedItems;

if (settings.AllowUpdatePath && viewModel.UpdatePath)
// When disabled these values are not updated.
if (!model.Disabled)
{
// Make it empty to force a regeneration
model.Path = "";
}
if (settings.AllowCustomPath)
{
model.Path = viewModel.Path;
}

if (settings.AllowUpdatePath && viewModel.UpdatePath)
{
// Make it empty to force a regeneration
model.Path = "";
}

var httpContext = _httpContextAccessor.HttpContext;
var httpContext = _httpContextAccessor.HttpContext;

if (httpContext != null && await _authorizationService.AuthorizeAsync(httpContext.User, Permissions.SetHomepage))
{
await updater.TryUpdateModelAsync(model, Prefix, t => t.SetHomepage);
}
if (httpContext != null && await _authorizationService.AuthorizeAsync(httpContext.User, Permissions.SetHomepage))
{
await updater.TryUpdateModelAsync(model, Prefix, t => t.SetHomepage);
}

await ValidateAsync(model, updater);
await ValidateAsync(model, updater, settings);
}

return Edit(model, context);
}

private async Task ValidateAsync(AutoroutePart autoroute, IUpdateModel updater)
private async Task ValidateAsync(AutoroutePart autoroute, IUpdateModel updater, AutoroutePartSettings settings)
{
if (autoroute.Path == "/")
{
Expand All @@ -116,9 +137,24 @@ private async Task ValidateAsync(AutoroutePart autoroute, IUpdateModel updater)
updater.ModelState.AddModelError(Prefix, nameof(autoroute.Path), S["Your permalink is too long. The permalink can only be up to {0} characters.", MaxPathLength]);
}

if (autoroute.Path != null && (await _session.QueryIndex<AutoroutePartIndex>(o => o.Path == autoroute.Path && o.ContentItemId != autoroute.ContentItem.ContentItemId).CountAsync()) > 0)
// This can only validate the path if the Autoroute is not managing content item routes or the path is absolute.
if (!String.IsNullOrEmpty(autoroute.Path) && (!settings.ManageContainedItemRoutes || (settings.ManageContainedItemRoutes && autoroute.Absolute)))
{
updater.ModelState.AddModelError(Prefix, nameof(autoroute.Path), S["Your permalink is already in use."]);
var possibleConflicts = await _session.QueryIndex<AutoroutePartIndex>(o => o.Path == autoroute.Path).ListAsync();
if (possibleConflicts.Any())
{
var hasConflict = false;
// This logic is different to the check in the handler as here we checking
if (possibleConflicts.Any(x => x.ContentItemId != autoroute.ContentItem.ContentItemId) ||
possibleConflicts.Any(x => !string.IsNullOrEmpty(x.ContainedContentItemId) && x.ContainedContentItemId != autoroute.ContentItem.ContentItemId))
{
hasConflict = true;
}
if (hasConflict)
{
updater.ModelState.AddModelError(Prefix, nameof(autoroute.Path), S["Your permalink is already in use."]);
}
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Routing;
using OrchardCore.ContentManagement;
using OrchardCore.ContentManagement.Handlers;
using OrchardCore.ContentManagement.Routing;

namespace OrchardCore.Autoroute.Handlers
{
public class AutorouteContentHandler : ContentHandlerBase
{
private readonly IAutorouteEntries _autorouteEntries;

public AutorouteContentHandler(IAutorouteEntries autorouteEntries)
{
_autorouteEntries = autorouteEntries;
}

public override Task GetContentItemAspectAsync(ContentItemAspectContext context)
{
return context.ForAsync<ContentItemMetadata>(metadata =>
{
// When a content item is contained we provide different route values when generating urls.
if (_autorouteEntries.TryGetEntryByContentItemId(context.ContentItem.ContentItemId, out var entry) &&
!string.IsNullOrEmpty(entry.ContainedContentItemId))
{
metadata.DisplayRouteValues = new RouteValueDictionary {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

one side effect is that if contained item routing is not enabled, generating a route for it with a url helper will generate a standard route (i.e. /Contents/Item/id) which will 404

{ "Area", "OrchardCore.Contents" },
{ "Controller", "Item" },
{ "Action", "Display" },
{ "ContentItemId", entry.ContentItemId},
{ "ContainedContentItemId", entry.ContainedContentItemId }
};
}

return Task.CompletedTask;
});
}
}
}
Loading