Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
There is currently no way to use tokens to extract subelements of webform composite elements. This can make it difficult for example, when using the remote post handler to correctly map webform address fields to the remote's expected post fields.
I was thinking the simplest way to allow this would be to use the [webform_submission:values:?] token. Currently it accepts element_key:format as an argument, and allowing format to contain a sub element key in addition to value and raw, would be fairly simple to implement.
Comment | File | Size | Author |
---|---|---|---|
#31 | allow_token_access_to-2873307-31.patch | 1.3 KB | jrockowitz |
| |||
#29 | Selection_249.png | 27.96 KB | frederickjh |
#29 | Selection_250.png | 67.32 KB | frederickjh |
#29 | Selection_248.png | 31.74 KB | frederickjh |
#26 | allow_token_access_to-2873307-26.patch | 17.72 KB | jrockowitz |
|
Comments
Comment #2
mikelutzThe attached patch overrides WebformCompositeBase::formatTextItem and WebformCompositeBase::formateHtmItem to accept a subelement key as a format for composite elements. This is a stab at a fix that works for my particular use case, but I'm not familiar enough with webform to know if it might have any unintended side effects. It might be better to just create a new token, but that would have significantly more overhead.
On a related note, as I was doing this, I wondered if it might also make sense to override the 3rd argument of that token, the items value, where if the value is numeric, rather than using it as a delimiter between items, it returns the item with that delta. I can't imagine anyone using a number as a delimiter, and it seems like being able to pull a specific delta out might be useful in some cases, for example [webform_submission:values:element_key:value:1]
Comment #3
mikelutzComment #4
Chris Burge CreditAttribution: Chris Burge commentedI'm running to the same issue. I need to access sub-components for e-mails. (e.g. in the salutation - 'Dear Mr. Smith' instead of 'Dear Mr. Charles A. Smith, Jr.').
What about adding a 'sub-component' format in addition to 'raw' and 'list'? This removes the risk of adversely affect the default behavior.
Simply returning $value[$format] assume the component has a single value, which may not be true. Supporting multiple values would require supporting deltas.
Comment #5
Chris Burge CreditAttribution: Chris Burge commentedPatch attached. It doesn't support multiple values.
Comment #6
mikelutzThat works too, but I'm not a fan of it just failing if there are multiple items. I'd like to address that use case somehow. I don't think there is any adverse affects from using the format to hold the sub_element key directly. Unless a composite element has a key called 'value', which maybe location does, I don't think there's an issue, and with #2, the current items function remains the same.
Comment #7
jrockowitz CreditAttribution: jrockowitz as a volunteer and at The Big Blue House commented@Chris Burge and @mikeNCM Thanks for taking a cracking at this issue.
We probably need to add full support for deltas and properties.
This is going to be a pain to implement and require some tests. At least, deltas are always numeric.
Comment #8
mikelutz@jrockowitz Alas, I am not good at writing and debugging tests, though I am working on it, and will submit some when I get a chance. In the meantime, here is a patch to support the token format you described above.
Comment #9
mikelutzOkay, this is the same patch, but it adds a new test form and test for the values token
Comment #11
mikelutzWhoops, my mistake. Here's a (hopefully) working version.
Comment #12
mikelutzComment #13
mikelutzSame patch, minus 3 extra lines I accidently left in from a previous attempt.
Comment #14
mikelutzComment #15
Chris Burge CreditAttribution: Chris Burge commented@mikeNCM - Thanks for pushing this issue forward.
In my testing of patch #13, the deltas functionality works. The sub-element functionality does not.
[webform_submission:values:single_address] - returns address (same as before patch)
[webform_submission:values:single_address:street] - returns nothing
[webform_submission:values:multiple_address:0] - returns first address
[webform_submission:values:multiple_address:0:street] - returns nothing
Comment #16
mikelutz@Chris
You need to use the same keys that webform uses, for address, that is address, address_2, city, state_province, postal_code, and country.
I believe @jrockowitz was just using street as an example key. It's not that actual key that that element uses for the street address.
When editing a webform composite element, the keys are shown in the ADDRESS SETTINGS block. Perhaps we need to document where to find the keys better.
Comment #17
mikelutzMy last patch should maintain backwards compatibility with any of the old style tokens, provided there are no formats that are also subelement keys or numeric, which there shouldn't be.
Comment #18
Chris Burge CreditAttribution: Chris Burge commentedMy last comment used the examples from #7 provided by @jrockowitz. In my actual testing, I used the following tokens with the name component:
(Single-valued component)
[webform_submission:values:name] - returns name (same as before patch)
[webform_submission:values:name:first] - returns nothing
(Multi-valued component)
[webform_submission:values:name:0] - returns first name
[webform_submission:values:name:0:first] - returns nothing
Comment #19
jrockowitz CreditAttribution: jrockowitz as a volunteer and at The Big Blue House commentedI suspect we might have to tweak the token syntax and write an update hook.
Next week, I can review the patch and make some tweaks. I want to make sure that we can support and future proof the webform submission token syntax.
I can see you started writing some new tests. I think a test_token_submission_value form that has some pre-populated basic, composite, and multiples that just displays the submission value on confirmation page using all the possible token variants could be very helpful. I think this test form could be pretty simple with maybe just 6 elements with a dozen or so tokens on the confirmation page.
Comment #20
mikelutz@Chris Can you give me steps to reproduce? Where are you using the tokens? I'm not having trouble accessing subelements in either the kernel tests or in my live site, but I'd love to know if I missed something. I haven't messed with the webform 5 codebase before so I may have missed something.
@jrockowitz I can definitely expand the test form slightly and add tokens to the confirmation page so we can add a functional test, and test more tokens. I didn't see an existing test for tokens, so I made the one just to test for the particular tokens I was adding. I thought it might be useful to add more token tests to it in the future, but I didn't want to put too much in this one patch. I might see if I can revamp a bit this weekend, create a separate issue and patch for generic token testing that we can go off of.
I'm not sure what makes the most sense with the syntax. I built off of your list above, but I'm not a huge fan of having the delta listed first. My feeling is that that last #format_items key, which holds a separator for multiple values should do double duty to hold the delta, since you will need either a separator OR a delta, but never both.
[webform_submission:values:?]
[webform_submission:values:ELEMENT_KEY] (exists)
[webform_submission:values:ELEMENT_KEY:ITEM_FORMAT] (exists)
[webform_submission:values:ELEMENT_KEY:ITEM_FORMAT:ITEMS_FORMAT|DELTA] (changed, if #items_format is numeric, treat it as a delta instead of a seperator)
[webform_submission:values:ELEMENT_KEY:SUBELEMENT_KEY] (new/changed, if the second argument is not a valid format returned by $element_manager->invokeMethod('getItemFormats', $element); assume it is a subelement key, and move the rest of the arguments up)
[webform_submission:values:ELEMENT_KEY:SUBELEMENT_KEY:ITEM_FORMAT] (same as above)
[webform_submission:values:ELEMENT_KEY:SUBELEMENT_KEY:ITEM_FORMAT:ITEMS_FORMAT|DELTA] (same as above)
[webform_submission:values:single_textfield]
[webform_submission:values:single_textfield:value]
[webform_submission:values:multiple_textfield]
[webform_submission:values:multiple_textfield:value:0]
[webform_submission:values:multiple_textfield:value:semicolon]
[webform_submission:values:single_address]
[webform_submission:values:single_address:city]
[webform_submission:values:single_address:value]
[webform_submission:values:single_address:city:value]
[webform_submission:values:multiple_address]
[webform_submission:values:multiple_address:value:0]
[webform_submission:values:multiple_address:value:semicolon]
[webform_submission:values:multiple_address:city]
[webform_submission:values:multiple_address:city:value]
[webform_submission:values:multiple_address:city:value:0]
[webform_submission:values:multiple_address:city:value:0:semicolon]
My other thought to make things less confusing, and continue to preserve compatibility with existing tokens is to make a new subelement_value token. So, you would end up with something like this:
[webform_submission:values:?]
[webform_submission:values:ELEMENT_KEY] (exists)
[webform_submission:values:ELEMENT_KEY:ITEM_FORMAT] (exists)
[webform_submission:values:ELEMENT_KEY:ITEM_FORMAT:ITEMS_FORMAT|DELTA] (changed, if #items_format is numeric, treat it as a delta instead of a seperator)
[webform_submission:subelement_values:?] (new)
[webform_submission:subelement_values:ELEMENT_KEY:SUBELEMENT_KEY] (new)
[webform_submission:subelement_values:ELEMENT_KEY:SUBELEMENT_KEY:ITEM_FORMAT] (new)
[webform_submission:subelement_values:ELEMENT_KEY:SUBELEMENT_KEY:ITEM_FORMAT:ITEMS_FORMAT|DELTA] (new)
[webform_submission:values:single_textfield]
[webform_submission:values:single_textfield:value]
[webform_submission:values:multiple_textfield]
[webform_submission:values:multiple_textfield:value:0]
[webform_submission:values:multiple_textfield:value:semicolon]
[webform_submission:values:single_address]
[webform_submission:subelement_values:single_address:city]
[webform_submission:values:single_address:value]
[webform_submission:subelement_values:single_address:city:value]
[webform_submission:values:multiple_address]
[webform_submission:values:multiple_address:value:0]
[webform_submission:values:multiple_address:value:semicolon]
[webform_submission:subelement_values:multiple_address:city]
[webform_submission:subelement_values:multiple_address:city:value]
[webform_submission:subelement_values:multiple_address:city:value:0]
[webform_submission:subelement_values:multiple_address:city:value:0:semicolon]
At this point, my patch put all the extra delta and subelement logic in the WebformElementBase and WebformCompositeElementBase format functions, so the above (or any other syntax tweaking) is pretty much confined to the token.inc file, and shouldn't be a big deal.
The second one does a better job at separating old/new functionality, but I'm not sure if it's more confusing. It looks more confusing at first glance, but it might be easier to document a second token for subelement values.
Comment #21
jrockowitz CreditAttribution: jrockowitz as a volunteer and at The Big Blue House commented@mikeNCM @Chris Burge I am going to take a crack at this and see if I can get better test coverage.
Comment #23
jrockowitz CreditAttribution: jrockowitz as a volunteer and at The Big Blue House commented@mikeNCM Your patch definitely pointed me in the right direction. I did have to approach the implementation from a slightly different angle.
Comment #24
Chris Burge CreditAttribution: Chris Burge commented@jrockowitz and @mikeNCM - Thanks for your work on this!
With the latest commit, I'm still finding that sub-elements aren't working. (I don't have time for more thorough testing at the moment.)
I think that that
$value
needs to be replaced with with$submission_data[$element_key]
($value
is undefined).Also, when checking
$delta
, I think we want to check that$delta
isn't NULL.With these changes, I was able to get the following patterns to work:
(Single-valued component)
[webform_submission:values:name:first] - now works
(Multi-valued component)
[webform_submission:values:name:0:first] - now works
(I'm testing with the e-mail handler, which uses Webform token substitution.)
Comment #26
jrockowitz CreditAttribution: jrockowitz as a volunteer and at The Big Blue House commented@Chris Burge Thanks for catching that mistake. I made your suggested tweaks and updated the tests.
Comment #28
jrockowitz CreditAttribution: jrockowitz as a volunteer and at The Big Blue House commentedI committed the patch, please download and review the latest dev release.
Comment #29
frederickjhI just tested the latest 8.x-5.x on simplytest.me and it seems to be working fine for tokens in email addresses but only the field part of the token shows after saving. Nothing shows for the subelements after saving while viewing the settings.
Entered tokens in the email fields:
Viewing the settings after saving:
Checking the token rendering in the email resend with debug on:
Comment #30
jrockowitz CreditAttribution: jrockowitz as a volunteer and at The Big Blue House commentedI missed that issue. The WebformEmailHandler is just trying to truncate the token.
Comment #31
jrockowitz CreditAttribution: jrockowitz as a volunteer and at The Big Blue House commentedThe attached patch fixes the immediate regression.
Comment #33
jrockowitz CreditAttribution: jrockowitz as a volunteer and at The Big Blue House commentedI committed the patch, please download and review the latest dev release.