Multiple Wordpress Loops - php

I'm working on a modified WordPress loop and I'm trying to achieve is a "sort of" multiple wordpress loops that will appear on my index file.
My goal is to create the following:
Loop #1: a WP loop that will display the (latest and the most recent published) post number 1, 2 & 3.
Loop #2: a WP loop that will display the (latest and the most recent published) post number 4, 5, 6, 7, 8 & 9
Loop #3: a WP loop that will display the (latest and the most recent published) post number 10, 11, 12 & 13
Loop #4: a WP loop that will display the (latest and the most recent published) post number 14 & 15
Loop #5: a WP loop that will display the all the remaining post (this excludes post #1 to 15, which was already displayed by the Loop#1-4).
*Loops 1-5 will be wrapped up in to one loop and will run in my index file.
I know, anyone can argue that I can do this in a simple wordpress loop. but the reason behind this is each Loops has it's own unique HTML Structure (this is actually my plan).
In the Loop #5, I have tried using the <?php query_posts('offset=15'); if ( have_posts() ) : while ( have_posts() ) : the_post(); ?> BUT the problem with this approach is it didn't worked well with the WP pagination. The problem is the when I tried to move to the Next Page or, the same set of post will be displayed which is the post #16 etc.
I am seeking your help and assistance that anyone could provide. I am a noob in WP Loops and has a very basic skills PHP.
Thank you everyone for your help.

You best solution would be to do a single loop with if's and an iterator. Like so:
$i = 1;
while (have_posts()) {
if ($i <= 3) {
[...]
} elseif ($i <= 9) {
[...]
} elseif ($i <= 13) {
[...]
} elseif ($i <= 15) {
[...]
} else {
[...]
}
$i++;
}
I would suggest separating each segment into a function/method that you call in each if statement to help keep things neat, but that is your call.

You should structure your query like so:
$q1 = new WP_Query(array(
'post__in' => array(1, 2, 3)
);
if ($q1->have_posts()) while ($q1->have_posts()) : $q1->the_post();
the_content(); // Structure your output normally here
endwhile;
And repeat for other queries, changing the variable name (q1 here) for each of them. For #5 you can use the 'post__not_in' key. See WP_Query reference for more options.
Alternate solution
Since you need this only to display different HTML output you could do a single loop, and conditionally insert different outputs according to the post id, like so:
if(have_posts()) while(have_posts()) : the_post();
switch(get_the_ID()) {
case 1: case 2: case 3:
// output for #1
break;
case 4: case 5: case 6: // ....
// output for #2
break;
default: // anything greater than 6 here
// default output
break;
}
endwhile;

See these all supported arguments for WP_Query OR query_posts
$args = array(
//////Author Parameters - Show posts associated with certain author.
'author' => 1,2,3, //(int) - use author id [use minus (-) to exclude authors by ID ex. 'author' => -1,-2,-3,]
'author_name' => 'luetkemj', //(string) - use 'user_nicename' (NOT name)
//////Category Parameters - Show posts associated with certain categories.
'cat' => 5,//(int) - use category id.
'category_name' => 'staff', 'news', //(string) - use category slug (NOT name).
'category__and' => array( 2, 6 ), //(array) - use category id.
'category__in' => array( 2, 6 ), //(array) - use category id.
'category__not_in' => array( 2, 6 ), //(array) - use category id.
//////Tag Parameters - Show posts associated with certain tags.
'tag' => 'cooking', //(string) - use tag slug.
'tag_id' => 5, //(int) - use tag id.
'tag__and' => array( 2, 6), //(array) - use tag ids.
'tag__in' => array( 2, 6), //(array) - use tag ids.
'tag__not_in' => array( 2, 6), //(array) - use tag ids.
'tag_slug__and' => array( 'red', 'blue'), //(array) - use tag slugs.
'tag_slug__in' => array( 'red', 'blue'), //(array) - use tag slugs.
//////Taxonomy Parameters - Show posts associated with certain taxonomy.
//Important Note: tax_query takes an array of tax query arguments arrays (it takes an array of arrays)
//This construct allows you to query multiple taxonomies by using the relation parameter in the first (outer) array to describe the boolean relationship between the taxonomy queries.
'tax_query' => array( //(array) - use taxonomy parameters (available with Version 3.1).
'relation' => 'AND', //(string) - Possible values are 'AND' or 'OR' and is the equivalent of ruuning a JOIN for each taxonomy
array(
'taxonomy' => 'color', //(string) - Taxonomy.
'field' => 'slug', //(string) - Select taxonomy term by ('id' or 'slug')
'terms' => array( 'red', 'blue' ), //(int/string/array) - Taxonomy term(s).
'include_children' => true, //(bool) - Whether or not to include children for hierarchical taxonomies. Defaults to true.
'operator' => 'IN' //(string) - Operator to test. Possible values are 'IN', 'NOT IN', 'AND'.
),
array(
'taxonomy' => 'actor',
'field' => 'id',
'terms' => array( 103, 115, 206 ),
'include_children' => false,
'operator' => 'NOT IN'
)
),
//////Post & Page Parameters - Display content based on post and page parameters.
'p' => 1, //(int) - use post id.
'name' => 'hello-world', //(string) - use post slug.
'page_id' => 1, //(int) - use page id.
'pagename' => 'sample-page', //(string) - use page slug.
'pagename' => 'contact_us/canada', //(string) - Display child page using the slug of the parent and the child page, separated ba slash
'post_parent' => 1, //(int) - use page id. Return just the child Pages.
'post__in' => array(1,2,3), //(array) - use post ids. Specify posts to retrieve.
'post__not_in' => array(1,2,3), //(array) - use post ids. Specify post NOT to retrieve.
//NOTE: you cannot combine 'post__in' and 'post__not_in' in the same query
//////Type & Status Parameters - Show posts associated with certain type or status.
'post_type' => array( //(string / array) - use post types. Retrieves posts by Post Types, default value is 'post';
'post', // - a post.
'page', // - a page.
'revision', // - a revision.
'attachment', // - an attachment. The default WP_Query sets 'post_status'=>'published', but atchments default to 'post_status'=>'inherit' so you'll need to set the status to 'inherit' or 'any'.
'my-post-type', // - Custom Post Types (e.g. movies)
),
'post_status' => array( //(string / array) - use post status. Retrieves posts by Post Status, default value i'publish'.
'publish', // - a published post or page.
'pending', // - post is pending review.
'draft', // - a post in draft status.
'auto-draft', // - a newly created post, with no content.
'future', // - a post to publish in the future.
'private', // - not visible to users who are not logged in.
'inherit', // - a revision. see get_children.
'trash' // - post is in trashbin (available with Version 2.9).
),
//NOTE: The 'any' keyword available to both post_type and post_status queries cannot be used within an array.
'post_type' => 'any', // - retrieves any type except revisions and types with 'exclude_from_search' set to true.
'post_status' => 'any', // - retrieves any status except those from post types with 'exclude_from_search' set to true.
//////Pagination Parameters
'posts_per_page' => 10, //(int) - number of post to show per page (available with Version 2.1). Use 'posts_per_page'=-1 to show all posts. Note if the query is in a feed, wordpress overwrites this parameter with the stored 'posts_per_rss' option. Treimpose the limit, try using the 'post_limits' filter, or filter 'pre_option_posts_per_rss' and return -1
'posts_per_archive_page' => 10, //(int) - number of posts to show per page - on archive pages only. Over-rides showposts anposts_per_page on pages where is_archive() or is_search() would be true
'nopaging' => false, //(bool) - show all posts or use pagination. Default value is 'false', use paging.
'paged' => get_query_var('page'), //(int) - number of page. Show the posts that would normally show up just on page X when usinthe "Older Entries" link.
//NOTE: You should set get_query_var( 'page' ); if you want your query to work with pagination. Since Wordpress 3.0.2, you dget_query_var( 'page' ) instead of get_query_var( 'paged' ). The pagination parameter 'paged' for WP_Query() remains the same.
//////Offset Parameter
'offset' => 3, //(int) - number of post to displace or pass over.
//////Order & Orderby Parameters - Sort retrieved posts.
'order' => 'DESC', //(string) - Designates the ascending or descending order of the 'orderby' parameter. Defaultto 'DESC'.
//Possible Values:
//'ASC' - ascending order from lowest to highest values (1, 2, 3; a, b, c).
//'DESC' - descending order from highest to lowest values (3, 2, 1; c, b, a).
'orderby' => 'date', //(string) - Sort retrieved posts by parameter. Defaults to 'date'.
//Possible Values://
//'none' - No order (available with Version 2.8).
//'ID' - Order by post id. Note the captialization.
//'author' - Order by author.
//'title' - Order by title.
//'date' - Order by date.
//'modified' - Order by last modified date.
//'parent' - Order by post/page parent id.
//'rand' - Random order.
//'comment_count' - Order by number of comments (available with Version 2.9).
//'menu_order' - Order by Page Order. Used most often for Pages (Order field in the EdiPage Attributes box) and for Attachments (the integer fields in the Insert / Upload MediGallery dialog), but could be used for any post type with distinct 'menu_order' values (theall default to 0).
//'meta_value' - Note that a 'meta_key=keyname' must also be present in the query. Note alsthat the sorting will be alphabetical which is fine for strings (i.e. words), but can bunexpected for numbers (e.g. 1, 3, 34, 4, 56, 6, etc, rather than 1, 3, 4, 6, 34, 56 as yomight naturally expect).
//'meta_value_num' - Order by numeric meta value (available with Version 2.8). Also notthat a 'meta_key=keyname' must also be present in the query. This value allows for numericasorting as noted above in 'meta_value'.
//'post__in' - Preserve post ID order given in the post__in array (available with Version 3.5).
//////Sticky Post Parameters - Show Sticky Posts or ignore them.
'ignore_sticky_posts' => false, //(bool) - ignore sticky posts or not. Default value is false, don't ignore. Ignore/excludsticky posts being included at the beginning of posts returned, but the sticky post will still be returned in the natural order othat list of posts returned.
//NOTE: For more info on sticky post queries see: http://codex.wordpress.org/Class_Reference/WP_Query#Sticky_Post_Parameters
//////Time Parameters - Show posts associated with a certain time period.
'year' => 2012, //(int) - 4 digit year (e.g. 2011).
'monthnum' => 3, //(int) - Month number (from 1 to 12).
'w' => 25, //(int) - Week of the year (from 0 to 53). Uses the MySQL WEEK command. The mode is dependenon the "start_of_week" option.
'day' => 17, //(int) - Day of the month (from 1 to 31).
'hour' => 13, //(int) - Hour (from 0 to 23).
'minute' => 19, //(int) - Minute (from 0 to 60).
'second' => 30, //(int) - Second (0 to 60).
//////Custom Field Parameters - Show posts associated with a certain custom field.
'meta_key' => 'key', //(string) - Custom field key.
'meta_value' => 'value', //(string) - Custom field value.
'meta_value_num' => 10, //(number) - Custom field value.
'meta_compare' => '=', //(string) - Operator to test the 'meta_value'. Possible values are '!=', '>', '>=', '<', or ='. Default value is '='.
'meta_query' => array( //(array) - Custom field parameters (available with Version 3.1).
array(
'key' => 'color', //(string) - Custom field key.
'value' => 'blue' //(string/array) - Custom field value (Note: Array support is limited to a compare value of 'IN', 'NOT IN', 'BETWEEN', or 'NOT BETWEEN')
'type' => 'CHAR', //(string) - Custom field type. Possible values are 'NUMERIC', 'BINARY', 'CHAR', 'DATE', 'DATETIME', 'DECIMAL', 'SIGNED', 'TIME', 'UNSIGNED'. Default value is 'CHAR'.
'compare' => '=' //(string) - Operator to test. Possible values are '=', '!=', '>', '>=', '<', '<=', 'LIKE', 'NOT LIKE', 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN'. Default value is '='.
),
array(
'key' => 'price',
'value' => array( 1,200 ),
'compare' => 'NOT LIKE'
)
//////Permission Parameters - Display published posts, as well as private posts, if the user has the appropriate capability:
'perm' => 'readable' //(string) Possible values are 'readable', 'editable' (possible more ie all capabilitiealthough I have not tested)
//////Parameters relating to caching
'no_found_rows' => false, //(bool) Default is false. WordPress uses SQL_CALC_FOUND_ROWS in most queries in order timplement pagination. Even when you don’t need pagination at all. By Setting this parameter to true you are telling wordPress not tcount the total rows and reducing load on the DB. Pagination will NOT WORK when this parameter is set to true. For more informatiosee: http://flavio.tordini.org/speed-up-wordpress-get_posts-and-query_posts-functions
'cache_results' => true, //(bool) Default is true
'update_post_term_cache' => true, //(bool) Default is true
'update_post_meta_cache' => true, //(bool) Default is true
//NOTE Caching is a good thing. Setting these to false is generally not advised. For more info on usage see: http://codex.wordpresorg/Class_Reference/WP_Query#Permission_Parameters
//////Search Parameter
's' => $s, //(string) - Passes along the query string variable from a search. For example usage see: http://www.wprecipes.com/how-to-display-the-number-of-results-in-wordpress-search
'exact' => true //(bool) - flag to make it only match whole titles/posts - Default value is false. For more information see: https://gist.github.com/2023628#gistcomment-285118
'sentance' => true //(bool) - flag to make it do a phrase search - Default value is false. For more information see: https://gist.github.com/2023628#gistcomment-285118
//////Post Field Parameters
//Not sure what these do. For more info see: http://codex.wordpress.org/Class_Reference/WP_Query#Post_Field_Parameters
//////Filters
//For more information on available Filters see: http://codex.wordpress.org/Class_Reference/WP_Query#Filters
);
$the_query = new WP_Query( $args );
// The Loop
if ( $the_query->have_posts() ) :
while ( $the_query->have_posts() ) : $the_query->the_post();
// Do Stuff
endwhile;
endif;
// Reset Post Data
wp_reset_postdata();
This will help you to query anything.
Hope it will help you.

Related

WordPress posts orderby meta value with strings and numbers

I have a custom field (advanced custom field) called custom_order and I want WordPress to sort all posts by the field values.
The custom_order field's values can be written in 3 ways:
numbers only (3, 400, 6424)
numbers, then strings (3A, 3B, 5000A)
numbers, then strings, then numbers (3A1, 3A2, 401AZ1, 9000A3, 9000A1)
More examples of custom_order values:
Wanted order:
1, 2, 3, 3A, 3B, 3C, 3CA, 4, 400, 401, 401A, 401AZ, 401Z, 9000, 9000A, 9000A1, 9000A3
Conditions:
3 should come before 200 (numeric order)
3 should come before 3A (number and strings)
3A should come before 3A1 (numbers, strings, numbers)
My try:
My current code is sorting by numbers (condition 1), but ignores condition 2 and condition 3.
Therefore, my code gives me this order:
1, 2, 3A, 3, 3C, 3B, 4 <-- all 3's are not ordered, which is bad
The code I'm using (in functions.php):
add_action('pre_get_posts', function ($q) {
if (
!is_admin() // Target only front end queries
&& $q->is_main_query() // Target the main query only
&& ($q->is_search() || $q->is_post_type_archive('data-base'))
) {
$q->set('meta_key', 'custom_order');
$q->set('order', 'DESC');
$q->set('orderby', 'meta_value_num');
}
});
I found a neat solution!
$q->set(
'meta_query',
array(
'relation' => 'OR', //**** Use AND or OR as per your required Where Clause
'clause1' => array(
'key' => 'custom_order',
'compare' => 'EXISTS',
),
)
);
$q->set(
'orderby',
array(
'meta_value_num' => 'ASC', // this reorders by numbers
'meta_value' => 'ASC', // this reorders by strings after sorting numbers
)
);

Wordpress sort by meta values

I have an issue I am trying to solve right now and having an issue finding a way to do it properly.
I have a college lecture series I need to sort I can sort it by a meta field for year just fine. But when I get to sorting by semester it sorts it in alphabetical and so it ends up sorting by Winter,Spring,Fall or Fall,Spring,Winter depending on if I tell it ASC or DESC.
I need to figure out how to do order this in the right order preferably without adding another field to the posts for sort priority
Query args currently written as follows which is obviously a bit messy.
$args = array(
'post_type' => 'mcm_geri-ed',
'posts_per_page' => $posts_per_page,
'meta_query' => array(
'semester' => array(
'key' => 'semester',
),
'year' => array(
'key' => 'year'
)
),
'orderby' => array(
'year' => 'DESC',
'semester' => array(
'value' => 'date'
)
),
'paged' => $paged
);
I don't think there is a way to do this with WP_Query directly. How about using posts_orderby and manipulating the ORDER-part of the SQL to be something like meta_year DESC, meta_semester = 'Spring' DESC, meta_semester = 'Fall' DESC. Look at the generated SQL to see what names you should use for meta_year and meta_semester (or trimester, really).
This isn't as effective as changing semester to a numerical value and adding the name while outputting, but it will work.
This is what I ultimately did. It was something different than what was suggested but using the filter suggested to get the result. The if statement has a couple of other caveats added to it due to the way I've built a sorting system for the page template. I also wrote this in a test environment hence the different post type from the original code.
// Custom Orderby filter to return the correct order for semester values.
add_filter('posts_orderby', 'orderby_pages_callback', 10, 2);
function orderby_pages_callback($orderby_statement, $wp_query) {
//Making sure this only happens when it needs to. Which is the right post type and if it isn't getting sorted by other functions.
if ($wp_query->get("post_type") === "test_semester" && !is_admin() && !isset($_GET['order']) && !isset($_GET['sort'])) {
return "CAST(mt1.meta_value AS CHAR) DESC, wp_postmeta.meta_value = 'Fall' DESC, wp_postmeta.meta_value = 'Winter' DESC, wp_postmeta.meta_value = 'Spring' DESC,wp_postmeta.meta_value = 'Summer' DESC";
} else {
//return your regularly scheduled programming
return $orderby_statement;
}
}

Is it possible to query posts in the same order as assigned?

I have a custom field named type, which is a a "radio button" data type and it has some choices. This custom field, is assigned to a custom post type named pproduct.
For example here are the choices of this custom field :
RED
BLUE
YELLOW
WHITE
BLACK
Only one can be selected from the above.
The below $args :
$args = array(
'post_type' => 'pproduct',
'posts_per_page' => -1,
'post_status'=>array('publish'),
'product' => $category->slug ,
'meta_query' => array(
'relation' => 'AND',
'type_clause' => array(
'key' => 'type',
),
'order_clause' => array(
'key' => 'order',
),
),
'orderby' => array(
'type_clause' => 'DESC',
'order_clause' => 'ASC',
),
);
will query all posts of post type pproduct, and it will sort it by two custom fields. Type and order . It will sort it in an alphabetical order.
Is it possible to modify this and sort it by the same order as the types are assigned? Does anyone know what happens if i don't use order by? I can see it brings the posts but what is the "default order" if it's not assigned by me.
EDIT 1 : Something like this
UPDATE:
I missunderstood your demand. If i get it right now, you want to make order as you assigned it in setting, simply like you write
RED
BLUE
YELLOW
WHITE
BLACK
That couldn't be achieved with WP query args, you will have to write your own database query to achieve this because query must know the order rules which is set by you (it does know alpabetical, numeric, date order etc. which can be simply derivated from field).
However if you could change values ACF to numeric (like u've posted in comment link) you win, then you will have to create translation array (to translate number to color name) if u will need to use value as color name/slug.
So in ACF settings choices:
1 : RED
2 : BLUE
3 : YELLOW
4 : WHITE
5 : BLACK
Query args will remain same (except type ordering DESC->ASC) and if you need to get the name from number, use this in loop:
$field = get_field_object( 'type' );
$value = $field['value'];
$color_name = $field['choices'][ $value ]; // this will be formated
$unformated_slug = sanitize_title( $color_name ); // change to lowercase and remove whitespaces etc..
// then you can work with $unformated_slug like your original field value eg:
if( $unformated_slug == 'red' ) {
/* do something here */
}
Changing choice values to numbers is the most simplier way, anything other will be too complicated.
--
Default order of posts is by date. If you want to set your order automatically for all queries or only for custom post type queries, see https://codex.wordpress.org/Plugin_API/Action_Reference/pre_get_posts

wrong with set compare in meta_query - wordpress

The checkboxs saved in db !
The db structure (wp_postmeta table) :
________________________________________________________________
| | |
| meta_key | meta_value |
|_______________|_______________________________________________|
| | |
| artist_nameaa | a:2:{i:51;s:2:"51";i:60;s:2:"60";} |
|_______________|_______________________________________________|
two checkboxs has been selected !
i want to find posts where artist_nameaa have 51 key in his array
51 is an example
Here is my try :
wp_reset_postdata();
global $post;
$args = array(
'post_type' => 'songs',
'meta_query' => array(
array(
'key' => 'artist_nameaa',
'value' => serialize(array($post->ID=>"$post->ID")),// a:1:{i:51;s:2:"51";}
'compare' => 'IN'
)
),
'no_found_rows' => true,
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
'ignore_sticky_posts' => 1,
'post__not_in' => array($post->ID),
'posts_per_page' => -1
);
$query = new WP_Query($args);
return $query;
The IN() comparison operator is used to replace several where clauses (docs). It will ultimately be looking for results that are an exact match.
What you are doing is more of a search. You have no idea where in the serialized string your data set will fall. For this type of search, you should use the LIKE operator (docs). You will need to utilize the wildcard flags for this type of search.
From what I can gather about the type of data you are storing, you may want to rethink your storage mechanism. Custom Fields do support multiple values for the same meta key, which would be a quick approach. You could also take advantage of Custom Post Types or a custom table (wpdb).

What is the algorithm for tag clouds?

I'd like to create a tag clouds, and I'm wondering based on what parameters I should do this.
Also, I don't want the same top tags to be displayed all the time, so how do big sites handle this?
I've got table that contains the items, a table that contains the tags (just tag id and tag text) and another table for normalization, with a row for each relationship between an item and a tag.
I think a good implementation with nice flexibility (and in PHP) is WordPress's implementaion. Have a look at their argument object in the documentation for wp_tag_cloud():
smallest - The smallest tag (lowest count) is shown at size 8
largest - The largest tag (highest count) is shown at size 22
unit - Describes 'pt' (point) as the font-size unit for the smallest and largest values
number - Displays at most 45 tags
format - Displays the tags in flat (separated by whitespace) style
separator - Displays whitespace between tags
orderby - Order the tags by name
order - Sort the tags in ASCENDING fashion
exclude - Exclude no tags
include - Include all tags
*topic_count_text_callback* - Uses function default_topic_count_text
link - view
taxonomy - Use post tags for basis of cloud
echo - echo the results
That's with this code as a sample:
<?php $args = array(
'smallest' => 8,
'largest' => 22,
'unit' => 'pt',
'number' => 45,
'format' => 'flat',
'separator' => \"\n\",
'orderby' => 'name',
'order' => 'ASC',
'exclude' => null,
'include' => null,
'topic_count_text_callback' => default_topic_count_text,
'link' => 'view',
'taxonomy' => 'post_tag',
'echo' => true ); ?>

Categories