davo Posted December 29, 2013 Share Posted December 29, 2013 I've adapted a simple menu script to show child items of the current page and output them as a menu list like this: function kiddiMenu(){ // Create the top navigation list by listing the children of the homepage. // If the section we are in is the current (identified by $page->rootParent) // then note it with <a class='on'> so we can style it differently in our CSS. // In this case we also want the homepage to be part of our top navigation, // so we prepend it to the pages we cycle through: $current_page = $pages->get("/planning-your-journey"); $homepage = $current_page; $children = $homepage->children; echo "<ul class='' >"; foreach($children as $child) { $class = $child === $page->rootParent ? " class='active'" : ''; echo "<li><a$class href='{$child->url}'><span class='l'></span><span class='r'></span><span class='t'>{$child->title}</span></a></li>"; } echo"</ul>"; } All is good if i write it into the template, but i'm trying to be tidier this time around and write it as a function that can be called from a number of templates. I'm not very experienced with this, but when I turn it into a module and call it from A template the browser complains like this: Error: Call to a member function get() on a non-object (line 47 of/var/www/clients/client13/web35/web/site/templates/myfunctions.inc) Could someone help please. Or should I just write it in the template file? cheers David Link to comment Share on other sites More sharing options...
Craig Posted December 29, 2013 Share Posted December 29, 2013 I think the problem here is down to variable scope. When the code was in your template, it had direct access to ProcessWire pages using the system variable $pages. When you put this inside a function, it's no longer available. The way you can fix this is to change it to this: function kiddiMenu(){ $current_page = wire('pages')->get("/planning-your-journey"); $homepage = $current_page; $children = $homepage->children; echo "<ul class='' >"; foreach($children as $child) { $class = $child === wire('page')->rootParent ? " class='active'" : ''; echo "<li><a$class href='{$child->url}'><span class='l'></span><span class='r'></span><span class='t'>{$child->title}</span></a></li>"; } echo"</ul>"; } The difference is that $pages and $page (the variables that are out of scope) are replaced with global function calls which return the same thing, and are available from anywhere in ProcessWire. The ProcessWire system variables are listed here - variables. Any time you're in a function or a module, just replace them with a call to the wire() function with the name as the parameter. E.g. wire('input') for $input. 4 Link to comment Share on other sites More sharing options...
Joss Posted December 30, 2013 Share Posted December 30, 2013 Yep, that one caught me out when I first started playing. Now I tend to do just about everything using functions on an inc file so that my templates are very clean and easy to swap around. Link to comment Share on other sites More sharing options...
3fingers Posted December 30, 2013 Share Posted December 30, 2013 function kiddiMenu($current= "/planning-your-journey/"){ $homepage = wire('pages')->get($current); $children = $homepage->children; echo "<ul class='' >"; foreach($children as $child) { $class = $child === wire('page')->rootParent ? " class='active'" : ''; echo "<li><a$class href='{$child->url}'><span class='l'></span><span class='r'></span><span class='t'>{$child->title}</span></a></li>"; } echo"</ul>"; } I think you can also pass a parameter to the function to make it reusable. 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