Jump to content

move code to function


davo
 Share

Recommended Posts

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

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.

  • Like 4
Link to comment
Share on other sites

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

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...