Project

General

Profile

Renderer Refactoring » History » Version 10

Philipp Gröbelbauer, 12.06.2024 12:29

1 1 Philipp Gröbelbauer
h1. Renderer Refactoring
2
3 8 Philipp Gröbelbauer
{{toc}}
4 7 Philipp Gröbelbauer
5 1 Philipp Gröbelbauer
Branch: https://git.math.uzh.ch/typo3/qfq/-/tree/F17252_Renderer_Refactoring
6
7
h2. Motivation
8 2 Philipp Gröbelbauer
9 1 Philipp Gröbelbauer
To achieve a more modern look and feel, QFQ Forms should support Bootstrap 5 in addition to the previously used Bootstrap 3.
10
However, implementing this functionality into the current codebase while still practicing "clean code" is not possible.
11
Therefore the current code is being refactored to support future expansion.
12
13
h2. Concept
14 2 Philipp Gröbelbauer
15 1 Philipp Gröbelbauer
Previously, preparation and rendering of the form with all its form elements was handled in AbstractBuildForm.php and BuildFormBootstrap.php.
16
The new concept introduces many new classes, making the code much more modular.
17
Most notably: *Separating Configuration and Rendering of Form and FormElements* !
18
By doing this, new Renderer Classes can be implemented in the future, which use the same AbstractFormElement objects to render the element in a different way (e.g. Bootstrap 5).
19
20 4 Philipp Gröbelbauer
h3. Class diagram
21 1 Philipp Gröbelbauer
22 4 Philipp Gröbelbauer
See the class diagram below:
23
24 1 Philipp Gröbelbauer
!renderer_class_diagram_update_2024.drawio.png!
25 4 Philipp Gröbelbauer
26
h3. Sequence Diagram Form and FormElement Instantiation
27
28
tbd
29
30
h3. Sequence Diagram Rendering
31
32
The diagram below describes the rendering process.
33
34
* The BaseRenderer (or any specific implementation of it) takes the previously instantiated Form object that describes all aspects of the form that is to be rendered.
35
36 6 Philipp Gröbelbauer
!renderer_sequence_diagram_update_2024.drawio.png!
37 9 Philipp Gröbelbauer
38
39
h2. Dev Guide
40
41
This section should answer common questions on how to use the refactored code and how to expand upon it.
42
43
h3. Adding a New Form Element
44
45
This chapter describes how new form elements can be added into QFQ in the new model.
46
In this example we are assuming a new FormElement "Chat" should be implemented in QFQ.
47
Follow these steps:
48
49 10 Philipp Gröbelbauer
h4. Create a FormElement class
50
51
Create a new class ChatFormElement in the folder Core>Form>FormElement.
52 9 Philipp Gröbelbauer
This class needs to extend AbstractFormElement and should call the parent's construct method when instantiated, as seen in the screenshot below.
53
If the form element you want to introduce is a ContainerFormElement, then extend ContainerFormElement instead of AbstractFormElement!
54
55 1 Philipp Gröbelbauer
!clipboard-202406121148-aqvlm.png!
56
57 10 Philipp Gröbelbauer
The job of this class is to prepare and process all data that is needed to display the element.
58
*This class must not return any HTML or make assumptions about the way in which the element will be displayed! It exists completely outside of the choice of BS3/BS5/etc.*
59
60
Preparation and processing of data can be done after calling parent::process.
61
62
63
h4. Add the new class to FeFactory
64
65
Add a new CASE block to the SWITCH statement in FeFactory.php.
66 9 Philipp Gröbelbauer
This way the factory will return an object of your newly created class when needed.
67 1 Philipp Gröbelbauer
It is best to add a new constant in Constants.php that defines the new FE type. In this example the constant FE_TYPE_CHAT is simply defined as 'chat'.
68
69
!clipboard-202406121152-vlscn.png!
70
71 10 Philipp Gröbelbauer
h4. Set up the BaseRenderer
72
73
Create a class ChatRenderer in the folder Core>Renderer>FormElement>Base.
74
It needs to extend the class FormElementRenderer.
75
This new class is supposed to render a chat element completely independent of the used CSS Framework.
76 1 Philipp Gröbelbauer
In practice, this class might stay empty.
77
78
!clipboard-202406121158-y2gwo.png!
79 10 Philipp Gröbelbauer
80
Next up, *edit the file Core>Renderer>FormElement>BaseRenderer.php* .
81
82
Add a new protected field "chatRenderer" of type ?FormElementRenderer to it.
83
!clipboard-202406121208-jwvbi.png!
84
85
In the constructor of BaseRenderer, instantiate an object ob your previously created ChatRenderer class and assign it to the new field.
86
87
!clipboard-202406121212-07qxh.png!
88
89
In the SWITCH statement of the renderFormElement function, add a new CASE block for your new FE.
90
This ensures that the BaseRenderer will be using your ChatRenderer class to render objects of the type ChatFormElement.
91
92
!clipboard-202406121213-kzi43.png!
93
94
95
96
h4. Create Specific Renderers
97
98
The Chat Form Element will have the same look