Jump to content

how to use selector in function?


bwakad
 Share

Recommended Posts

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

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

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

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

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

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

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


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

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

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"); 
}
  • Like 2
Link to comment
Share on other sites

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

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.

  • Like 3
Link to comment
Share on other sites

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.

  • Like 7
Link to comment
Share on other sites

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

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);
    }
}
  • Like 1
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...