So, I thought I would share with the Drupal community some code I wrote to create a browsable tree view of vocabularies in a taxonomy that are all single level. After days of searching (without any luck) for a module that would create a tree structure of my single level vocabularies, I wrote some code that dynamically creates the tree structure.
So why not just create the vocabularies in a tree structure to begin with? I think this is the norm for many sites, but the nodes in my site do not have a clear tree hierarchy that is agreed upon by all of the people that use my site, as well as if you want to change the tree structure (with many nodes already added) it's not that easy. Plus, I wanted the tree structure to be dynamic. In fact, I want to be able to offer different trees to accommodate different users.
The method to creating the tree structure is to define the vocabulary hierarchy using the vocabulary ids (4,8,6,2: where these are the vid's of the vocabularies I want to create a tree for). Then, traverse the vocabularies, in the above order, using the terms as folders, and the nodes as the tree leaves. The nodes in the sub terms/folders must be present in the parent folder. Thus, creating a tree view of the nodes across single level vocabularies.
Here is the code in action:
http://www.videobjj.com/?q=tree
I know how to program in PHP but not a Drupal guru, so the code is written using a view, then using template.php to generate the node listing for the view page. I am sure the code can be easily modified into a module. The beauty of the code, is at any point I can change the vocabulary order, and create a different tree structure without ever having to modify the taxonomy vocabulary hierarchies. The down side, is that the tree is programmaticly driven, meaning the more vocabularies (terms,nodes), the more resources are required to generate the tree. However, the code is recursive and as fast as I can make it.
If you are interested in the code, let me know and I will send it to you. Send me an email via the contact button from the site above. If enough people drive interest, I will try to make a module out of it.
I am thinking that others have had to be as frustrated as me trying to figure this out... Maybe it will help someone...
John
Comments
Not neccessarily needs to be a module
I think you did a very good job the way you made your tree using Views and template.php code. So you might not need to create a module for this. Why not explain here how you did manage to create the tree with single level vocabularies. Other users might help you on enhancing the code.
You might also consider publishing a step by step documentation in the Drupal.org How To section: http://drupal.org/handbook/customization/howto
If your code in template is too large, you might consider creating a module. But if you do so, make sure it will still use Views.
/*_*/
http://www.xmacinfo.com
Here's the code
I've had a few requests already for the code, and based on xmacinfo's suggestion, here's the code and how to use it. I was thinking that maybe someone else could have a look at the code and make any updates to refine or improve it. One suggestion to make it better is:
* Currently, it builds the tree on all the nodes that are in the vocabulary definition. However, it could be updated to only create the tree based on the nodes filtered from the view in the selected vocabularies.
The code is based on the javascript "Simple Tree Menu" at http://www.dynamicdrive.com/dynamicindex1/navigate1.htm
You will need to download the above JS code and place in your theme directory (or in any location the js files can be read). In my case, simply created a "simpletree" directory in my theme directory:
# mkdir sites/all/themes/barlow/simpletree
Here's a directory listing of the files you will need in simpletree folder:
# ls
closed.gif list.gif open.gif simpletree.css simpletreemenu.js
You will also need to update your "page,tpl.php" file in your theme directory to add the necessary java script code to initialize the js files:
# vi page.tpl.php
Add the following between the head tags (be sure to change it where simpletree lives in your path) :
Now, create a view called "tree". This will simple provide a page to create the tree structure in. It doesn't actually use (yet) any nodes filtered.
* Click Admin/Views/Add
* Name: Tree
* Click Page
* Click Check box for "Provide Page View"
* URL: tree
* Uncheck "Use Pager"
* Click "Save"
Now, you simply theme your view by add add the following code to your template.php file in your theme folder:
Make changes to the code above to work for your environment:
In the "function phptemplate_views_view_nodes_tree($view, $nodes, $type)" function, you will want to define the tree using the vocabulary id's of your taxonomy. In this case, vocabulary "11" is the top folder in the tree, followed by "9", etc...
# Define vocabulary tree
$vocabTree=array(11,9,2,3);
Also, in my case, I wanted to have an additional description (vocabulary term) when displaying the titile of the node. The second argument of the bldTree function is the vocabulary ID of the vocabulary for the nodes that contains a description. In other words, for my site, every node is assigned a term in vocabulary 7 that helps to describe the node. This term is then appended to the node title in the tree. To not use this feature, change the 7 below to 0:
# Call recursive function to build tree
$output.=bldTree($vocabTree,7,FALSE,NULL,NULL);
That's it! Hopefully this make sense...
If you do get it working, please post here that you got it working. If people start to use it, i will try to create a how to page once the code is more mature.
John
Update: Now integrates with views
It turns out that it was easy to integrate with views, and use the nodes filtered from views by just sending the array of nodes to the recursive function. I have also made a few minor changes to the code to create a category heading per vocabulary folder, I also included a parameter that allows the node to display the vote count (in my case jrating).
I have also updated my page (http://www.videobjj.com/?q=tree) to show 2 separate trees as well as a filter that only shows nodes that have 3 stars or higher for that tree. To get this working you have to setup the views to work with tabs(each tab is a view). Each view must have a corresponding function in template.php to theme it. In my case, I have four views with four functions in template.php:
Alot of the code in each function above is just repeated for each view. Thus, it would be better to have the repeatable code in one single function then called in each view theme function. But, it works for now...
Also, note, I added the last argument (TRUE) to the bldTree function that means append the vote for the node as part of the description of the leaf nodes in the tree.
Also, note, the second tree is identified as "treemenu2".
Finally, Here's the updated code for the main bldTree function in template.php (append this code just below the above code in template.php):
John
Now with Cache
I have it working with cache for much faster performance. I also added subroutine for all views instead of copy/paste. Let me know if you would like the update of code. Don't want to repost unless someone wants it...
Please do try to post it
Please do.
I'd be interested to know how you do this.
/*_*/
http://www.xmacinfo.com
Tree browser with cache
So, building the tree on every visit was time consuming especially on my very old server. Decided to use a file based cache that gets built on a daily basis. Basically, if user browses the tree and its more than 24 hours old, it will rebuild the tree and cache it. You will need to update the putCache and getCache functions to write to a writable directory on your server. Also, i minimized the views functions to call a function which builds the tree. This avoided duplicating the same code over and over for each view tab. I haven't spent a lot of time on the updated code, so I am sure there is some error checking that could be added but it is working fine in my environment for the past couple of days.
Here's the update of the code:
A working version for Drupal 6.x
The taxonomy tree is pretty cool. However it's not working with Drupal 6.x. (I guess g051798 are using 5.x)
The main difference:
1. Drupal 6.x has View2.
2. the taxonomy module is modified.
3. I am using Multiple vocabulary.
The tweak I made:
1. create a file views-view-unformatted--taxonomy-tree.tpl.php and put it under the default theme folder.
2. put the following code in the file:
Note:
1. I changed bldTree function so it's not recursive any more.
2. BatchbldTree will loop through all the vocabularies.
3. taxonomy_get_vocabulary() is replaced by taxonomy_vocabulary_load().
4. taxonomy_select_nodes() results is objects instead of arrary. so mysql_num_rows(), mysql_fetch_array() will give an error message like "warning: mysql_num_rows(): supplied argument is not a valid MySQL result resource".
5. I haven't tried the cache feature.
6. I am still working on this and I will report any new progress.
Looks good. Do you have a demo?
wchen,
Looks good. Do you have a demo of it working. You are correct, I am using version 5.x. I don't have 6.x yet so not able to see your code working. I do have a couple of questions. Are your vocabularies single level or do you have vocabs in hierarchy? Will it work for vocabs that have more than one level? Your example code has a tree of vocabs 2,2 which are the same. Will it work for diff vocabs. I think it will but just curious.
Looking forward to your updates as you progress.
John
Hi, John, Unfortunately I
Hi, John,
Unfortunately I can't setup a demo site. I am using hierarchy vocabularies and it works fine. The only reason that vocabs 2,2 is I only had one vocabulary at that time. I did more test with multiple vocabularies and it works fine.
You have done a great job and I am happy that I can contribute a little bit.