Discussion:
[TYPO3-english] Rendering sys_category tree in FE
Jan Kornblum
2013-12-31 17:43:10 UTC
Permalink
Dear newsgroup,

i've got an extended sys_category model to categorize own "recipe"
records. Everything is fine and rendering the category tree in the
backend using makeCategorizable() to assign categories works. Now i
would like to render a category tree in the frontend (like a HMENU
does) to filter my "recipe" records. how to realize this the best way?

"categoryRepository->findAll()" returns a "flat" result where each
category has got a "parent" property but somthing like "subcategories"
is missing. Do i have to rebuild the category array myself to store
each categories subcategories to be able to loop over them in fluid? Or
are there any possibilities given by the core API or by fluid to render
a category tree like a HMENU in the frontend?

Kind regards and "einen guten Rutsch", Jan
Torsten Schrade
2014-01-02 06:37:28 UTC
Permalink
Hi Jan,

happy new year to you. I had a similar task some time ago. I've put my
solution together as a little example extension. Check out this link:

https://github.com/digicademy/categories_example

Have fun and best regards,
Torsten
Post by Jan Kornblum
Dear newsgroup,
i've got an extended sys_category model to categorize own "recipe"
records. Everything is fine and rendering the category tree in the
backend using makeCategorizable() to assign categories works. Now i
would like to render a category tree in the frontend (like a HMENU
does) to filter my "recipe" records. how to realize this the best way?
"categoryRepository->findAll()" returns a "flat" result where each
category has got a "parent" property but somthing like "subcategories"
is missing. Do i have to rebuild the category array myself to store
each categories subcategories to be able to loop over them in fluid? Or
are there any possibilities given by the core API or by fluid to render
a category tree like a HMENU in the frontend?
Kind regards and "einen guten Rutsch", Jan
Jan Kornblum
2014-01-03 08:04:20 UTC
Permalink
Hi Torsten,
Post by Torsten Schrade
happy new year to you. I had a similar task some time ago. I've put my
https://github.com/digicademy/categories_example
Happy new year to you, too. Thank you very much for this example!

Kind regards, Jan
Jan Kornblum
2014-01-03 16:27:25 UTC
Permalink
Hi Torsten, again,

am i right that your example code doesn't not handle recursive
categories? It looks like it just can handle 2 levels (parent and
child)... Or do i miss anything?

Kind regards, Jan
Torsten Schrade
2014-01-04 16:26:07 UTC
Permalink
Hi Jan,
Post by Jan Kornblum
am i right that your example code doesn't not handle recursive
categories? It looks like it just can handle 2 levels (parent and
child)... Or do i miss anything?
Quite right, at the time i just needed two levels ;) But the need for
recursion is of course a good point and I changed the extension to
support this. Check out the lates master, it now supports a tree depth
of five levels. If more levels are really really needed, they could
just be added fluidwise. Infinite recursion is nothing easily achieved
with pure Fluid and therefore not implemented.

Cheers and happy testing,
Torsten
Philipp Gampe
2014-01-04 19:56:52 UTC
Permalink
Hi Torsten,
Post by Torsten Schrade
Infinite recursion is nothing easily achieved
with pure Fluid and therefore not implemented.
You do this via a partial. Just make sure to pass some kind of recursion
stop variable.

Best regards
--
Philipp Gampe ? PGP-Key 0AD96065 ? TYPO3 UG Bonn/K?ln
Documentation ? Active contributor TYPO3 CMS
TYPO3 .... inspiring people to share!
Torsten Schrade
2014-01-04 22:55:20 UTC
Permalink
Hi Philipp
Post by Philipp Gampe
Post by Torsten Schrade
Infinite recursion is nothing easily achieved
with pure Fluid and therefore not implemented.
You do this via a partial. Just make sure to pass some kind of recursion
stop variable.
Many thanks, that was a pretty good tip! Appears to be one of the
obvious things that are sometimes so hard to see? ;)
The example is now working perfectly with infinite recursion and the
amount of Fluid code is greatly reduced.

Thanks again and cheers,
Torsten
Jan Kornblum
2014-01-06 08:46:30 UTC
Permalink
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

Ralf-Rene Schröder
2014-01-04 00:52:28 UTC
Permalink
Now i would like to render a category tree in the frontend (like a HMENU does)
to filter my "recipe" records. how to realize this the best way?
Maybe this helps:
in TYPO3 6.2 there would be a HMENU special type categories
(i don't know if it is ready now, or usable for nested categories)

http://docs.typo3.org/typo3cms/TyposcriptReference/latest/ContentObjects/Hmenu/#hmenu-special-categories
--
image[FORMAT] - Ralf-Ren? Schr?der
http://www.image-format.eu ... Wir geben Ihrem Image das richtige Format

aktueller TIPP: www.startnext.de/typo3-theme-packages
Jan Kornblum
2014-01-04 14:03:08 UTC
Permalink
Hi Ralf-Rene,
Post by Ralf-Rene Schröder
in TYPO3 6.2 there would be a HMENU special type categories
(i don't know if it is ready now, or usable for nested categories)
http://docs.typo3.org/typo3cms/TyposcriptReference/latest/ContentObjects/Hmenu/#hmenu-special-categories
Thanks a lot. I've already read about this, too. But this will just
generate a menu of *pages* belonging to given categories. I nee to have
a menu of categories, independent from pages etc. Just the category
tree itself ;)

Kind regards, Jan
info
2014-01-04 00:55:08 UTC
Permalink
Ik ben van 31 december tot en met 5 januari afwezig. Maandag 6 januari zal ik uw e-mail beantwoorden.

Ik wens u een succesvol 2014.

Met vriendelijke groet,

Michael Albers
Concatenate
Loading...