Sticky Posts for b2evolution 0.9.x

Published by Andrew Hreschak in Web Development, b2evolution 0.9.x, PHP
Published on 09/10/05 @ 07:23:00 pm using 1122 words, and has 38809 views

This PHP hack for b2evo skins gives the ability to designate a particular post in each blog on a b2evolution system as a "sticky post" (i.e. that post will always appear at the top of the blog, and will not be listed chronologically). This is useful for creating a post which describes the contents of the blog or category, or which contains some other information which would be useful to have shown always on the entry page to a specific b2evo blog.

First, modify your "blogs" table so you can assign a post ID as 'sticky' for each blog. You will be able to set this in the b2evolution back office later. Assigning a value of 0 (zero) will mean no sticky post. I altered the b2evo blogs table via phpMyAdmin with the following mySQL command:

ALTER TABLE `evo_blogs` ADD `blog_stickypost_ID` INT( 10 ) DEFAULT '0' NOT NULL

Next crack open admin/b2blogs.php and perform the following two hacks. First find and add:

param( 'blog_pingblodotgs', 'integer', 0 );
$edited_Blog->set( 'pingblodotgs', $blog_pingblodotgs );
 
param( 'blog_stickypost_ID', 'integer', 0 ); // stickypost hack
$edited_Blog->set( 'stickypost_ID', $blog_stickypost_ID ); // stickypost hack

Then find and add:

$blog_pingweblogs = get_bloginfo( 'pingweblogs' );
$blog_pingblodotgs = get_bloginfo( 'pingblodotgs' );
$blog_stickypost_ID = get_bloginfo( 'stickypost_ID' ); // stickypost hack
require( dirname(__FILE__).'/_blogs_advanced.form.php' );

Close it and open admin/_blogs_advanced.form.php then find and add:

<fieldset>
<legend><?php echo T_('Advanced options') ?></legend>
<?php
form_checkbox( 'blog_allowtrackbacks', $blog_allowtrackbacks, T_('Allow trackbacks'), T_("Allow other bloggers to send trackbacks to this blog, letting you know when they refer to it. This will also let you send trackbacks to other blogs.") );
form_checkbox( 'blog_allowpingbacks', $blog_allowpingbacks, T_('Allow pingbacks'), T_("Allow other bloggers to send pingbacks to this blog, letting you know when they refer to it. This will also let you send pingbacks to other blogs.") );
?>
</fieldset>
 
<?php // stickypost hack ?>
<fieldset>
<legend><?php echo T_('Advanced options') ?></legend>
<?php
form_text( 'blog_stickypost_ID', $blog_stickypost_ID, 8, T_('StickyPost ID'), T_('This is the Post ID of the post currently designated as this blog\'s sticky post. Set it to 0 to have no stickypost') );
?>
</fieldset>
<?php // end stickypost hack ?>
 
<?php form_submit(); ?>

Now open b2evocore/_class_blog.php and do 2 changes. Find and add:

var $disp_bloglist = 1;
var $in_bloglist = 1;
var $UID;
var $stickypost_ID; // stickypost hack

then find and add:

$this->in_bloglist = $db_row->blog_in_bloglist;
$this->UID = $db_row->blog_UID;
$this->stickypost_ID = $db_row->blog_stickypost_ID; // stickypost hack
}

Okay now to use it. First, set up the whole stickypost thing. In _main.php find and add:

<!-- =================================== START OF MAIN AREA =================================== -->
 
<?php // START OF STICKYPOST
 
if( $disp == 'posts' ) { // only do this for multi-post pages
 
$sql = "SELECT blog_stickypost_ID FROM $tableblogs WHERE blog_ID = $blog";
$sticky_post = $DB->get_var($sql);
$Item = Item_get_by_ID( $sticky_post );
 
if( $sticky_post ) { // only do this if stickypost is not 0
 
$sql = "SELECT postcat_post_ID, postcat_cat_ID FROM $tablepostcats WHERE postcat_post_ID = $sticky_post ORDER BY postcat_post_ID, postcat_cat_ID";
$rows = $DB->get_results( $sql, ARRAY_A );
if( count( $rows ) ) foreach( $rows as $myrow ) {
$postcat_post_ID = $myrow["postcat_post_ID"];
if( ! isset( $cache_postcats[$postcat_post_ID] ) ) {
$cache_postcats[$postcat_post_ID] = array();
}
$cache_postcats[$postcat_post_ID][] = $myrow["postcat_cat_ID"];
}
?> 

These changes perform several functions. First, they check to see if the blog is displaying a multi-post page. If the blog is in single-post mode, the sticky post functions are skipped. Likewise, if stickypost is set to 0, skip the sticky. cache_postcats is normally set by the posts loop, so we can trick the system and set it here manually for the sticky.

Next we add all the code that makes a post a post, but not including the stuff that adds comments and the comment form. After the above add:

<div class="bPost" lang="<?php $Item->lang() ?>">
<?php
locale_temp_switch( $Item->locale ); // Temporarily switch to post locale
$Item->anchor(); // Anchor for permalinks to refer to
?>
<div class="bSmallHead">
<a href="<?php $Item->permalink() ?>" title="<?php echo T_('Permanent link to full entry') ?>"><img src="img/icon_minipost.gif" alt="Permalink" width="12" height="9" class="middle" /></a>
<?php
$Item->issue_time();
echo ', ', T_('Categories'), ': ';
$Item->categories();
echo ', ';
$Item->wordcount();
echo ' ', T_('words'), ' &nbsp; ';
locale_flag( $Item->locale, 'h10px' );
?>
</div>
<h3 class="bTitle"><?php $Item->title(); ?></h3>
<div class="bText">
<?php $Item->content(); ?>
<?php link_pages() ?>
</div>
<div class="bSmallPrint">
<a href="<?php $Item->permalink() ?>" title="<?php echo T_('Permanent link to full entry') ?>" class="permalink_right"><img src="img/chain_link.gif" alt="<?php echo T_('Permalink') ?>" width="14" height="14" border="0" class="middle" /></a>
<?php $Item->feedback_link( 'comments' ) // Link to comments ?>
<?php $Item->feedback_link( 'trackbacks', ' &bull; ' ) // Link to trackbacks ?>
<?php $Item->feedback_link( 'pingbacks', ' &bull; ' ) // Link to trackbacks ?>
<?php $Item->edit_link( ' &bull; ' ) // Link to backoffice for editing ?>
<?php $Item->trackback_rdf() // trackback autodiscovery information ?>
</div>
<?php
locale_restore_previous();  // Restore previous locale (Blog locale)
?>
</div> 

Nothing novel here... it's just the post loop... however this is only going to run once for the sticky. If you want to style your sticky differently then use new CSS class names to differentiate them from the main post loop.

To complete the sticky in 3 easy steps add the following code after the code above:

<?php
unset($cache_postcats);
} // end if stickypost is not 0
} // end if disp=posts
// END OF STICKYPOST ?>
 
<?php // ------------------------------------ START OF POSTS ----------------------------------------

The only thing remaining to take care, other than setting the post ID of the sticky itself, is to tell the regular posts loop to ignore the stickypost so that it doesn't appear twice on the blog. So, still in _main.php, find and add:

if( isset($MainList) ) while( $Item = $MainList->get_item() )
{
if( $Item->get('ID') == $sticky_post ) {
continue;
}
$MainList->date_if_changed(); 

The code below is the block added to _main.php for the darkling/brightling series of custom b2evo skins located on this site...

<div id="maincontent">

<?php // START OF STICKYPOST
if( $disp == 'posts' ) { // only do this for multi-post pages
$sql = "SELECT blog_stickypost_ID FROM $tableblogs WHERE blog_ID = $blog";
$sticky_post = $DB->get_var($sql);
$Item = Item_get_by_ID( $sticky_post );
if( $sticky_post ) { // only do this if stickypost is not 0
$sql = "SELECT postcat_post_ID, postcat_cat_ID FROM $tablepostcats WHERE postcat_post_ID = $sticky_post ORDER BY postcat_post_ID, postcat_cat_ID";
$rows = $DB->get_results( $sql, ARRAY_A );
if( count( $rows ) ) foreach( $rows as $myrow ) {
$postcat_post_ID = $myrow["postcat_post_ID"];
if( ! isset( $cache_postcats[$postcat_post_ID] ) ) {
$cache_postcats[$postcat_post_ID] = array();
}
$cache_postcats[$postcat_post_ID][] = $myrow["postcat_cat_ID"];
}
?>

<div class="bPost" lang="<?php $Item->lang() ?>">
<?php
locale_temp_switch( $Item->locale ); // Temporarily switch to post locale
$Item->anchor(); // Anchor for permalinks to refer to
?>
 
<div class="bSmallHead">
<?php
echo '', T_('Categories'), ': ';
$Item->categories();
?>
<br />
Posted by: <a href="<?php $Blog->disp( 'blogurl', 'raw' ) ?>?author=<?php the_author_ID() ?>" title="<?php echo T_('Browse all posts by this author') ?>"><?php $Item->Author->prefered_name() ?></a>&nbsp; |&nbsp;
<?php
$Item->wordcount();
echo ' ', T_('words');
?>
</div>
 
<h2 class="topheading"><a href="<?php $Item->permalink() ?>" title="<?php echo T_('Permanent link to full entry') ?>" class="permalink_left"><?php $Item->title(); ?></a></h2>
<div class="bText">
 
<?php $Item->content('#','#',$Item->get('title'),'','<p>Read full text of ','...</p>','htmlbody',10); ?>
 
<?php link_pages() ?>
</div>


<div class="bSmallPrint">
<a href="<?php $Item->permalink() ?>" title="<?php echo T_('Permanent link to full entry') ?>" class="permalink_right"><img src="img/post.gif" alt="Permanent link to full entry" />&nbsp;Permalink</a>
 
<?php $Item->edit_link( ' ' ) // Link to backoffice for editing ?>
<?php $Item->trackback_rdf() // trackback autodiscovery information ?>
</div>
<?php
locale_restore_previous();  // Restore previous locale (Blog locale)
?>
</div> 

<?php
unset($cache_postcats);
} // end if stickypost is not 0
} // end if disp=posts
// END OF STICKYPOST ?>
<!-- END STICKY POST INCLUSION -->

<?php // START POSTS

Sweet! So now we go into the b2evo backoffice and first select a blog, then select the advanced tab. Our code hacks have inserted a new form field at the end of the page wherein we can assign the sticky post ID number. That's where we tell it which post is sticky, or 0 for no stickypost. Do this for each post on the b2evo blog system, and you're all set.

Contemporaneous Auditory Narcotics:
or, What my speakers are currently pumping...
Roni Size - Wayz Of The Dragon

2 comments

Comment from: bonus dei casiṇ online [Visitor]  
bonus dei casiṇ online

Thanks for such a nice article.

10/08/09 @ 02:36
Comment from: Jarrett [Visitor]  
Jarrett

Thanks. There is much very useful information on your blog for me.

06/17/10 @ 13:08