Problem/Motivation
I'm trying to use a boolean field as a setting for a design and am running into an issue. It looks like the BooleanSetting class is using the field's markup rather than its raw value to compare the value. Meaning rather than the comparing boolean value of "0" or "false", it's rendering the field which is including twig debug output (if twig debugging is enabled), field wrappers, etc. There's also an option called "Use a string" but I don't see any other reference to that being used elsewhere, and don't think it impacts this.
Steps to reproduce
Create a boolean field on a content type, use it as a setting for another field, and verify that it never resolves as a boolean value.
Proposed resolution
In BooleanSetting:process() change $output = $this->renderer->render($build); to $output = $this->renderer->render($build[0]); or, provide a new setting for BooleanSetting to optionally only compare the raw value as opposed to the rendered value.
| Comment | File | Size | Author |
|---|
Comments
Comment #2
omkar-pd commentedWill work on this.
Comment #3
omkar-pd commentednot able to reproduce the issue.
Comment #4
rhys commentedI hope I understand the problem here. You are using something like {% if setting %} in a template with debugging turned on. The biggest problem with your suggestion is that in the case of using different content plugins (such as twig) to generate the boolean value, this would fail.
I probably should add the ability to do a filter_var on the rendered output (while being stripped of tags), as that is a possible combination with the twig/token content plugin. That would also cover future content plugins.
The difficulty here is that I'm trying to accommodate string-based output (such as Off/On) as well as the boolean-based output (true/false). If the "Use as string" was repurposed to ignore the boolean-based output, I'd probably just need an option to use the UI values as opposed to the rendered value.
I'm open to different ways to solve this problem, such that it makes sense from the UI standpoint.
Comment #5
rhys commented@rromore After looking at it a bit more deeply, could I get you to check if changing the filter_var line to
solves your problem? This makes much more sense for output from the other content sources as well.
Comment #6
rromore commentedYeah that's the gist of what I'm trying to do, using a conditional in twig to control whether content is output or not. I'll try to explain more fully just so we're on the same page.
I have a design component called "accordion" which has two regions defined, "items" and "properties", as well as three settings defined, "attributes", "multiselectable", and "bordered". The twig template for this design will add the "bordered" class if the "bordered" field is checked, and set "aria-multiselectable" attribute to "true" if the "multiselectable" field is checked. The "bordered" and "multiselectable" fields are placed in the "properties" region and are formatted to output as boolean with display "1/0". (Quick sidenote: the properties field is never actually printed in the twig template, I just needed the fields to be not in the "hidden" region because otherwise the field data was never actually attached to the object entity. It might make more sense to have like a DesignProperty entity, like with design settings and sources, and be able to assign fields/content/whatever to that instead.)
Next I have an "accordion" entity type (I'm using paragrahs but I think it can be any type of entity that extends ContentEditable), which is using the designs_entity module for displaying. These settings are set to use the "accordion" design component as its design, and in the "Settings" fieldset, sets the "bordered" setting to use "content" and the "bordered" field, and the "multiselectable" setting to use the "multiselectable" field.
So when I create an "accordion" entity and enable the "bordered" field and view the entity, the bordered class is never added. Diving into the code and displaying the value BooleanSetting:process() is comparing to a boolean, I see the following:
Adding "strip_tags()" does seem to work, though. I'm just wondering if the entire boolean field should be rendered first and then compared, or if just the value should be compared.
Comment #7
rhys commentedOkay, I definitely understand where you are coming from, and I had designed it for something similar to this. Your use of the properties region is what I would recommend using, since you're using the content element plugin (rather than the token or twig ones).
I'm not sure I follow about the DesignProperty idea, if you could elaborate on that I would greatly appreciate it.
The idea with the design content plugins, is to provide a render array for the settings plugins to process or for the regions to simply render. This keeps the process simple and consistent. The problem lies here in that rendering is adding all the additional field related content (which is superfluous when being used for the settings), which for boolean entities being tested in twig template, is a problem. To keep it simplified, I'm going to go with the strip_tags option, since that is what would be required in twig templating when using rendered boolean fields in similar ways. e.g. (
{% if field_iadf_p_accordion_multisel | render | strip_tags | trim %})The only problem with comparing the value, is that we may not always get from the content plugins, the content of a field (it may come from other sources), so there isn't a reliable way to check for this condition. Rather the safest bet is to treat the render array as if it will produce a boolean recognizable result (minus any templating -- hence the strip_tags).
I just noticed that I'm also not using the check for the string value properly, so I've added in that check.
Comment #9
rhys commentedComment #10
rhys commented