Category Tree Structure
Category Hierarchy
-- Category tree with path
SELECT entity_id, parent_id, path, level, name, children_count
FROM catalog_category_entity
ORDER BY path;
+-----------+-----------+-------------+-------+---------------+---------------+
| entity_id | parent_id | path | level | name | children_count|
+-----------+-----------+-------------+-------+---------------+---------------+
| 1 | 0 | 1 | 0 | Root | 1 |
| 2 | 1 | 1/2 | 1 | Default | 3 |
| 3 | 2 | 1/2/3 | 2 | Electronics | 2 |
| 4 | 2 | 1/2/4 | 2 | Clothing | 2 |
| 5 | 3 | 1/2/3/5 | 3 | Phones | 0 |
| 6 | 3 | 1/2/3/6 | 3 | Laptops | 0 |
| 7 | 4 | 1/2/4/7 | 3 | Men | 0 |
| 8 | 4 | 1/2/4/8 | 3 | Women | 0 |
+-----------+-----------+-------------+-------+---------------+---------------+
Path Explanation
Path: 1/2/3/5
1 = Root category (invisible)
2 = Default category
3 = Electronics
5 = Phones
Level 0 = Root
Level 1 = Top level (Default)
Level 2 = Sub level (Electronics, Clothing)
Level 3 = Sub-sub level (Phones, Laptops)
URL Keys and Category URLs
URL Key Configuration
// Category URL key
$category->setUrlKey('electronics');
// URL: https://example.com/electronics.html
// Category with parent path
// URL: https://example.com/electronics/phones.html
// URL suffix configuration
// Stores > Configuration > Catalog > Catalog > Category URL Suffix
// Default: .html
URL Rewrite for Categories
-- Auto-generated URL rewrites
SELECT request_path, target_path, redirect_type
FROM url_rewrite
WHERE entity_type = 'category' AND entity_id = 5 AND store_id = 1;
+---------------------------+----------------------------+---------------+
| request_path | target_path | redirect_type |
+---------------------------+----------------------------+---------------+
| electronics/phones.html | catalog/category/view/id/5 | 0 |
+---------------------------+----------------------------+---------------+
Category URL Generation
// Get category URL
$category = $categoryRepository->get(5, $storeId);
$url = $category->getUrl();
// Returns: https://example.com/electronics/phones.html
// Get category URL key
$urlKey = $category->getUrlKey();
// Returns: 'phones'
// Set custom URL key
$category->setUrlKey('smartphones');
$category->save();
// URL becomes: https://example.com/electronics/smartphones.html
URL Key Rules
- Lowercase only
- Hyphens for spaces
- No special characters
- Must be unique within parent
- Auto-generated from name if not set
Examples:
Electronics → electronics
T-Shirts → t-shirts
Kids Clothing → kids-clothing
Display Modes and Anchor Categories
Display Modes
// Category display mode
$category->setDisplayMode('PRODUCTS'); // Products only
$category->setDisplayMode('PAGE'); // CMS page
$category->setDisplayMode('PRODUCTS_AND_PAGE'); // Products + CMS
// Set CMS page for category
category->setCmsPageId(5);
// or
$category->setLandingPage('about-us');
Anchor Categories
// Is anchor (use for layered navigation)
$category->setIsAnchor(1); // Yes - shows layered navigation
$category->setIsAnchor(0); // No - no layered navigation
// Anchor = includes products from subcategories
// Electronics (anchor=1)
// ├── Phones (has products)
// └── Laptops (has products)
// Electronics page shows products from Phones AND Laptops
Anchor vs Non-Anchor
| Feature | Anchor (1) | Non-Anchor (0) |
|---|---|---|
| Layered navigation | Yes | No |
| Shows subcategory products | Yes | No |
| Filter by attributes | Yes | No |
| Performance | Slower | Faster |
Display Mode Configuration
// Products per page
$category->setPageSize(20);
// Product listing order
$category->setDefaultSortBy('position');
// Options: position, name, price, sku
// Product listing direction
$category->setDefaultSortOrder('asc');
// Options: asc, desc
// Show product count
$category->setIsShowProductCount(true);
// Show in navigation
category->setIncludeInMenu(1);
// Active status
$category->setIsActive(1);
Category Attributes and Management
Category Attributes
-- Category attributes
SELECT a.attribute_code, a.frontend_input, a.is_required
FROM eav_attribute a
WHERE a.entity_type_id = 3
LIMIT 15;
+---------------------+-----------------+-------------+
| attribute_code | frontend_input | is_required |
+---------------------+-----------------+-------------+
| name | text | 1 |
| image | media_image | 0 |
| page_layout | select | 0 |
| url_key | text | 0 |
| url_path | text | 0 |
| is_active | boolean | 1 |
| is_anchor | boolean | 0 |
| position | text | 0 |
| children_count | text | 0 |
| description | textarea | 0 |
| display_mode | select | 0 |
| cms_page | select | 0 |
| default_sort_by | select | 0 |
| page_size | text | 0 |
| default_sort_order | select | 0 |
+---------------------+-----------------+-------------+
Programmatic Category Management
// Create category
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$objectManager->get(
\Magento\Catalog\Model\CategoryFactory::class
)->create();
$category->setName('New Category')
->setUrlKey('new-category')
->setParentId(3) // Parent category ID
->setIsActive(1)
->setIsAnchor(1)
->setDisplayMode('PRODUCTS')
->setDefaultSortBy('position')
->setPageSize(20)
->save();
// Update category
$category = $categoryRepository->get(5);
$category->setName('Updated Name');
$category->save();
// Delete category
$category->delete();
// Get category tree
$tree = $category->getTreeModel();
$tree->load();
$tree->loadInBackground();
// Get child categories
$children = $category->getChildrenCategories();
foreach ($children as $child) {
echo $child->getName();
}
Category Collection
// Get all active categories
$collection = $objectManager->get(
\Magento\Catalog\Model\ResourceModel\Category\Collection::class
);
$collection->addFieldToFilter('is_active', 1)
->addFieldToFilter('level', ['gteq' => 1])
->addFieldToFilter('level', ['lteq' => 3]);
// Get root categories
$rootCategories = $collection->addFieldToFilter('parent_id', 1);
// Get category with product count
$collection->addCountToSelect();
foreach ($collection as $category) {
echo $category->getName() . ' (' . $category->getProductCount() . ')';
}
Quiz
1. What does the category path represent?
2. What does is_anchor=1 enable?
3. What are the display modes?
Flashcards
Question
What is a category path?
Click to reveal answer
Answer
Slash-separated ancestor IDs: 1/2/3/5 (root/parent/category/leaf)
Question
What is is_anchor?
Click to reveal answer
Answer
Enables layered navigation and shows subcategory products
Question
What are display modes?
Click to reveal answer
Answer
PRODUCTS, PAGE, PRODUCTS_AND_PAGE
Question
How are category URLs generated?
Click to reveal answer
Answer
From url_key attribute with suffix (e.g., electronics/phones.html)
Question
What is children_count?
Click to reveal answer
Answer
Number of direct child categories
Revision Notes
Key Takeaways
- 1. Category tree uses path column for hierarchy (1/2/3/5)
- 2. URL keys generate category URLs (electronics/phones.html)
- 3. is_anchor=1 enables layered navigation and subcategory products
- 4. Display modes: PRODUCTS, PAGE, PRODUCTS_AND_PAGE
- 5. Category attributes: name, image, url_key, is_active, is_anchor
Interview Tips
- • Explain the category tree structure using path column
- • Discuss anchor vs non-anchor categories
- • Describe URL key generation and URL rewrites
Cheat Sheet
Category Structure:
path: 1/2/3/5 (root/parent/category/leaf)
level: depth in tree
children_count: direct children
URL:
url_key + suffix = URL
electronics/phones.html
Display:
display_mode: PRODUCTS/PAGE/PRODUCTS_AND_PAGE
default_sort_by: position/name/price/sku
page_size: products per page
Anchor:
is_anchor=1: layered navigation + subcategory products
is_anchor=0: no layered navigation
Attributes:
name, image, url_key, is_active, is_anchor,
position, display_mode, cms_page, default_sort_by