[TYPO3-english] Rendering sys_category tree in FE

Jan Kornblum jan.kornblum at gmx.de
Mon Jan 6 09:46:30 CET 2014


Hi Torsten and Philipp,

inspired by you, i've also got a working solution with infinite 
recursion in between. It is not perfect yet and everything is written 
into the repository class, but it is working.


### CategoryRepository:

/**
 * findAllAsRecursiveTreeArray
 *
 * @param \Vendor\Ext\Domain\Model\Category $selectedCategory
 * @return array $categories
 */
public function findAllAsRecursiveTreeArray($selectedCategory = NULL) {
	$categoriesArray = $this->findAllAsArray($selectedCategory);
	$categoriesTree = $this->buildSubcategories($categoriesArray, NULL);
	return $categoriesTree;
}

/**
 * findAllAsArray
 *
 * @param \Vendor\Ext\Domain\Model\Category $selectedCategory
 * @return array $categories
 */
public function findAllAsArray($selectedCategory = NULL){
	$localCategories = $this->findAll();
	$categories = array();
	// Transform categories to array
	foreach($localCategories as $localCategory){
		$newCategory = array(
			'uid' => $localCategory->getUid(),
			'title' => $localCategory->getTitle(),
			'parent' => 
($localCategory->getParent()?$localCategory->getParent()->getUid():NULL),
			'subcategories' => null,
			'isSelected' => ($selectedCategory == $localCategory ? true : false)
		);
		$categories[] = $newCategory;
	}
	return $categories;
}

/**
 * findSubcategoriesRecursiveAsArray
 *
 * @param \Vendor\Ext\Domain\Model\Category $parentCategory
 * @return array $categories
 */
public function findSubcategoriesRecursiveAsArray($parentCategory){
	$categories = array();
	$localCategories = $this->findAllAsArray();
	foreach($localCategories as $category) {
		if(($parentCategory && $category['uid'] == $parentCategory->getUid()) 
|| !$parentCategory){
			$this->getSubcategoriesIds($localCategories, $category, 
$categories);
		}
	}
	return $categories;
}


/**
 * getSubcategoriesIds
 *
 * @param array $categoriesArray
 * @param array $parentCategory
 * @param array $subcategoriesArray
 * @return void
 */
private function getSubcategoriesIds($categoriesArray,$parentCategory, 
&$subcategoriesArray){
	$subcategoriesArray[] = $parentCategory['uid'];
	foreach($categoriesArray as $category){
		if($category['parent'] == $parentCategory['uid']){
			$this->getSubcategoriesIds($categoriesArray, $category, 
$subcategoriesArray);
		}
	}
}


/**
 * buildSubcategories
 *
 * @param array $categoriesArray
 * @param array $parentCategory
 * @return array $categories
 */
private function buildSubcategories($categoriesArray,$parentCategory){
	$categories = NULL;
	foreach($categoriesArray as $category){
		if($category['parent'] == $parentCategory['uid']){
			$newCategory = $category;
			$newCategory['subcategories'] = 
$this->buildSubcategories($categoriesArray, $category);
			$categories[] = $newCategory;
		}
	}
	return $categories;
}



### Category - List Template:

<ul>
	<f:for each="{categories}" as="category" iteration="categoryIterator">
		<f:render partial="Category/PropertiesList" 
arguments="{category:category, selectedCategory:selectedCategory}" />
	</f:for>
</ul>



### Category - List Partial

<li {f:if(condition: '{category.isSelected}', then: ' 
class="selected"', else: '')}>
    <f:link.action arguments="{category:category.uid}">
        {category.title}
    </f:link.action>
    <f:if condition="{category.subcategories}">
        <ul>
            <f:for each="{category.subcategories}" as="subcategory" 
iteration="categoryIterator">
                <f:render partial="Category/PropertiesList" 
arguments="{category:subcategory, selectedCategory:selectedCategory}" 
/>
            </f:for>
        </ul>
    </f:if>
</li>


Wouldn't it be a good idea to extend the core categorization api to 
have subcategories automatically beeing hold in a category's 
"subcategories" property? Currently, there is just a "parent" property 
available. When having a "subcategories" property in addition, most of 
the code above to create a recursive tree array wouldn't be needed any 
longer and many tasks using categories would be much easier... I've 
already created an issue for this some time ago:

http://forge.typo3.org/issues/53091#change-188285

What do you think?

Kind regards, Jan




More information about the TYPO3-english mailing list