Jump to content

Using $pages in custom function

Vineet Sawant

Recommended Posts

Hello all,

So me being a noob can't figure out how can I use $pages->get or find in my custom function.

function printTitle($page_id){
     echo "Title of the page is ".$pages->get("id={$page_id}");

Above code is giving me error :

 Error: Call to a member function get() on a non-object 

From what I've read probably, I should be using $wire('pages')->get.

But this gives following error:

Error: Function name must be a string

Removing $ from wire solves above error but it doesn't print anything.

Any help would be very much appreciated.

Thanks a lot.

Link to comment
Share on other sites

Vineet - it's all about variable scope. $pages (or any of the other PW variables) can't exist inside a function like that.

You need to use: wire('pages')->get or define $pages = wire('pages') at the start of your function and then you can use: $pages.

Nevermind - sorry, apparently I didn't actually read your post :)

Looks like renobird's suggestion should be spot on!

Link to comment
Share on other sites


You are getting the page correctly, try adding title to the end.

echo wire('pages')->get("id={$page_id}")->title;

...and perhaps what onjegolders mentioned as well. I think omitted title should still output the page ID.

  • Like 1
Link to comment
Share on other sites

Thank you guys for quick reply, will try defining $pages so I have following code now. And it prints nothing :(

function printPage($page_id){
	$pages = wire('pages');
	echo "Page Title: ".$pages->get("id=$page_id")->title;
Edited by Vineet Sawant
Link to comment
Share on other sites

  • 11 months later...

I'm having the same issue.

This is my function (which is sit on another php file )to print archive post, similar as the wordpress archive widget

function archive () {
$out = "
$start    = new DateTime('2010-01-01');
//$start->modify('first day of this month');
$end      = new DateTime('2015-02-01');
//$end->modify('first day of next month');
$interval = DateInterval::createFromDateString('1 month');
$period   = new DatePeriod($start, $interval, $end);

$a = array();
foreach ($period as $dt) {
    array_push($a, $dt);
$a = array_reverse($a);

foreach ($a as $dt) {
    $d = $dt->format("Y-m-d");
    $nextmonth = date('Y-m-d', strtotime('+1 month', strtotime($d)));
    $count = count($pages->find("template=post, post_date>=$d, post_date<$nextmonth"));
    if ($count > 0) {
        $out .= "<a href='{$pages->get('template=home')->url}" . date('Y', strtotime($d)) . "/" . date('m', strtotime($d)) . "'>" . date('M Y', strtotime($d)) . " (" . $count . ")" . "</a><br/>";

return $out;

In a template file, the code will looks



$out = "This is content.";

$sidebar = archive();

$page->body .= $out;

include('./main.php');  // the master output file

I will get this error in the log

Error:     Call to a member function find() on a non-object (line 26 of /var/www/html/pw1/site/templates/archive.php)

  • Like 1
Link to comment
Share on other sites

It's not only the same error in the log, but you're also doing the same thing wrong. You can't use $pages in functions because of variable scope. ProcessWire makes these object automatically available for the scope of the templatefiles, but inside a function is a new scope, so you need to either redefine the variable itself or use a function to get the object. 

// Template scope

$id = 15; // simple variable, defined by you
$pages = $pages; // the pages object, defined automatically by processwire

function something(){ 
  // this is now a new variable scope 
  // neither $pages nor $id are available here.
  // the api variables are not a special global variable

  $pages = wire('pages');
  // OR just

It's the same reason, why you can't use $pages in modules. $page/$pages and the other variables are just convenient to use in templates. Everywhere else you need to call them differently.

  • Like 7
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

  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Similar Content

    • By Shohan Arafat
      I was looking for code sample where I can attach a textarea for setting up a content in my page. And I wanted to do it programatically. But I can't find a way to do that. Is it possible to add a content textarea with program?
    • By Robin S
      This module lets you add some custom menu items to the main admin menu, and you can set the dropdown links dynamically in a hook if needed.
      Sidenote: the module config uses some repeatable/sortable rows for the child link settings, similar to the ProFields Table interface. The data gets saved as JSON in a hidden textarea field. Might be interesting to other module developers?
      Custom Admin Menus
      Adds up to three custom menu items with optional dropdowns to the main admin menu.
      The menu items can link to admin pages, front-end pages, or pages on external websites.
      The links can be set to open in a new browser tab, and child links in the dropdown can be given an icon.
      Requires ProcessWire v3.0.178 or newer.
      Example of menu items

      Module config for the menus

      Link list shown when parent menu item is not given a URL

      Setting child menu items dynamically
      If needed you can set the child menu items dynamically using a hook.
      $wire->addHookAfter('CustomAdminMenus::getMenuChildren', function(HookEvent $event) { // The menu number is the first argument $menu_number = $event->arguments(0); if($menu_number === 1) { $colours = $event->wire()->pages->findRaw('template=colour', ['title', 'url', 'page_icon']); $children = []; foreach($colours as $colour) { // Each child item should be an array with the following keys $children[] = [ 'icon' => $colour['page_icon'], 'label' => $colour['title'], 'url' => $colour['url'], 'newtab' => false, ]; } $event->return = $children; } }); Create multiple levels of flyout menus
      It's also possible to create multiple levels of flyout submenus using a hook.

      For each level a submenu can be defined in a "children" item. Example:
      $wire->addHookAfter('CustomAdminMenus::getMenuChildren', function(HookEvent $event) { // The menu number is the first argument $menu_number = $event->arguments(0); if($menu_number === 1) { $children = [ [ 'icon' => 'adjust', 'label' => 'One', 'url' => '/one/', 'newtab' => false, ], [ 'icon' => 'anchor', 'label' => 'Two', 'url' => '/two/', 'newtab' => false, 'children' => [ [ 'icon' => 'child', 'label' => 'Red', 'url' => '/red/', 'newtab' => false, ], [ 'icon' => 'bullhorn', 'label' => 'Green', 'url' => '/green/', 'newtab' => false, 'children' => [ [ 'icon' => 'wifi', 'label' => 'Small', 'url' => '/small/', 'newtab' => true, ], [ 'icon' => 'codepen', 'label' => 'Medium', 'url' => '/medium/', 'newtab' => false, ], [ 'icon' => 'cogs', 'label' => 'Large', 'url' => '/large/', 'newtab' => false, ], ] ], [ 'icon' => 'futbol-o', 'label' => 'Blue', 'url' => '/blue/', 'newtab' => true, ], ] ], [ 'icon' => 'hand-o-left', 'label' => 'Three', 'url' => '/three/', 'newtab' => false, ], ]; $event->return = $children; } }); Showing/hiding menus according to user role
      You can determine which menu items can be seen by a role by checking the user's role in the hook.
      For example, if a user has or lacks a role you could include different child menu items in the hook return value. Or if you want to conditionally hide a custom menu altogether you can set the return value to false. Example:
      $wire->addHookAfter('CustomAdminMenus::getMenuChildren', function(HookEvent $event) { // The menu number is the first argument $menu_number = $event->arguments(0); $user = $event->wire()->user; // For custom menu number 1... if($menu_number === 1) { // ...if user does not have some particular role... if(!$user->hasRole('foo')) { // ...do not show the menu $event->return = false; } } });  
    • By opalepatrick
      I see old posts saying that repeaters are not the way to go in Custom Process Modules. If that is the case, when using forms (as I am trying to do) how would one tackle things like repeat contact fields where there can be multiple requirements for contact details with different parameters? (Like point of contact, director, etc) or even telephone numbers that have different uses?
      Just for background I am creating a process module that allows me to create types of financial applications in the admin area (no need to publish any of this, pure admin) that require a lot of personal or company information.
      Maybe I am thinking about this incorrectly?
    • By rjgamer
      is there a hook after the current (active) page got created? Or which method got called in the Page class after the Constructor of the current page got initialized?
    • By rjgamer
      Hi guys,
      the field "redirect_last" of type DateTime got not updated. The update on the field "redirect_counter" works and got saved.
      Does anybody know what I did wrong in my code?
      if ($input->urlSegment(1) === 'redirect') { $page->of(false); $page->redirect_last = time(); $page->redirect_counter += 1; if ($page->save('redirect_counter')) { $session->redirect($page->website_url, 302); } } Thanks.
  • Create New...