The MU forums have moved to WordPress.org

Sitewide most recent posts on any page (16 posts)

  1. cfish
    Member
    Posted 14 years ago #

    I wanted a simple method for displaying the most recent posts from all/any blog in WPMU in any page on my website.

    Having looked around here it seems that you can easily display the most recent post from one or more blogs but what if one blog contains 2 (or more) of the most recent 10 posts? Also, most solutions here rely on the fact that WPMU is running in the background and therefore plugins etc. can be used.

    My solution solves both these problems. It is independent of WPMU (except for accessing the database) and it will display the most recent x (user configurable) posts in a simple html format including links to the original articles, author name and how long ago the post was made.

    Now I'm not a PHP/MySQL expert but the following code works well for me. If anyone would like to suggest improvements, either in code or functionality, I'd be very grateful.

    <?php
    $show       = 10;                 # The number of posts to display on this page
    $characters = 500;                # The maximum number of characters to display from each post
    $user       = "db_user";          # The database user name
    $password   = "db_user_password"; # The database user password
    $db         = "db_name";          # The name of your WPMU database
    ?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>My WPMU Blogs | Most recent posts</title>
    </head>
    <body>
    
    <h1>Most recent posts</h1>
    
    <?php
    # connect to mysql and test the connection
    $link = mysql_connect("localhost", $user, $password);
    if (!$link) die ("cannot connect to mysql - check ID and Password");
    
    # select the database once connected
    mysql_select_db($db, $link) or die ("cannot select the database - check Name");
    
    # get an array containing all blog ids and count how many there are
    $query="SELECT blog_id FROM wp_blogs";
    $result=mysql_query($query);
    $count=mysql_num_rows($result);
    
    # compile a query for all posts from all blogs and order with most recent first
    $i=0;
    while ($row=mysql_fetch_array($result)) {
    	$i++;
    	$blog_id=$row[blog_id];
    	if ($i < $count) {
    	$post_query .= "SELECT post_date, UNIX_TIMESTAMP(post_date) AS date, post_title, guid, post_content, post_author, display_name FROM wp_".$blog_id."_posts LEFT JOIN wp_users ON wp_".$blog_id."_posts.post_author = wp_users.ID  WHERE post_status = 'publish' AND post_type = 'post' UNION ALL ";
    	}else{
    	$post_query .= "SELECT post_date, UNIX_TIMESTAMP(post_date) AS date, post_title, guid, post_content, post_author, display_name FROM wp_".$blog_id."_posts LEFT JOIN wp_users ON wp_".$blog_id."_posts.post_author = wp_users.ID WHERE post_status = 'publish' AND post_type = 'post' ORDER BY post_date DESC LIMIT $show;";
    	}
    }
    
    # run the query
    $post_result=mysql_query($post_query);
    
    # process and format each post from the query result
    while ($post_row=mysql_fetch_array($post_result)) {
    	# process post title and link
    	$post_title=$post_row[post_title];
    	$post_url=$post_row[guid];
    
    	# process post content: remove images and captions,  remove leading line breaks and returns, truncate, remove last character if it's a space and add a "more" link, replace breaks and returns with html paragraphs
    	$post_content=strip_tags($post_row[post_content]);
    	$post_content=preg_replace("/\[caption(.+?)\]/", "", $post_content);
    	$post_content=str_replace("[/caption]", "", $post_content);
    	while (substr($post_content, 0, 1) == chr(13) OR substr($post_content, 0, 1) == chr(10)){$post_content = substr($post_content, 1);}
    	if (strlen($post_content) > $characters) {
    		$post_content=substr($post_content, 0, $characters);
    		if (substr($post_content, -1, 1) == " "){$post_content = substr($post_content, 0, ($characters -1));}
    		$post_content=$post_content . "&hellip; <a href=\"$post_url\">more</a>";
    	}
    	$post_content=str_replace(chr(13).chr(10).chr(13).chr(10), "</p>\n<p>", $post_content);
    
    	# process time: determine how long ago the post was made and format accordingly
    	$post_date=$post_row[date];
    	$period=time()-$post_date;
    
    	if ($period <3600){
    		$period=floor($period/60);
    		if ($period==0){$period="Posted: less than one minute ago";}
    		elseif($period==1){$period="Posted: $period minute ago";}
    		else{$period="Posted: $period minutes ago";}
    	}
    	elseif ($period <86400)
    	{
    		$period=floor($period/3600);
    		if ($period==1){$period="Posted: $period hour ago";}else{$period="Posted: $period hours ago";}
    	}
    	else
    	{
    		$period=floor($period/86400);
    		if ($period==1){$period="Posted: $period day ago";}else{$period="Posted: $period days ago";}
    	}
    
    	$display_name=$post_row[display_name];
    
    	# output html
    	echo "<h2><a href=\"$post_url\">$post_title</a></h2>\n<p>$period by $display_name</p>\n<p>$post_content</p>\n\n";
    }
    
    # close the sql connection
    mysql_close($link);
    ?>
    </body>
    </html>
  2. buaan
    Member
    Posted 14 years ago #

    Just posting to say this was exactly what I was looking for.

    Works perfectly, code is well structured and commented.

    Great work :)

  3. chaoflux23
    Member
    Posted 14 years ago #

    Sweet. Thanks!

  4. Arthran
    Member
    Posted 14 years ago #

    Anybody got an example of this working?

  5. SteveAtty
    Member
    Posted 14 years ago #

    I suspect on a large/heavily used site that union code will be a huge resource hog. Why not just loop round each blog in turn and take the last published post?

    Also the guid doesn't always contain the url of the post, much better to use the blog_id and post_id and the built in function to return the current permalink.

  6. viniciusandre
    Member
    Posted 14 years ago #

    Try to use $wpdb class. Wordpress doesn't need to connect again to the database (that was already done since wp-config was loaded).

  7. perezae
    Member
    Posted 14 years ago #

    What file should this code be placed in. Sorry, new to WPMU.

  8. andrea_r
    Moderator
    Posted 14 years ago #

    You don't. It's a standalone file. The OP built it to show recent posts form their MU site on another php page outside of the MU installation.

    If you hang on a bit, Ron & I will be releasing another featured posts plugin with widget.

  9. zazinteractive
    Member
    Posted 14 years ago #

    How would you modify the code to make it show latest from only a certain specified blog

  10. andrea_r
    Moderator
    Posted 14 years ago #

  11. JsonB123
    Member
    Posted 14 years ago #

    Hey there, would it be possible to also put a custom RSS / Mail subscribe to the posts grabbed (and only those posts grabbed) via the code from the OP?

    Is there a way to build "custom rss" feeds in WordPress/MU? I just need a starting place; thanks guys!

  12. andrea_r
    Moderator
    Posted 14 years ago #

    If you use the sitewide tags plugin to get all the posts, then the tags blog (or the main one if you use that) will have any feeds that WP normally does. Except they'll be filled with sitewide content.

  13. JsonB123
    Member
    Posted 14 years ago #

    @andrea_r:

    Right, but won't that make all the links to the posts in the feed/subscribe email point to the "tags" blog as opposed to the actual blog that they are coming from? I would need the link to go to the real blog, not the global tags blog.

  14. andrea_r
    Moderator
    Posted 14 years ago #

    The permalinks that the SWT plugin uses DO go back to the originating blog.

    POC: http://homeschooljournal.net

  15. clmnsbzy
    Member
    Posted 14 years ago #

    I adapted to use the wpdb class which is more effective, i guess:

    <?php
    $show       = 3;                 # The number of posts to display on this page
    $characters = 500;                # The maximum number of characters to display from each post
    ?>
    
    <h1>Most recent posts</h1>
    
    <?php
    #globalize wpdb
    global $wpdb;
    
    # get an array containing all blog ids and count how many there are
    $result = $wpdb->get_col("SELECT blog_id FROM $wpdb->blogs WHERE public = '1' AND archived = '0' AND mature = '0' AND spam = '0' AND deleted = '0' AND blog_id != '1'");
    $count = $wpdb->num_rows;
    
    # compile a query for all posts from all blogs and order with most recent first
    $i=0;
    foreach ($result as $blog_id) {
    	$i++;
    	if ($i < $count) {
    	$post_query .= "SELECT post_date, UNIX_TIMESTAMP(post_date) AS date, post_title, guid, post_content, post_author, display_name FROM wp_".$blog_id."_posts LEFT JOIN wp_users ON wp_".$blog_id."_posts.post_author = wp_users.ID  WHERE post_status = 'publish' AND post_type = 'post' UNION ALL ";
    	}else{
    	$post_query .= "SELECT post_date, UNIX_TIMESTAMP(post_date) AS date, post_title, guid, post_content, post_author, display_name FROM wp_".$blog_id."_posts LEFT JOIN wp_users ON wp_".$blog_id."_posts.post_author = wp_users.ID WHERE post_status = 'publish' AND post_type = 'post' ORDER BY post_date DESC LIMIT $show;";
    	}
    }
    
    # run the query
    $post_result = $wpdb->get_results($post_query);
    
    # process and format each post from the query result
    foreach ($post_result as $post_row) {
    	# process post title and link
    	$post_title=$post_row->post_title;
    	$post_url=$post_row->guid;
    
    	# process post content: remove images and captions,  remove leading line breaks and returns, truncate, remove last character if it's a space and add a "more" link, replace breaks and returns with html paragraphs
    	$post_content=strip_tags($post_row->post_content);
    	$post_content=preg_replace("/\[caption(.+?)\]/", "", $post_content);
    	$post_content=str_replace("[/caption]", "", $post_content);
    	while (substr($post_content, 0, 1) == chr(13) OR substr($post_content, 0, 1) == chr(10)){$post_content = substr($post_content, 1);}
    	if (strlen($post_content) > $characters) {
    		$post_content=substr($post_content, 0, $characters);
    		if (substr($post_content, -1, 1) == " "){$post_content = substr($post_content, 0, ($characters -1));}
    		$post_content=$post_content . "&hellip; <a href=\"$post_url\">more</a>";
    	}
    	$post_content=str_replace(chr(13).chr(10).chr(13).chr(10), "</p>\n<p>", $post_content);
    
    	# process time: determine how long ago the post was made and format accordingly
    	$post_date=$post_row->date;
    	$period=time()-$post_date;
    
    	if ($period <3600){
    		$period=floor($period/60);
    		if ($period==0){$period="Posted: less than one minute ago";}
    		elseif($period==1){$period="Posted: $period minute ago";}
    		else{$period="Posted: $period minutes ago";}
    	}
    	elseif ($period <86400)
    	{
    		$period=floor($period/3600);
    		if ($period==1){$period="Posted: $period hour ago";}else{$period="Posted: $period hours ago";}
    	}
    	else
    	{
    		$period=floor($period/86400);
    		if ($period==1){$period="Posted: $period day ago";}else{$period="Posted: $period days ago";}
    	}
    
    	$display_name=$post_row->display_name;
    
    	# output html
    	echo "<h2><a href=\"$post_url\">$post_title</a></h2>\n<p>$period by $display_name</p>\n<p>$post_content</p>\n\n";
    }
    
    ?>

    Maybe I'll find the time to make a plugin out of it, since the ahp sitewide recent posts plugin does not really work. great code cfish, thanks!

  16. chicoi08
    Member
    Posted 14 years ago #

    how can i use this?

    can i just copy this and then save it as a php file then upload to mu-plugins?

About this Topic