Problem/Motivation
It's not super friendly to use the drupal_htmx wrapper format, add a few things to help DX with the Htmx object.
The way to get the URL of the current page is to use Url::fromRoute('<current>'), Then you need to remember that it doesn't give you the query parameters of the current url. If you're working with a GET request, your form state is gone. So you also need to add \Drupal::request()->query->all(); but that comes with extra values like form_build_id, form_token, op that you don't want in your URL since the values are coming from your actual form.
Steps to reproduce
Proposed resolution
Automatically add the wrapper format parameters to Urls when using Htmx->get/post/patch/delete, leave an option to opt-out and request a full page with all the regions and blocks surrounding the content if necessary.
Automatically figure out the current url and remove unwanted query string parameters from other form submissions and history state management.
Remaining tasks
User interface changes
Introduced terminology
API changes
Data model changes
Release notes snippet
| Comment | File | Size | Author |
|---|
Issue fork drupal-3546105
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #3
nod_depends on #3522597: Return only main content for selected htmx requests
Comment #4
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #8
fathershawnI put up MR!13205. I discussed this idea with @nod_ in Slack. The static method makes creating or modifying the Url object relatively simple and the changes are fewer and easier to test.
Here's an example code block:
Comment #9
nod_I'm not happy with that static method being the only way to add the wrapper format.
We can add the static method but I want to add the htmx wrapper format by default to the Urls the Htmx class handles, and provide a way to opt-out when necessary. The wrapper format is an implementation detail of Drupal, people using Htmx in Drupal shouldn't have to know about this.
Making a test harder to write, and in exchange we won't have to explain anything about wrapper formats to users is a good compromise to me.
Comment #10
fathershawnMade a couple of suggestions. I'll check back later to see if the unit test is running.
Comment #13
fathershawnOpened an MR with a working kernel test to your issue branch @nod_
Comment #14
fathershawnGitlab CI doesn't like MRs between issue branches:
but the kernel test passes locally.
Comment #17
fathershawnRefactored the test to use a data provider.
Comment #18
nod_That looks good, thanks!
Comment #19
fathershawnComment #20
fathershawnI have a concern with current url and query parameters.
If the form is using get, won’t the url for a new request contain the prior request parameters?
Comment #21
nicxvan commentedRe 14 yes tests won't run in MR between branches without a lot of work.
It's still helpful sometimes to see the diff!
Comment #22
nod_@fathershwan: it sure will, that's the point and that's why we filter out the Drupal specific pieces out of the get parameters. We need that for
TranslateFilterFormat least.If we have another method in the Url object or somewhere else that does this I'd be happy to remove this chunk of code from the Htmx object, but I don't have a good place for it somewhere else
Comment #23
fathershawn@nod_ My concern is about a conflict with the state stored in the form and the state stored in the request URL. Consider a form with an input A that responds to user interaction and sends the values in a get request.
Focusing only on values for clarity
data-hx-get="/path?A=1Now if I set the value to 2 I am explicitly declaring that I will send 1. Isn't that confusing? It seems like the state encoded in the form should be the source of truth.
Comment #24
nod_should be good to go, maybe comments needs some work? not good at that.
Comment #25
fathershawnThis looks good to go to me.
Comment #26
fathershawnI found myself wondering tonight if we should be building a clean url using URL::fromRouteMatch if we are going to build them for people as a convenience?
Comment #27
nod_started to go another way in #3538544: Ajaxify the user interface translation forms
Instead of handling that in the backend, the query string is added from the front and we have an extra drupal-specific attribute that controls it
Comment #28
fathershawnComment #29
nod_Comment #30
nod_Back to green
Comment #31
fathershawnI know that predicting the future is hard. I'm wondering if #3544632: Return only main content for endpoints designed to service htmx requests lands how many dedicated routes we will build. Will most requests use such dedicated routes? If we think that is likely, should we reverse the polarity of the data attribute added here and make the default to be no wrapper format parameter?
Comment #32
nod_My main objective with htmx and forms is to make sure htmx and regular requests follow the same code path, unlike what's happening with Ajax today. I'm thinking most uses of htmx will be in the context of a form (for now at least) where it makes sense to add the wrapping format by default. Even if we query an htmx route, adding the wrapper format parameter shouldn't be a problem.
All that to say I think we should keep the default as adding the wrapper format.
Comment #33
nod_Comment #34
fathershawnI think this needs a CR. Adding the tag - remove if I'm off base!
Comment #35
godotislateSome comments on the MR. For the comments on the tests, I realized after making my suggestions that the test code was largely lifted from the other existing test class. A lot of suggestions are nits or style, though I think the missing commas should at least be fixed.
Comment #36
nod_thanks, updated.
Comment #37
godotislatePHPCS issues in the build.
Comment #38
godotislateAdded a CR from what I understand of the issue: https://www.drupal.org/node/3558614. Please review. Otherwise I think this is good for RTBC.
Comment #39
godotislateComment #40
papagrandeI reviewed the CR and while my HTMX experience is still low, the explanation itself is clear to me.
Comment #41
fathershawnThe CR should also describe the effect of the data attribute on the wrapper format.
Comment #42
fathershawnI added the detail I think is needed to the CR and ready for another review.
Comment #43
godotislateNice, CR lgtm.
Comment #44
mxh commentedI have tried out the MR within the scope of #3560641: HTMX hx-boost does not work with core/drupal.htmx library and it turns out this has one good change and one bad change when using hx-boost on the
<body>element:Not setting to NW as I'm not into the details of this issue, but at least posting what I found out from my scope.
Comment #45
nod_Once again should have listened to @fathershawn earlier 😂 in #31.
Reversing the attribute default. This should behave more as expected.
Comment #46
fathershawnIf this works out in for @mxh in their testing, then I'll adjust the CR
Comment #47
nod_For default I went with only main response when using ->get/post/patch/etc. and the full page when using ->boost() not sure it's a great idea to have different default but that seemed reasonable.
Comment #48
nod_changed my mind, keeping the full page by defaut on all requests, to use the special drupal output you need to opt-in, hopefully that will prevent folks from being tripped up by this and we can just use that in core when we need it.
Comment #49
nod_Comment #50
fathershawnReviewed recent changes and I affirm this is still RTBC.
Thanks for the refactor @nod_ !!
Comment #51
fathershawnNice re-write on the CR. I changed the title to HTMX requests may be configured to use the drupal_htmx wrapper format.
Comment #52
mxh commentedI can confirm the recent changes make usage of
hx-boostmore straightforward. Now, without specifying anything else, the whole response is returned as expected. Network logs show the attachedajax_page_statequery arguments, whereas the URL history contains the link's href only (withoutajax_page_state). This is what I consider to be expected. It's nice to see the attachments being loaded only once, which the main reason why I want to usehx-boost. Great to see this working, thank you!Comment #53
longwaveWondering why it needs to be specified in the factory method when it could just be a separate method in the chain? Boolean arguments are harder to reason about and less readable (though named arguments helps here). As this feature is opt-in and disabled by default it makes more sense to me to move the opt-in to its own explicit method call, ie.
could be
?
Comment #54
idiaz.ronceroI came here from #3560641: HTMX hx-boost does not work with core/drupal.htmx library: in my case, I wasn't using hx-boost but a more specific usage of data-hx-attributes on some links to reload only certain parts of the page while keeping brower history up to date.
Kind of a "hx-boost" manually constructed.
I had the same problem with the ajax_page_state being pushed to they query URL parameters, and with the patch applied I can confirm that they are gone.
Comment #55
nod_Comment #56
fathershawnThe revisions requested by @longwave look good. This really improved the feature. All tests passing. Still RTBC
Comment #57
longwaveThanks for the last minute change. This is going to be super helpful so good to get it into 11.3.x.
Committed and pushed ca4031b9136 to 11.x and 62362fa40d1 to 11.3.x. Thanks!