To register for an Internet.com membership to receive newsletters and white papers, use the Register button ABOVE.
To participate in the message forums BELOW, click here
how to sort authors into divs from left to right by newest post
I'm making a blog using wordpress with multiple authors and currently each author's posts are placed into a vertical div from left to right in a set order (ie tony, hippie, erik etc) and I am trying to sort the authors from left to right according to who has posted most recently. I was getting help on this site in another post about using arrays but it kind of changed topics so I thought I'd start a new thread. I've gotten no help at all from the wordpress.org site...thanks a lot!
I've no idea what you can or cannot do with a "WP_Query", so this may be of no help. The way I'd solve it is by querying the db for posts from all authors at once (and being more efficient in the same time since that's one query instead of four) and order by author ascending and time of last post descending.
Just used to show three divs with different border colours for the sake of this example's output. Your CSS will put them where you want to.
// This is where your code would start with the proper query instead of my fake one.
$res = new MockResult();
if ($res) {
while ($row = $res->fetch_assoc()) {
/* array key must be unique, so if more than one person has the same name
you need to use $row['author_name'] . '_' . $row['author_id']
The name is used for ordering. If you don't care about that, then author_id is fine.
(and if you don't need krsort and ksort below, just the author_id is fine */
$author[$row['author_name']][] = $row;
}
foreach($author as $k => $v) {
/* $v[0] is the first post for each author.
since it's sorted by date DESC, it's the latest post by that poster
$v is the array of all posts for that author.
*/
$order[$v[0]['post_date']][$k] = $v;
}
/* Both krsort and ksort below should not have to be used if you order your
sql result properly. Unless I'm misstaken. Do double check it.
I didn't sort my test data, so I needed this anyway.
*/
// Sort by dates in descending order
krsort($order);
// for each date, sort by author name in ascending order
foreach ($order as $k => $v) {
ksort($order[$k], SORT_STRING);
}
}
else {
// error
exit;
}
so I need to figure out how to assign the values to the array using a wp_query instead of the values you assigned to the array right? I think I need more help about how the keys are created and values assigned if you aren't directly assigning them like you show here:
I just simulated the behaviour of performing a query and using its result for mysql_fetch_assoc. So this part
PHP Code:
// This is where your code would start with the proper query instead of my fake one.
$res = new MockResult();
if ($res) {
while ($row = $res->fetch_assoc()) {
would become something like
PHP Code:
// This is where your code would start with the proper query instead of my fake one.
$qry = 'The sql query'; // we get to this further down
$res = mysql_query($qry)
if ($res) {
while ($row = $res->mysql_fetch_assoc()) {
Your fields (corresponding to the array element keys) may have other names than what I used, such as person instead of author, created or modified instead of post_date etc.
And you'd obviously need to get more information than just name and date, such as the actual post, title etc.
This information should let you handle the SQL yourself: http://codex.wordpress.org/Database_Description.
After a quick glance at http://core.trac.wordpress.org/brows...udes/query.php, I'd definitely forgo WP_query and handle this specific SQL query on my own.
Quote:
Currently, the only database supported by WordPress Version 2.7 is MySQL version 4.0 or greater.
So for one, we know that it's indeed mysql or mysqli you should use.
$qry = "SELECT u.id, u.nicename, post_date, post_content, post_title
FROM wp_posts INNER JOIN wp_users AS u ON post_author = u.id
WHERE nicename = 'tony' OR nicename = 'eric' OR nicename = 'hippie'
ORDER BY nicename ASC, post_date DESC";
I put all the stuff together in my index.php file, I know I'm doing something stupid, because it's just outputting the code as text. For the query, can you explain what it is doing? And do I need to use the $wpdb variable they have setup to talk to the database? :
PHP Code:
<?php
get_header ();
?>
<div id="box">
$qry = "SELECT u.id, u.nicename, post_date, post_content, post_title
FROM wp_posts INNER JOIN wp_users AS u ON post_author = u.id
WHERE nicename = 'tony' OR nicename = 'eric' OR nicename = 'hippie'
ORDER BY nicename ASC, post_date DESC";
$res = mysql_query($qry)
if ($res) {
while ($row = $res->mysql_fetch_assoc()) {
$author[$row['author_name']][] = $row;
}
foreach($author as $k => $v) {
I've no idea if you know any SQL at all, so bear with me if I'm explaining things you know.
This part tells the db what fields your interested in. Think of these as columns in a spreadsheet, and you're telling the db which of these columns should be retrieved.
Code:
SELECT field1, field 2, ..., fieldN
Table in which to find the columns
Code:
FROM table1
One table is not enough. Inner join tells the db to combine the first table with the second table. Every post where table1.someColumn is equal to table2.aColumn will be joined together. If there is no matching value in table2, then no row is retrieved from table1. (Compare this to LEFT JOIN where every row in table1 is retrieved, and if someColumn has no matching value in aColumn, the columns from table2 are filled with null values for this row).
Code:
INNER JOIN table2 ON table1.someColumn = table2.aColumn
users
id name
--- -------
1 tony
2 eric
posts
id author title
-- -------- ------------------------
1 1 Tony's first post
2 2 Eric's first post
3 2 Eric's second post
.... (for which author is neither 1 or 2) ...
115 2 Eric's third post
SELECT name, title
FROM users
INNER JOIN posts ON posts.author = author.id
This would link the user row for 'tony', id = 1, to the post with title "Tony's first post", author = 1, since id = author.
It would do the same for user 'eric', but get the posts with id 2, 3 and 115, where author = 2, since that matches eric's user id.
And the result is:
name title
------ ------------------
tony Tony's first post
eric Eric's first post
eric Eric's second post
eric Eric's third post
(just never assume this comes in any specific order, unless you tell the db to order the result in some way)
The where clause tells the DB that we only want posts where a certain field or fields matches certain criteria
Code:
WHERE somefield = somevalue
WHERE nicename = 'eric' OR nicename like 'tony%'
Only include rows from users where the user's name is eric, or where the user's name starts with tony (tony_the_tiger would be ok, but not tiger_tony)
Order by tells the db how to order the result. ASC stands for ascending, DESC for descending, and ordering is done depending on the data type of the field. An int field will be sorted as number, where 9 comes before 10, while a text field like nicename will be ordered as a string, where 10 comes before 9.
First order by field2 from lowest to highest, then for any rows having the same field2 value, also order by field1 in descending orer.
Code:
ORDER BY field2 ASC, field1 DESC
And no, you do not have to use the instance of word press db class. There are some things I don't like about it at all. For example, it has a member method called prepare, which "prepares" a query, except that it has nothing to do with prepared statements. In other words, it has no correlation to functions like mysqli->prepare(). Moreover, it does some unnecessary things, such as replacing '%s' with %s, "%s" with %s, and then replacing %s with '%s'. The result is that whatever the user (you) uses, it will always turn out to be '%s' in the end. Why not just assume that the coder deals with writing correct code in the first place, or at least learn to do so when he recognizes his error?
Also, the code is riddled with the error supression operator @. And there are word press specific settings for how to deal with errors. Perhaps it's useful if you have no control over this for some reason.
It would be interesting to hear what others think, but I'd skip wpdb and do this with mysqli.
Quote:
Originally Posted by griever
I was wondering where I should put the "Loop" that wordpress uses to output the posts. My old loops, one for each author, was:
I bet a lot of this is wordpress specific but any help is really appreciated
With my solution, you wouldn't. You'd use the loop I suggested in my first post.
Not really. Apart from the db schema they use, for which info is here, this is pretty much generic.
thanks for the explanation! I've been going over what's going on, and for now, it's getting to my "box" div and stopping. The page code stops there as well. It outputs the header but never calls out the sidebar or the footer. Maybe it is running into an error and exiting after that ksort section? Also I closed the php tag just before the end of the "box" div.
PHP Code:
<?php
get_header ();
?>
<div id="box">
<?php
$qry = "SELECT u.id, u.nicename, post_date, post_content, post_title
FROM wp_posts INNER JOIN wp_users AS u ON post_author = u.id
WHERE nicename = 'tony' OR nicename = 'eric' OR nicename = 'hippie'
ORDER BY nicename ASC, post_date DESC";
$res = mysql_query($qry);
if ($res) {
while ($row = $res->mysql_fetch_assoc()) {
$author[$row['author_name']][] = $row;
}
foreach($author as $k => $v) {
Cannot use string offset as an array for line 25 which is
$order[$v[0]['post_date']][$k] = $v;
here is my newest code:
PHP Code:
<?php
get_header ();
?>
<div id="box">
<?php
$qry = "SELECT u.id, user_nicename, post_date, post_content, post_title
FROM wp_posts INNER JOIN wp_users AS u ON post_author = u.id
WHERE user_nicename = 'tony' OR user_nicename = 'eric' OR user_nicename = 'hippie'
ORDER BY user_nicename ASC, post_date DESC";
$res = mysql_query($qry);
if ($res) {
while ($row = mysql_fetch_assoc($res)) {
$author[$row['author_name']][] = $row;
}
foreach($author as $k => $v) {
While there is no field named 'author_name' in the SQL query. Either change 'author_name' to 'nicename' everywhere in the code, or change the SQL to be "SELECT ..., nicename AS author_name, ..."
I changed all the author_name to user_nicename but the same error pops up. Does this error have to do with a field being called out as a string instead of an int or vice versa?
PHP Code:
<?php
get_header ();
?>
<div id="box">
<?php
$qry = "SELECT u.id, user_nicename, post_date, post_content, post_title
FROM wp_posts INNER JOIN wp_users AS u ON post_author = u.id
WHERE user_nicename = 'tony' OR user_nicename = 'eric' OR user_nicename = 'hippie'
ORDER BY user_nicename ASC, post_date DESC";
$res = mysql_query($qry);
if ($res) {
while ($row = mysql_fetch_assoc($res)) {
$author[$row['user_nicename']][] = $row;
}
foreach($author as $k => $v) {
now the error message remained but output a little bit before:
string(4) "DESC"
Fatal error: Cannot use string offset as an array in /home1/hippievs/public_html/wp-content/themes/duel/index.php on line 26
PHP Code:
<?php
get_header ();
?>
<div id="box">
<?php
$qry = "SELECT u.id, user_nicename, post_date, post_content, post_title
FROM wp_posts INNER JOIN wp_users AS u ON post_author = u.id
WHERE user_nicename = 'tony' OR user_nicename = 'eric' OR user_nicename = 'hippie'
ORDER BY user_nicename ASC, post_date DESC";
$res = mysql_query($qry);
if ($res) {
while ($row = mysql_fetch_assoc($res)) {
$author[$row['user_nicename']][] = $row;
}
var_dump($order);
foreach($author as $k => $v) {
Since $order has not been used in this little piece of code before the var_dump, that has been set before. Use some other variable instead. $orderByDate or whatever.