Mijn vraag
Ik wil graag mijn hoofdmenu in de JSON API op kunnen halen, maar ik loop tegen een probleem aan om de array met alle menu items op de juiste manier op te bouwen om de child menu items netjes te nesten.
De opbouw die ik graag zou willen:
Met de volgende code lukt het me om tot 3 subniveau's te komen, maar dat kan natuurlijk netter en zonder herhalen van code. Het nesten wil ik automatisch laten verlopen, omdat je anders zo oneindig door kunt schrijven en het op deze manier om een soort van "hard coded" nesting gaat. Kan iemand me uitleggen hoe ik dit op een nette manier, met snelle performance, voor elkaar kan krijgen?
Met daarbij de output (bij item met ID 50 gaat het mis, dit is een child van item met ID 49, en zo dus in de "subitems" van 49 moeten komen):
De PHP code die ik nu heb doet nu het volgende:
Menu locaties ophalen -> ID van het menu dat nu op de header-menu locatie is ingesteld
Als er een menu is ingesteld: ophalen menu items
Dan komt er een array terug met deze opbouw (versimpelde weergave):
Daarna loopt de code met een foreach door alle items heen, en maakt daarbij onderscheid tussen absolute "root" items en items die een child zijn.
In dit voorbeeld is het 2e item met ID 25 een child van het eerste item met ID 23. Alle onnodige data heb ik daar even tussenuit gehaald. Maar dat gaat zo "oneindig" verder, het volgende item met bijvoorbeeld ID 28 kan weer een child zijn van ID 25, enzovoort. En juist daar gaat het mis, bij het nesten van childs onder andere childs, etc.
Relevante software en hardware die ik gebruik
WordPress 5.3.2
Wat ik al gevonden of geprobeerd heb
Dingen zoals array_walk (_recursive), veel gezocht. Maar geen van de topics hier of op bijvoorbeeld Stackoverflow kan me geven wat ik zoek. En daarnaast wil ik ook graag leren begrijpen wat ik het beste kan doen met dit probleem
Ik wil graag mijn hoofdmenu in de JSON API op kunnen halen, maar ik loop tegen een probleem aan om de array met alle menu items op de juiste manier op te bouwen om de child menu items netjes te nesten.
De opbouw die ik graag zou willen:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
| { "nav": { "23": { "ID": 23, "url": "http://localhost/", "title": "Home", "target": "", "classes": [ "" ], "subitems": { "24": { "ID": 24, "url": "http://localhost/voorbeeld-pagina/", "title": "Voorbeeld pagina TEST", "target": "", "classes": [ "test-class" ], "parent": "23", "subitems": { "49": { "ID": 49, "url": "http://localhost/voorbeeld-pagina/", "title": "Voorbeeld pagina", "target": "", "classes": [ "test1", "test2" ], "parent": "24", "subitems": { "50": { "ID": 50, "url": "http://localhost/", "title": "Home", "target": "", "classes": [ "" ], "parent": "49" } } } } } } }, "48": { "ID": 48, "url": "http://localhost/test-pagina/", "title": "test pagina", "target": "", "classes": [ "" ] } } } |
Met de volgende code lukt het me om tot 3 subniveau's te komen, maar dat kan natuurlijk netter en zonder herhalen van code. Het nesten wil ik automatisch laten verlopen, omdat je anders zo oneindig door kunt schrijven en het op deze manier om een soort van "hard coded" nesting gaat. Kan iemand me uitleggen hoe ik dit op een nette manier, met snelle performance, voor elkaar kan krijgen?
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
| // Menu items $menu_locations = get_nav_menu_locations(); if ( isset( $menu_locations['header-menu'] ) ) { $get_menu_items = wp_get_nav_menu_items( $menu_locations['header-menu'] ); $root_parent_item = null; $subitem_parent = false; foreach ( $get_menu_items as $item ) { $item_id = $item->ID; $parent = $item->menu_item_parent; if ( ! $parent ) { $output['nav'][ $item_id ] = array( 'ID' => $item_id, 'url' => $item->url, 'title' => $item->title, 'target' => $item->target, 'classes' => $item->classes, ); $root_parent_item = $item_id; } else { if( empty ($subitem_parent) ) { $output['nav'][ $root_parent_item ]['subitems'][ $item_id ] = array( 'ID' => $item_id, 'url' => $item->url, 'title' => $item->title, 'target' => $item->target, 'classes' => $item->classes, 'parent' => $parent, ); $subitem_parent = $item_id; } else { $output['nav'][ $root_parent_item ]['subitems'][ $subitem_parent ]['subitems'][ $item_id ] = array( 'ID' => $item_id, 'url' => $item->url, 'title' => $item->title, 'target' => $item->target, 'classes' => $item->classes, 'parent' => $parent, ); } } } } |
Met daarbij de output (bij item met ID 50 gaat het mis, dit is een child van item met ID 49, en zo dus in de "subitems" van 49 moeten komen):
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
| { "nav": { "23": { "ID": 23, "url": "http://localhost/", "title": "Home", "target": "", "classes": [ "" ], "subitems": { "24": { "ID": 24, "url": "http://localhost/voorbeeld-pagina/", "title": "Voorbeeld pagina TEST TITLE", "target": "", "classes": [ "test-classje" ], "parent": "23", "subitems": { "49": { "ID": 49, "url": "http://localhost/voorbeeld-pagina/", "title": "Voorbeeld pagina", "target": "", "classes": [ "test1", "test2" ], "parent": "24" }, "50": { "ID": 50, "url": "http://localhost/", "title": "Home", "target": "", "classes": [ "" ], "parent": "49" } } } } }, "48": { "ID": 48, "url": "http://localhost/test-pagina/", "title": "test pagina", "target": "", "classes": [ "" ] } } } |
De PHP code die ik nu heb doet nu het volgende:
Menu locaties ophalen -> ID van het menu dat nu op de header-menu locatie is ingesteld
Als er een menu is ingesteld: ophalen menu items
Dan komt er een array terug met deze opbouw (versimpelde weergave):
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
| array(5) { [0]=> object(WP_Post)#5594 (37) { ["ID"]=> int(23) ["menu_item_parent"]=> string(1) "0" ["url"]=> string(17) "http://localhost/" ["title"]=> string(4) "Home" ["classes"]=> array(1) { [0]=> string(0) "" ["menu_item_parent"]=> string(1) "0" } array(5) { [0]=> object(WP_Post)#5594 (37) { ["ID"]=> int(25) ["menu_item_parent"]=> string(1) "0" ["url"]=> string(17) "http://localhost/" ["title"]=> string(4) "Home" ["classes"]=> array(1) { [0]=> string(0) "" ["menu_item_parent"]=> string(2) "23" } } |
Daarna loopt de code met een foreach door alle items heen, en maakt daarbij onderscheid tussen absolute "root" items en items die een child zijn.
In dit voorbeeld is het 2e item met ID 25 een child van het eerste item met ID 23. Alle onnodige data heb ik daar even tussenuit gehaald. Maar dat gaat zo "oneindig" verder, het volgende item met bijvoorbeeld ID 28 kan weer een child zijn van ID 25, enzovoort. En juist daar gaat het mis, bij het nesten van childs onder andere childs, etc.
Relevante software en hardware die ik gebruik
WordPress 5.3.2
Wat ik al gevonden of geprobeerd heb
Dingen zoals array_walk (_recursive), veel gezocht. Maar geen van de topics hier of op bijvoorbeeld Stackoverflow kan me geven wat ik zoek. En daarnaast wil ik ook graag leren begrijpen wat ik het beste kan doen met dit probleem