Creating a backend list and edit form for custom data

In this article you learn how to create backend lists and forms for admins to manage custom data. You will learn how a controller, model, list view and form view play together and how to write the classes and templates for each. This is described in a step-by-step tutorial and on the sub-pages you find detailled information of each concept.

Note: Upgrade to CB 3.3.3 (Wordpress/Joomla) or CB 3.3.12 (Magento 2) to make use of the properties. Naming of KenedoProperty settings have changed (old names are upward-compatible) and the documentation uses the new names only.

Create a menu in the backend

The left-hand side menu in CB is handled by the view adminmainmenu. By way of template overrides, we add a link to the list view we will create. You find the original template in {{APPLICATION_DIR}}/views/adminmainmenu/tmpl/default.php. For practical reasons, the default template loads another template named extra_menu_items.php, which is meant for additions to the menu without the need to override the entire menu.

You can override that extra menu items template by adding a file in this location:

{{CUSTOMIZATION_DIR}}/templates/adminmainmenu/extra_menu_items.php

1 2 3 4 5 6 7 8 9 10 <?php defined('CB_VALID_ENTRY') or die(); /** @var $this ConfigboxViewAdminmainmenu */ ?> <ul class="menu-list"> <li class="menu-list-item item-adminconfig"> <a class="menu-link ajax-target-link" href="<?php echo KLink::getRoute('index.php?option=com_configbox&controller=adminlogos');?>"><?php echo KText::_('Logos');?></a> </li> </ul>

We are mentioning the controller while getting the link for the menu. This controller will be responsible to handle the page.

The link to your list:

1 echo KLink::getRoute('index.php?option=com_configbox&controller=adminlogos');

You see that all link URLs are done using KLink::getRoute(). As parameter you supply a URI starting with index.php and you append a query string. option=com_configbox is fixed, controller=adminlogos instructs the system to use the controller (we create this in the next step). The query string parameter ‘task‘ would instruct which task to execute - ‘display’ is the default task if you omit it.

Create a controller

All browser HTTP requests go through controllers. The KenedoController base class has generic methods for tasks like ‘display’, ‘edit’, ‘store’, ‘delete’ etc.

In our controller files we simply supply configuration, but we could also override the task methods.

Upon clicking a menu in the backend, a page should be rendered. For this operation, we need a controller. Since it is a custom controller, we should create the file in the following path:

{{CUSTOMIZATION_DIR}}/controllers/adminlogos.php

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 <?php defined('CB_VALID_ENTRY') or die(); class ConfigboxControllerAdminlogos extends KenedoController { /** * @return ConfigboxModelAdminlogos * @throws Exception */ protected function getDefaultModel() { return KenedoModel::getModel('ConfigboxModelAdminlogos'); } /** * @return ConfigboxViewAdminlogos * @throws Exception */ protected function getDefaultView() { return $this->getDefaultViewList(); } /** * @return ConfigboxViewAdminlogos * @throws Exception */ protected function getDefaultViewList() { return KenedoView::getView('ConfigboxViewAdminlogos'); } /** * @return ConfigboxViewAdminlogo * @throws Exception */ protected function getDefaultViewForm() { return KenedoView::getView('ConfigboxViewAdminlogo'); } }

About the methods:

  • getDefaultModel() - returns the model responsible for any tasks to execute.

  • getDefaultViewList() - returns the view responsible for rendering a list of records

  • getDefaultViewForm() - returns the view for rendering an edit form for a record

  • getDefaultView() - This is used for frontend use of a controller, for backend you can just return the list view.

For more details about the controllers, please refer https://rovexo.atlassian.net/wiki/spaces/CD/pages/202473580.

Create a model

Model is responsible to handle all the database operations. As mentioned in the above controller, we should create a model class in the following path:

{{CUSTOMIZATION_DIR}}/models/adminlogos.php

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 <?php defined('CB_VALID_ENTRY') or die(); class ConfigboxModelAdminlogos extends KenedoModel { function getTableName() { return '#__configbox_external_logos'; } function getTableKey() { return 'id'; } function getPropertyDefinitions() { $propDefs = array(); $propDefs['id'] = array( 'name'=>'id', 'type'=>'id', 'default'=>0, 'label'=>KText::_('ID'), 'canSortBy'=>true, 'positionList'=>10000, 'positionForm'=>10000, ); $propDefs['title'] = array( 'name'=>'title', 'label'=>KText::_('Title'), 'type'=>'translatable', 'langType'=>1053, 'required'=>true, 'makeEditLink'=>true, 'component'=>'com_configbox', 'controller'=>'adminlogos', 'canSortBy'=>20000, 'positionList'=>20000, 'positionForm'=>20000, ); $propDefs['file'] = array ( 'name'=>'file', 'label'=>KText::_('Logo File'), 'type'=>'image', 'appendSerial'=>true, 'allowedExtensions'=>array('jpg', 'jpeg', 'png', 'gif'), 'allowedMimeTypes'=>array('image/jpg', 'image/png', 'image/gif'), 'required'=>false, 'maxFileSizeKb'=>2000, 'dirBase'=>KenedoPlatform::p()->getDirDataStore().'/public/custom_media/logos', 'urlBase'=>KenedoPlatform::p()->getUrlDataStore().'/public/custom_media/logos', 'options'=>'SAVE_FILENAME', 'positionForm'=>30000, ); return $propDefs; } }

KenedoModels contain generic functions for CRUD operations and typically you only need to supply configuration:

  • getTableName() - returns the name of the DB table that stores the model’s data (#__ is a placeholder for a table prefix)

  • getTableKey() - returns the name of the primary key column.

  • getPropertyDefinitions() - returns settings for each property of the records. In the above code, we have defined 3 properties - ID, Title and the uploaded file.

For more details about the models, please refer https://rovexo.atlassian.net/wiki/spaces/CD/pages/202440771. Properties are described in KenedoProperty.

Create DB update script to create a table

With your model’s properties in place, you create the database table using an update script. It will be executed automatically by the Kenedo platform (during app initialisation on Joomla and WP, during setup:upgrade on M2).

The following file can be used to create a table to store the logos:

{{CUSTOMIZATION_DIR}}/updates/0.0.1.php

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <?php defined('CB_VALID_ENTRY') or die(); $db = KenedoPlatform::getDb(); if (ConfigboxUpdateHelper::tableExists('#__configbox_external_logos') == false) { $query = " CREATE TABLE `#__configbox_external_logos` ( `id` INT UNSIGNED PRIMARY KEY AUTO_INCREMENT, `file` VARCHAR(127) NOT NULL DEFAULT '' ) ENGINE InnoDB "; $db->setQuery($query); $db->query(); }

Note: The property ‘title’ (type translatable) stores itself in a separate table (configbox_strings) and does need a column in the base table.

Execution of database scripts are maintained by the configbox_system_vars table. The last executed version is noted down in this table. For more details about the execution procedure, please refer to the article about https://rovexo.atlassian.net/wiki/spaces/CD/pages/202375241.

Create the views

The views responsible to render the listing and form should be created in this step. We have to create 2 views as mentioned in the controller - one for displaying a list of record, the other for an edit form.

For more details about the views, please refer https://rovexo.atlassian.net/wiki/spaces/CD/pages/202506318.

Creating view for the list

The following files are needed to create the list view:

{{CUSTOMIZATION_DIR}}/views/adminlogos/tmpl/default.php

This file just loads a generic template for HTML of lists.

1 2 3 <?php defined('CB_VALID_ENTRY') or die(); require(KPATH_LISTING_TMPL);

{{CUSTOMIZATION_DIR}}/views/adminlogos/metadata.xml

This file is for Joomla - it ensures that this view does not show up in the Joomla menu manager.

1 2 3 4 <?xml version="1.0" encoding="utf-8"?> <metadata> <view hidden="true" /> </metadata>

{{CUSTOMIZATION_DIR}}/views/adminlogos/view.html.php

This file holds the configuration for the view.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <?php defined('CB_VALID_ENTRY') or die(); class ConfigboxViewAdminlogos extends KenedoView { public $component = 'com_configbox'; public $controllerName = 'adminlogos'; /** * @return ConfigboxModelAdminlogos * @throws Exception */ function getDefaultModel() { return KenedoModel::getModel('ConfigboxModelAdminlogos'); } function getPageTitle() { return KText::_('Logos'); } }

Creating view for form

The following files are needed to create the form view. It follows the same principles as the list view.

{{CUSTOMIZATION_DIR}}/views/adminlogo/tmpl/default.php

1 2 3 <?php defined('CB_VALID_ENTRY') or die(); require(KPATH_DETAILS_TMPL);

{{CUSTOMIZATION_DIR}}/views/adminlogo/metadata.xml

1 2 3 4 <?xml version="1.0" encoding="utf-8"?> <metadata> <view hidden="true" /> </metadata>

{{CUSTOMIZATION_DIR}}/views/adminlogo/view.html.php

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <?php defined('CB_VALID_ENTRY') or die(); class ConfigboxViewAdminlogo extends KenedoView { public $component = 'com_configbox'; public $controllerName = 'adminlogos'; /** * @return ConfigboxModelAdminlogos */ function getDefaultModel() { return KenedoModel::getModel('ConfigboxModelAdminlogos'); } function getPageTitle() { return KText::_('Logo'); } }

Verify the output

After creating the files and code as per the above instructions, we should be able to see the following:

  1. Menu added to the backend

  2. Upon clicking the menu, a listing of all the logos can be seen

  3. By clicking one of the logos, we can edit the details of that logo

  4. We can add a new logo by clicking the Add button

Using the Kenedo platform, we have successfully created a fully functional listing and form with minimum effort.