Recent Topics

1 Mar 30, 2007 11:26    

Hello,

I've modified [url=http://www.petitbourgeois.com/]my install[/url] of 1.9.3 to hide empty categories from the cat list. Rationale goes like this: I use my blog both for private and public publishing, and some categories are used only by private posts -- they're useless for non-identified visitors.

So I want to hide categories that contain no posts. However, categories are hierarchically organized, and a parent cat might have no posts while its children do -- that parent would need to be displayed. So a simple test on cat_postcount would not work.

So what does this hack precisely do?

- makes available in $cache_categories, a cumulative count of posts visible to the current user, contained by each category AND its children (called cat_postcount_subs)
- makes available in $cache_categories, a cumulative count of posts with status "published", contained by each category AND its children (called cat_postcount_pubsubs)
- hides categories that contain no posts visible to the current user
- hides categories that contain no published posts when generating the static version of a blog's home page

This is a hack, I've had to modify a core file (_category.funcs.php) so it's a pretty brittle solution. I am not sure if the maintainers will consider it good enough to integrate in the main code. Actually, I suspect there are more elegant ways to achieve what I did in that file (the extra SQL query is probably superfluous) but I'm just too lazy to take care of that aspect just now -- and it works.

The code

In inc/MODEL/collections/_category.funcs.php
line 329, under

$this_cat['cat_postcount'] = 0;


ADD

$this_cat['cat_postcount_subs'] = 0;
$this_cat['cat_postcount_pubsubs'] = 0;

line 446, under

$cache_categories[$cat_ID]['cat_postcount'] = $myrow['cat_postcount'];


ADD

$cache_categories[$cat_ID]['cat_postcount_subs'] = $myrow['cat_postcount'];

line 450, under

$ItemQuery = & new ItemQuery( $dbtable, $dbprefix, $dbIDname );


ADD

$ItemQuery->where_chapter( $blog, '', array() );
// * Restrict to only published posts
$ItemQuery->where_visibility( array('published') );
$ItemQuery->where_datestart( '', '', '', '', $timestamp_min, $timestamp_max );
$sql = 'SELECT postcat_cat_ID AS cat_ID, COUNT(*) AS cat_postcount'
				.$ItemQuery->get_from()
				.$ItemQuery->get_where()
				.$ItemQuery->get_group_by()."
				GROUP BY cat_ID";
foreach( $DB->get_results( $sql, ARRAY_A, 'Load postcounts' ) as $myrow )
{
	$cat_ID = $myrow['cat_ID'];
	if( !isset($cache_categories[$cat_ID]) )
		echo '<p>*** WARNING: There are '.$myrow['cat_postcount'].' posts attached to non existant category #'.$cat_ID.'. You must fix the database! ***</p>';
	// echo 'Postcount for cat #', $cat_ID, ' is ', $myrow['cat_postcount'], '<br />';
	$cache_categories[$cat_ID]['cat_postcount_pubsubs'] = $myrow['cat_postcount'];
}
foreach( $cache_categories as $cat_ID => $onecat )
{ // Now let's bubble them up
	$thisID = $cat_ID;
	// echo 'Processing cat #'.$thisID.': ';
	while ($cache_categories[$thisID]['cat_parent_ID'] > 0) {
		$parentID = $cache_categories[$thisID]['cat_parent_ID'];
		$cache_categories[$parentID]['cat_postcount_subs'] += $cache_categories[$cat_ID]['cat_postcount'];
		$cache_categories[$parentID]['cat_postcount_pubsubs'] += $cache_categories[$cat_ID]['cat_postcount_pubsubs'];
		// echo 'parent #', $parentID, ' is now ', $cache_categories[$parentID]['cat_postcount_subs'], '; ';
		$thisID = $parentID;
	}
	// echo '.<br/>';
}

Categories now expose the following properties:
- cat_postcount_subs (count of posts in current category and its children)
- cat_postcount_pubsubs (count of published posts in current category and its children)

Now let's use those values in the categories display plugin:

In plugins/_categories.plugin.php
line 86, in the options description, ADD

*                - 'option_hide_empty' : true|false (Default: true)

line 138, under

if(!isset($params['option_all'])) $params['option_all'] = T_('All');


ADD

// Hide empty categories?
if(!isset($params['option_hide_empty'])) $params['option_hide_empty'] = true;

line 272, under

$cat = get_the_category_by_ID( $cat_ID );


ADD

global $generating_static;
if (($cat['cat_postcount_subs'] < 1 || ($cat['cat_postcount_pubsubs'] < 1 && !empty($generating_static))) && $this->params['option_hide_empty'])
{ // Skip empty cats
	return '';
}

Feedback most welcome: maybe I've done something that was already there and I didn't notice, or maybe I've done it in an inefficient way (that's quite likely, in fact). I hope it helps, though!

Best,

Raphaƫl


Form is loading...