A list in the control panel
So far blog posts can be added only through phpMyAdmin. They should be managed by an administrator from the panel — that is what the administrator part of a component is for. It is built like the site part, but a screen has a toolbar with buttons. Let us make the first screen — the list of posts.
Files
Create four files by hand:
administrator/components/com_hello/
├── hello.xml
├── services/provider.php
├── src/
│ ├── Controller/
│ │ └── DisplayController.php
│ ├── Model/
│ │ └── PostsModel.php
│ └── View/
│ └── Posts/
│ └── HtmlView.php
└── tmpl/
└── posts/
└── default.phpNote the namespace: it has Administrator instead of Site.
The controller
// administrator/components/com_hello/src/Controller/DisplayController.php
namespace My\Component\Hello\Administrator\Controller;
defined('_JEXEC') or die;
use Joomla\CMS\MVC\Controller\BaseController;
class DisplayController extends BaseController
{
protected $default_view = 'posts';
}The model
// administrator/components/com_hello/src/Model/PostsModel.php
namespace My\Component\Hello\Administrator\Model;
defined('_JEXEC') or die;
use Joomla\CMS\MVC\Model\ListModel;
use Joomla\Database\QueryInterface;
class PostsModel extends ListModel
{
protected function getListQuery(): QueryInterface
{
$db = $this->getDatabase();
return $db->getQuery(true)
->select($db->quoteName(['id', 'title', 'published', 'created']))
->from($db->quoteName('#__hello_posts'))
->order($db->quoteName('id') . ' DESC');
}
}Unlike the site model, there is no published = 1 condition here: the administrator sees hidden posts too.
The view with a toolbar
// administrator/components/com_hello/src/View/Posts/HtmlView.php
namespace My\Component\Hello\Administrator\View\Posts;
defined('_JEXEC') or die;
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
use Joomla\CMS\Toolbar\ToolbarHelper;
class HtmlView extends BaseHtmlView
{
public array $items = [];
public function display($tpl = null): void
{
$this->items = $this->getModel()->getItems();
ToolbarHelper::title('Hello: posts');
ToolbarHelper::addNew('post.add');
parent::display($tpl);
}
}ToolbarHelper::title() sets the screen title, addNew() adds the New button. The post.add argument is the action the button submits: the add() method of the PostController controller. It appears in the next lesson.
The layout
<?php
// administrator/components/com_hello/tmpl/posts/default.php
defined('_JEXEC') or die;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Router\Route;
?>
<form action="<?php echo Route::_('index.php?option=com_hello&view=posts'); ?>"
method="post" name="adminForm" id="adminForm">
<table class="table">
<thead>
<tr>
<th>Title</th>
<th>Published</th>
<th>ID</th>
</tr>
</thead>
<tbody>
<?php foreach ($this->items as $item) : ?>
<tr>
<td>
<a href="<?php echo Route::_('index.php?option=com_hello&task=post.edit&id=' . (int) $item->id); ?>">
<?php echo $this->escape($item->title); ?>
</a>
</td>
<td><?php echo $item->published ? 'Yes' : 'No'; ?></td>
<td><?php echo (int) $item->id; ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<input type="hidden" name="task" value="">
<?php echo HTMLHelper::_('form.token'); ?>
</form>A list in the panel is always wrapped in a form named adminForm. Toolbar buttons have no forms of their own: when pressed they write their action into the hidden task field and submit this form. HTMLHelper::_('form.token') adds a hidden field with a protection token.
The result
Open Components → Hello in the panel. Instead of an error you see the "Hello: posts" screen with a table of two posts and the New button. The button and the post links still lead to an error — there is no PostController yet.
Toolbar buttons
| Call | Button |
|---|---|
ToolbarHelper::addNew('post.add') | New |
ToolbarHelper::save('post.save') | Save & Close |
ToolbarHelper::apply('post.apply') | Save |
ToolbarHelper::cancel('post.cancel') | Close |
ToolbarHelper::deleteList('', 'posts.delete') | Delete the ticked rows |
ToolbarHelper::preferences('com_hello') | Component options |
Actions on ticked rows — posts.delete, posts.publish — are handled by a list controller. It extends the ready-made AdminController class, and the table gets a column of checkboxes.
Common mistake
The form in the layout is given another name, or the hidden task field is forgotten. Toolbar buttons look for exactly the adminForm form and the task field in it — without them pressing New does nothing, and a JavaScript error appears in the browser console.