Jetpack Infinite Scroll ignore posts already displayed - php

I am using JetPack's Infinite Scroll on the homepage of our site and it is working fine but I also want to display certain posts on there.
If a post is displayed outside the infinite loop I want it to be removed from the so there is no duplication.
I have a global array set up using bm_ignoreposts and have added it to the infinite loop render but for some reason it is not working. Here is the code.
Functions.php
The infinite renderer.
add_filter( 'infinite_scroll_archive_supported', 'tweakjp_custom_is_support' );
function mm_infinite_scroll_render() {
global $post;
while ( have_posts() ) : the_post();
bm_ignorePost($post->ID);
get_template_part( 'content-inf' );
endwhile;
}
The query
function mm_infinite_scroll_query_args($args) {
$new_args = array(
'posts_per_page' => $args['posts_per_page'],
'paged' => $args['paged'],
'orderby' => 'date',
'order' => 'DESC',
'post_type' => array( 'post', 'features', 'it_hardware', 'videos' ),
'post_status' => 'publish',
);
return $new_args;
}
For reference here is the ignore posts code:
function bm_ignorePost ($id) {
if (!is_page()) {
global $bmIgnorePosts;
$bmIgnorePosts[] = $id;
}
}

I decided to not use JetPack anymore and go for a custom Javascript version which uses AJAX to load new posts running a new query.
After speaking to Jetpack support, they believe it is not possible based on how the plugin works.

Related

Wordpress hook to display latest pending posts instead of already published

I'm stuck on something that I'm sure must be pretty simple but is getting me nuts. I'm forced at work to use WordPress, which I have zero experience with, and I'm struggling so far to understand how it operates regarding hooks and filters.
What I want is pretty simple:I'm using the latest posts block to display posts written by users. Except that the page I'm working on would be the front end for the website's moderator who would have to see the posts with the 'pending' status, not the 'publish' one. I couldn't find any option to change that in the editor, so I'm trying to set a hook to change the query from 'post_status' => 'publish' to 'post_status' => 'pending', but it's not working, I get a 'Oops! That page canโ€™t be found.'
Here's what I wrote in my functions.php:
function name_of_the_function( $query ) {
if( get_query_var('pagename') == 'name_of_the_page' && current_user_can('publish_posts') && $query->is_main_query() ) {
$query->set( 'post_status', 'pending' );
return $query;
}
}
add_filter( 'pre_get_posts', 'name_of_the_function' );
If I leave this function exactly like that but write 'publish' instead of 'pending' the page displays correctly the last published posts, but with 'pending' I get the message I mentioned before. And I tried with add_action instead of add_filter and got hte same results.
I'd like to add that I do have pending posts awaiting, and if I write the following in my page template, they are found:
$args = array (
'cat' => 5,
'post_status' => 'pending'
);
$query = new WP_Query( $args );
while ( $query->have_posts() ) {
$query->the_post();
echo get_the_title();
}
Just to check, directly in the wp-includes/latest-posts.php file, I changed :
$args = array(
'posts_per_page' => $attributes['postsToShow'],
'post_status' => 'publish',
'order' => $attributes['order'],
'orderby' => $attributes['orderBy'],
'suppress_filters' => false,
);
to :
$args = array(
'posts_per_page' => $attributes['postsToShow'],
'post_status' => 'pending',
'order' => $attributes['order'],
'orderby' => $attributes['orderBy'],
'suppress_filters' => false,
);
It works and displays the pending posts but of course I can't use that as the file would be erased at every WordPress update.
Sorry for the long post but I'm lost now and don't know what else to do, I've looked all other the intrnet but can't find an answer to this, I would really appreciate any help regarding that matter, thanks in advance.
By using the pre_get_posts with $query->is_main_query(), you apply this to the query that WordPress uses to find the page (the main query). Your code needs to be changed to:
function name_of_the_function( $query ) {
if ( is_admin() || $query->is_main_query() ) {
return $query;
}
if( get_query_var('pagename') == 'name_of_the_page' && current_user_can('publish_posts') ) {
$query->set( 'post_status', 'pending' );
}
return $query;
}
add_filter( 'pre_get_posts', 'name_of_the_function' );
So basically, don't run this on any query in the admin or any query that is the main query, but only run it on a specific page for people with specific capabilities.

Using wp_insert_post() - creates duplicates

I am adding one CPT to another CPT dynmaically. When using wp_insert_post() it creates duplicates when I add_action('init', 'function_name'); Any idea what hook to use to simply add them:
function cpt_to_cpt(){
// Grab posts
$args = array(
'post_type' => ' custom_type1 ',
'order' => 'ASC',
'post_status' => 'publish',
'numberposts' => -1,
);
$posts = get_posts($args);
foreach ( $posts as $post ) {
wp_insert_post(array(
'post_type' => 'custom_type2',
'post_title' => $post->post_title,
'post_date' => $post->post_date,
'post_author' => $post->post->author,
'post_status' => 'publish',
)
);
}
add_action('init', 'cpt_to_cpt');
Try using:
wp_loaded
add_action('wp_loaded', 'cpt_to_cpt');
or
wp
add_action('wp', 'cpt_to_cpt')
WordPress init and wp_loaded hooks fire on the "loading" stage. It means they both can fire more than one time when refreshing the page.
Solution 1
You can use another hook that fires later.
wp hook, for instance, fires on the "processing" stage and should run only once.
add_action('wp', 'cpt_to_cpt');
Order of precedence: init ๐Ÿ † wp_loaded ๐Ÿ † wp
Solution 2
If you really want to use init hook and make sure it will run one time. You can use the snippet below.
function cpt_to_cpt() {
$runtime = 'run_only_01;
if (get_option('my_run_only_once_option') != $runtime) {
$updated = update_option('my_run_only_once_option', $runtime);
if ($updated === true) {
// do some stuff
}
}
}
add_action('init', 'cpt_to_cpt');
It will create an option on your wp_option table. In the end, you need to delete the option manually (on your database) or in your code.
delete_option('my_run_only_once_option');
Solution 3
Maybe the best professional solution to create multiple posts or CPTs (custom post types) should be using wp-cli (command line interface for WordPress).
Please take a look in the documentation here: https://developer.wordpress.org/cli/commands/post/

Display child post on parent post page in wordpress

Our current website is using custom posts with parent/child posts.
When viewing a (parent) post, a plugin is used to pull its child posts and those are displayed in a tab on the page.
We are using a new version of that custom theme on several websites now and are no longer using parent/child relationship. Instead we have metaboxes in our custom posts types and all additional information can be filed right there.
I wanted to update this particular website with the latest version of the theme, but since it's using parent/child relationship I wanted to add a few lines of code to the theme in order to achieve the same result and keep the old posts the way they are instead of modifying them all.
Here's what I want to do : I want a very simple way to display all child post (in order) on a parent post page.
I've found a few ideas here and there but none seems to be working so far. (Here's one for example : http://www.wpbeginner.com/wp-tutorials/how-to-display-a-list-of-child-pages-for-a-parent-page-in-wordpress/ as well as this one https://wordpress.stackexchange.com/questions/153042/how-to-display-list-of-child-pages-with-parent-in-wordpress). I don't know if it has to do with the fact that i'm using post rather than pages.
I don't want a list of the child post but rather display the content of those directly. Was thinking the best way to achieve this might be to create a function to retrieve the child post and then echoing the result in the template. That way without having to change our theme it could work with our different website.
EDIT :
So far here's what i've tried within single.php :
$query = new WP_Query( array(
'post_parent' => get_the_ID(),
));
while($query->have_posts()) {
$query->the_post();
the_content(); //Outputs child's content as it is
}
wp_reset_query();`
I then changed the code to :
$new_args = array(
'order' => 'ASC',
'post_parent' => get_the_ID()
);
$new_query = new WP_Query( $new_args);
if ($new_query->have_posts() ) {
while($new_query->have_posts() ) {
$new_query->the_post();
the_content();
}
wp_reset_query();
}
and then since it didn't work either i've changed it to :
$children = get_children( array('post_parent' => get_the_ID()) );
foreach ( $children as $children_id => $children ) {
the_title();
the_content();
}
The latest seems to be able to return some results, it "knows" that the current post has children in it but i'm displaying the title and content of the current post. I'm pretty sure I shouldn't be using the_content() in here.
Ok, try something like this inside your post template within the loop. It should help you to output child posts inside particular post.
<?php
/Somwhere in the loop/
$query = new WP_Query( array(
'post_parent' => get_the_ID(),
'posts_per_page' => 3, //shows only 3 children. If you want to show all of them, comment this line
));
while($query->have_posts()) {
$query->the_post();
/*Output the child markup here*/
the_content(); //Outputs child's content as it is
}
wp_reset_query();
?>
UPDATED:
Ok, you can try to use post_parent__in & array of IDs, this should work too.
<?php
/Somwhere in the loop/
$query = new WP_Query( array(
'post_parent__in' => array(get_the_ID()),
'posts_per_page' => 3, //shows only 3 children. If you want to show all of them, comment this line
));
while($query->have_posts()) {
$query->the_post();
/*Output the child markup here*/
}
wp_reset_query();
?>
If not, here is the way to output contents of the posts you got using get_children function. This should probably work too
<?php
$children = get_children( array('post_parent' => get_the_ID()) );
foreach ( $children as $children_id => $child ) {
echo $child->post_title;
echo str_replace( ']]>', ']]>',apply_filters( 'the_content', $child->post_content )); //mimic the_content() filters
//echo $child->post_content; // if you do not need to filter the content;
}
?>
/* Fetch only one level child pages of a parent page */
$pages = get_pages(
array (
'parent' => 'parent_id',
'post_type => 'page',
'post_status' => 'publish',
);
$ids = wp_list_pluck( $pages, 'ID' );
/* Return page IDs in array format */
/* You can retrieve "post_title", "guid", "post_name" instead of "ID"
/* Fetch all child pages of a parent page*/
$pages = get_pages(
array (
'parent' => '-1',
'child_of' => 'parent_id', /* Return child of child for current page id */
'post_type => 'page',
'post_status' => 'publish',
);
$ids = wp_list_pluck( $pages, 'ID' );
/* Return page IDs in array format */
/* You can retrieve "post_title", "guid", "post_name" instead of "ID" */

Hide specific posts from category list in wordpress

I'm having some trouble displaying a list of posts from a Wordpress Category that will exclude a certain number of post based on a custom field using Advance Custom Fields.
Here's the current code I'm using that hides it nicely:
while ( have_posts() ) : the_post();
$is_taken = get_field('taken_check', $this_id);
if ($is_taken!=1) {
get_template_part( 'basket_selection' );
}
endwhile;
However, it simply just hides the post but still considers it as a post on the "posts_per_page" function.
For example, There are 20 posts in total and I've set the limit to 10 posts per page. If I hide 3 posts with the code above, it will only display 7 posts in page 1 and 10 posts in page 2.
Is there a way to simply just ignore the hidden posts and not count it as a "post"?
Try this:
Apply Custom Fields Parameters in get_post query itself.
$posts = get_posts(array(
'posts_per_page' => 10,
'post_type' => '<YOUR_POST_TYP>',
'meta_key' => 'taken_check',
'meta_value' => '<DEFAULT_VALUE_OF_taken_check>'
));
Lots to read here: http://codex.wordpress.org/Template_Tags/get_posts
I've managed to solve it by changing the get_posts to wp_query within the category.php.
I first added this code to detect the current category viewed and filter the query to only display taken_check = 0.
$this_cat = get_category(get_query_var('cat'), 'ARRAY_A', false);
foreach ($this_cat as $this_cat){
$this_catid = $this_cat;
break;
}
$args = array(
'posts_per_page' => 10,
'post_type' => 'post',
'cat' => $this_catid,
'orderby' => 'title',
'order' => 'ASC',
'paged' => $paged,
'meta_query' => array(
array(
'key' => 'taken_check',
'value' => '0',
)
)
);
$wp_query = new WP_Query($args);
I then just continued with the default loop sequence. The only weird code is the unnecessary foreach loop to detect the current category based on the current page and not from a post. Still puzzled as to why I can't just use $this_cat[0] since it's an array. It keep returning blank.
Oh well, but it works now with pagination, so I'm happy :)
Thanks for all the help!

Disable latest posts from being queried in the home page

I was tasked to display posts group by their categories, and I suppose I could do that with WP_Query. The problem is, wordpress still queries for the latests posts on the index page. How do I prevent that from happening?
I used the plugin MySQL Profiler to check what were being queried.
Why don't you just use custom query in index.php.
Something like this:
$args = array(
'post_type' => 'post',
'post_status'=>'publish',
'posts_per_page'=>5,
'orderby' => 'date',
'order' => 'DESC'
);
$temp=$wp_query;//save the main query
$wp_query=new WP_Query($args);
while ( have_posts() ) : the_post();
get_template_part(...);
endwhile;
$wp_query=$temp;//restore the main $wp_query
And to group posts by categories I would use this code from WordPress StackExchange.

Categories