Try ...
$tree = Group::get()->toTree()->toJson();
Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.
Hey,
I am using a nested set (https://github.com/lazychaser/laravel-nestedset) to hold a hierarchy of user groups.
I now want to be able to select a group for a user, using a treeview. I was thinking maybe something like this:
https://vuejs.org/v2/examples/tree-view.html
Has anyone got any experience of anything like this?
My biggest concern, is getting the data into the correct structure for Vue.
Mick
Try ...
$tree = Group::get()->toTree()->toJson();
Yes, I used this for my CMS (my content is hierarchical). I was using the Baum package, so some implementation details will be different.
First step was to create an internal API to make a Collection of the tree-like content and return it as JSON:
[
{
id: 1,
parent_id: null,
depth: 0,
title: "Root item",
...
children: [
{
id: 2,
parent_id: 1,
depth: 1,
title: "First child"
...
children: [
{
...
}
]
},
{
id: 7,
...
}
]
},
{
id: 15
...
}
]
As @topvillas mentioned, the package can help you with this. Depending on your needs, you may need to fiddle with the data structure though, and that can be a pain.
You can then bring this into Vue by making an AJAX request (e.g. with Axios).
You then need to create a recursive component -- i.e. a component that includes itself. My component was called PagesTree, so its template structure was like this:
<template>
<li>
<ul>
<pages-tree v-for="tree in tree.children" :tree="tree"></pages-tree>
</ul>
</li>
</template>
Then you use this template by sticking it inside a <ul>.
I removed a bunch of code to simplify it, but you get the basic idea. It actually turned out really, really complicated in my case, although that's partly because I'm inexperienced with this stuff. I did need to do some data manipulation in JS, after retrieving it from my API.
Thanks guys. I will let you know how I get on.
I my experience these things always do get complicated and I'm hoping to avoid it this time.
Any chance I can see your code to make your data structure?
Sure -- though it is a bit of a mess! I've tried to include only the relevant code here, but may have missed some:
class ApiController extends Controller
{
public function getFullContentTree()
{
$roots = ContentPage::roots()->get();
return ContentPage::getTree( $roots, Request::get('depth') );
}
public function getPartialContentTree()
{
$root = Request::get('root');
if ( is_numeric($root) )
{
$root = ContentPage::find($root);
}
return ContentPage::getTree( Request::get('root'), Request::get('depth') );
}
}
class ContentPage extends Node
{
public static function getTree($roots, $depth = null)
{
return (new ContentTreeBuilder)->getTree($roots, $depth);
}
// Takes a url, an array of urls, or a single page object, and returns a collection of pages
public static function normaliseToCollection($pages)
{
if ( is_numeric($pages) )
{
$pages = self::find($pages);
}
if ( is_object($pages) && get_class($pages) === self::class )
{
$collection = new Collection;
$collection->add($pages);
return $collection;
}
if ( is_string($pages) )
{
$pages = [$pages];
}
if ( is_array($pages) )
{
$collection = new Collection;
foreach ( $pages as $page )
{
$collection->add( self::get($page) );
}
return $collection;
}
return $pages;
}
}
// I've extended the Baum package with some extra methods
use Baum\Node as Baum;
class Node extends Baum
{
public static function getChildren(Node $node, $depth)
{
if ( is_null($depth) )
{
return $node->getDescendantsAndSelf();
}
return $node->getDescendantsAndSelf($depth);
}
}
class ContentTreeBuilder
{
public function getTree($roots, $depth = null)
{
$roots = ContentPage::normaliseToCollection($roots);
$tree = new Collection;
foreach ($roots as $root)
{
$tree->add( ContentPage::getChildren($root, $depth)->toHierarchy()->first() );
}
return $tree;
}
}
Thanks Mike
Got mine working.
I did use this:
$tree = Group::get()->toTree()->toJson();
Then just have to rename one key in my JSON.
Thanks,
Mick
Please or to participate in this conversation.