Hooking modules to the Category Back Office in Prestashop

If you want to add extra fields to the category configuration page, there is no better way than using a module hooked to DisplayBackOfficeCategory. Let’s see how to implement it!

Download Project Files

Starting with a simple module

First, download the project file, and place the module you will find inside the “start” folder in the modules/ folder of your prestashop installation.

Open up displaybocategorytut.php, it’s just a very basic module structure.

if (!defined('_PS_VERSION_'))
	exit;

class displayBoCategoryTut extends Module
{

	protected $_errors = array();
	protected $_html = '';


	public function __construct()
	{
		$this->name = 'displaybocategorytut';
		$this->tab = 'front_office_features';
		$this->version = '1.0';
		$this->author = 'Nemo';
		$this->need_instance = 0;
		
		$this->bootstrap = true;

	 	parent::__construct();

		$this->displayName = $this->l('Display BO Category Tutorial');
		$this->description = $this->l('Displays an additional field in the category back office');
	}
	
	public function install()
	{
		if (!parent::install())
			return false;
		return true;
	}

	public function uninstall()
	{
		if (!parent::uninstall())
			return false;
		return true;
	}

}

The first thing we need is of course some additional data we want to save and retrieve. For this reason, we need an extra method to modify the database, and add a further column to the category table:

	public function alterTable($method = 'add')
	{
		if($method == 'add')
			$sql = 'ALTER TABLE ' . _DB_PREFIX_ . 'category ADD `myowninput` VARCHAR (255) NOT NULL';
		else 
			$sql = 'ALTER TABLE ' . _DB_PREFIX_ . 'category DROP COLUMN `myowninput`';

		if(!Db::getInstance()->Execute($sql))
			return false;
		return true;
	}

Explanation: since we need the extra column, we are using a single method to add and remove it. We are passing in a “method” parameter, so that we can switch between actions depending on our needs.

As mentioned, we need this column to be added when installing, and removed when uninstalling, so let’s amend the install and uninstall methods as well:



	public function install()
	{
		if (!parent::install() OR
			!$this->alterTable() OR
			!$this->registerHook('displayBackOfficeCategory') OR
			!$this->registerHook('categoryAddition') OR
			!$this->registerHook('categoryUpdate')
			)
			return false;
		return true;
	}

	public function uninstall()
	{
		if (!parent::uninstall() OR
			!$this->alterTable('remove'))
			return false;
		return true;
	}

Additionally, I am registering two hooks to update the field’s value. This would not be necessary if we had a Category class override to take care of the extra field (see more on Extending PrestaShop Objects).

Next, we will need some way to retrieve our custom field from the database

	public function getMyOwnInput($id_category)
	{
		return Db::getInstance()->getValue('SELECT myowninput FROM '._DB_PREFIX_.'category WHERE id_category = '. (int)$id_category);
	}

Then, it’s time to display something in the category back office. Let’s create the hooking method:

	public function hookDisplayBackOfficeCategory($params)
	{

		// we need an actual id, otherwise if we are just adding the category this field can be left empty
		if(Tools::getValue('id_category'))
			$myowninput = $this->getMyOwnInput(Tools::getValue('id_category'));
		else $myowninput = '';

		$this->context->smarty->assign(array(
			'myowninput'=> $myowninput
		));


		return $this->display(__FILE__, 'backoffice.tpl');
	}

Explanation: First off, we make sure we have a category ID that we can use to retrieve the value from the database. We use a switch to prevent the script from causing trouble in case there is none (that is, we are just creating a new category). Then, we assign the input value to the template, and return it. We don’t have it yet, so let’s create a new file inside views\templates\hook, naming it backoffice.tpl

Let’s add some simple markup:

<div class="form-group">
	<label class="control-label col-lg-3">
		<span class="label-tooltip">
			{l s='Custom Input' mod='displaybocategorytut'}
		</span>
	</label>
	<div class="col-lg-4">
		<input type="text" name="myowninput" value="{$myowninput}">
	</div>
	<div class="col-lg-6 col-lg-offset-3">
	</div>
</div>

We are ready to install the module! Go ahead and do it from the modules page. If everything goes smoothly as it should, reach a category and click edit (or add one). It should display our new field:

New input in the PrestaShop Category Back Office

It won’t do much at the time being, since we are not saving the value on submit. For this, we need another couple of methods that will take advantage of the hooks we registered upon install:

	public function hookCategoryAddition($params)
	{
		Db::getInstance()->update('category', array('myowninput' => pSQL(Tools::getValue('myowninput'))), 'id_category = ' . $params['category']->id);
	}

	public function hookCategoryUpdate($params)
	{
		$this->hookCategoryAddition($params);
	}

Explanation: here we are using some standard code to update the database: the myowninput value is sent over via POST when submitting the page, and the $params variable passed to the method contains a useful Category object, from which we are taking the ID.

Now write something in the field and save, it should be stored in the database! To make sure everything runs smoothly, create a new category as well, adding content to our field before submitting the page.

Once everything works, you can try to expand the module with hooks, in the front office as well, and take full advantage of the new value.

Additional Resources

You like the tuts and want to say "thank you"? Well, you can always feel free to donate:

  • http://www.rescatalo.com/ David Peribáñez

    Great tutorial Nemops.

You like the tuts and want to say "thank you"? Well, you can always feel free to donate: