Problem/Motivation
I wanted to convert the prev/next buttons in a webform wizard from secondary to ghost (for prev) and primary (for next).
I went on and implemented template_preprocess_webform_actions() preprocess where I wanted to add the custom classes. For primary button it was fine, because I could just add $variables['element']['wizard_next']['#attributes']['class'][] = 'btn-primary'.
For the ghost button instead, I need to define
$variables['element']['wizard_prev']['#attributes']['class'][] = 'btn';
$variables['element']['wizard_prev']['#attributes']['class'][] = 'custom-button-ghost';because of the initial check in input--submit.html.twig template. With that added, the check is skipped and the primary/secondary classes are not added.
What is also strange, is that we have two different attributes/classes, btn-primary and button--primary and that just adds extra confusion.
Proposed resolution
Is there a reason why bs_bootstrap does not support ghost buttons and we have that defined in our custom theme?
Should we expand that, add ghost button to bs_bootstrap and extend the submit template?
Not sure what would be the best approach to solve the extra btn class definition in the preprocess.
Comments
Comment #2
sasanikolic commentedComment #3
sasanikolic commentedComment #4
pivica commentedYeah, the current implementation is a bit ugly and done quickly.
> $variables['element']['wizard_prev']['#attributes']['class'][] = 'custom-button-ghost';
I am not sure what is custom-button-ghost here i guess it is a custom class for a specific project?
> What is also strange, is that we have two different attributes/classes, btn-primary and button--primary and that just adds extra confusion.
Yes because Drupal core is saying that it's primary button is button--primary and Bootstrap is saying btn-primary. So we have two conventions here.
Current input--submit.html.twig template is trying to solve these two conventions and simplify usage for 'most' of use cases. Currently, it supports core button--primary, button--danger CSS classes and treats all other cases as Bootstrap secondary button. Meaning this should work for regular Drupal forms - proper Bootstrap CSS classes will be attached, etc.
I am not sure how to solve this conflict properly? You want to support a ghost button but that is not something that Drupal is defining, or at least it didn't do it before, right? Maybe something changed with Claro admin theme?
The easiest way is to attach 'btn' class to custom cases and then attach your additional custom CSS classes. This worked for now for other custom cases. You anyway need to define preprocessor and inject your custom CSS class, so adding a btn class is not a big deal.
Now if you want to just attach custom-button-ghost CSS class and not btn i guess you would not be able to do right now with the current template, you would need to override it in child theme. IMHO overriding template is fine in this case because this is a Bootstrap base theme and by default, it should always attach btn base class.
Hopes these informations are clearing stuff a bit. I am open to suggestions on how to improve this.
Comment #5
sasanikolic commentedFor sure, I already realized those things and it's a bit tricky.
I was just wondering if we should somehow solve this in bs_bootstrap so that custom custom button classes could be added more easily, without template overrides or adding the btn class. Otherwise, we need to document this somewhere for future reference.
That said, maybe adding a key class/attribute like button--custom when defining "custom-button-ghost" in the preprocess, for example, and checking for that in the template would somehow make sense?
Would be great if we could prevent new users from spending too much time debugging this kind of stuff.
Comment #6
pivica commented> Otherwise, we need to document this somewhere for future reference.
If this is a Bootstrap based theme then it would make sense that by default all buttons use Bootstrap btn base class for that.
> That said, maybe adding a key class/attribute like button--custom when defining "custom-button-ghost" in the preprocess, for example, and checking for that in the template would somehow make sense?
If we really want to do this I don't think we should use class/attribute for this but inject custom variable in preprocessor and then check in the template should we use default logic or just pass through. How does this sound to you?
Comment #7
pivica commentedWebform submodule webform_bootstrap is doing something similar in `_webform_bootstrap_convert_button_classes()`:
And this is called in hook_link_alter() and template_preprocess_file_managed_file(). Similar but a bit different approach and done in PHP instead of template.
Comment #8
pivica commentedNot sure about this. Changing anything in this logic could break now custom themes, and we do not want to do it for 1.x.
The `btn` CSS class is a base CSS class for a Bootstrap button so it kinda make sense that if you want to add some custom button class you should also add `btn`.
On the other hand having button button--primary and btn btn-primary on the same element is a bit too much.
Let's move this to 2.x version with a two possible options to solve this:
- Instead of converting to Bootstrap buttons maybe we define Drupal button classes to work like Bootstrap classes - this will be easy with applying mixins or using SASS @extend rule. This would allow us to leave core input--submit template. Not sure will Bootstrap like this, we need to test.
- If first option does not work let's do then like webform is doing by converting Drupal button classes to appropriate Bootstrap classes.