Skip to content

Commit e926c7e

Browse files
committed
Document list views
Closes #510
1 parent 1246891 commit e926c7e

File tree

2 files changed

+280
-0
lines changed

2 files changed

+280
-0
lines changed

docs/php/api/list_views.md

Lines changed: 279 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,279 @@
1+
# List Views
2+
3+
List views are a generic solution for the creation of listings that are ubiquitous in the software.
4+
In contrast to [grid views](grid_views.md), list views do not specify a particular layout.
5+
The developer must specify a custom template that takes care of the rendering of the entries.
6+
A list view takes care of sorting, filtering and pagination, and ensure that a lot of boilerplating becomes obsolete.
7+
8+
The implementation essentially offers the following advantages:
9+
1. A uniform appearance and usability for the user.
10+
2. An easy way for developers to create their own list views.
11+
3. An easy way for developers to extend existing list views using plugins.
12+
13+
## Usage
14+
15+
### AbstractListView
16+
17+
List views obtain their data from a database object list and display it using custom template.
18+
19+
Example:
20+
21+
```php
22+
<?php
23+
24+
namespace wcf\system\listView\user;
25+
26+
use wcf\data\DatabaseObjectList;
27+
use wcf\system\listView\AbstractListView;
28+
use wcf\system\WCF;
29+
30+
class ExampleListView extends AbstractListView
31+
{
32+
#[\Override]
33+
protected function createObjectList(): DatabaseObjectList
34+
{
35+
return new ExampleList();
36+
}
37+
38+
#[\Override]
39+
public function isAccessible(): bool
40+
{
41+
return true;
42+
}
43+
44+
#[\Override]
45+
public function renderItems(): string
46+
{
47+
return WCF::getTPL()->render('wcf', 'exampleListItems', ['view' => $this]);
48+
}
49+
}
50+
```
51+
52+
Example `exampleListItems.tpl`:
53+
54+
```smarty
55+
{foreach from=$view->getItems() item='item'}
56+
<div class="listView__item" data-object-id="{$item->getObjectID()}">
57+
<h2>{$item->getTitle()}</h2>
58+
</div>
59+
{/foreach}
60+
```
61+
62+
### AbstractListViewPage
63+
64+
A list view can be displayed on a page by inheriting from `AbstractListViewPage`.
65+
66+
Example:
67+
68+
```php
69+
<?php
70+
71+
namespace wcf\page;
72+
73+
use wcf\system\listView\user\ArticleListView;
74+
75+
class ExampleListPage extends AbstractListViewPage
76+
{
77+
#[\Override]
78+
protected function createListView(): ExampleListView
79+
{
80+
return new ExampleListView();
81+
}
82+
}
83+
```
84+
85+
```smarty
86+
{include file='header'}
87+
88+
<div class="section">
89+
{unsafe:$listView->render()}
90+
</div>
91+
92+
{include file='footer'}
93+
```
94+
95+
## Sorting
96+
97+
The `addAvailableSortFields` method allows you to define columns that the user can use to sort the list.
98+
The columns must exist in the linked database object list.
99+
100+
```php
101+
class ExampleListView extends AbstractListView
102+
{
103+
public function __construct() {
104+
$this->addAvailableSortFields([
105+
new ListViewSortField('time', 'wcf.global.date'),
106+
new ListViewSortField('title', 'wcf.global.title'),
107+
]);
108+
}
109+
}
110+
```
111+
112+
By default, sorting is based on the `id` (first parameter) of the specified sort field.
113+
Optionally, you can specify the name of an alternative database column to be used for sorting instead:
114+
115+
```php
116+
new ListViewSortField('title', 'wcf.global.title', 'table_alias.columnName'),
117+
```
118+
119+
The default sorting can be defined after the configuration of the sort fields has been defined:
120+
121+
```php
122+
class ExampleListView extends AbstractListView
123+
{
124+
public function __construct()
125+
{
126+
$this->addAvailableSortFields([
127+
new ListViewSortField('time', 'wcf.global.date'),
128+
new ListViewSortField('title', 'wcf.global.title'),
129+
]);
130+
131+
$this->setSortField('title');
132+
$this->setSortOrder('ASC');
133+
}
134+
}
135+
```
136+
137+
## Filtering
138+
139+
Filters can be defined for columns so that the user has the option to filter by the content of a column.
140+
141+
```php
142+
class ExampleListView extends AbstractListView
143+
{
144+
public function __construct()
145+
{
146+
$this->addAvailableFilters([
147+
new TextFilter('title', 'wcf.global.title'),
148+
]);
149+
}
150+
}
151+
```
152+
153+
## Customization
154+
155+
### Number of Items
156+
157+
By default, list views use a pagination that shows 20 items per page. You can set a custom number of items per page:
158+
159+
```php
160+
class ExampleListView extends AbstractListView
161+
{
162+
public function __construct()
163+
{
164+
$this->setItemsPerPage(50);
165+
}
166+
}
167+
```
168+
169+
There are some cases where only a list with a fixed number of items is required, for example, showcasing the 10 latests items.
170+
171+
```php
172+
class ExampleListView extends AbstractListView
173+
{
174+
public function __construct()
175+
{
176+
$this->fixedNumberOfItems(10);
177+
}
178+
}
179+
```
180+
181+
### CSS Class Names
182+
183+
Optionally, a CSS class can be set on the surrounding HTML element:
184+
185+
```php
186+
class ExampleListView extends AbstractListView
187+
{
188+
public function __construct()
189+
{
190+
$this->setCssClassName('exampleList');
191+
}
192+
}
193+
```
194+
195+
### Additional Parameters
196+
197+
A list view can be provided with additional parameters, e.g. to filter them by a specific category:
198+
199+
```php
200+
class ExampleListView extends AbstractListView
201+
{
202+
public function __construct(public readonly int $categoryID)
203+
{
204+
parent::__construct();
205+
}
206+
207+
#[\Override]
208+
protected function createObjectList(): DatabaseObjectList
209+
{
210+
$list = new ExampleList();
211+
$list->getConditionBuilder()->add('categoryID = ?', [$this->categoryID]);
212+
213+
return $list;
214+
}
215+
216+
#[\Override]
217+
public function getParameters(): array
218+
{
219+
return ['categoryID' => $this->categoryID];
220+
}
221+
}
222+
```
223+
224+
```php
225+
<?php
226+
227+
namespace wcf\page;
228+
229+
use wcf\system\listView\AbstractListView;
230+
use wcf\system\request\LinkHandler;
231+
232+
class ExampleListPage extends AbstractListViewPage
233+
{
234+
public int $categoryID = 0;
235+
236+
#[\Override]
237+
public function readParameters()
238+
{
239+
if (isset($_REQUEST['categoryID'])) {
240+
$this->categoryID = \intval($_REQUEST['categoryID']);
241+
}
242+
243+
parent::readParameters();
244+
}
245+
246+
#[\Override]
247+
protected function createListView(): AbstractListView
248+
{
249+
return new ExampleListView($this->categoryID);
250+
}
251+
252+
#[\Override]
253+
protected function initListView(): void
254+
{
255+
parent::initListView();
256+
257+
$this->listView->setBaseUrl(LinkHandler::getInstance()->getControllerLink(static::class, [
258+
'categoryID' => $this->categoryID,
259+
]));
260+
}
261+
}
262+
```
263+
264+
## Events
265+
266+
Existing list views can be modified using events.
267+
268+
Example of adding an additional sort field:
269+
270+
```php
271+
$eventHandler->register(
272+
\wcf\event\listView\user\ArticleListViewInitialized::class,
273+
static function (\wcf\event\listView\user\ArticleListViewInitialized $event) {
274+
$event->listView->addAvailableSortField(
275+
new ListViewSortField('example', 'wcf.global.example'),
276+
);
277+
}
278+
);
279+
```

mkdocs.yml

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

0 commit comments

Comments
 (0)