What I'd like to do is grab all of the child categories of a specific parent category. I'm assuming the best way to do this is by using the parent's ID and of those child categories that are returned, I'd like to grab their child categories as well.
Check below example to get the list of all subcategories of specific parent category using parent category ID using objectManager.
<?php
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$catId = 2; //Parent Category ID
$subCategory = $objectManager->create('Magento\Catalog\Model\Category')->load($catId);
$subCats = $subCategory->getChildrenCategories();
$_helper = $this->helper('Magento\Catalog\Helper\Output');
?>
<ul class="sub-cat-ul">
<?php
foreach ($subCats as $subcat) {
$_category = $objectManager->create('Magento\Catalog\Model\Category')->load($subcat->getId());
$subcaturl = $subcat->getUrl();
$_imgHtml = '';
if ($_imgUrl = $_category->getImageUrl()) {
$_imgHtml = '<img src="' . $_imgUrl . '" />';
$_imgHtml = $_helper->categoryAttribute($_category, $_imgHtml, 'image');
} ?>
<li class="cat-li">
<div class="cat-image">
<a href="<?php echo $subcaturl ?>"><?php echo $_imgHtml;?></a>
</div>
<div class="info">
<h4><?php echo $subcat->getName(); ?></h4>
<a class="link" href="<?php echo $subcaturl ?>"><?php /* @escapeNotVerified */ echo __('View more') ?></a>
</div>
</li>
<?php } ?>
</ul>
=====
Check below example to list of all subcategories of specific parent category using parent category ID using the repository.
First of all add CategoryRepository in construct:
<?php
protected $categoryRepository;
public function __construct(
\Magento\Catalog\Model\CategoryRepository $categoryRepository
) {
$this->categoryRepository = $categoryRepository;
}
?>
Now you can use the following way:
<?php
$categoryId = [YOUR_CATEGORY_ID];
$category = $this->categoryRepository->get($categoryId);
$subCategories = $category->getChildrenCategories();
foreach($subCategories as $subCategory) {
echo $subCategory->getName();
/* For Sub Categories */
if($subcategorie->hasChildren()) {
$childCategoryObj = $this->categoryRepository->get($subCategory->getId());
$childSubcategories = $childCategoryObj->getChildrenCategories();
foreach($childSubcategories as $childSubcategory) {
echo $childSubcategory->getName();
}
}
}
?>
-
2
-
3You shouldn't use the objectManager like this. Reference: magento.stackexchange.com/questions/117098/… – Frank Groot Mar 12 '19 at 10:08
You need to add a dependency to your class \Magento\Catalog\Model\ResourceModel\Category\CollectionFactory
.
Like this:
protected $categoryCollectionFactory;
public function __construct(
...
\Magento\Catalog\Model\ResourceModel\Category\CollectionFactory $categoryCollectionFactory,
...
) {
...
$this->categoryCollectionFactory = $categoryCollectionFactory;
...
}
public function getDescendants($category, $levels = 2)
{
if ((int)$levels < 1) {
$levels = 1;
}
$collection = $this->categoryCollectionFactory->create()
->addPathsFilter($category->getPath().'/')
->addLevelFilter($category->getLevel() + $levels);
return $collection;
}
now you just need to call the method getDescendants
with the $category
object as a parameter and the number of levels you need for subcategories (2 in your case).
-
I'm giving this a shot, but can you clarify what code should be used in the phtml file? – Paul Jul 15 '16 at 15:11
-
you need to add this code to your block class, and in your phtml you can use
$block->getDescendents($category, 2)
where$category
is the main category. (I don't know where you get that from). – Marius♦ Jul 15 '16 at 15:19 -
@Marius Hey Marius, I know an old post but how does one work out what should be where the ... are? – Jon Holland Sep 16 '19 at 10:12
-
Always try to use repository. Here is an example.
Inject CategoryRepository
by construct
protected $categoryRepository;
public function __construct(
\Magento\Catalog\Model\CategoryRepository $categoryRepository
) {
$this->categoryRepository = $categoryRepository;
}
Now you can use following way:
$parent_category_id = 3;
$categoryObj = $this->categoryRepository->get($parent_category_id);
$subcategories = $categoryObj->getChildrenCategories();
foreach($subcategories as $subcategorie) {
echo ' --> '.$subcategorie->getName().'<br/>';
}
For 2 level child category:
$categoryObj = $this->categoryRepository->get($parent_category_id);
$subcategories = $categoryObj->getChildrenCategories();
foreach($subcategories as $subcategorie) {
echo ' --> '.$subcategorie->getName().'<br/>';
if($subcategorie->hasChildren()) {
$childCategoryObj = $this->categoryRepository->get($subcategorie->getId());
$childSubcategories = $childCategoryObj->getChildrenCategories();
foreach($childSubcategories as $childSubcategorie) {
echo ' --> '.$childSubcategorie->getName().'<br/>';
}
}
}
-
this will get you only 1 level of subcategories. The OP asked for 2 levels. – Marius♦ Jul 15 '16 at 14:53
-
1Even better than using the repository model directly, use the interface.
\Magento\Catalog\Api\CategoryRepositoryInterface
– Andrei Oct 1 '17 at 10:44 -
How to limit getChildrenCategories to 4 only? I need first 4 children categories of parent category – jafar pinjar Nov 10 '18 at 7:43
Use below code to get all active child categories of a specific category.
Function getChildCategories($categoryId) gives all child categories. Where $categoryId - is parent category id
<?php
namespace YourModuleName\CategoryLink\Block;
use Magento\Framework\View\Element\Template;
use Magento\Framework\View\Element\Template\Context;
use Magento\Catalog\Model\CategoryFactory;
/**
* Category link block
*/
class Link extends Template
{
/**
* @var Magento\Catalog\Model\CategoryFactory
*/
protected $_categoryFactory;
/**
*
* @param Context $context
* @param array $data
*/
public function __construct(
Context $context,
CategoryFactory $categoryFactory,
array $data = []
) {
parent::__construct($context, $data);
$this->_categoryFactory = $categoryFactory;
}
/**
* Get children categories
*
* @param $categoryId Parent category id
* @return Magento\Catalog\Model\ResourceModel\Category\Collection
*/
public function getChildCategories($categoryId)
{
$_category = $this->_categoryFactory->create();
$category = $_category->load($categoryId);
//Get category collection
$collection = $category->getCollection()
->addIsActiveFilter()
->addOrderField('name')
->addIdFilter($category->getChildren());
return $collection;
}
}
$category->getChildren() - This will gives all chid categories ids.
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$category = $objectManager->get('Magento\Framework\Registry')->registry('current_category');//get current category
$catId = $category->getId(); // Parent Category ID
$subcategory = $objectManager->create('Magento\Catalog\Model\Category')->load($catId);
$subcats = $subcategory->getChildrenCategories();
$categoryHelper = $this->getCategoryHelper();
<div class="category_bg mobile">
<ul id="main_cat_bg" class="main_cat_bg">
<?php
$cat_togg = 0;
foreach ($subcats as $subcat) {
if (!$subcat->getIsActive()) {
continue;
}
$_category = $objectManager->create('Magento\Catalog\Model\Category')->load($subcat->getId());
//$_outputhelper = $this->helper('Magento\Catalog\Helper\Output');
$helper = $this->helper('SR\CategoryImage\Helper\Category');
$subcaturl = $subcat->getUrl();
$imageUrlthum = $helper->getImageUrl($_category->getData('thumbnail'));
//$imageUrlthum = resize($_category->getData('thumbnail'),153,153);
//$cat_desc = $_category->getCatDescription();
$_imgHtml = '';
if ($imageUrlthum) {
$_imgHtml = '<img src="' . $imageUrlthum. '" />';
//$_imgHtml = $_outputhelper->categoryAttribute($_category, $_imgHtml, 'image');
/* @escapeNotVerified */
}
?>
<li>
<div class="sub_cat_content_main">
<div class="cat_image_text">
<a href="<?php echo $subcaturl ?>">
<?php echo $_imgHtml;?>
<!--<div class="desicription_part">-->
<?php //echo $cat_desc; ?>
<!--</div>-->
</a>
<div class="sub_name_bg">
<a href="<?php echo $subcaturl ?>">
<?php echo $subcat->getName(); ?>
</a>
</div>
<!-- Start 3rd Level Chiled Category-->
<?php
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$object_managertwo = $objectManager->create('Magento\Catalog\Model\Category')->load($subcat->getId());
$subcatslevelthird = $object_managertwo->getChildrenCategories();
?>
<?php if ($subcatslevelthird->count() > 0) { ?>
<ul class="sub_cat_bg">
<?php
foreach ($subcatslevelthird as $subcatthird) {
$_outputhelper = $this->helper('Magento\Catalog\Helper\Output');
$subcaturl = $subcatthird->getUrl();
?>
<li class="cat_image_bg">
<a class="level-top" href="<?php //echo $subcaturl ?>">
<span><?php //echo $subcatthird->getName(); ?></span>
</a>
<div class="child_name_bg">
<span><?php echo $subcatthird->getName(); ?></span>
</div>
<!-- Start 4th Level Chiled Category-->
<?php
$_objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$object_managerthree = $_objectManager->create('Magento\Catalog\Model\Category')->load($subcatthird->getId());
$subcatslevel = $object_managerthree->getChildrenCategories();
?>
<?php if ($subcatslevel->count() > 0){?>
<ul class="chiled_cat_bg">
<?php
foreach ($subcatslevel as $subcatlevel) {
$_outputhelper = $this->helper('Magento\Catalog\Helper\Output');
$subcaturl = $subcatlevel->getUrl();
?>
<li class="cat_image_bg">
<a class="level-top" href="<?php echo $subcaturl ?>">
<span><?php echo $subcatlevel->getName(); ?></span>
</a>
</li>
<?php } ?>
</ul>
<?php } ?>
<!-- End 4th level Chiled Category-->
</li>
<?php } ?>
</ul>
<?php } ?>
<!-- End 3rd level Chiled Category-->
</div>
</div>
</li>
<?php } ?>
</ul>
<div id="view_more">
View more
</div>
</div>
-
I want to be sorted children categories, by category name, please help on this? – Kamlesh Yaduwanshi Aug 9 '19 at 12:05
-
$subcats = $subcategory->getChildrenCategories();
– Kamlesh Yaduwanshi Aug 9 '19 at 12:04