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

Proposal: config to disable/customize attribute inheritance #1520

Closed
metametadata opened this issue Jun 26, 2023 · 3 comments
Closed

Proposal: config to disable/customize attribute inheritance #1520

metametadata opened this issue Jun 26, 2023 · 3 comments
Labels
enhancement New feature or request under discussion Issues that are being considered but require further alignment

Comments

@metametadata
Copy link

Even though inheritance allows writing more concise code in typical cases, I'd strongly consider turning it off in my projects.

I find it difficult to reason about code because of inheritance when there are nested elements which have different hx- attributes and it all behaves in unexpected way. It's extra non-trivial because not all attributes are inherited (for example, hx-post), so I have to check the documentation for that additionally.

I've tried hx-disinherit="*" but it seems to have an effect only on immediate children. I.e. I can't set it in body to get what I want.

Idea: add an extension or a new attribute to disable inheritance in all the children of the element, their children, etc. For example, it could be an attribute hx-recursive-disinherit="*".

And then I'd likely want to keep inheritance of, say, hx-ext="morph". So the new toggle should also support more fine-grained configuration, e.g. something like hx-recursive-disinherit="not hx-ext, not hx-some-other-inherited-attr, hx-some-attr-which-should-be-disinherited".

@alexpetros alexpetros added the enhancement New feature or request label Jul 17, 2023
@alexpetros
Copy link
Collaborator

This came up in the discord too. The basic proposal is to add an attribute that either lets you disable inheritance globally, or specify which attributes are inherited by default:

// Disable all inheritance
htmx.config.implicitInheritance = false

// Enable it for certain attributes by default
htmx.config.implicitInheritance = ['hx-disable', 'hx-boost']

cc @gnat @1cg

@alexpetros alexpetros changed the title Proposal: disable inheritance recursively Proposal: config to disable/customize attribute inheritance Jul 17, 2023
@alexpetros alexpetros added the under discussion Issues that are being considered but require further alignment label Jul 17, 2023
@th3n3rd
Copy link

th3n3rd commented Sep 17, 2023

The main issue I face is that I found it counter-intuitive that moving a piece of html around does change it's behaviour, it makes refactoring a lot harder for no good reason.

I think the current behaviour breaks the Locality of Behaviour the author advocate for so much. For instance I cannot just work with fragments, which are typically separated pieces of code that live on their own, I often need to know more, e.g. their surrounding, in order to understand the fragment behaviour.

IMHO increases the likelihood of introducing undesired bugs, i.e. somebody excluding some parameters in the parent without knowing it will affect fragments living elsewhere.

Inheritance must be an explicit exercise, e.g. we should have hx-inherit.

An example in the attached screenshot:
Screenshot 2023-09-17 at 15 01 08

Description:

  • The page started by loading /products/fendt?edition=standard
  • The platinum checkbox has then been clicked reloading only the inner part of the page (and updating the url to platinum)
  • The buy button (and recommendations) have been clearly re-fetched with the right values (i.e. from $54 to $954)
  • When the buy button is clicked the client sends standard instead of platinum, despite the hidden form input clearly stating the right values
  • Culprit: the original product placeholder is still in the page, and it still populated with hx-vals containing the standard edition, which somehow affects the behaviour of a buy button all the way down
  • Result: LoB broken IMHO, by looking at the buy button NOBODY could have guessed that standard would be sent instead of platinum, and I had to look few layers above in order to spot the problem.

Lesson learned, should not leave the containers/placeholders around because the default inheritance can break stuff in a non trivial way.

@Telroshan
Copy link
Collaborator

Closing this as since this issue was opened, htmx.config.disableInheritance is now a thing, see the attribute inheritance section in the docs!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request under discussion Issues that are being considered but require further alignment
Projects
None yet
Development

No branches or pull requests

4 participants