try new way to create URLs
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
namespace zero.Core.Entities
|
||||
{
|
||||
public interface IRoutedEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// Url for this entity
|
||||
/// </summary>
|
||||
public string Url { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,9 @@ namespace zero.Core.Entities
|
||||
/// </summary>
|
||||
public class Page : ZeroEntity, IPage
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public string Url { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public string ParentId { get; set; }
|
||||
|
||||
@@ -25,7 +28,7 @@ namespace zero.Core.Entities
|
||||
|
||||
|
||||
[Collection("Pages")]
|
||||
public interface IPage : IZeroEntity, IAppAwareEntity, IZeroDbConventions
|
||||
public interface IPage : IZeroEntity, IAppAwareEntity, IZeroDbConventions, IRoutedEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// Id of the parent page
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using zero.Core.Api;
|
||||
using zero.Core.Entities;
|
||||
|
||||
@@ -9,6 +10,11 @@ namespace zero.Core.Routing
|
||||
{
|
||||
public interface IPageUrlResolver
|
||||
{
|
||||
/// <summary>
|
||||
/// Get URL for a page
|
||||
/// </summary>
|
||||
Task<string> GetUrl(IPage page);
|
||||
|
||||
/// <summary>
|
||||
/// Get URL for a page
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
using Raven.Client.Documents;
|
||||
using Raven.Client.Documents.Linq;
|
||||
using Raven.Client.Documents.Session;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using zero.Core.Api;
|
||||
using zero.Core.Entities;
|
||||
using zero.Core.Entities.Messages;
|
||||
using zero.Core.Extensions;
|
||||
using zero.Core.Messages;
|
||||
using zero.Core.Utils;
|
||||
|
||||
namespace zero.Core.Routing
|
||||
{
|
||||
public class PageUrlProviderOld : IUrlProvider<PageRoute>
|
||||
{
|
||||
public string Alias => "zero.pages";
|
||||
|
||||
public const string PAGE_COLLECTION = "page";
|
||||
|
||||
public const string PAGE_TYPE = "pageType";
|
||||
|
||||
protected IDocumentStore Raven { get; private set; }
|
||||
|
||||
protected IMessageAggregator Messages { get; private set; }
|
||||
|
||||
protected IPageUrlResolver PageUrlResolver { get; set; }
|
||||
|
||||
|
||||
protected IApplicationContext Context { get; private set; }
|
||||
|
||||
public PageUrlProviderOld(IDocumentStore raven, IMessageAggregator messages, IPageUrlResolver pageUrlResolver, IApplicationContext context)
|
||||
{
|
||||
Raven = raven;
|
||||
Messages = messages;
|
||||
PageUrlResolver = pageUrlResolver;
|
||||
Context = context;
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<PageRoute> Resolve(IRoute route)
|
||||
{
|
||||
PageRoute resolved = new PageRoute(route);
|
||||
|
||||
List<string> ids = new List<string>();
|
||||
RouteReference reference = route.References.SingleOrDefault(x => x.Collection == PAGE_COLLECTION);
|
||||
|
||||
ids.Add(reference.Id);
|
||||
ids.AddRange(route.Dependencies);
|
||||
|
||||
using IAsyncDocumentSession session = Raven.OpenAsyncSession();
|
||||
|
||||
Dictionary<string, IPage> pages = await session.LoadAsync<IPage>(ids);
|
||||
|
||||
if (!pages.TryGetValue(reference.Id, out IPage page) || page.AppId != route.AppId)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
resolved.Page = page;
|
||||
resolved.Parents = pages.Where(x => x.Key != reference.Id).Select(x => x.Value).ToList();
|
||||
|
||||
return resolved;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<IList<IRoute>> Run()
|
||||
{
|
||||
using IAsyncDocumentSession session = Raven.OpenAsyncSession();
|
||||
|
||||
List<IRoute> allRoutes = new List<IRoute>();
|
||||
IList<IPage> pages = await session.Query<IPage>().ToListAsync();
|
||||
IEnumerable<IGrouping<string, IPage>> groupedPages = pages.GroupBy(x => x.AppId);
|
||||
|
||||
foreach (var group in groupedPages)
|
||||
{
|
||||
IApplicationContext context = await Context.ForId(group.Key);
|
||||
|
||||
IList<IRoute> routes = TraversePageChildren(context, null, new List<IPage>() { }, group);
|
||||
allRoutes.AddRange(routes);
|
||||
}
|
||||
|
||||
return allRoutes;
|
||||
}
|
||||
|
||||
|
||||
protected IRoute BuildRoute(IApplicationContext context, IPage page, IEnumerable<IPage> parents)
|
||||
{
|
||||
UrlInfo info = PageUrlResolver.GetUrl(context, page, parents);
|
||||
|
||||
IRoute route = new Route()
|
||||
{
|
||||
Id = String.Concat("routes.", IdGenerator.Create()),
|
||||
AppId = context.AppId,
|
||||
Url = info.IsUrl ? info.Text.EnsureStartsWith('/') : null,
|
||||
ProviderAlias = Alias
|
||||
};
|
||||
|
||||
route.Params.Add(PAGE_TYPE, page.PageTypeAlias);
|
||||
route.References.Add(new RouteReference(page.Id, PAGE_COLLECTION));
|
||||
|
||||
if (parents != null)
|
||||
{
|
||||
foreach (IPage parent in parents)
|
||||
{
|
||||
route.Dependencies.Add(parent.Id);
|
||||
}
|
||||
}
|
||||
|
||||
return route;
|
||||
}
|
||||
|
||||
|
||||
IList<IRoute> TraversePageChildren(IApplicationContext context, IPage parent, IEnumerable<IPage> parents, IEnumerable<IPage> allPages)
|
||||
{
|
||||
List<IRoute> routes = new List<IRoute>();
|
||||
IEnumerable<IPage> currentPages = allPages.Where(x => x.ParentId == parent?.Id);
|
||||
|
||||
foreach (IPage page in currentPages)
|
||||
{
|
||||
IRoute route = BuildRoute(context, page, parents);
|
||||
routes.Add(route);
|
||||
routes.AddRange(TraversePageChildren(context, page, parents.Union(new List<IPage>() { page }), allPages));
|
||||
}
|
||||
|
||||
return routes;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
using Raven.Client.Documents;
|
||||
using Raven.Client.Documents.Linq;
|
||||
using Raven.Client.Documents.Session;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using zero.Core.Api;
|
||||
using zero.Core.Database.Indexes;
|
||||
using zero.Core.Entities;
|
||||
using zero.Core.Entities.Messages;
|
||||
using zero.Core.Extensions;
|
||||
using zero.Core.Messages;
|
||||
using zero.Core.Utils;
|
||||
|
||||
namespace zero.Core.Routing
|
||||
{
|
||||
public class PageUrlProviderTest
|
||||
{
|
||||
public string Alias => "zero.pages";
|
||||
|
||||
public const string PAGE_COLLECTION = "page";
|
||||
|
||||
public const string PAGE_TYPE = "pageType";
|
||||
|
||||
protected IDocumentStore Raven { get; private set; }
|
||||
|
||||
protected IMessageAggregator Messages { get; private set; }
|
||||
|
||||
protected IPageUrlResolver PageUrlResolver { get; set; }
|
||||
|
||||
protected IApplicationContext Context { get; private set; }
|
||||
|
||||
|
||||
public PageUrlProviderTest(IDocumentStore raven, IMessageAggregator messages, IPageUrlResolver pageUrlResolver, IApplicationContext context)
|
||||
{
|
||||
Raven = raven;
|
||||
Messages = messages;
|
||||
PageUrlResolver = pageUrlResolver;
|
||||
Context = context;
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool UrlChanged(IPage previous, IPage current)
|
||||
{
|
||||
return previous == null || !previous.Alias.Equals(current.Alias) || !previous.ParentId.Equals(current.ParentId);
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task GetDependencies(IPage model)
|
||||
{
|
||||
// TODO get all pages (and other routes) which have this page as a dependency and update them
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<IRoute> CreateRoute(IPage model)
|
||||
{
|
||||
using IAsyncDocumentSession session = Raven.OpenAsyncSession();
|
||||
|
||||
Pages_ByHierarchy.Result result = await session.Query<Pages_ByHierarchy.Result, Pages_ByHierarchy>()
|
||||
.ProjectInto<Pages_ByHierarchy.Result>()
|
||||
.Include<Pages_ByHierarchy.Result, IPage>(x => x.Path.Select(p => p.Id))
|
||||
.FirstOrDefaultAsync(x => x.Id == model.Id);
|
||||
|
||||
IList<IPage> parents = (await session.LoadAsync<IPage>(result.Path.Select(x => x.Id))).Select(x => x.Value).ToList();
|
||||
|
||||
return new Route()
|
||||
{
|
||||
Id = String.Concat("routes.", IdGenerator.Create()),
|
||||
AppId = model.AppId,
|
||||
Url = GetUrl(model, parents),
|
||||
ProviderAlias = Alias
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Create url for page
|
||||
/// </summary>
|
||||
protected string GetUrl(IPage page, IEnumerable<IPage> parents)
|
||||
{
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
|
||||
stringBuilder.Append('/');
|
||||
|
||||
if (parents != null)
|
||||
{
|
||||
foreach (IPage parent in parents)
|
||||
{
|
||||
stringBuilder.Append(parent.Alias);
|
||||
stringBuilder.Append('/');
|
||||
}
|
||||
}
|
||||
|
||||
stringBuilder.Append(page.Alias);
|
||||
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,12 @@
|
||||
using System;
|
||||
using Raven.Client.Documents;
|
||||
using Raven.Client.Documents.Session;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using zero.Core.Api;
|
||||
using zero.Core.Database.Indexes;
|
||||
using zero.Core.Entities;
|
||||
|
||||
namespace zero.Core.Routing
|
||||
@@ -13,6 +17,49 @@ namespace zero.Core.Routing
|
||||
|
||||
const bool TRAILING_SLASH = false;
|
||||
|
||||
protected IDocumentStore Raven { get; private set; }
|
||||
|
||||
|
||||
public PageUrlResolver(IDocumentStore raven)
|
||||
{
|
||||
Raven = raven;
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<string> GetUrl(IPage page)
|
||||
{
|
||||
using IAsyncDocumentSession session = Raven.OpenAsyncSession();
|
||||
|
||||
Pages_ByHierarchy.Result result = await session.Query<Pages_ByHierarchy.Result, Pages_ByHierarchy>()
|
||||
.ProjectInto<Pages_ByHierarchy.Result>()
|
||||
.Include<Pages_ByHierarchy.Result, IPage>(x => x.Path.Select(p => p.Id))
|
||||
.FirstOrDefaultAsync(x => x.Id == page.Id);
|
||||
|
||||
IList<IPage> parents = (await session.LoadAsync<IPage>(result.Path.Select(x => x.Id))).Select(x => x.Value).ToList();
|
||||
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
|
||||
if (parents != null)
|
||||
{
|
||||
foreach (IPage parent in parents)
|
||||
{
|
||||
stringBuilder.Append(parent.Alias);
|
||||
stringBuilder.Append(PATH_SEPARATOR);
|
||||
}
|
||||
}
|
||||
|
||||
stringBuilder.Append(page.Alias);
|
||||
stringBuilder.Append(PATH_SEPARATOR);
|
||||
|
||||
if (!TRAILING_SLASH)
|
||||
{
|
||||
stringBuilder.Remove(stringBuilder.Length - 1, 1);
|
||||
}
|
||||
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public UrlInfo GetUrl(IApplicationContext context, IPage page, IEnumerable<IPage> parents)
|
||||
|
||||
Reference in New Issue
Block a user