7
Let's roll this back a little bit, and examine what has changed and why.
As we worked on 2.5.9, a lot of effort when in to standardizing the display of system generated elements, and a special emphasis was given to Bootstrap based themes. Older modules, designed and coded long before there was a bootstrap framework, generally looked terrible. To be blunt, it generally looked like crap. The most common reason was due to bringing in CSS that was incompatible, causing serious visual breakage.
Newer modules, designed with bootstrap in mind, looked OK, but many themes came with a set of hacks to apply to the system and modules to fix some problems. Templates manipulated generated HTML to change elements, as well as add or remove attributes to make certain modules look better.
The problem was, not each theme had the same set of changes. So, each time a module was updated, different themes would break. If a module was reworked to look good under bootstrap, it broke when used with older themes.
The big problem, when we looked at it, was that PHP code (domain logic) was setting style attributes (presentation details,) and there was no way to override PHP code by theme. If it is set in the PHP code side, there is no way to know how the theme will interpret it. Some frameworks, such as Bootstrap, feature semantic classes rather than just visual classes, and that is good, but those semantics are unique to Bootstrap, and even specific versions of Bootstrap. Further, while Bootstrap enjoys wide adoption, it is far from the only scaffolding, and many find fault with it. If we code core to Bootstrap, we severely limit ourselves.
XOOPS inherently has a separation between logic, data and presentation. The Smarty template engine makes it possible to build a set of data in a PHP program that is passed to the engine, where the set of data is merged with a set of templates that control how the data is presented, and how it looks. XOOPS provides for themes which can override the templates provided by the module.
There are, unfortunately, places where PHP code belches out raw HTML, and thus becomes involved in the visual presentation aspects. The biggest example of those was the form elements. All the form element rendering was stripped out into classes implementing the \XoopsFormRendererInterface. The exact renderer used can be controlled by or overridden by the theme by specifying a theme_autorun.php file.
To achieve the goal of a consistent look and feel it was necessary to ignore the class attributes, managed by the FormElement::setClass() method. The existence of that method violates that separation between logic and presentation. It might be possible to whitelist a set of allowable classes, but to make that work across all themes, we would have to dictate our own intermediate set of semantic classes, and translate those in the renderer. Just to understand the scope of that effor, Bootstrap is now a version 4 of their semantics, and it is still evolving. The setClass() and getClass() methods are relics, and should have been marked a deprecated. They open a set of problems that cannot be fixed.
But, that doesn't mean all hope is gone. The solution to the missing setClass() is simple -- do it in the theme!
There should be a template where the form is displayed. Within that template, you can address each form element by its ID, so a script section can easily set any desired attribute, including class. Add a comment or two about why these are needed, and you make a template that others can easily adapt for any CSS framework. And it is all in the control of the theme, not some chunk of PHP code that needs to be hacked again and again over time.
It is just a growing pain.