-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Add IShapePlacementProvider and ShapeTablePlacementProvider #6780
Conversation
Will do a review more in details asap, but looks great! Hmm, just one question about ordering, i assume that a dynamic placement would need an higher precedence than the ones defined in modules and the current theme. E.g. the templates feature has an higher priority because, as i remember, the shape binding resolvers are explicitly called before using shape descriptors in a regular way. One solution would be to register The other solution being to let the placement resolved as before but after having called the dynamic resolvers before. But on another side i like these new interfaces as |
Placement resolvers are called in reverse order, so the last registered has a higher priority. |
@TFleury I have not looked into more detail but I guess - all we need is to replace For example, services.AddOrchardCms()
.ConfigureServices(services =>
{
services.AddScoped<IContentDisplayHandler, CustomPlacementDisplayHandler>();
}, -100); and in public CustomPlacementDisplayHandler(MyPlacementService service)
{
}
public async Task BuildDisplayAsync(ContentItem contentItem, BuildDisplayContext context)
{
context.FindPlacement = myPlacementService.FindPlacement
} and provide all your dynamic placement logic in |
Just forked your branch, i will try it and review it tomorrow, looks good after a quick look! Maybe just some formatting to do, e.g. a space after the |
@TFleury here's the quick and dirty implementation of an idea without modifying in DisplayManagement ( i.e. in a Module) https://gist.github.com/ns8482e/a0cb2399a2849af0ef9e335b28567a27 However, in ideal solution - I would foresee an event like named |
@ns8482e Thank you for this contribution. I had not seen this possibility when creating the PR. I like the idea of combining PlacementInfos. On the other hand, I found relevant to to move ShapeTable placement resolution outside of I removed We just need to decide which is the best option. I prefer to have one provider interface used by multiple services, rather than having multiple handlers replacing the |
I would not change FindPlacementDelegate as it's a public property of
Yes that's could be an option to register provider for ShapeTable However IMO keeping
I am in for it - In my example above - i used var context = new BuildDisplayContext(
itemShape,
actualDisplayType,
groupId,
_shapeFactory,
await _layoutAccessor.GetLayoutAsync(),
new ModelStateWrapperUpdater(updater)
);
await BindPlacementAsync(context);
// >>>> Find Placement Here with event or serviceprovider
await _handlers.InvokeAsync((handler, contentItem, context) => handler.BuildDisplayAsync(contentItem, context), contentItem, context, _logger); But IMHO adding an new handler event is much more relevant as we already have interface defined i.e. |
src/OrchardCore/OrchardCore.DisplayManagement/BaseDisplayManager.cs
Outdated
Show resolved
Hide resolved
src/OrchardCore/OrchardCore.DisplayManagement/OrchardCoreBuilderExtensions.cs
Outdated
Show resolved
Hide resolved
|
||
var placement = descriptor.Placement(placementContext); | ||
if (placement != null) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe some fast paths, here or before by the caller in BindPlacementAsync()
E.g.
if (placementResolvers.Count == 1)
{
return placementResolvers[0].ResolvePlacement(placementContext);
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aggregate helper seems to be efficient (See source), do you think this will make a difference ?
I optimized CombinePlacements
to return immediatly when first
is null
. (only one comparison against three before)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay cool then ;)
Yes, i'm used to look at the dotnet runtime repo
directly, e.g. here for Aggregate.cs
I did some apache benchmarks but didn't see any significant difference
@ns8482e I took a quick look at your suggestion in your above comment, the problem is that @TFleury i left you some suggestions, otherwise LGTM Combining the placements looks good but i'm thinking about perf, so not sure at 100%, maybe better to just use the 1rst non null placement as you did before. So maybe better to wait for the next triage, but it should not block this PR |
@jtkech Exactly - In my comment above I was suggesting to have event/hook just before calling See https://gist.github.com/ns8482e/a0cb2399a2849af0ef9e335b28567a27 to achieve similar behavior, I had to add |
The goal is to add a way to provide shape placement overrides at runtime without rebuilding ShapeTable (as discussed in #6503)
The new
IShapePlacementProvider
interface allows to asynchronously (usefull if it relies on an async placement store) build anIPlacementInfoResolver
for eachIBuildShapeContext
.The
IPlacementInfoResolver
implementation keeps placement rules for the currentIBuildShapeContext
to be able to quickly resolve shape placements synchronously.This PR don't add any direct way to provide placement in admin UI, but opens a way to add this feature.
Breaking changes
RemovedIBuildShapeContext
argument fromFindPlacementDelegate
because it's not used anywhere.BaseDisplayManager
to newly createdShapeTablePlacementProvider
(the firstIShapePlacementProvider
implementation).It allowed me to remove
BaseDisplayManager
direct dependencies onIShapeTableManager
andIThemeManager