dlen Posted April 29, 2016 Share Posted April 29, 2016 Hi , a bloody beginners question: in the function declaration you start with <?php, but you don't end with ?>. Why is this? Thanks... Link to comment Share on other sites More sharing options...
arjen Posted April 29, 2016 Share Posted April 29, 2016 Hi dlen, I don't know to which particular post you are referring too, but in general: this is why. See our PHP Coding Style Guide for more information. 3 Link to comment Share on other sites More sharing options...
a-ok Posted October 8, 2020 Share Posted October 8, 2020 On 2/22/2013 at 9:06 PM, mindplay.dk said: This is so common - I do things like this all the time, not just for menus. Does anyone else think this should be part of the core? For now, I wrote a simple flat function: /** * Recursive traverse and visit every child in a sub-tree of Pages. * * @param Page $parent root Page from which to traverse * @param callable $enter function to call upon visiting a child Page * @param callable|null $exit function to call after visiting a child Page (and all of it's children) */ function visit(Page $parent, $enter, $exit=null) { foreach ($parent->children() as $child) { call_user_func($enter, $child); if ($child->numChildren > 0) { visit($child, $enter, $exit); } if ($exit) { call_user_func($exit, $child); } } } With PHP 5.3 you can generate a menu (or whatever else) recursively as simple as this: visit( $pages->get('/menus/main') , function(Page $page) { echo '<li><a href="' . $page->url . '">' . $page->title . '</a>'; if ($page->numChildren > 0) { echo '<ul>'; } } , function(Page $page) { echo '</li>'; if ($page->numChildren > 0) { echo '</ul>'; } } ); Dead simple. I've seen the options for modules etc. that generate menus - they seem to grow out of control with a million options, and my own helpers seem to evolve the same way, and it doesn't jive with the beautiful, self-contained, simple templates you normally get away with in PW. Would it make sense to have a standard visit() method in Page in the core? I realise this post is SUPER old but I'm after something similar that outputs/builds an array, rather than markup. Something like... menu => array( main => array( 1023 => array( id => 1023 title => 'Menu item 1', children => null ), 1024 => array( id => 1024 title => 'Menu item 1', children => array( 3000 => array( id => 3000 title => 'Child menu item 1', children => null ), 3001 => array( id => 3001 title => 'Child menu item 2', children => null ) ) ), 1024 => array( id => 1024 title => 'Menu item 1', children => array( 3000 => array( id => 3000 title => 'Child menu item 1', children => array( 4001 => array( id => 4001 title => 'Child menu item 2', children => null ), 4002 => array( id => 4002 title => 'Child menu item 2', children => null ) ) ), 3001 => array( id => 3001 title => 'Child menu item 2', children => null ) ) ) ) ) Link to comment Share on other sites More sharing options...
kongondo Posted October 14, 2020 Share Posted October 14, 2020 On 10/8/2020 at 12:34 PM, a-ok said: but I'm after something similar that outputs/builds an array, rather than markup. What's your use case? Deeply nested arrays can get unwieldy and depending on how big they are, consume a lot of memory. I find it simpler to work with flat(ter) arrays with in-built relationships between the members. I then run that through a recursive function. Something like this: <?php namespace ProcessWire; $menu = array( 1 => array( 'id' => 1023, 'title' => 'Menu item 1', 'parent' => null, // this menu item does not have a parent/top level ), 2 => array( 'id' => 1024, 'title' => 'Menu item 2', 'parent' => null, ), 3 => array( 'id' => 3000, 'title' => 'Child 1 of Menu item 2', 'parent' => 1024, // its parent is item with ID 1024 ), 4 => array( 'id' => 3001, 'title' => 'Child 2 of Menu item 2', 'parent' => 1024, ), 5 => array( 'id' => 3003, 'title' => 'Child 1 of Child Menu item 2', 'parent' => 3001, ), 6 => array( 'id' => 1027, 'title' => 'Menu item 4', 'parent' => null, ), 7 => array( 'id' => 3009, 'title' => 'Child 1 of Menu item 4', 'parent' => 1027, ), 8 => array( 'id' => 4001, 'title' => 'Child 1 of Child 1 of Menu item 4', 'parent' => 3009, ), 9 => array( 'id' => 4002, 'title' => 'Child 2 of Child 1 of Menu item 4', 'parent' => 3009, ), ); 1 Link to comment Share on other sites More sharing options...
a-ok Posted October 14, 2020 Share Posted October 14, 2020 2 hours ago, kongondo said: What's your use case? Deeply nested arrays can get unwieldy and depending on how big they are, consume a lot of memory. I find it simpler to work with flat(ter) arrays with in-built relationships between the members. I then run that through the recursive function. Something like this: <?php namespace ProcessWire; $menu = array( 1 => array( 'id' => 1023, 'title' => 'Menu item 1', 'parent' => null, // this menu item does not have a parent/top level ), 2 => array( 'id' => 1024, 'title' => 'Menu item 2', 'parent' => null, ), 3 => array( 'id' => 3000, 'title' => 'Child 1 of Menu item 2', 'parent' => 1024, // its parent is item with ID 1024 ), 4 => array( 'id' => 3001, 'title' => 'Child 2 of Menu item 2', 'parent' => 1024, ), 5 => array( 'id' => 3003, 'title' => 'Child 1 of Child Menu item 2', 'parent' => 3001, ), 6 => array( 'id' => 1027, 'title' => 'Menu item 4', 'parent' => null, ), 7 => array( 'id' => 3009, 'title' => 'Child 1 of Menu item 4', 'parent' => 1027, ), 8 => array( 'id' => 4001, 'title' => 'Child 1 of Child 1 of Menu item 4', 'parent' => 3009, ), 9 => array( 'id' => 4002, 'title' => 'Child 2 of Child 1 of Menu item 4', 'parent' => 3009, ), ); @kongondo This is super interesting. My set up in PW is the following: Works Categories Artworks Digital Painting Books Editions Work Work Work Activities Categories Events Reading Talks Workshops Exhibitions Curated Group Solo Publications Anthologisations Books Editing Essays Activity Activity Activity And what I'm wanting to do on the front end (with JS) is when the user clicks 'Works' then it shows the first category level ('Artworks', 'Books', 'Editions'), then if the user clicks 'Artworks' it would show 'Digital' and 'Painting' while keeping the previous 'parents' active. I'll figure out the JS somehow for the menu but I'm guessing your method (which I think is a super smart way of doing it) would structurally allow for this sort of functionality? Link to comment Share on other sites More sharing options...
kongondo Posted October 14, 2020 Share Posted October 14, 2020 (edited) 32 minutes ago, a-ok said: would structurally allow for this sort of functionality? Yes, it should. As long as you tell the JS what criteria to use to filter things. I don't know if you are using vanilla JS or some library but the principle is the same. You will filter out/in items to either remove/hide OR add/display depending on whether you filtered out or in. 32 minutes ago, a-ok said: I'm guessing your method (which I think is a super smart way of doing it) This is how we do it in Menu Builder, giving us flexibility to create all sorts of menus. If you have more questions specific to your use case (including the JS), please open a new thread so that we stay on topic in this thread. Thanks. Edited October 14, 2020 by kongondo 1 Link to comment Share on other sites More sharing options...
a-ok Posted October 14, 2020 Share Posted October 14, 2020 2 minutes ago, kongondo said: Yes, it should. As long as you tell the JS what criteria to use to filter things. I don't know if you are using vanilla JS or some library but the principle is the same. You will filter out/in items to either remove/hide OR add/display depending on whether you filtered out or in. This is how we do it in Menu Builder, giving us flexibility to create all sorts of menus. If you have more questions specific to your use case (including the JS), please open a new thread so that we stay on topic in this thread. Thanks. @kongondo Thanks! Using vanilla/alpine/react sort of thing but yeah principle should be the same ? Okay great. Will be in touch if I have any more questions but super appreciate the help/advice. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now