[PrestaShop 1.7] Ajouter un champ à une catégorie

PrestaShop
  • Accueil
  • Blog
  • [PrestaShop 1.7] Ajouter un champ à une catégorie

Je vous propose aujourd’hui un tuto PrestaShop pour ajouter un champ aux catégories pour ensuite l’afficher ou non sur le front office. C’est parti !

 

Constat : Limite de champs pour les catégories

J’ai récemment rencontré deux cas très précis pour des marchands avec qui je travaille régulièrement :

  • premier cas : le e-commerçant voulait afficher un titre de catégorie assez long pour son référencement mais il ne voulait pas que ce titre soit utilisé dans les menus, dans le fil d’ariane ou dans le bloc catégorie de la colonne gauche.
  • second cas : mon client voulait deux champs supplémentaires pour exporter vers les comparateurs et places de marché des noms et descriptions de catégories différents de ceux présents sur sa boutique pour éviter du duplicate content.

Dans les deux cas, ce tutoriel PrestaShop répond parfaitement au problème concret !
 

Tuto PrestaShop : ajouter un champ pour les catégories

C’est parti pour résoudre le cas numéro 1. Le tuto PrestaShop se déroule en 5 étapes assez simples vous allez voir. Penchons-nous d’abord sur les 4 premières étapes :
 

1. Ajouter un champ dans la base de données

Connectez-vous à Phpmyadmin et ajoutez le champ “titre_2” dans la . Dans mon exemple, le préfixe de table étant “ps1720_”, la table est “ps1720_category_lang”.

prestashop 1.7 ajouter champ categories
On ajoute le champ dans la table ps_category_lang

prestashop 1.7 ajouter champ categories
On nomme le champ et on choisit le type “text”

 

2. Modifier la Classe Category.php

Copiez le fichier www/classes/Category.php dans www/override/classes/Category.php et ne conservez que ce code dans le fichier :

<?php
/**
* Override Class CategoryCore
*/
class Category extends CategoryCore
{
public $titre_2;

/**
* @see ObjectModel::$definition
*/
public static $definition = array(
'table' => 'category',
'primary' => 'id_category',
'multilang' => true,
'multilang_shop' => true,
'fields' => array(
'nleft' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedInt'),
'nright' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedInt'),
'level_depth' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedInt'),
'active' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool', 'required' => true),
'id_parent' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedInt'),
'id_shop_default' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'),
'is_root_category' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool'),
'position' => array('type' => self::TYPE_INT),
'date_add' => array('type' => self::TYPE_DATE, 'validate' => 'isDate'),
'date_upd' => array('type' => self::TYPE_DATE, 'validate' => 'isDate'),
/* Lang fields */
'name' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isCatalogName', 'required' => true, 'size' => 128),
'link_rewrite' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isLinkRewrite', 'required' => true, 'size' => 128),
'description' => array('type' => self::TYPE_HTML, 'lang' => true, 'validate' => 'isCleanHtml'),
'meta_title' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'size' => 128),
'meta_description' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'size' => 255),
'meta_keywords' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'size' => 255),
'titre_2' => array('type' => self::TYPE_HTML, 'lang' => true, 'validate' => 'isCleanHtml'),
),
);
}

Notez que seules les lignes 7 et 35 ont été ajouté par rapport au fichier original.
 
 

3. Modifier le Controller Admin AdminCategoriesController.php

Copiez le fichier www/controllers/admin/AdminCategoriesController.php dans www/override/controllers/admin/AdminCategoriesController.php et ne conservez que ce code dans le fichier :

<?php
/**
* @property Category $object
*/
class AdminCategoriesController extends AdminCategoriesControllerCore
{
public function __construct()
{
$this->bootstrap = true;
$this->table = 'category';
$this->className = 'Category';
$this->lang = true;
$this->deleted = false;
$this->explicitSelect = true;
$this->_defaultOrderBy = 'position';
$this->allow_export = true;

AdminController::__construct();

$this->fieldImageSettings = array(
'name' => 'image',
'dir' => 'c'
);

$this->fields_list = array(
'id_category' => array(
'title' => $this->trans('ID', array(), 'Admin.Global'),
'align' => 'center',
'class' => 'fixed-width-xs'
),
'name' => array(
'title' => $this->trans('Name', array(), 'Admin.Global')
),
'titre_2' => array(
'title' => $this->trans('Titre 2', array(), 'Admin.Global'),
'orderby' => false
),
'description' => array(
'title' => $this->trans('Description', array(), 'Admin.Global'),
'callback' => 'getDescriptionClean',
'orderby' => false
),
'position' => array(
'title' => $this->trans('Position', array(), 'Admin.Global'),
'filter_key' => 'sa!position',
'position' => 'position',
'align' => 'center'
),
'active' => array(
'title' => $this->trans('Displayed', array(), 'Admin.Global'),
'active' => 'status',
'type' => 'bool',
'class' => 'fixed-width-xs',
'align' => 'center',
'ajax' => true,
'orderby' => false
)
);

$this->bulk_actions = array(
'delete' => array(
'text' => $this->trans('Delete selected', array(), 'Admin.Actions'),
'icon' => 'icon-trash',
'confirm' => $this->trans('Delete selected items?', array(), 'Admin.Notifications.Warning')
)
);
$this->specificConfirmDelete = false;
}

public function renderForm()
{
$this->initToolbar();

/** @var Category $obj */
$obj = $this->loadObject(true);
$context = Context::getContext();
$id_shop = $context->shop->id;
$selected_categories = array((isset($obj->id_parent) && $obj->isParentCategoryAvailable($id_shop))? (int)$obj->id_parent : (int)Tools::getValue('id_parent', Category::getRootCategory()->id));
$unidentified = new Group(Configuration::get('PS_UNIDENTIFIED_GROUP'));
$guest = new Group(Configuration::get('PS_GUEST_GROUP'));
$default = new Group(Configuration::get('PS_CUSTOMER_GROUP'));

$unidentified_group_information = sprintf($this->trans('%s - All people without a valid customer account.', array(), 'Admin.Catalog.Feature'), '<b>'.$unidentified->name[$this->context->language->id].'</b>');
$guest_group_information = sprintf($this->trans('%s - Customer who placed an order with the guest checkout.', array(), 'Admin.Catalog.Feature'), '<b>'.$guest->name[$this->context->language->id].'</b>');
$default_group_information = sprintf($this->trans('%s - All people who have created an account on this site.', array(), 'Admin.Catalog.Feature'), '<b>'.$default->name[$this->context->language->id].'</b>');

if (!($obj = $this->loadObject(true))) {
return;
}

$image = _PS_CAT_IMG_DIR_.$obj->id.'.'.$this->imageType;
$image_url = ImageManager::thumbnail($image, $this->table.'_'.(int)$obj->id.'.'.$this->imageType, 350, $this->imageType, true, true);

$image_size = file_exists($image) ? filesize($image) / 1000 : false;
$images_types = ImageType::getImagesTypes('categories');
$format = array();
$thumb = $thumb_url = '';
$formatted_category= ImageType::getFormattedName('category');
$formatted_small = ImageType::getFormattedName('small');
foreach ($images_types as $k => $image_type) {
if ($formatted_category == $image_type['name']) {
$format['category'] = $image_type;
} elseif ($formatted_small == $image_type['name']) {
$format['small'] = $image_type;
$thumb = _PS_CAT_IMG_DIR_.$obj->id.'-'.$image_type['name'].'.'.$this->imageType;
if (is_file($thumb)) {
%<br />
20 $thumb_url = ImageManager::thumbnail($thumb, $this->table.'_'.(int)$obj->id.'-thumb.'.$this->imageType, (int)$image_type['width'], $this->imageType, true, true);
}
}
}

if (!is_file($thumb)) {
$thumb = $image;
$thumb_url = ImageManager::thumbnail($image, $this->table.'_'.(int)$obj->id.'-thumb.'.$this->imageType, 125, $this->imageType, true, true);
ImageManager::resize(_PS_TMP_IMG_DIR_.$this->table.'_'.(int)$obj->id.'-thumb.'.$this->imageType, _PS_TMP_IMG_DIR_.$this->table.'_'.(int)$obj->id.'-thumb.'.$this->imageType, (int)$image_type['width'], (int)$image_type['height']);
}

$thumb_size = file_exists($thumb) ? filesize($thumb) / 1000 : false;

$menu_thumbnails = [];
for ($i = 0; $i < 3; $i++) {
if (file_exists(_PS_CAT_IMG_DIR_.(int)$obj->id.'-'.$i.'_thumb.jpg')) {
$menu_thumbnails[$i]['type'] = HelperImageUploader::TYPE_IMAGE;
$menu_thumbnails[$i]['image'] = ImageManager::thumbnail(_PS_CAT_IMG_DIR_.(int)$obj->id.'-'.$i.'_thumb.jpg', $this->context->controller->table.'_'.(int)$obj->id.'-'.$i.'_thumb.jpg', 100, 'jpg', true, true);
$menu_thumbnails[$i]['delete_url'] = Context::getContext()->link->getAdminLink('AdminCategories').'&deleteThumb='.$i.'&id_category='.(int)$obj->id;
}
}

$this->fields_form = array(
'tinymce' => true,
'legend' => array(
'title' => $this->trans('Category', array(), 'Admin.Catalog.Feature'),
'icon' => 'icon-tags'
),
'input' => array(
array(
'type' => 'text',
'label' => $this->trans('Name', array(), 'Admin.Global'),
'name' => 'name',
'lang' => true,
'required' => true,
'class' => 'copy2friendlyUrl',
'hint' => $this->trans('Invalid characters:', array(), 'Admin.Notifications.Info').' <>;=#{}',
),
array(
'type' => 'text',
'label' => $this->trans('Titre 2', array(), 'Admin.Global'),
'name' => 'titre_2',
'lang' => true,
'hint' => $this->trans('Front field', array(), 'Admin.Notifications.Info')
),
array(
'type' => 'switch',
'label' => $this->trans('Displayed', array(), 'Admin.Global'),
'name' => 'active',
'required' => false,
'is_bool' => true,
'values' => array(
array(
'id' => 'active_on',
'value' => 1,
'label' => $this->trans('Enabled', array(), 'Admin.Global')
),
array(
'id' => 'active_off',
'value' => 0,
'label' => $this->trans('Disabled', array(), 'Admin.Global')
)
)
),
array(
'type' => 'categories',
'label' => $this->trans('Parent category', array(), 'Admin.Catalog.Feature'),
'name' => 'id_parent',
'tree' => array(
'id' => 'categories-tree',
'selected_categories' => $selected_categories,
'disabled_categories' => (!Tools::isSubmit('add'.$this->table) && !Tools::isSubmit('submitAdd'.$this->table)) ? array($this->_category->id) : null,
'root_category' => $context->shop->getCategory()
)
),
array(
'type' => 'textarea',
'label' => $this->trans('Description', array(), 'Admin.Global'),
'name' => 'description',
'autoload_rte' => true,
%<br />
20 'lang' => true,
'hint' => $this->trans('Invalid characters:', array(), 'Admin.Notifications.Info').' <>;=#{}'
),
array(
'type' => 'file',
'label' => $this->trans('Category Cover Image', array(), 'Admin.Catalog.Feature'),
'name' => 'image',
'display_image' => true,
'image' => $image_url ? $image_url : false,
'size' => $image_size,
'delete_url' => self::$currentIndex.'&'.$this->identifier.'='.$this->_category->id.'&token='.$this->token.'&deleteImage=1',
'hint' => $this->trans('This is the main image for your category, displayed in the category page. The category description will overlap this image and appear in its top-left corner.', array(), 'Admin.Catalog.Help'),
'format' => $format['category']
),
array(
'type' => 'file',
'label' => $this->trans('Category thumbnail', array(), 'Admin.Catalog.Feature'),
'name' => 'thumb',
'display_image' => true,
'image' => $thumb_url ? $thumb_url : false,
'size' => $thumb_size,
'format' => isset($format['small']) ? $format['small'] : $format['category'],
'hint' => $this->trans('Displays a small image in the parent category\'s page, if the theme allows it.', array(), 'Admin.Catalog.Help'),
),
array(
'type' => 'file',
'label' => $this->trans('Menu thumbnails', array(), 'Admin.Catalog.Feature'),
'name' => 'thumbnail',
'ajax' => true,
'multiple' => true,
'max_files' => 3,
'files' => $menu_thumbnails,
'url' => Context::getContext()->link->getAdminLink('AdminCategories').'&ajax=1&id_category='.$this->id.'&action=uploadThumbnailImages',
'hint' => $this->trans('The category thumbnail appears in the menu as a small image representing the category, if the theme allows it.', array(), 'Admin.Catalog.Help'),
),
array(
'type' => 'text',
'label' => $this->trans('Meta title', array(), 'Admin.Global'),
'name' => 'meta_title',
'maxlength' => 70,
'maxchar' => 70,
'lang' => true,
'rows' => 5,
'cols' => 100,
'hint' => $this->trans('Forbidden characters:', array(), 'Admin.Notifications.Info').' <>;=#{}'
),
array(
'type' => 'textarea',
'label' => $this->trans('Meta description', array(), 'Admin.Global'),
'name' => 'meta_description',
'maxlength' => 160,
'maxchar' => 160,
'lang' => true,
'rows' => 5,
'cols' => 100,
'hint' => $this->trans('Forbidden characters:', array(), 'Admin.Notifications.Info').' <>;=#{}'
),
array(
'type' => 'tags',
'label' => $this->trans('Meta keywords', array(), 'Admin.Global'),
'name' => 'meta_keywords',
'lang' => true,
'hint' => $this->trans('To add "tags," click in the field, write something, and then press "Enter."', array(), 'Admin.Catalog.Help').' '.$this->trans('Forbidden characters:', array(), 'Admin.Notifications.Info').' <>;=#{}'
),
array(
'type' => 'text',
'label' => $this->trans('Friendly URL', array(), 'Admin.Global'),
'name' => 'link_rewrite',
'lang' => true,
'required' => true,
'hint' => $this->trans('Only letters, numbers, underscore (_)%2<br />
0and the minus (-) character are allowed.', array(), 'Admin.Catalog.Help')
),
array(
'type' => 'group',
'label' => $this->trans('Group access', array(), 'Admin.Catalog.Feature'),
'name' => 'groupBox',
'values' => Group::getGroups(Context::getContext()->language->id),
'info_introduction' => $this->trans('You now have three default customer groups.', array(), 'Admin.Catalog.Help'),
'unidentified' => $unidentified_group_information,
'guest' => $guest_group_information,
'customer' => $default_group_information,
'hint' => $this->trans('Mark all of the customer groups which you would like to have access to this category.', array(), 'Admin.Catalog.Help')
)
),
'submit' => array(
'title' => $this->trans('Save', array(), 'Admin.Actions'),
'name' => 'submitAdd'.$this->table.($this->_category->is_root_category && !Tools::isSubmit('add'.$this->table) && !Tools::isSubmit('add'.$this->table.'root') ? '': 'AndBackToParent')
)
);

$this->tpl_form_vars['shared_category'] = Validate::isLoadedObject($obj) && $obj->hasMultishopEntries();
$this->tpl_form_vars['PS_ALLOW_ACCENTED_CHARS_URL'] = (int)Configuration::get('PS_ALLOW_ACCENTED_CHARS_URL');
$this->tpl_form_vars['displayBackOfficeCategory'] = Hook::exec('displayBackOfficeCategory');

// Display this field only if multistore option is enabled
if (Configuration::get('PS_MULTISHOP_FEATURE_ACTIVE') && Tools::isSubmit('add'.$this->table.'root')) {
$this->fields_form['input'][] = array(
'type' => 'switch',
'label' => $this->trans('Root Category', array(), 'Admin.Catalog.Feature'),
'name' => 'is_root_category',
'required' => false,
'is_bool' => true,
'values' => array(
array(
'id' => 'is_root_on',
'value' => 1,
'label' => $this->trans('Yes', array(), 'Admin.Global')
),
array(
'id' => 'is_root_off',
'value' => 0,
'label' => $this->trans('No', array(), 'Admin.Global')
)
)
);
unset($this->fields_form['input'][2], $this->fields_form['input'][3]);
}
// Display this field only if multistore option is enabled AND there are several stores configured
if (Shop::isFeatureActive()) {
$this->fields_form['input'][] = array(
'type' => 'shop',
'label' => $this->trans('Shop association', array(), 'Admin.Global'),
'name' => 'checkBoxShopAsso',
);
}

// remove category tree and radio button "is_root_category" if this category has the root category as parent category to avoid any conflict
if ($this->_category->id_parent == (int)Configuration::get('PS_ROOT_CATEGORY') && Tools::isSubmit('updatecategory')) {
foreach ($this->fields_form['input'] as $k => $input) {
if (in_array($input['name'], array('id_parent', 'is_root_category'))) {
unset($this->fields_form['input'][$k]);
}
}
}

if (!($obj = $this->loadObject(true))) {
return;
}

$image = ImageManager::thumbnail(_PS_CAT_IMG_DIR_.'/'.$obj->id.'.'.$this->imageType, $this->table.'_'.(int)$obj->id.'.'.$this->imageType, 350, $this->imageType, true);

$this->fields_value = array(
'image' => $image ? $image : false,
'size' => $image ? filesize(_PS_CAT_IMG_DIR_.'/'.$obj->id.'.'.$this->imageType) / 1000 : false
);

// Added values of object Group
$category_groups_ids = $obj->getGroups();

$groups = Group::getGroups($this->context->language->id);
// if empty $carrier_groups_ids : object creation : we set the default groups
if (empty($category_groups_ids)) {
$preselected = array(Configuration::get('PS_UNIDENTIFIED_GROUP'), Configuration::get('PS_GUEST_GROUP'), Configuration::get('PS_CUSTOMER_GROUP'));
$category_groups_ids = array_merge($category_groups_ids, $preselected);
}
foreach ($groups as $group) {
$this->fields_value['groupBox<br />
_'.$group['id_group']] = Tools::getValue('groupBox_'.$group['id_group'], (in_array($group['id_group'], $category_groups_ids)));
}

$this->fields_value['is_root_category'] = (bool)Tools::isSubmit('add'.$this->table.'root');

return AdminController::renderForm();
}
}

Notez qu’on a copié seulement les fonctions suivantes :
public function __construct()
public function renderForm()

Voici ci-dessous le détail des modifications pour mieux comprendre.
Dans la fonction __construct dans l’array à la ligne 25 on ajoute les infos pour le titre_2 :
$this->fields_list = array(
'id_category' => array(
'title' => $this->trans('ID', array(), 'Admin.Global'),
'align' => 'center',
'class' => 'fixed-width-xs'
),
'name' => array(
'title' => $this->trans('Name', array(), 'Admin.Global')
),
'titre_2' => array(
'title' => $this->trans('Titre 2', array(), 'Admin.Global'),
'orderby' => false
),
'description' => array(
'title' => $this->trans('Description', array(), 'Admin.Global'),
'callback' => 'getDescriptionClean',
'orderby' => false
),
'position' => array(
'title' => $this->trans('Position', array(), 'Admin.Global'),
'filter_key' => 'sa!position',
'position' => 'position',
'align' => 'center'
),
'active' => array(
'title' => $this->trans('Displayed', array(), 'Admin.Global'),
'active' => 'status',
'type' => 'bool',
'class' => 'fixed-width-xs',
'align' => 'center',
'ajax' => true,
'orderby' => false
)
);

Dans la fonction renderForm, on modifie l’array de la ligne 135 comme suit en ajoutant le champ “titre 2” :
'input' => array(
array(
'type' => 'text',
'label' => $this->trans('Name', array(), 'Admin.Global'),
'name' => 'name',
'lang' => true,
'required' => true,
'class' => 'copy2friendlyUrl',
'hint' => $this->trans('Invalid characters:', array(), 'Admin.Notifications.Info').' <>;=#{}',
),
array(
'type' => 'text',
'label' => $this->trans('Titre 2', array(), 'Admin.Global'),
'name' => 'titre_2',
'lang' => true,
'hint' => $this->trans('Front field', array(), 'Admin.Notifications.Info')
),

 
 

4. Afficher le champ sur le front office

Dans notre exemple, on veut pouvoir afficher un titre de catégorie différent de celui affiché dans le fil d’ariane, donc on va éditer le fichier www/themes/nom-du-theme/templates/catalog/listing/category.tpl :

{**
* 2007-2017 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2017 PrestaShop SA
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*}
{extends file='catalog/listing/product-list.tpl'}

{block name='product_list_header'}
<div class="block-category card card-block hidden-sm-down">
<h1 class="h1">
{if $category.titre_2}
{$category.titre_2}
{else}
{$category.name}
{/if}
</h1>
{if $category.description}
<div id="category-description" class="text-muted">{$category.description nofilter}</div>
{/if}
{if $category.image.large.url}
<div class="category-cover">
<img src="{$category.image.large.url}" alt="{$category.image.legend}">
</div>
{/if}
</div>
<div class="text-sm-center hidden-md-up">
<h1 class="h1">{$category.name}</h1>
</div>
{/block}

Dans ce fichier, j’ai indiqué que si le champ titre_2 est rempli, alors on l’affiche. Si non, on affiche le nom par défaut de la catégorie.
 
 

5. Vider le cache des overrides et savourer !

Pour pouvoir utiliser les modifications, vous devez vider le cache. Pour ce faire, supprimez le fichier : www/app/cache/prod/class_index.php
Il se peut si vous avez activer le mode debug que vous deviez supprimer le même fichier dans le dossier dev donc : www/app/cache/dev/class_index.php

prestashop 1.7 ajouter champ categories
Votre champ est désormais présent dans l’admin !

Remplissez le champ et voyez le résultat de votre optimisation seo pour PrestaShop en front office 🙂
prestashop 1.7 ajouter champ categories
 

Afficher le nouveau champ pour les sous-catégories

[Edit du 21/07/2018] Je vais vous expliquer comment afficher le nouveau champ catégorie lorsque cette catégorie est une sous-catégorie. Dans ce cas, il faut surcoucher le fonctionnement de base de PrestaShop.
Editez l’override www/override/classes/Category.php – créez-le si inexistant – en modifiant la fonction getSubCategories de la façon suivante :

/**
* Return current category childs
*
* @param int $idLang Language ID
* @param bool $active return only active categories
*
* @return array Categories
*/
public function getSubCategories($idLang, $active = true)
{
$sqlGroupsWhere = '';
$sqlGroupsJoin = '';
if (Group::isFeatureActive()) {
$sqlGroupsJoin = 'LEFT JOIN `'._DB_PREFIX_.'category_group` cg ON (cg.`id_category` = c.`id_category`)';
$groups = FrontController::getCurrentCustomerGroups();
$sqlGroupsWhere = 'AND cg.`id_group` '.(count($groups) ? 'IN ('.implode(',', $groups).')' : '='.(int) Group::getCurrent()->id);
}

$result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('
SELECT c.*, cl.`id_lang`, cl.`name`, cl.`description`, cl.`link_rewrite`, cl.`meta_title`, cl.`meta_keywords`, cl.`meta_description`, cl.`titre_2`
FROM `'._DB_PREFIX_.'category` c
'.Shop::addSqlAssociation('category', 'c').'
LEFT JOIN `'._DB_PREFIX_.'category_lang` cl ON (c.`id_category` = cl.`id_category` AND `id_lang` = '.(int) $idLang.' '.Shop::addSqlRestrictionOnLang('cl').')
'.$sqlGroupsJoin.'
WHERE `id_parent` = '.(int) $this->id.'
'.($active ? 'AND `active` = 1' : '').'
'.$sqlGroupsWhere.'
GROUP BY c.`id_category`
ORDER BY `level_depth` ASC, category_shop.`position` ASC');

foreach ($result as &$row) {
$row['id_image'] = Tools::file_exists_cache($this->image_dir.$row['id_category'].'.jpg') ? (int) $row['id_category'] : Language::getIsoById($idLang).'-default';
$row['legend'] = 'no picture';
}

return $result;
}

Vous pouvez donc remarquer que j’ai ajouté le champ cl.titre_2 à la requête SQL SELECT pour que l’information soit récupérée. Il suffit alors d’afficher cette variable comme les autres pour vos sous-catégories.
Je peux à présent utiliser la variable {$subcategory.titre_2} pour mes sous-catégories.
 

Fichiers pour ajouter un champ aux catégories

Voici les fichiers à télécharger pour réaliser le tuto PrestaShop :

A bientôt pour un nouveau tuto PrestaShop !

27 commentaires sur “[PrestaShop 1.7] Ajouter un champ à une catégorie

  1. Bonjour Arnaud,
    je me suis inspiré de ce tuto pour afficher 2 nouveaux champs de date dans les pages CMS.
    La bdd et le rendu en FO fonctionne. Mais je n’arrive pas à savoir comment ajouter les champs dans les pages cms en BO

    1. Bonjour,
      Merci pour le commentaire.
      Je me note pour un futur article / tuto PrestaShop 😉

  2. Bonjour Arnaud, je suis intéressé par la version 1.7.8, car dans ton tuto, il n’y a pas le fichier AdminCategoriesController.php. Aurai-tu une solution ?
    Merci pour tes conseils et tuto toujours de bonne qualité !

  3. Bonjour,

    Merci pour ce super tuto très pratique mais je rencontre un problème.

    Je suis sur version prestashop 1.7.5.1, j’ai voulu utiliser ton tuto pour rajouter un champ de type prix sur les pages categories en utilisant au lieu de titre_2 donc prix_2 et une table dans phpmyadmin de type int.
    Le prix 2 d’affiche bien dans le backoffice mais quand j’essaye d’enregistrer j’ai le message d’erreur suivant :
    Unknown column ‘prix_2’ in ‘field list’

    UPDATE `mod554_category` SET `id_category` = ‘3’,`nleft` = ‘3’,`nright` = ’12’,`level_depth` = ‘2’,`active` = ‘1’,`id_parent` = ‘2’,`id_shop_default` = ‘1’,`is_root_category` = ‘0’,`position` = ‘0’,`date_add` = ‘2020-02-05 16:30:56’,`date_upd` = ‘2020-03-31 11:24:20’,`prix_2` = ‘1’ WHERE `id_category` = 3

    Et j’ai vider le cache.

    Je n’arrive pas à trouver ou j’ai fais une erreur, pouvez vous m’aider s’il vous plait ?

    Merci beaucoup

  4. Hello, je viens d’appliquer le tuto à la version 1.7.6.2 mais cela ne fonctionne pas, j’ai des erreurs PHP, dommage ! Car la balise H1 personnalisée me semble nécessaire pour un bon référencement. En attendant un nouveau tuto, connaîtriez-vous un module prestashop qui fonctionnerait ?
    En tous cas merci de votre travail !

    1. Bonjour Dino,
      J’ai noté et j’avais prévu de faire une vidéo sur le sujet.
      Restez connecté !

  5. Bonjour,
    Merci pour le tuto.
    J’essaye de l’appliquer à la nouvelle version 1.7.6 or le fichier AdminCategoriesController.php n’existe plus ..:/
    Merci

    1. Bonjour,
      En effet, le tuto n’est pas valable pour cette nouvelle version !
      Un nouveau tuto sera sûrement publié 😉

  6. Bonjour,
    Merci pour ce tuto fort intéressant, avez vous la même solution mais pour créer un deuxième champ texte en bas de page des catégories?
    Merci,

    1. Bonjour Antoine,
      Il vous suffit de dupliquer le tuto avec un second champ en plus de “titre_2” 🙂
      A bientôt 🙂

  7. Merci pour ce tuto ! Mais si je veux l’afficher dans les sous-catégories ?
    $subcategory.titre_2 ne fonctionne pas 🙂

    1. Hello,
      J’ai mis à jour l’article avec la réponse pour ajouter un nouveau champ aux sous-catégories de PrestaShop et aussi pour utiliser ce champ dans les fichiers tpl 🙂

  8. Bonjour,
    Après avoir crée le champs en base de donnée, je n’ai pas le champ qui s’est ajouté dans la view du BO… Avez-vous une solution ?
    Merci 🙂

    1. Bonjour Yassir,
      En effet, je vais mettre à jour le tuto car j’avais indiqué 5 étapes or seule la première s’affiche. Il manque notamment celle pour remplacer les fichiers AdminCategoriesController.php et Category.php en faisant des overrides.
      Je viens de mettre à jour 😉
      A bientôt !

  9. Pour Prestashop 1.7.3 cela ne marche pas, le titre est bien dans la basse de données, mais il ne s’affiche pas dans le champ en BO et il disparaît quand on réenregistre la page de la catégorie.

    1. Bonjour Lola,
      Merci pour votre commentaire,
      J’ai bien testé ce jour et l’information est bien enregistrée.
      C’est le fichier AdminCategoriesController.php qui gère l’affichage en admin, avez-vous bien remplacé ce fichier aussi ?
      A bientôt 🙂

  10. Bonjour,
    Merci pour ce tuto qui m’a bien servi.
    Quel serait la procédure pour l’ajout d’un champs de type image ?
    Toujours en prestashop 1.7.

    1. Bonjour Gazmasta,
      Merci pour le commentaire,
      Je me note de rédiger un billet sur ce point car c’est une demande récurrente en effet 😉

Laisser un avis

Consultez les autres articles