Jump to content

PW3 - Adding Category Posts Count to Sidebar


ridgedale
 Share

Recommended Posts

Reference: PW 3.0.62 and uikit3 based site using the Reglar-Master profile.

I'm trying to add a count of the number of category posts to display beside each of the category titles listed in the sidebar on the blog page.

The following code displays the total number posts on each category page:

<span class='uk-text-muted'>Total <?php echo page()->title; ?> posts: <?php echo count(pages()->get('/blog/')->children("categories=$page")); ?></span>

The following default code displays the heading and a list of the categories:

<?php 
    $categories = pages()->get('/categories/'); 
    echo ukNav($categories->children, [ 'header' => $categories->title  ]);
?>

but I want to add the respective number of posts on the same line as each category title listed. When I try replacing the default code with the following:

<?php 
    $categories = pages()->get('/categories/'); 
    $catposts = count($categories->children("categories=$page"));
    echo ukNav($categories->children . ' ' . $catposts, [ 'header' => $categories->title  ]);
?>

I get the following error:

Quote

Fatal error: Call to a member function wire() on string in /home/thehanys/public_html/site-hps/templates/_uikit.php on line 99

which refers to the following code in the _uikit.php file:

$page = $items->wire('page'); // current page

and when I try:

<?php 
    $categories = pages()->get('/categories/');
    $catposts = count($categories->children("categories=$page"));
    echo ukNav($categories->title);
	foreach ($categories as $category) {
		echo $category->children . ' ' . $catposts;		
	}
?>

or:

<?php 
    $categories = pages()->get('/categories/');
    $catposts = count(pages()->get('/blog/')->children("categories=$page"));
    echo ukNav($categories->title);
	foreach ($categories as $category) {
		echo $category->children . ' ' . $catposts;		
	}
?>

I get the same error.

If I change

Quote

children("categories=$page")

to

Quote

children("categories=$category")

I get the following error messages:

Quote

Notice: Undefined variable: category in /home/thehanys/public_html/site-hps/templates/blog.php on line 24

Fatal error: Call to a member function wire() on string in /home/thehanys/public_html/site-hps/templates/_uikit.php on line 99

Any advice on where I am going wrong would be very much appreciated.

Link to comment
Share on other sites

I don't think there's a way to call ukNav and have it include the page count without modifying the function itself.  From what I see (I'm not familiar with the UIKit3 profile) the lines where the links are generated are either 135 or 153. So you could clone (probably, since ukNav is rather generic) or modify (with a third optional argument that indicates that page counts should be displayed?) the ukNav function, retrieve $item->children->count() inside the loop and insert that count into the link.

  • Like 2
Link to comment
Share on other sites

if u wanna use ukNav() function, u would need to edit it to display count.

I dont know how your categories and post are structured, but based on ur post, this can maybe help:

$categories = $pages->get('/categories/'); 

echo "<ul class='uk-nav uk-nav-default'>";
  foreach($categories->children() as $cat) {
       echo "<li><a href='$cat->url'>{$cat->title} {$pages->find('categories=$cat')->count}</a></li>";
  }
echo "</ul>";
  

 

  • Like 2
Link to comment
Share on other sites

16 hours ago, BitPoet said:

I don't think there's a way to call ukNav and have it include the page count without modifying the function itself.  From what I see (I'm not familiar with the UIKit3 profile) the lines where the links are generated are either 135 or 153. So you could clone (probably, since ukNav is rather generic) or modify (with a third optional argument that indicates that page counts should be displayed?) the ukNav function, retrieve $item->children->count() inside the loop and insert that count into the link.

Hi BitPoet,

I backed up the _uikit.php file and replaced line 153 with the following:

$out .= "<a href='$item->url'>$item->title</a> <span class=''>$item->children->count()</span>";

but that simply outputs: count(), not the number of category posts.

I must be doing something wrong. Any ideas?

Edited by ridgedale
typo error
Link to comment
Share on other sites

10 hours ago, lokomotivan said:

if u wanna use ukNav() function, u would need to edit it to display count.

I dont know how your categories and post are structured, but based on ur post, this can maybe help:


$categories = $pages->get('/categories/'); 

echo "<ul class='uk-nav uk-nav-default'>";
  foreach($categories->children() as $cat) {
       echo "<li><a href='$cat->url'>{$cat->title} {$pages->find('categories=$cat')->count}</a></li>";
  }
echo "</ul>";
  

Hi lokomotivan,

I tried the above code as there is nothing special about the way the categories have been created /categories/<categoryname>. When I add the code you provided it generated the following error:

Quote

Fatal error: Exception: Unknown Selector operator: '=$' -- was your selector value properly escaped? field='categories', value='cat', selector: 'categories=$cat' (in /<homepath>/public_html/wire/core/Selectors.php line 396) #0 /<homepath>/public_html/wire/core/Selectors.php(439): ProcessWire\Selectors->create('categories', '=$', 'cat') #1 /<homepath>/public_html/wire/core/Selectors.php(159): ProcessWire\Selectors->extractString('categories=$cat') #2 /<homepath>/public_html/wire/core/Selectors.php(145): ProcessWire\Selectors->setSelectorString('categories=$cat') #3 /<homepath>/public_html/wire/core/PagesLoader.php(217): ProcessWire\Selectors->init('categories=$cat') #4 /<homepath>/public_html/wire/core/Pages.php(232): ProcessWire\PagesLoader->find('categories=$cat', Array) #5 /<homepath>/public_html/wire/core/Wire.php(383): ProcessWire\Pages->___find('categories=$cat') #6 /<homepath>/public_html/wire/core/WireHooks.php(698): ProcessWire\Wire->_callMethod('___find', Array) #7 /<homepath>/public_h in /<homepath>/public_html/index.php on line 64
Error: Exception: Unknown Selector operator: '=$' -- was your selector value properly escaped? field='categories', value='cat', selector: 'categories=$cat' (in /<homepath>/public_html/wire/core/Selectors.php line 396) #0 /<homepath>/public_html/wire/core/Selectors.php(439): ProcessWire\Selectors->create('categories', '=$', 'cat') #1 /<homepath>/public_html/wire/core/Selectors.php(159): ProcessWire\Selectors->extractString('categories=$cat') #2 /<homepath>/public_html/wire/core/Selectors.php(145): ProcessWire\Selectors->setSelectorString('categories=$cat') #3 /<homepath>/public_html/wire/core/PagesLoader.php(217): ProcessWire\Selectors->init('categories=$cat') #4 /<homepath>/public_html/wire/core/Pages.php(232): ProcessWire\PagesLoader->find('categories=$cat', Array) #5 /<homepath>/public_html/wire/core/Wire.php(383): ProcessWire\Pages->___find('categories=$cat') #6 /<homepath>/public_html/wire/core/WireHooks.php(698): ProcessWire\Wire->_callMethod('___find', Array) #7 /<homepath>/public_h This error message was shown because: site is in debug mode. ($config->debug = true; => /site/config.php). Error has been logged.

 

It looks like it doesn't like the $cat reference in:


$pages->find('categories=$cat')

Again I must be doing something wrong. Any ideas where I am going wrong?

 

Link to comment
Share on other sites

when you put variables in selectors you need to use double quotes! otherwise php will use $var as regular string and not as a variable.

// this does not work
$pages->find('categories=$cat')

// this works
$pages->find("categories=$cat")

edit: just saw you have some more code...

// change this
echo "<li><a href='$cat->url'>{$cat->title} {$pages->find('categories=$cat')->count}</a></li>";

// to something like that
echo "<li><a href='{$cat->url}'>{$cat->title} " . $pages->find("categories=$cat")->count . "</a></li>";

 

  • Like 2
Link to comment
Share on other sites

46 minutes ago, ridgedale said:

I backed up the _uikit.php file and replaced line 153 with the following:


$out .= "<a href='$item->url'>$item->title</a> <span class=''>$item->children->count()</span>";

but that simply outputs: count(), not the number of category posts.

You need to either put the call to count() outside of the string or use curly braces. So both of these should work:

// outside of string
$out .= "<a href='$item->url'>$item->title</a> <span class=''>" . $item->children->count() . "</span>";
// or with curly braces
$out .= "<a href='$item->url'>$item->title</a> <span class=''>{$item->children->count()}</span>";

 

  • Like 3
Link to comment
Share on other sites

Hi Bernhard / BitPoet / lokomotivan,

Thanks again for all your feedback.

I tried BitPoet's amended code which allows the site styling to remain unchanged:

$out .= "<a href='$item->url'>$item->title <span class='uk-align-right'>" . $item->children->count() . "</span></a>";

In order to prevent all navigation elements displaying the count output I duplicated and renamed the ukNav function, added the renamed function to the end of the _uikit.php file and called the renamed function with the updated code.

However all the post count values are returned as zero. See attached screen grab: SidebarOutput01.png.

I also tried lokomotivan's suggestion with the corrected php code, leaving the _uikit.php untouched:

$categories = $pages->get('/categories/'); 
echo "<ul class='uk-nav uk-nav-default'>";
  foreach($categories->children() as $cat) {
       echo "<li><a href='$cat->url'>". $cat->title . $pages->find("categories=$cat")->count . "</li>";
  }
echo "</ul>";

lokomotivan's code does actually return the correct category count values, as far as I can tell. However, because the output is not being generated via/through the ukNav function it messes up the site layout. See attached screen grab: SidebarOutput02.png.

I tried integrating lokomotivan's code into the renamed ukNav function by adding the following variable declarations after immediately line 102 (original ukNav function line numbering):

	$categories = $items->get('/categories/');
	$cat = $categories->children();

and replacing the original line 153 of the _uikit.php file with:

$out .= "<a href='$item->url'>$item->title <span class='uk-align-right'>" . $pages->find("categories=$cat")->count . "</span></a>";

Then tried calling the renamed function, but get the following error:

Quote

Fatal error: Call to a member function children() on null in /<homepath>/templates/_uikit.php on line 989

The renamed function is baulking at the following variable declaration that I added:

$cat = $categories->children();

Almost certainly the code I've used is incorrect/invalid. Any ideas where I am going wrong?

 

SidebarOutput01.png

SidebarOutput02.png

Link to comment
Share on other sites

Those kind of errors can easily be debugged with Tracy. Just install it and then you can do a bd($yourvar) and see what your variable is internally.

In your case it would be null, so your get() is wrong somehow. On mobile, so I hope this already helps :)

Link to comment
Share on other sites

Hi Bernhard / BitPoet / lokomotivan,

I'm using the built-in debugging for this setup. So I'm a bit wary about adding another module that might conflict.

I think the problem is that in this instance I'm trying to gather information from both UiKit3 and PW3 functions and they don't appear to be passing variables between them.

That's my guess as I am no expert.

What I can see is that the ukNav function (_uikit.php) variable $item is generating the ids of the categories (which I can output replacing:

$out .= "<a href='$item->url'>$item->title <span class='uk-align-right'>" . $item->children->count() . "</span></a>";

with:

$out .= "<a href='$item->url'>$item->title <span class='uk-align-right'>" . $item . "</span></a>";

and also from $item the category title is generated and output.

Another _uikit.php function ukBlogPosts should be able to generate the total number of blog posts. But when I call it using count(ukBlogPosts($posts)) the output is 1, so either I have misunderstood or I am not using the correct code to retrieve the required information.

The only thing I can think of at this stage is to try to retrieve a count of all the pages where the parent ID matches $item. It would appear I need to reference some, if not all, of the ukBlogPosts function, but all attempts so far have failed to generate the correct output.

Any more thoughts would be very welcome.

Thanks for all your patience.

Link to comment
Share on other sites

28 minutes ago, ridgedale said:

I'm using the built-in debugging for this setup.

what is the built in debugging? again my recommendation: use tracy ;) you'll get nice info like this:

screen_shot_2016-08-24_at_8_46_10_am.png
screen_shot_2016-03-24_at_5_31_24_pm.pnghttps://processwire.com/blog/posts/introducing-tracy-debugger/#bardump

 

31 minutes ago, ridgedale said:

Another _uikit.php function ukBlogPosts should be able to generate the total number of blog posts. But when I call it using count(ukBlogPosts($posts)) the output is 1, so either I have misunderstood or I am not using the correct code to retrieve the required information.

you could just do a bd(ukBlogPosts($posts)) and see what this function returns and why count(ukBlog...) returns 1. you could also see the docs to this function in the code that says that it returns a string: https://github.com/ryancramerdesign/regular/blob/master/site-regular/templates/_uikit.php#L720 ... so count() correctly returns 1 ;)

----------

but back to your initial question: i think it would be much easier to just use the API and forget about the uikit functions that are shipped with the profile! in your case it would be as easy as this:

<ul>
  <?php
  foreach($pages->get('/categories')->children as $cat) {
    echo '<li class...>' . $cat->title . ' (' . $cat->numChilrden(true) . ')</li>';
  }
  ?>
</ul>

 

  • Like 1
Link to comment
Share on other sites

Hi Bernard,

Thanks for all your input. I clearly need to to do a lot of reading before I implement TracyDebugger. Plus I the feedback you have provided shows I need to read all the comments in the base code.

Apologies. :(

In the end I've learned the screwed layout issue encountered using lokomotivan's code suggestion was caused by a missing </a>!!

The final code to get the required data delivered needed no changes to the _uikit.php, just an edit of the sidebar code on the blog.php page. I replaced the following code:

<?php 
    $categories = pages()->get('/categories/'); 
    echo ukNav($categories->children, [ 'header' => $categories->title  ]);
?>

with:

<?php
	$categories = $pages->get('/categories/'); 
	echo "<ul class='uk-nav uk-nav-default'>";
	echo "<li class='uk-nav-header'>Categories</li>";
	foreach($categories->children() as $category) {
		echo "<li class='uk-nav-divider'></li>";
		echo "<li><a href='$category->url'>". $category->title . "<span class='uk-align-right'>" . $pages->find("categories=$category")->count . "</span></a></li>";
		}
	echo "</ul>";
?>

Many thanks again to you all for all your advice and assistance.

 

Link to comment
Share on other sites

Hi Bernhard,

Apologies, I forgot to answer your question.

PW3 has built-in debugging by editing the /site/config.php file: changing the folloing line:

$config->debug = false;

to:

$config->debug = true;

That is what I have been using. It is very possible that TracyDebugger may provide more detailed and clearer debugging information as you have indicated.

That is something I will have to learn. ;)

Thanks again for all your help.

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

×
×
  • Create New...