Jump to content
ridgedale

PW3 - Adding Category Posts Count to Sidebar

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.

Share this post


Link to post
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

Share this post


Link to post
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

Share this post


Link to post
Share on other sites

Hi BitPoet/lokomotivan,

Thank you for the suggestions. I'll let you know how I get on.

Thanks again.

Share this post


Link to post
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

Share this post


Link to post
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?

 

Share this post


Link to post
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

Share this post


Link to post
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

Share this post


Link to post
Share on other sites

Yep, they are right, sorry about that :)

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>";

 

  • Like 1

Share this post


Link to post
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

Share this post


Link to post
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 :)

Share this post


Link to post
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.

Share this post


Link to post
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

Share this post


Link to post
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.

 

Share this post


Link to post
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.

Share this post


Link to post
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 muzzer
      Existing PW site version 2.7.2 core running on php7.1. Site is perhaps 7 yrs old and never misses a beat. Can't speak highly enough about this solid version, but....
      As new php versions are released (v8 in the next year I think?) and each seems to get quicker I'm looking at upgrading to php7.3 or 7.4 and upgrading the site to PW v3.x.
      I've been away from the forums since v3 was released so don't know much about it. I guess it's stable as it's been around for ages now, but what I'm wondering is:
      what are the real advantages of upgrading to v3 for a site which is actively used but with only periodic development. And what are the disadvantages if any? Is there any speed impact (good or bad) in either general site speed under 3.x or admin-use speed/ease of use? any issues with either PW version with newer php versions (>7.1) I should know about? is there any good write-ups/vids about new features etc of v3 compared to v2.7? Thank you
       
    • By Peter Knight
      I'm getting the following error. Having posted it in the GitHub I realise I should post it here instead.
      Warning: count(): Parameter must be an array or an object that implements Countable in /var/www/vhosts/domain.com/httpdocs/site/assets/cache/FileCompiler/site/modules/MarkupSEO/MarkupSEO.module on line 245 I know MarkupSEO is an old and relatively discontinued Module these days but was hoping to fix by upgrading both PHP and PW to latter versions.
      I am now running ProcessWire 3.0.148 © 2020 and PHP 7.3.13
      Issue persists.
    • By VeiJari
      Hello forum,
      This is really a weird one, because front end editing works in a earlier website we did to a customer. 
      When I check the source code for current website it does initiate front end edit: 
      <span id=pw-edit-1 class='pw-edit pw-edit-InputfieldPageTitle' data-name=title data-page=1021 data-lang='1017' style='position:relative'><span class=pw-edit-orig>Tekijät</span><span class=pw-edit-copy id=pw-editor-title-1021 style='display:none;-webkit-user-select:text;user- select:text;' contenteditable>Tekijät</span></span>  But when I double click nothing happens (yes I'm 100% sure I'm superuser and logged in)
      I also tried to apply the front end with other methods than:
      $page->edit('title'); But didn't work either.
      We are using jquery 2.2.4, so it should not be a problem.
      Is this a bug related to current master or something else?
      Someone else having this problem as well?
    • By louisstephens
      From my last post, I was given a good idea on how to count the repeater items, and it worked wonderfully. I got my code working well and the columns (based on the count) all work well as well. Now, I have a head scratcher on my hands. 
      <?php $buttonsIncluded = $page->special_custom_buttons->find('special_custom_buttons_include=1'); $buttonsIncludedCount = count($buttonsIncluded); $buttonsIncludedCountAdditional = $buttonsIncludedCount +1; echo $buttonsIncludedCount; ?> <div class="row"> <?php foreach($buttonsIncluded as $button): ?> <?php if($button->custom_buttons_include): ?> <?php if($buttonsIncludedCountAdditional == 2): ?> <div class="col-6"> <a href=""><?php echo $button->custom_buttons_text; ?></a> </div> <?php elseif($buttonsIncludedCountAdditional == 3): ?> <div class="col-4"> <a href=""><?php echo $button->custom_buttons_text; ?></a> </div> <?php elseif($buttonsIncludedCountAdditional == 4): ?> <div class="col-3"> <a href=""><?php echo $button->custom_buttons_text; ?></a> </div> <?php endif; ?> <?php endif; ?> <?php endforeach; ?> </div> All of this is included in a larger foreach statement that is pulling in other data (like body copy etc etc) from a Page Table field. As you can see in my code above, I am adding "1" to the count, so I can have space in the grid layout for a new button.
      So, right now: it looks something like: 
      [repeater button] [repeater button] [repeater button] [space for new button] What I really need to do is to pull in the button from the Page Table and add it into the new space so it looks like:
      [repeater button] [repeater button] [repeater button] [button from Page Table] Is this even possible todo, or is there a better way to go about this? 
       
      *Edit*
      So, I really just overlooked something quite easy here. Since the grid is based on 12 columns, I could just take 12 and divide by $buttonsIncludedCountAdditional which would give me the remaining col width to use outside the foreach loop. I was trying to make this too complicated.
    • By louisstephens
      Is it possible to use count() to return a number of repeater items don't have a checkbox checked? In my current set up, I have a repeater on the page "dev_repeater" with a checkbox called "dev_repeater_exclude". I need to get a count of the current items that do not have it checked so I can pass it to my css grid to alter the column width.
×
×
  • Create New...