Welcome Guest, Not a member yet? Register   Sign In
tree-like menu structure
#1

[eluser]Keph[/eluser]
Hi,

I'm writing a custom CMS with a menu grouping together different categories for the site. My client wants me to implement a tree-like structure, so that each category can have its subcategories which can have its own set of sub-subcategories, and so on.

I've got a mysql table having, among others, fields: name (which serves as id, since it's unique), and parent_name, specifying the parent (sub)category to which the entry belongs.

I'll admit, I have a bit of a problem in getting it to work, so if anyone has any ideas, please go ahead Wink

Regards,
Keph
#2

[eluser]gtech[/eluser]
Have you tried downloading a javascript tree.. Dtree is quite good you can place the javascript in your view and then build up the array by looping through your data base results. each element in the tree can be linked to a url so when you click on it you can redirect to a different controller.

[url="http://www.destroydrop.com/javascripts/tree/"](Javascript dtree)[/url]

dunno if that helps.. there are loads of javascript trees out there but you may need to check the license agreements if you are doing it for a commercial release.
#3

[eluser]BlueCamel[/eluser]
I just completed my first pass at creating a tree menu for a work project. I based it on code I previously used outside of CI and converted it into a CI navigation plugin. My site menu is not stored in since it is not going to be dynamically modified. Instead, I stored the menu as a nested array of names and urls in a config var. When the plugin is initialized the config var is read to retrieve the 'sitemenu' array. This is nice as I can easily override the sitemenu for specific controllers by using existing config methods prior to initializing the site menu plugin.

The plugin, when initialized, uses $CI->uri->uri_string() to find the current page inside the nested array. The code returns an single array (not nested) of all visible menu items. Each item in the array lists the name, url, depth, and if it is the selected page. This array of menu items is passed to my view for formating and display.

Here's a sample of a nested menu array I might use. It's nice because it doesn't care about directory structure, views, or controllers. If you want to see a working sample of the code that was NOT done with CI, check out www.audubonpark.org. Same code, no CI.

Code:
$config['sitemenu'] = array(
    array('Home', '/index'),
    array('Menu Item', '/index/item'),
    array(
        array('Sub Menu Item 1', '/items'),
    ),
    array('Other Menu', '/index/item2'),
)
#4

[eluser]Keph[/eluser]
[quote author="gtech" date="1195434346"]
[url="http://www.destroydrop.com/javascripts/tree/"](Javascript dtree)[/url]
[/quote]

Not exactly what I was looking for, but this might be useful for the cms category-editor itself Smile

BlueCamel: that might help. I mean, the code itself would probably not be applicable to what I'm designing, because I need all elements to be visible, or at least loaded on the page. Still, the uri bit got me thinking: theoretically, I might be able to apply some xpath to do the job Wink

I still need to figure out a way to programmatically sort items so that the array looks like

parent1
parent1-child1
parent1-child2
parent2
parent2-child1
parent2-child2
parent3
parent4

and so on. Any ideas? Smile
#5

[eluser]gtech[/eluser]
Could you not just put a sequence number field in the database?
Or maybe a nextID field so the database can be used like a linked list?

Code:
name childstartid parentid nextid

The nextId will point to the next row in the same hierarchy the end of the list points to NULL.
The childStartId will point to the first child

The same process can be used up and down the hierarchy. You will have to maintain the "pointers" when inserting and deleting, but will be easier to maintain then a sequence number if you insert a row in the middle of a list.

Code:
root
|
|   (childstartid)
+---------------------> Parent1
                          | |       (childstartid)
                          | +----------------------> Parent1-Child1
                          |                                 |
                          |(nextid)                         |(nextId)
                          |                                \|/
                         \|/                         Parent1-Child2
                        Parent2

as an after thought if you wanted to store many different routes for the same data then you might want to create a separate lookup table


content-table <----&gt; lookup <------&gt; routes table

[edit]
The Lookup would contain the parentid,nextid,childstartid,routeid and the contentid (or name)

The content table would contain: contentid, title, data .... and what ever else you require

The routes table would contain: routeid, route_name, description
[/edit]


you may want to think about adding a hierarchy field in the lookup this can help you ensure a childs nextid doesnt point to its parent otherwise you might end up going around in circles.
#6

[eluser]wiredesignz[/eluser]
You do require numeric id's for this to work, ie:

node_id = int(11) auto_increment
node_name = varchar(50)
node_route = text
node_parent_id = int(11) <-- value from parent node_id, root nodes parent_id = 0
#7

[eluser]esra[/eluser]
Thunder UK's Nested Set code on the wiki and associated thread includes a categories sample. The database table for the sample application could be adapted to include a url column for encapsulating categories with a link. The sample also demonstrates how to nest unordered lists in a hierarchy (in this case categoies and subcategories). Because the sample uses nested sets, categories can be nested deeply. With Thunder UK's example, the sample would support a single nested tree, but you could add a column to allow the table to support multiple trees.

Another approach is to use the Adjacency List model where a parent_id field is used to create a hierarchy of nested categories. The Adjacency List model uses recursion. A Main menu item has no parent, but subcategories are associated with a parent category via its id column. You should be able to find a thread or two on the forums with code for implementing the Adjacency List model. Joomla and Mambo 1.x.x used the Adjacency List model for menus. You might take a look at how it was handled there. Joomla 1.5 uses the nested sets model for menus.

EDIT: Did not read far enough down the thread before posting. It looks like wiredesignz is showing the Adjacency List model. Note the parent_id column.
#8

[eluser]CI pedro[/eluser]
Keph,

I recently had a need for the same type of tree based menu you are looking for. I would definitely look into the nested set code that esra suggested. Once you see how it works it is really powerful and easy to use.
#9

[eluser]Keph[/eluser]
Guys, the nested set model is complete and total brilliance! Thanks to everyone who have suggested it!

Just in case anyone'll be looking for a solution to my problem, there's a great article on this site.

Regards,
Keph




Theme © iAndrew 2016 - Forum software by © MyBB