Skip to content

Commit 25525ad

Browse files
authored
Merge pull request #521 from WoltLab/6.2-grid-views
Document Grid views
2 parents fbb0dd3 + f6e3755 commit 25525ad

File tree

2 files changed

+354
-0
lines changed

2 files changed

+354
-0
lines changed

docs/php/api/grid_views.md

Lines changed: 353 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,353 @@
1+
# Grid Views
2+
3+
Grid views are a generic solution for the creation of listings that are ubiquitous in the software.
4+
In addition to rendering, the grid view also take care of sorting, filtering and pagination, and ensure that a lot of boilerplating becomes obsolete.
5+
6+
The implementation essentially offers the following advantages:
7+
1. A uniform appearance and usability for the user.
8+
2. An easy way for developers to create their own grid views.
9+
3. An easy way for developers to extend existing grid views using plugins.
10+
11+
## Usage
12+
13+
### AbstractGridView
14+
15+
Grid views obtain their data from a database object list and display it using a defined column configuration.
16+
17+
Example:
18+
19+
```php
20+
<?php
21+
22+
namespace wcf\system\gridView\admin;
23+
24+
use wcf\data\DatabaseObjectList;
25+
use wcf\system\gridView\AbstractGridView;
26+
use wcf\system\gridView\GridViewColumn;
27+
use wcf\system\gridView\renderer\ObjectIdColumnRenderer;
28+
29+
final class ExampleGridView extends AbstractGridView
30+
{
31+
public function __construct()
32+
{
33+
$this->addColumns([
34+
GridViewColumn::for('id')
35+
->label('wcf.global.objectID')
36+
->renderer(new ObjectIdColumnRenderer())
37+
->sortable(),
38+
GridViewColumn::for('title')
39+
->label('wcf.global.title')
40+
->sortable()
41+
->titleColumn()
42+
]);
43+
}
44+
45+
#[\Override]
46+
public function isAccessible(): bool
47+
{
48+
return true;
49+
}
50+
51+
#[\Override]
52+
protected function createObjectList(): DatabaseObjectList
53+
{
54+
return new ExampleDatabaseObjectList();
55+
}
56+
}
57+
```
58+
59+
### AbstractGridViewPage
60+
61+
A grid view can be displayed on a page by inheriting from `AbstractGridViewPage`.
62+
63+
Example:
64+
65+
```php
66+
<?php
67+
68+
namespace wcf\acp\page;
69+
70+
use wcf\page\AbstractGridViewPage;
71+
72+
final class ExampleListPage extends AbstractGridViewPage
73+
{
74+
#[\Override]
75+
protected function createGridView(): AbstractGridView
76+
{
77+
return new ExampleGridView();
78+
}
79+
}
80+
```
81+
82+
```smarty
83+
{include file='header'}
84+
85+
<div class="section">
86+
{unsafe:$gridView->render()}
87+
</div>
88+
89+
{include file='footer'}
90+
```
91+
92+
## Columns
93+
94+
Columns can be created using the `GridViewColumn::for` method. This expects a unique string as a parameter, which is equivalent to the corresponding key in the data source.
95+
96+
The `label` method can be used to give the column a human readable label.
97+
98+
Example:
99+
100+
```php
101+
final class FooGridView extends AbstractGridView
102+
{
103+
public function __construct()
104+
{
105+
$this->addColumns([
106+
GridViewColumn::for('id')
107+
->label('wcf.global.objectID'),
108+
GridViewColumn::for('name')
109+
->label('wcf.global.name'),
110+
]);
111+
}
112+
}
113+
```
114+
115+
### Renderer
116+
117+
Renderers can be applied to columns to format the output. A column can have multiple renderers. The renderers are applied in the order in which they were set.
118+
119+
```php
120+
GridViewColumn::for('foo')
121+
->renderer([
122+
new FooColumnRenderer(),
123+
new BarColumnRenderer(),
124+
])
125+
```
126+
127+
#### CategoryColumnRenderer
128+
129+
`CategoryColumnRenderer` can be set to columns that contain the ID of categories. This results in the name of the category being output.
130+
131+
#### CurrencyColumnRenderer
132+
133+
`CurrencyColumnRenderer` formats the content of a column as a currency. Expects the content of the column to be a decimal.
134+
135+
Example:
136+
137+
```php
138+
GridViewColumn::for('foo')
139+
->renderer(new CurrencyColumnRenderer('EUR'))
140+
```
141+
142+
#### DefaultColumnRenderer
143+
144+
The `DefaultColumnRenderer` is implicitly applied to all columns unless one ore more renderers have been explicitly set.
145+
146+
#### EmailColumnRenderer
147+
148+
`EmailColumnRenderer` formats the content of the column as an email address.
149+
150+
#### FilesizeColumnRenderer
151+
152+
`FilesizeColumnRenderer` formats the content of the column as a file size.
153+
154+
#### IpAddressColumnRenderer
155+
156+
`IpAddressColumnRenderer` outputs the value by attempting to interpret it as IPv4 if possible, otherwise shows the IPv6 address.
157+
158+
#### LinkColumnRenderer
159+
160+
`LinkColumnRenderer` allows the setting of a link to a column.
161+
162+
Example:
163+
164+
```php
165+
GridViewColumn::for('foo')
166+
->renderer(new LinkColumnRenderer(FooEditForm::class))
167+
```
168+
169+
#### NumberColumnRenderer
170+
171+
`NumberColumnRenderer` formats the content of a column as a number using `StringUtil::formatNumeric()`.
172+
173+
#### ObjectIdColumnRenderer
174+
175+
`ObjectIdColumnRenderer` formats the content of a column as an object id.
176+
177+
#### PhraseColumnRenderer
178+
179+
`PhraseColumnRenderer` attempts to evaluate the value as a phrase and outputs it as plain text otherwise.
180+
181+
#### TimeColumnRenderer
182+
183+
`TimeColumnRenderer` renders a unix timestamp into a human readable format.
184+
185+
#### TruncatedTextColumnRenderer
186+
187+
`TruncatedTextColumnRenderer` truncates the content of a column to a length of 80 characters (default value).
188+
189+
#### UserColumnRenderer
190+
191+
`UserColumnRenderer` formats the content of a column as a user.
192+
193+
#### UserLinkColumnRenderer
194+
195+
`UserLinkColumnRenderer` is a combination of the `UserColumnRenderer` and the `LinkColumnRenderer`.
196+
197+
Example:
198+
199+
```php
200+
GridViewColumn::for('foo')
201+
->renderer(new UserLinkColumnRenderer(FooEditForm::class))
202+
```
203+
204+
### Custom Renderer
205+
206+
If necessary, you can define your own renderers:
207+
208+
```php
209+
GridViewColumn::for('id')
210+
->renderer([
211+
new class extends DefaultColumnRenderer {
212+
public function render(mixed $value, DatabaseObject $row): string
213+
{
214+
return 'foo: ' . $value;
215+
}
216+
},
217+
]),
218+
```
219+
220+
### Row Link
221+
222+
A row link applies a link to every column in the grid.
223+
224+
```php
225+
final class FooGridView extends AbstractGridView
226+
{
227+
public function __construct()
228+
{
229+
$this->addRowLink(new GridViewRowLink(FooEditForm::class));
230+
}
231+
}
232+
```
233+
234+
The constructor supports 3 optional parameters:
235+
1. `string $controllerClass`: The controller to which the link should refer.
236+
2. `array $parameters`: Additional parameters for the controller.
237+
3. `string $cssClass`: CSS class for the link.
238+
239+
### Sorting
240+
241+
Columns can be marked as sortable so that the user has the option of sorting according to the content of the column.
242+
243+
```php
244+
GridViewColumn::for('foo')
245+
->sortable()
246+
```
247+
248+
By default, sorting is based on the `id` of the column.
249+
Optionally, you can specify the name of an alternative database column to be used for sorting instead:
250+
251+
```php
252+
GridViewColumn::for('foo')
253+
->sortable(sortByDatabaseColumn: "table_alias.columnName")
254+
```
255+
256+
The default sorting can be defined after the column configuration has been defined:
257+
258+
```php
259+
final class FooGridView extends AbstractGridView
260+
{
261+
public function __construct()
262+
{
263+
GridViewColumn::for('title')
264+
->sortable();
265+
266+
$this->setSortField('title');
267+
$this->setSortOrder('ASC');
268+
}
269+
}
270+
```
271+
272+
### Filtering
273+
274+
Filters can be defined for columns so that the user has the option to filter by the content of a column.
275+
276+
```php
277+
GridViewColumn::for('foo')
278+
->filter(new FooFilter())
279+
```
280+
281+
#### BooleanFilter
282+
283+
`BooleanFilter` is a filter for columns that contain boolean values (`1` or `0`).
284+
285+
#### CategoryFilter
286+
287+
`CategoryFilter` is a filter for columns that contain category ids.
288+
289+
```php
290+
GridViewColumn::for('categoryID')
291+
->filter(new CategoryFilter((new CategoryNodeTree('identifier'))->getIterator()))
292+
```
293+
294+
#### I18nTextFilter
295+
296+
`I18nTextFilter` is a filter for text columns that are using i18n phrases.
297+
298+
#### IpAddressFilter
299+
300+
`IpAddressFilter` is a filter for columns that contain IPv6 addresses, allowing the user to enter addresses in the IPv4 format too.
301+
302+
#### NumericFilter
303+
304+
`NumericFilter` is a filter for columns that contain numeric values.
305+
306+
#### ObjectIdFilter
307+
308+
`ObjectIdFilter` is a filter for columns that contain object ids.
309+
310+
#### SelectFilter
311+
312+
`SelectFilter` allows a column to be filtered on the basis of a select dropdown.
313+
314+
```php
315+
GridViewColumn::for('foo')
316+
->filter(new SelectFilter([
317+
1 => 'value 1',
318+
0 => 'value 0',
319+
]));
320+
```
321+
322+
#### TextFilter
323+
324+
`TextFilter` is a filter for text columns.
325+
326+
#### TimeFilter
327+
328+
`TimeFilter` is a filter for columns that contain unix timestamps.
329+
330+
#### UserFilter
331+
332+
`UserFilter` is a filter for columns that contain user ids.
333+
334+
### Events
335+
336+
Existing grid views can be modified using events.
337+
338+
Example of adding an additional column:
339+
340+
```php
341+
$eventHandler->register(
342+
\wcf\event\gridView\UserRankGridViewInitialized::class,
343+
static function (\wcf\event\gridView\UserRankGridViewInitialized $event) {
344+
$event->gridView->addColumnBefore(
345+
GridViewColumn::for('hideTitle')
346+
->label('hideTitle')
347+
->renderer(new NumberColumnRenderer())
348+
->sortable(),
349+
'requiredPoints'
350+
);
351+
}
352+
);
353+
```

mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ nav:
3939
- 'Fields': 'php/api/form_builder/form_fields.md'
4040
- 'Validation and Data': 'php/api/form_builder/validation_data.md'
4141
- 'Dependencies': 'php/api/form_builder/dependencies.md'
42+
- 'Grid Views': 'php/api/grid_views.md'
4243
- 'Package Installation Plugins': 'php/api/package_installation_plugins.md'
4344
- 'RPC API': 'php/api/rpc_api.md'
4445
- 'User Activity Events': 'php/api/user_activity_events.md'

0 commit comments

Comments
 (0)