I'm currently looking for help with linking the main category links in the header menu directly to their first subcategory.
In other words:
when clicking on the category link I would like to add the ID of the first subcategory at the end, ie
route=product/category&path=18_59
instead of
route=product/category&path=18
Does anyone has a suggestion how to do that?
<div id="menu">
<ul>
<?php foreach ($categories as $category) { ?>
<li><a href="<?php echo $category['href']; ?>"><?php echo $category['name']; ?></a>
<?php if ($category['children']) { ?>
<div>
<?php for ($i = 0; $i < count($category['children']);) { ?>
<ul>
<?php $j = $i + ceil(count($category['children']) / $category['column']); ?>
<?php for (; $i < $j; $i++) { ?>
<?php if (isset($category['children'][$i])) { ?>
<li><a href="<?php echo $category['children'][$i]['href']; ?>"><?php echo $category['children'][$i]['name']; ?></a></li>
<?php } ?>
<?php } ?>
</ul>
<?php } ?>
</div>
<?php } ?>
</li>
<?php } ?>
</ul>
</div>
Welcome to StackOverflow !
This could be achieved by getting the first child of the main category and we have two options, one cleaner and one easier.
The cleaner one . This would require the changes in the catalog/controller/common/header.php
and model catalog/model/catalog/category.php
, let's go on step by step. First, add the new necessary function into the category model:
public function getCategoryFirstChildId($category_id) {
$query = $this->db->query('SELECT category_id FROM '. DB_PREFIX .'category WHERE parent_id = '. (int)$category_id .' ORDER BY category_id ASC LIMIT 1');
return $query->row['category_id'];
}
This function will get all the categories where parent_id
is the $category_id
given as a parameter, sort them ascending by category_id
(You can change that to whatever sorting You want) and return only the first one.
Now let's go to the controller - we will edit the part where categories are loaded:
foreach ($categories as $category) {
if ($category['top']) {
// Level 2
$children_data = array();
$children = $this->model_catalog_category->getCategories($category['category_id']);
foreach ($children as $child) {
$data = array(
'filter_category_id' => $child['category_id'],
'filter_sub_category' => true
);
$product_total = $this->model_catalog_product->getTotalProducts($data);
$children_data[] = array(
'name' => $child['name'] . ($this->config->get('config_product_count') ? ' (' . $product_total . ')' : ''),
'href' => $this->url->link('product/category', 'path=' . $category['category_id'] . '_' . $child['category_id'])
);
}
/*NEW =>*/ $first_child_id = $this->model_catalog_category->getCategoryFirstChildId($category['category_id']);
// Level 1
$this->data['categories'][] = array(
'name' => $category['name'],
'children' => $children_data,
'column' => $category['column'] ? $category['column'] : 1,
'href' => $this->url->link('product/category', 'path=' . $category['category_id'] . '_' . $first_child_id)
// >>> >>> >>> >>> >>> >>> >>> ^^^^^^^^^^^^^^^^^^^^^^^^
);
}
}
This should be it. Be wise that this though cleaner way requires one more DB query per category thus may slow down (though a tiny bit) the site when large number of categories is being processed.
The easier way - need changes to be done only within header controller (no new function is added to the model):
foreach ($categories as $category) {
if ($category['top']) {
// Level 2
$children_data = array();
/*NEW =>*/ $first_child_id = 0;
/*NEW =>*/ $first_child = true;
$children = $this->model_catalog_category->getCategories($category['category_id']);
foreach ($children as $child) {
/*NEW =>*/ if($first_child) {
/*NEW =>*/ $first_child = false;
/*NEW =>*/ $first_child_id = $child['category_id'];
/*NEW =>*/ }
$data = array(
'filter_category_id' => $child['category_id'],
'filter_sub_category' => true
);
$product_total = $this->model_catalog_product->getTotalProducts($data);
$children_data[] = array(
'name' => $child['name'] . ($this->config->get('config_product_count') ? ' (' . $product_total . ')' : ''),
'href' => $this->url->link('product/category', 'path=' . $category['category_id'] . '_' . $child['category_id'])
);
}
// Level 1
$this->data['categories'][] = array(
'name' => $category['name'],
'children' => $children_data,
'column' => $category['column'] ? $category['column'] : 1,
'href' => $this->url->link('product/category', 'path=' . $category['category_id'] . '_' . $first_child_id)
// >>> >>> >>> >>> >>> >>> >>> ^^^^^^^^^^^^^^^^^^^^^^^^
);
}
}
The easier way will also work very well and would be a little quicker but the first category it will point to will always be the one that comes as first when sorting ascending by sort_order
- whenever it may change, the main category will point to a different child category...
I didn't test neither of the ways but I believe they will work on 100%.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.