bwakad Posted May 13, 2014 Share Posted May 13, 2014 Does anyone know how to use this code in a function? I have had no luck with it so far. Once I read some were to use wire->pages but could not find more info about it. function selector($selects){ $selects = $pages->find("template=child-template, limit=2, sort=company"); return $selects; So I can use it on some page as : selector(); Link to comment Share on other sites More sharing options...
diogo Posted May 13, 2014 Share Posted May 13, 2014 You can't use the API variables inside functions because of function scope. Use wire() instead $selects = wire('pages')->find("template=child-template, limit=2, sort=company"); Here's an explanation: https://processwire.com/talk/topic/5133-wire-function/?p=49459 2 Link to comment Share on other sites More sharing options...
bwakad Posted May 13, 2014 Author Share Posted May 13, 2014 You can't use the API variables inside functions because of function scope. Use wire() instead $selects = wire('pages')->find("template=child-template, limit=2, sort=company"); Here's an explanation: https://processwire.com/talk/topic/5133-wire-function/?p=49459 my code now looks like this, but no output - must be doing something wrong but have no idea what...: //functions.php function selector() { $selects = wire("pages")->find("template=child-template, limit=2, sort=company"); return $selects; } //mytemplate.php selector(); foreach // etc Link to comment Share on other sites More sharing options...
adrian Posted May 13, 2014 Share Posted May 13, 2014 One comment on your function - there is no need to have $selects as an argument in your function. You can leave it blank between the (). You need to: echo selector(); EDIT: You need to do something with the results of selector(). You could put a foreach inside the function if the output will always be formatted the same way, or do as Ozwim suggests below if you want to treat them differently each time. Link to comment Share on other sites More sharing options...
owzim Posted May 13, 2014 Share Posted May 13, 2014 Are you assigning the return of the function to something? $results = selector(); foreach($results as $result) { echo "{$result->title} <br>"; } 1 Link to comment Share on other sites More sharing options...
diogo Posted May 13, 2014 Share Posted May 13, 2014 if you only return the result inside the function instead of echoing, you have to echo the function itself: //functions.php function selector() { $selects = wire("pages")->find("template=child-template, limit=2, sort=company"); return $selects; } //mytemplate.php echo selector(); // <- echo here Link to comment Share on other sites More sharing options...
bwakad Posted May 13, 2014 Author Share Posted May 13, 2014 Normally I use something like this : if($page === $page->rootParent) { // if this page is rootparent $selects = $pages->find("template=child-template, limit=2, sort={$page->name}"); // example provincie // We have sorted by page-name if current page is a rootparent. } and on my template: foreach ($selects as $child){ and then the usual: echo $child->title // etc. if you only return the result instead of echoing, you have to echo the function: //functions.php function selector() { $selects = wire("pages")->find("template=child-template, limit=2, sort=company"); return $selects; } //mytemplate.php echo selector(); // <- echo here I did, and I get some results, but it brings me back to id nrs... when I use the normal code on the template page itself (without function) I get my results the way intended... Link to comment Share on other sites More sharing options...
Martijn Geerts Posted May 13, 2014 Share Posted May 13, 2014 (edited) You echo a PageArray.side note: If you use a variable only ones, why you need that variable at all. You could return it directly. Edited May 13, 2014 by Martijn Geerts Link to comment Share on other sites More sharing options...
diogo Posted May 13, 2014 Share Posted May 13, 2014 I don't know what is the intended result, but, as Martijn said, $selects holds a PageArray, and now, so does selector(). You have to treat it as one: foreach( selector() as $s ) echo $s->title; Link to comment Share on other sites More sharing options...
bwakad Posted May 13, 2014 Author Share Posted May 13, 2014 Yes, I understand that. Strange thing is, if I use the $selects = like from my original code, and after this include a file with layout and all, it simply works. Just not when I use $selects = inside a function because I need to use echo as suggested. So when I write it as code, after include my layout it works. When I echo function() and include my layout it doesn't. Link to comment Share on other sites More sharing options...
diogo Posted May 13, 2014 Share Posted May 13, 2014 That's strange... I tried it, and works normaly: function selector() { return wire('page')->children(); } echo selector(); // echoes 1001|1003|1005|1006|1020 Link to comment Share on other sites More sharing options...
Martijn Geerts Posted May 13, 2014 Share Posted May 13, 2014 function selector() { $selects = wire("pages")->find("template=child-template, limit=2, sort=company"); return $selects; } echo selector(); // 1234|5678|9101 // this is the same: function selector() { return wire("pages")->find("template=child-template, limit=2, sort=company"); } echo selector(); // 1234|5678|9101 // this will will do the same except you bind it to a variable, so there's no real function for the function at all. $page_array = wire("pages")->find("template=child-template, limit=2, sort=company"); echo $page_array; // 1234|5678|9101 Link to comment Share on other sites More sharing options...
bwakad Posted May 13, 2014 Author Share Posted May 13, 2014 This is normally my code: if($page === $page->rootParent) { // if this page is rootparent $selects = $pages->find("template=child-template, limit=2, sort={$page->name}"); // example provincie // We have sorted by page-name if current page is a rootparent. } if ($page->parent === $page->rootParent) { // if parent of this page is rootparent $field = $page->parent->get("name"); $selects = $pages->find("template=child-template, {$field}={$page->id}, limit=2, sort=-created"); // example field = provincie, page id = child // We have sorted by date DESC if current page is a child. } // on browse inc is simply the foreach($selects as $child){include("./myinclude/browse.inc"); // browse.inc holds html for display But in this normal code I have my layout and names visible. while with the function I get simply ID's. That's what puzzles me... Link to comment Share on other sites More sharing options...
diogo Posted May 13, 2014 Share Posted May 13, 2014 this will will do the same except you bind it to a variable, so there's no real function for the function at all Not like it is now. But it's still a valid exercise, change only a little bit and the function can become very useful function selector($tpl) { return wire("pages")->find("template=$tpl, limit=2, sort=company"); } 2 Link to comment Share on other sites More sharing options...
Martijn Geerts Posted May 13, 2014 Share Posted May 13, 2014 Do you foreach $selects from the function? If so that not accessible outside the function. Link to comment Share on other sites More sharing options...
bwakad Posted May 13, 2014 Author Share Posted May 13, 2014 do you mean: foreach needs to be inside the function? as owzim suggested? I also get a error on the get() on a non-object inside the function itself. I am guessing I can't use a function : that is based on the page I am on without using the foreach in the function and because get() can't (yet) be used. My layout is different on certain pages, so I can't really put all of that inside a function. I thought I could simply make the $selects = change by using a function... bummer Link to comment Share on other sites More sharing options...
Martijn Geerts Posted May 14, 2014 Share Posted May 14, 2014 Please re-read the posts... The function is the actual PageArray... I am guessing I can't use a function : Look at Diogo's example how useful a function can be. My layout is different on certain pages, so I can't really put all of that inside a function. Why not ? You can get variables inside the function if wished, again look at Diogo's example. You have to use wire('pages'), wire('page'), wire('config'), etc. etc. inside functions because of variable scope. 3 Link to comment Share on other sites More sharing options...
nik Posted May 14, 2014 Share Posted May 14, 2014 You've been tripped by scopes. Twice. Other guys have given you the solution to both problems above but you're going around in circles. I'll try once more. The first problem was using $pages inside a function. That and many other variables are not visible in a function due to scoping (see the post diogo linked to in the very first response to your question). You fixed this first scoping issue by replacing $pages with wire('pages'). But when you assign the results of the find() function to a variable $selects inside your function, you're inside another scope - a scope that is not visible outside your function. Returning the value of $selects returns only, well, the value. It does not expose a variable called $selects to be usable outside the scope of your function. So you'll need to either use the returned value straight away (see diogo's foreach example) or assign it to a variable. This is actually exactly what owzim proposed earlier on. If you take a closer look at his code you'll see the foreach is not inside the function but outside. Maybe you got confused by the same variable name. Something like this should work (with minimal changes to what you originally had): function selector() { $selects = wire("pages")->find("template=child-template, limit=2, sort=company"); return $selects; } $selects = selector(); include("./myinclude/browse.inc"); // browse.inc holds html for display Personally I would avoid using the same variable name twice to avoid confusing myself. Here's an example combination of what has been said earlier in this thread by others: function selector($tpl) { return wire("pages")->find("template=$tpl, limit=2, sort=company"); } $selects = selector("child-template"); include("./myinclude/browse.inc"); // browse.inc holds html for display Functions are useful and I really hope you're able to wrap your head around them (and scopes and variables) eventually. Reading a book explaining the very basics of PHP programming might be beneficial. 7 Link to comment Share on other sites More sharing options...
bwakad Posted May 14, 2014 Author Share Posted May 14, 2014 Yesterday, I have used the first example as Nik pointed out later. But with my second code (below) I ran into problems with the $page->parent->get("name"); I then rolled back to my original code which was placed on the template file itself. I do want to thank all for thinking with me as it's been a great learning exercise and probably turn to the function on a later time. if ($page->parent === $page->rootParent) { // if parent of this page is rootparent $field = $page->parent->get("name"); $selects = $pages->find("template=child-template, {$field}={$page->id}, limit=2, sort=-created"); // example field = provincie, page id = child Link to comment Share on other sites More sharing options...
diogo Posted May 14, 2014 Share Posted May 14, 2014 It's the last time that I say this, but $page->parent->get("name"); should be wire("page")->parent->get("name"); Link to comment Share on other sites More sharing options...
bwakad Posted May 14, 2014 Author Share Posted May 14, 2014 Oops. Sorry Diogo - I used wire("page->parent") - my mistake (hope I can say that the last time) 1 Link to comment Share on other sites More sharing options...
kongondo Posted May 14, 2014 Share Posted May 14, 2014 ....nothing to see here, run along, ta ta... 3 Link to comment Share on other sites More sharing options...
bwakad Posted May 18, 2014 Author Share Posted May 18, 2014 I have a browse.php template which includes certain layout. For my parent (field select) pages as well as their children I use the same layout. But for members browsing I use another layout. So 1 template, 2 includes. Using my first function (post on top) I did not really know how to implement the members code. But then I started follow a course and hence: Just to make my function selector look more nice I used switch() - learned in PHP course. Hope you guys like my efforts: function selects(){ // set required variables; $page = wire("page"); $pages = wire("pages"); $noresult = wire("config")->urls->root; $layout = "browse.inc"; switch ($page->id) { case '1006': case '1008': case '1026': case '1077': case '1127': case '1138': case '1156': // cases up until here have same selector, e.g. parent field select $selector = "template=child-template, limit=4, sort={$page->name}"; break; case '1171': // this case is for members, selector and include layout change $selector = "roles=member|employer|applicant"; $layout = "members.inc"; break; default: // this is the default if none of the cases match, e.g. children field select $selector = "template=child-template, {$page->parent->name}={$page->id}, limit=4, sort=-{created}"; break; } // construct what we are selecting. Now I do not have to use $selects = $users->find($selector); $selects = $pages->find($selector); // we output something else if nothing is there if (!count($selects)) { return "<div class='medium-12 columns'><h3>No items are found.</h3> <p>try searching through our indexes at <a href='{$noresult}'>ClientC</a> or use the search form on the right.</p></div>"; } else { // construct quantity found $message = "Showing {$selects->count} out of {$selects->getTotal()}"; // contruct pagination $pagination = $selects->renderPager(array( 'listMarkup' => "<ul class='MarkupPagerNav pagination'>{out}</ul>", 'currentItemClass' => 'current' )); // call layout for results: display quantity, paginator, foreach, and markup include($layout); } } 1 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