feat: Add HtmxorComponentResult and HtmxorHtmlRenderer#41
feat: Add HtmxorComponentResult and HtmxorHtmlRenderer#41
Conversation
|
HtmlRenderer uses HtmlRootComponent, which is public. I added HtmxorHtmlRenderer and it renders components based on HtmxorRootComponent so I had to change the visibility to public as well. It now throws the "warning CA1815: HtmxorRootComponent should override Equals" when compiling and the checks all fail, treating that as an error. |
|
|
||
| private void BuildRenderTree(RenderTreeBuilder builder) | ||
| { | ||
| var pageLayoutType = ComponentType.GetCustomAttribute<LayoutAttribute>()?.LayoutType; |
There was a problem hiding this comment.
Should this be using HtmxLayout instead if one is present?
| var pageLayoutType = ComponentType.GetCustomAttribute<LayoutAttribute>()?.LayoutType; | |
| // Since GetCustomAttributes does not guarantee the order of attributes | |
| // returned, having a priority allows users to define a default HtmxLayout | |
| // e.g. in their _Imports.razor, and then override that on a component base, | |
| // just as they can with the @layout directive in razor files. | |
| var pageLayoutType = ComponentLayoutType = componentType | |
| .GetCustomAttributes<HtmxLayoutAttribute>(true) | |
| .OrderBy(x => x.Priority) | |
| .LastOrDefault() | |
| ?.LayoutType ?? | |
| ComponentType | |
| .GetCustomAttribute<LayoutAttribute>() | |
| ?.LayoutType; |
Why is |
- Introduced `HtmxorComponentEndpointHost` class to act as a root component when executing a Htmxor Component endpoint. - Added `HtmxorComponentResultExecutor` class to execute the result of an HTTP request in the context of an endpoint. - Created `HtmxorComponentResult` class that renders a Razor Component. - Implemented `HtmxorComponentResultOfT` class, which is a generic version of `HtmxorComponentResult`.
Updated the XML comments in two classes, HtmxorComponentResult and PropertyHelper. Removed the <see cref="..."/> tags for better readability and clarity. This change does not affect production code.
Significant changes include: - Added new usings in Program.cs for Htmxor.Endpoints.Results and HtmxorExamples.Components.Pages. - Demonstrated the mapping of a page/component in Program.cs. - In HtmxorComponentResultExecutor.cs, refactored RenderComponentToResponse method to improve component rendering process. - Introduced GetFormHandler method in HtmxorComponentResultExecutor.cs to handle form requests. - Deleted the file HtmxorHtmlRenderer.cs as it was no longer needed.
- Introduced `HtmxorComponentEndpointHost` class to act as a root component when executing a Htmxor Component endpoint. - Added `HtmxorComponentResultExecutor` class to execute the result of an HTTP request in the context of an endpoint. - Created `HtmxorComponentResult` class that renders a Razor Component. - Implemented `HtmxorComponentResultOfT` class, which is a generic version of `HtmxorComponentResult`.
Updated the XML comments in two classes, HtmxorComponentResult and PropertyHelper. Removed the <see cref="..."/> tags for better readability and clarity. This change does not affect production code.
2f3a04d to
c72411c
Compare
This update refines the process of retrieving custom attributes in HtmxorComponentEndpointHost, ensuring a more reliable order by introducing a priority system. This allows users to define a default HtmxLayout and override it on a component basis. In addition, the code in HtmxorComponentResultExecutor has been simplified by directly assigning the 'isBadRequest' variable within the conditional statement, reducing redundancy and improving readability.
|
@egil I believe I can encapsulate most of the functionality of the htmxor renderer with the exception of rendering the App root component markup, which a call to a component renderer would not have awareness of. Since the root component typically wraps a Router component the HtmxorComponentResult has to go another way. To get closer I think the ideal approach would require passing a root Layout and DefaultLayout to the component result renderer. This would require duplicating the markup inside App.razor though unless App.razor uses a layout itself. The layout approach where the App root component uses a Layout that can be shared with the HtmxorComponentResult may be the cleanest approach. app.MapGet("/greeting", () => new HtmxorComponentResult<GreetingComponent>() {
RootLayout = typeof(AppLayout), // optional root layout
DefaultLayout = typeof(MainLayout) // optional default layout if component doesn't specify a layout via Htmx attributes or @layout
}
); |
|
Isn't supporting the "full page" render path irrelevant in this scenario? Just as with |
Most likely so. I'll stick with matching the RazorComponentResult approach. |
This is just a first effort so far, untested but I figured I would draft PR this before getting too deep.
HtmxorComponentEndpointHostclass to act as a root component when executing a Htmxor Component endpoint.HtmxorComponentResultExecutorHtmxorComponentResultclass that renders a Razor Component.HtmxorComponentResultOfTclass, which is a generic version ofHtmxorComponentResult.