Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
278 changes: 278 additions & 0 deletions docs/php/api/list_views.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,278 @@
# List Views

List views are a generic solution for the creation of listings that are ubiquitous in the software.
In contrast to [grid views](grid_views.md), list views do not specify a particular layout.
The developer must specify a custom template that takes care of the rendering of the entries.
A list view takes care of sorting, filtering and pagination, and ensure that a lot of boilerplating becomes obsolete.

The implementation essentially offers the following advantages:
1. A uniform appearance and usability for the user.
2. An easy way for developers to create their own list views.
3. An easy way for developers to extend existing list views using plugins.

## Usage

### AbstractListView

List views obtain their data from a database object list and display it using custom template.

Example:

```php
<?php

namespace wcf\system\listView\user;

use wcf\data\DatabaseObjectList;
use wcf\system\listView\AbstractListView;
use wcf\system\WCF;

/**
* @extends AbstractListView<Example, ExampleList>
*/
class ExampleListView extends AbstractListView
{
#[\Override]
protected function createObjectList(): DatabaseObjectList
{
return new ExampleList();
}

#[\Override]
public function isAccessible(): bool
{
return true;
}

#[\Override]
public function renderItems(): string
{
return WCF::getTPL()->render('wcf', 'exampleListItems', ['view' => $this]);
}
}
```

Example `exampleListItems.tpl`:

```smarty
{foreach from=$view->getItems() item='item'}
<div class="listView__item" data-object-id="{$item->getObjectID()}">
<h2>{$item->getTitle()}</h2>
</div>
{/foreach}
```

### AbstractListViewPage

A list view can be displayed on a page by inheriting from `AbstractListViewPage`.

Example:

```php
<?php

namespace wcf\page;

use wcf\system\listView\user\ArticleListView;

/**
* @extends AbstractListViewPage<ExampleListView>
*/
class ExampleListPage extends AbstractListViewPage
{
#[\Override]
protected function createListView(): ExampleListView
{
return new ExampleListView();
}
}
```

```smarty
{include file='header'}

<div class="section">
{unsafe:$listView->render()}
</div>

{include file='footer'}
```

## Sorting

The `addAvailableSortFields` method allows you to define columns that the user can use to sort the list.
The columns must exist in the linked database object list.

```php
class ExampleListView extends AbstractListView
{
public function __construct() {
$this->addAvailableSortFields([
new ListViewSortField('time', 'wcf.global.date'),
new ListViewSortField('title', 'wcf.global.title'),
]);
}
}
```

By default, sorting is based on the `id` (first parameter) of the specified sort field.
Optionally, you can specify the name of an alternative database column to be used for sorting instead:

```php
new ListViewSortField('title', 'wcf.global.title', 'table_alias.columnName'),
```

The default sorting can be defined after the configuration of the sort fields has been defined:

```php
class ExampleListView extends AbstractListView
{
public function __construct()
{
$this->addAvailableSortFields([
new ListViewSortField('time', 'wcf.global.date'),
new ListViewSortField('title', 'wcf.global.title'),
]);

$this->setSortField('title');
$this->setSortOrder('ASC');
}
}
```

## Filtering

Filters can be defined for columns so that the user has the option to filter by the content of a column.

```php
class ExampleListView extends AbstractListView
{
public function __construct()
{
$this->addAvailableFilters([
new TextFilter('title', 'wcf.global.title'),
]);
}
}
```

## Customization

### Number of Items

By default, list views use a pagination that shows 20 items per page. You can set a custom number of items per page:

```php
class ExampleListView extends AbstractListView
{
public function __construct()
{
$this->setItemsPerPage(50);
}
}
```

There are some cases where only a list with a fixed number of items is required, for example, showcasing the 10 latests items.

```php
class ExampleListView extends AbstractListView
{
public function __construct()
{
$this->fixedNumberOfItems(10);
}
}
```

### CSS Class Names

Optionally, a CSS class can be set on the surrounding HTML element:

```php
class ExampleListView extends AbstractListView
{
public function __construct()
{
$this->setCssClassName('exampleList');
}
}
```

### Additional Parameters

A list view can be provided with additional parameters, e.g. to filter them by a specific category:

```php
class ExampleListView extends AbstractListView
{
public function __construct(public readonly int $categoryID)
{
parent::__construct();
}

#[\Override]
protected function createObjectList(): DatabaseObjectList
{
$list = new ExampleList();
$list->getConditionBuilder()->add('categoryID = ?', [$this->categoryID]);

return $list;
}

#[\Override]
public function getParameters(): array
{
return ['categoryID' => $this->categoryID];
}
}
```

```php
class ExampleListPage extends AbstractListViewPage
{
public int $categoryID = 0;

#[\Override]
public function readParameters()
{
if (isset($_REQUEST['categoryID'])) {
$this->categoryID = \intval($_REQUEST['categoryID']);
}

parent::readParameters();
}

#[\Override]
protected function createListView(): AbstractListView
{
return new ExampleListView($this->categoryID);
}

#[\Override]
protected function initListView(): void
{
parent::initListView();

$this->listView->setBaseUrl(LinkHandler::getInstance()->getControllerLink(static::class, [
'categoryID' => $this->categoryID,
]));
}
}
```

## Events

Existing list views can be modified using events.

Example of adding an additional sort field:

```php
$eventHandler->register(
\wcf\event\listView\user\ArticleListViewInitialized::class,
static function (\wcf\event\listView\user\ArticleListViewInitialized $event) {
$event->listView->addAvailableSortField(
new ListViewSortField('example', 'wcf.global.example'),
);
}
);
```
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ nav:
- 'Validation and Data': 'php/api/form_builder/validation_data.md'
- 'Dependencies': 'php/api/form_builder/dependencies.md'
- 'Grid Views': 'php/api/grid_views.md'
- 'List Views': 'php/api/list_views.md'
- 'Package Installation Plugins': 'php/api/package_installation_plugins.md'
- 'RPC API': 'php/api/rpc_api.md'
- 'User Activity Events': 'php/api/user_activity_events.md'
Expand Down