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

feat: Add ability to utilize multiple htmx configurations #10

Closed
wants to merge 3 commits into from

Conversation

tanczosm
Copy link
Collaborator

@tanczosm tanczosm commented Jan 26, 2024

Based on conversation regarding configuration on startup I realized that it isn't unreasonable to have different configurations for different pages. While a single config per-site might work I think a better approach would be to also allow for named configurations along with a default configuration. Htmx could potentially have different configurations across different pages, since the configs are page-level.

Adding a specific configuration for a page could just involve configuring the HtmxConfigHeadOutlet as follows:

<HtmxConfigHeadOutlet Configuration="articles"/>

or leave Configuration off to use the default configuration

Then implement a config we can create a config builder that works like the following:

builder.AddHtmxor()
	.WithDefaultConfiguration(config =>
	{
		config.SelfRequestsOnly = true;
	})
	.WithNamedConfiguration("articles", config =>
	{
		config.SelfRequestsOnly = true;
		config.GlobalViewTransitions = true;
	});

Side Effects
HtmxAntiforgeryOptions will need to be configured globally for the site on startup instead since there is no reasonable way to know which config should be used per-request

feat: Add Htmx named configuration options

- Added support for default and named configurations in the `HtmxorConfigBuilder` class
- Updated `HtmxConfigHeadOutlet` to use the configured JSON configuration
- Created a new file `HtmxorConfigBuilder.cs` to handle Htmx configuration options
- Refactored the `WebApplicationBuilderExtensions` class to use the new `HtmxorConfigBuilder`
@egil
Copy link
Owner

egil commented Jan 27, 2024

I am not sure of the implications of enabling configuration based on individual pages or groups of pages. It's certainly not all configuration options that make sense to change on a per-page basis, most seem to be controllable on individual elements and are just defaults.

A few questions:

  1. Can you describe one or more scenarios/options that make sense to change on a per-page basis?
  2. Does htmx pick up on configuration changes in the head element on hx requests?
  3. Will it cause hard to detect bugs if one page has a different behavior than others? Is there edge cases where htmxor code changes its behavior depending on the config, and would need to know the page that triggered a requests config and page being targeted in a requests config?

Design of the feature:

In configuration, I am not opposed to having "named" configurations. I guess individual pages can set this via the <HeadContent> tag, e.g.:

<HeadContent>
    <HtmxConfigHeadOutlet Configuration="articles"/>
</HeadContent>

An alternative is to register HtmxConfig as a scoped service instead of a singleton. That would allow individual pages to override the config by having it injected into them and changing settings as needed. And since the config is scoped to the request, the change would only apply to that specific page, e.g.;

@inject HtmxConfig config
@code {
  protected override void OnInitialized()
  {
    config.Timeout = Timespan.FromSeconds(2);
  }
}

A 3rd option is to allow setting up configurations that match path templates, such that the path of a request determines the config:

builder.AddHtmxor(config =>
	{
		config.SelfRequestsOnly = true; // is the default btw.
	})
	.WithPathConfiguration("/articles/**", config =>
	{
		config.GlobalViewTransitions = true;
	});

@tanczosm
Copy link
Collaborator Author

tanczosm commented Jan 28, 2024

I would see configuration changes more localized to certain sections of your site. By design htmx configs are set at a page-level, and you can't make the assumption that the whole site will function as an SPA. Consider also a site that has a front-facing side and an administrative side. Or perhaps an ecommerce side and media presentation side. They might have different configuration requirements.

I used named configurations in my code writeup because they are pre-built into the options pattern. I think it's simple to reason about if you are just applying that code to a layout page that is used by a group of pages. The route approach, while nice, is probably not needed if you consider a section like articles will likely share a similar layout with the same head anyway.

I can see a strong argument for the injection approach though, as that would allow you to localize the configuration in the same place as the layout. If the spirit of htmx is to localize most page state in the dom, then injection of the config and manipulation of it on the same layout page could be a winner (even though it's technically in a code section). I personally see layouts as being the strongest contender for manipulating a config.

So I could see this as a working solution then. Keep the default configuration format that is set up in Program.cs, but register as a scoped service instead as you mentioned. Any changes that are made to the config would be done as a mutation of the default state.

@egil
Copy link
Owner

egil commented Jan 28, 2024

Really good points. I'll set up a test that verifies config can be scoped.

@egil
Copy link
Owner

egil commented Jan 28, 2024

Getting scoped working wasn't a five minute thing so I'll park this for now and get back to it. Also being able to extend HtmxConfig with more options for people using HX extensions.

@tanczosm
Copy link
Collaborator Author

tanczosm commented Jan 29, 2024

Are extension configurations assumed to just be part of the htmx config? Do you know any extensions that utilize custom htmx configuration variables? I'll take another stab at this after I finish the response handling.

@egil
Copy link
Owner

egil commented Jan 29, 2024

For extension configs I am thinking users should be able to create a derived type of HtmxConfig. That way they can add anything they want to HtmxConfig without breaking the internal bits that depend on certain aspects of HtmxConfig in Htmxor.

@egil egil closed this Apr 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants