Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feature(views): lists can be rendered as tables
The list view functions now accept `table` as a `list_type` value. This outputs a bordered, one-column table with no headings. Columns and their headings are specified via `Elgg\Views\TableColumn` objects. The `ColumnFactory` class (accessible via `elgg()->table_columns`) includes methods for creating columns based on core views, or properties/methods. Newest users admin page now shows other useful info Fixes Elgg#9629
- Loading branch information
Showing
25 changed files
with
698 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
<?php | ||
namespace Elgg\Views; | ||
|
||
/** | ||
* A renderer for a column of table cells and a header | ||
*/ | ||
interface TableColumn { | ||
|
||
/** | ||
* Get the rendered heading cell. Cell will be auto-wrapped with a TH element if the | ||
* returned string doesn't begin with "<th" or "<td". | ||
* | ||
* @return string e.g. "Title" or "<th>Title</th>" | ||
*/ | ||
public function renderHeading(); | ||
|
||
/** | ||
* Render a value cell. Cell will be auto-wrapped with a TD element if the returned | ||
* string doesn't begin with "<th" or "<td". | ||
* | ||
* @param mixed $item Object/row from which to pull the value | ||
* @param string $type Type of object | ||
* @param array $item_vars Parameters from the listing function | ||
* | ||
* @return string e.g. "My Great Title" or "<td>My Great Title</td>" | ||
*/ | ||
public function renderCell($item, $type, $item_vars); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
<?php | ||
namespace Elgg\Views\TableColumn; | ||
|
||
use Elgg\Views\TableColumn; | ||
|
||
/** | ||
* Table column rendered by a function | ||
*/ | ||
class CallableColumn implements TableColumn { | ||
|
||
/** | ||
* @var string | ||
*/ | ||
private $heading; | ||
|
||
/** | ||
* @var callable | ||
*/ | ||
private $renderer; | ||
|
||
/** | ||
* Constructor | ||
* | ||
* @param callable $renderer Rendering function | ||
* @param string $heading Heading | ||
*/ | ||
public function __construct(callable $renderer, $heading) { | ||
$this->renderer = $renderer; | ||
$this->heading = $heading; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function renderHeading() { | ||
return $this->heading; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function renderCell($item, $type, $item_vars) { | ||
return call_user_func($this->renderer, $item, $type, $item_vars); | ||
} | ||
} |
145 changes: 145 additions & 0 deletions
145
engine/classes/Elgg/Views/TableColumn/ColumnFactory.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
<?php | ||
namespace Elgg\Views\TableColumn; | ||
|
||
use Elgg\Values; | ||
use Elgg\Views\TableColumn; | ||
|
||
/** | ||
* Factory for table column objects | ||
* | ||
* @internal Use elgg()->table_columns to access the instance of this. | ||
* | ||
* @method TableColumn admin($heading = null, $vars = []) | ||
* @method TableColumn banned($heading = null, $vars = []) | ||
* @method TableColumn container($heading = null, $vars = []) | ||
* @method TableColumn excerpt($heading = null, $vars = []) | ||
* @method TableColumn icon($heading = null, $vars = []) | ||
* @method TableColumn item($heading = null, $vars = []) | ||
* @method TableColumn language($heading = null, $vars = []) | ||
* @method TableColumn link($heading = null, $vars = []) | ||
* @method TableColumn owner($heading = null, $vars = []) | ||
* @method TableColumn time_created($heading = null, $vars = []) | ||
* @method TableColumn time_updated($heading = null, $vars = []) | ||
* @method TableColumn description($heading = null) | ||
* @method TableColumn email($heading = null) | ||
* @method TableColumn name($heading = null) | ||
* @method TableColumn type($heading = null) | ||
* @method TableColumn username($heading = null) | ||
* @method TableColumn getSubtype($heading = null) | ||
* @method TableColumn getDisplayName($heading = null) | ||
* @method TableColumn getMimeType($heading = null) | ||
* @method TableColumn getSimpleType($heading = null) | ||
*/ | ||
class ColumnFactory { | ||
|
||
/** | ||
* Make a column from one of the page/components/column/* views. | ||
* | ||
* @param string $name Column name (view will be "page/components/column/$name") | ||
* @param string $heading Optional heading | ||
* @param array $vars View vars (item, item_vars, and type will be merged in) | ||
* | ||
* @return ViewColumn | ||
*/ | ||
public function fromView($name, $heading = null, $vars = []) { | ||
$view = "page/components/column/$name"; | ||
|
||
if (!is_string($heading)) { | ||
if (elgg_language_key_exists("table_columns:fromView:$name")) { | ||
$heading = elgg_echo("table_columns:fromView:$name"); | ||
} else { | ||
$title = str_replace('_', ' ', $name); | ||
$heading = elgg_ucwords($title); | ||
} | ||
} | ||
|
||
return new ViewColumn($view, $heading, $vars); | ||
} | ||
|
||
/** | ||
* Make a column by reading a property of the item | ||
* | ||
* @param string $name Property name. e.g. "description", "email", "type" | ||
* @param string $heading Heading | ||
* | ||
* @return CallableColumn | ||
*/ | ||
public function fromProperty($name, $heading = null) { | ||
if (!is_string($heading)) { | ||
if (elgg_language_key_exists("table_columns:fromProperty:$name")) { | ||
$heading = elgg_echo("table_columns:fromProperty:$name"); | ||
} else { | ||
$title = str_replace('_', ' ', $name); | ||
$heading = elgg_ucwords($title); | ||
} | ||
} | ||
|
||
$renderer = function ($item) use ($name) { | ||
return $item->{$name}; | ||
}; | ||
|
||
return new CallableColumn($renderer, $heading); | ||
} | ||
|
||
/** | ||
* Make a column by calling a method on the item | ||
* | ||
* @param string $name Method name. e.g. "getSubtype", "getDisplayName" | ||
* @param string $heading Heading | ||
* @param array $args Method arguments | ||
* | ||
* @return CallableColumn | ||
*/ | ||
public function fromMethod($name, $heading = null, $args = []) { | ||
if (!is_string($heading)) { | ||
if (elgg_language_key_exists("table_columns:fromMethod:$name")) { | ||
$heading = elgg_echo("table_columns:fromMethod:$name"); | ||
} else { | ||
$title = str_replace('_', ' ', $name); | ||
$heading = elgg_ucwords($title); | ||
} | ||
} | ||
|
||
$renderer = function ($item) use ($name, $args) { | ||
return call_user_func_array([$item, $name], $args); | ||
}; | ||
|
||
return new CallableColumn($renderer, $heading); | ||
} | ||
|
||
/** | ||
* Handle undefined method calls | ||
* | ||
* @param string $name Method name | ||
* @param array $arguments Arguments | ||
* @return mixed | ||
*/ | ||
public function __call($name, $arguments) { | ||
// allow hook to hijack magic methods | ||
$column = elgg_trigger_plugin_hook('table_columns:call', $name, [ | ||
'arguments' => $arguments, | ||
]); | ||
if ($column instanceof TableColumn) { | ||
return $column; | ||
} | ||
|
||
if (elgg_language_key_exists("table_columns:fromView:$name")) { | ||
array_unshift($arguments, $name); | ||
return call_user_func_array([$this, 'fromView'], $arguments); | ||
} | ||
|
||
if (elgg_language_key_exists("table_columns:fromProperty:$name")) { | ||
array_unshift($arguments, $name); | ||
return call_user_func_array([$this, 'fromProperty'], $arguments); | ||
} | ||
|
||
if (elgg_language_key_exists("table_columns:fromMethod:$name")) { | ||
array_unshift($arguments, $name); | ||
return call_user_func_array([$this, 'fromMethod'], $arguments); | ||
} | ||
|
||
// empty column and error | ||
_elgg_services()->logger->error(__CLASS__ . ": No method defined '$name'"); | ||
return new CallableColumn([Values::class, 'getNull'], ''); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
<?php | ||
namespace Elgg\Views\TableColumn; | ||
|
||
use Elgg\Views\TableColumn; | ||
|
||
/** | ||
* Table column rendered by a view | ||
*/ | ||
class ViewColumn implements TableColumn { | ||
|
||
/** | ||
* @var string | ||
*/ | ||
private $heading; | ||
|
||
/** | ||
* @var string | ||
*/ | ||
private $view; | ||
|
||
/** | ||
* @var array | ||
*/ | ||
private $vars; | ||
|
||
/** | ||
* Constructor | ||
* | ||
* @param string $view The view to render the value | ||
* @param string $heading Heading | ||
* @param array $vars Vars to merge into the view vars | ||
*/ | ||
public function __construct($view, $heading = null, $vars = []) { | ||
$this->view = $view; | ||
$this->vars = $vars; | ||
|
||
if (!is_string($heading)) { | ||
$heading = elgg_echo("ViewColumn:view:$view"); | ||
} | ||
$this->heading = $heading; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function renderHeading() { | ||
return $this->heading; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function renderCell($item, $type, $item_vars) { | ||
$vars = $this->vars + [ | ||
'item' => $item, | ||
'item_vars' => $item_vars, | ||
'type' => $type, | ||
]; | ||
|
||
return elgg_view($this->view, $vars); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
|
||
.elgg-newest-users td + td { | ||
white-space: nowrap; | ||
} |
Oops, something went wrong.