-
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
DisplayAsync to return actual pre-rendered IHtmlContent #15247
Conversation
src/OrchardCore/OrchardCore.DisplayManagement/Implementation/DefaultHtmlDisplay.cs
Outdated
Show resolved
Hide resolved
src/OrchardCore/OrchardCore.DisplayManagement/Implementation/DisplayHelper.cs
Outdated
Show resolved
Hide resolved
src/OrchardCore/OrchardCore.DisplayManagement/PositionWrapper.cs
Outdated
Show resolved
Hide resolved
src/OrchardCore/OrchardCore.DisplayManagement/Implementation/DefaultHtmlDisplay.cs
Outdated
Show resolved
Hide resolved
src/OrchardCore/OrchardCore.DisplayManagement/Implementation/DisplayHelper.cs
Outdated
Show resolved
Hide resolved
@@ -50,6 +50,16 @@ public async Task<IHtmlContent> ExecuteAsync(DisplayContext context) | |||
// Check if the shape is pre-rendered. | |||
if (shape is IHtmlContent htmlContent) | |||
{ | |||
if (htmlContent is PositionWrapper wrapper) |
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.
I don't see how this would not break something in OC. Or the PositionWrapper would be useless.
Have you tried to check where this is called (outside of Blazor) to see what could go wrong?
Also, can you explain why this is fixing the exception? Technically this wrapper is invoking the same WriteTo
as if you return the wrapped value.
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.
Example of things to try with this change: Widgets, FlowPart, BagPart, GraphQL rendering, layouts, custom placement.
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.
It would not break anything in OC, rather fixes Blazor component rendering.
PositionWrapper is nothing but holds pre-rendered IHtmlContent, and it can only contain one IHtmlContent. Hence there no need of nesting PositionWrapper in PositionWrapper.
Currently In ThemeLayout we use PositionWrapper to pre-render (and useful while maintaining position on zone) before we place on Layout. This allows to have lazy placed zones to be rendered on Layout but requires us to call DisplayAsync twice 8880 on zones, that unnecessary nests PositionWrapper in PositionWrapper.
This PR returns the original pre-rendered IHtmlContent when the shape provided in DisplayAsync is PositionWrapper and avoids nesting of PositionWrapper when called multiple times.
This allows thread that Writes to the stream is the same that owns the Dispatcher that generated IHtmlContent for blazor component.
I had not understood this at first look. Now I get it, I thought your code was removing all wrappers, not just the nested ones. And this is raising a good point actually, maybe we shouldn't wrap position wrappers, that is kind of a bug. Can you try to do that instead? We could also add a |
I'll update the code, to use static |
…er is now sealed and have private constructor.
FYI @sebastienros , this happens when the |
|
||
public static PositionWrapper TryWrap(object value, string position) | ||
{ | ||
if (value is PositionWrapper wrapper) |
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.
is IPositioned
?
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.
I used PositionWrapper
because return value must be both IPositioned
and IShape
@@ -65,13 +65,13 @@ public virtual ValueTask<IShape> AddAsync(object item, string position) | |||
|
|||
_items ??= []; | |||
|
|||
if (item is IHtmlContent) | |||
if (item is IHtmlContent htmlContent) |
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.
Can't this whole if/else/else be a single TryWrap?
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.
updated
else if (value is string stringContent) | ||
return new PositionWrapper(stringContent, position); | ||
else | ||
throw new System.NotSupportedException($"Type of {nameof(value)} must be either {nameof(String)}, {nameof(IHtmlContent)} or {nameof(PositionWrapper)}."); |
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.
TryWrap
should it return a new wrapper in this case instead of throwing?
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.
Should it unwrap if the position is "" ? Is that the meaning of "" in ThemeLayout.cs?
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.
Should it unwrap if the position is "" ? Is that the meaning of "" in ThemeLayout.cs?
It's default, I believe when empty it will sort based on the order of items added
TryWrap
should it return a new wrapper in this case instead of throwing?
Throwing NotSupportedException
because value
is not either string
, IHtmlContent
or PositionWrapper
. Position wrapper doesn't support any other object - unless we return null
instead of throwing exception - please suggest @sebastienros
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.
Updated to return null instead of throwing exception
I saw a test failing on the CI |
fixed |
Component tag helper / Html Helper is not able to render Razor Components for nested
PositionWrapper
components in .NET8.Suggested change here to have,
DisplayAsync
to return actual pre-renderedIHtmlContent
instead ofPositionWrapper
Fixes #15235
Fixes #15211
/cc @sebastienros