From e926c7ea829652c136e259243d557b511722ba48 Mon Sep 17 00:00:00 2001 From: Marcel Werk Date: Tue, 17 Jun 2025 15:47:50 +0200 Subject: [PATCH 1/2] Document list views Closes #510 --- docs/php/api/list_views.md | 279 +++++++++++++++++++++++++++++++++++++ mkdocs.yml | 1 + 2 files changed, 280 insertions(+) create mode 100644 docs/php/api/list_views.md diff --git a/docs/php/api/list_views.md b/docs/php/api/list_views.md new file mode 100644 index 000000000..eee6635de --- /dev/null +++ b/docs/php/api/list_views.md @@ -0,0 +1,279 @@ +# 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 +render('wcf', 'exampleListItems', ['view' => $this]); + } +} +``` + +Example `exampleListItems.tpl`: + +```smarty +{foreach from=$view->getItems() item='item'} +
+

{$item->getTitle()}

+
+{/foreach} +``` + +### AbstractListViewPage + +A list view can be displayed on a page by inheriting from `AbstractListViewPage`. + +Example: + +```php + + {unsafe:$listView->render()} + + +{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 +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'), + ); + } +); +``` diff --git a/mkdocs.yml b/mkdocs.yml index f77b2c553..69e83ca04 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -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' From 49eb198c89c2584ffa72ecb963a8c508723eec47 Mon Sep 17 00:00:00 2001 From: Marcel Werk Date: Wed, 25 Jun 2025 12:12:21 +0200 Subject: [PATCH 2/2] Apply suggestions from code review --- docs/php/api/list_views.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/docs/php/api/list_views.md b/docs/php/api/list_views.md index eee6635de..1b8853c46 100644 --- a/docs/php/api/list_views.md +++ b/docs/php/api/list_views.md @@ -27,6 +27,9 @@ use wcf\data\DatabaseObjectList; use wcf\system\listView\AbstractListView; use wcf\system\WCF; +/** + * @extends AbstractListView + */ class ExampleListView extends AbstractListView { #[\Override] @@ -72,6 +75,9 @@ namespace wcf\page; use wcf\system\listView\user\ArticleListView; +/** + * @extends AbstractListViewPage + */ class ExampleListPage extends AbstractListViewPage { #[\Override] @@ -222,13 +228,6 @@ class ExampleListView extends AbstractListView ``` ```php -