Exclude specific post from WP-feed - wordpress

I know that you can generate a feed using urls like: ?cat=3&feed=rss2
And you can switch it around to exclude the category 3 by putting a subtract sign in front: ?cat=-3&feed=rss2
But, it doesn't look like you can do the same for posts? I'm using the JW video Player and have loaded the related plugin. The related plugin can take an rss-feed (media rss) as the parameter so it can link to other videos/wordpress posts that are related.
My problem is that currently this means that the active video also appears in the related videos feed.
What would be the best solution for solving this problem? I aim to create my own rss feed generator in the future, but for now I just want to keep it simple and use the generated feeds that wordpress creates. Is there a simple way to add support for an url parameter named post for example? It could then take post=-7 to exclude post with id 7 from displaying in the feed.
Or is there better solutions for this?

You can use a function
function exclude_category($query){
if ( $query->is_home || $query->is_feed || $query->is_archive ) {
$query->set('cat', '-1');
}
return $query;
}
add_filter('pre_get_posts', 'exclude_category');
see'a

Instead of explaining the mechanisem - there are many plugins just for that ..
One that I know is :
StelthPubish
Edit I
I do not know about the URL - but you can try use the
function ok9_feed_filter($query) {
if ( !$query->is_admin && $query->is_feed) {
$query->set('post__not_in', array(15, 6) ); // page /post id
}
return $query;
}
add_filter( 'pre_get_posts', 'ok9_exclude_filter' );
or this
function ok9_feed_exlude($where, $wp_query = NULL) {
global $wpdb;
if ( !$wp_query )
global $wp_query;
if ($wp_query->is_feed) {
// exclude post id
$where .= " AND $wpdb->posts.ID NOT IN (15, 6)";
}
return $where;
}
add_filter( 'posts_where','ok9_feed_exlude', 1, 2 );
If you do not want to use a fixed id in the function - you can always add a custom field in the posts you want to exclude , and use that in the query ..

Related

Ordering By Menu Order in the Wordpress REST API?

I am trying to display posts using the REST API and I want to display them in menu order based on how they are positioned in the admin menu.
I installed a plugin that allowed me to move posts to any position in the admin. I know querying the posts the normal way with wordpress there is a orderby: menu_order option, which would do what I am looking for, but I can't figure it out with the REST API.
My REST API looks like this:
https://example.com/wp-json/wp/v2/qd_leadership?_embed&per_page=100&orderby=menu_order
So I've tried that and that does not work. It says menu_order isn't an option. I also saw a post here:
Query WordPress (REST) posts by the order they appear on the admin
That had a similar question. The only answer on that post is to not have any orderby parameter and that should display them in the menu order, but that did not work for me. So I am stumped on how to order the posts from the REST API in menu order?
Its bug of wp core in rest api so you could use below hack for the solution.Please add below code in your active theme's function.php
add_filter( 'rest_post_collection_params', 'my_prefix_add_rest_orderby_params', 10, 1 );
function my_prefix_add_rest_orderby_params( $params ) {
$params['orderby']['enum'][] = 'menu_order';
return $params;
}
Tested and works.
Thanks to raju_eww for the hint in the right direction. But in case of a custom post type collection the filter hook name has to be like this:
add_filter( 'rest_custom-post-type_collection_params', 'my_prefix_add_rest_orderby_params', 10, 1 );
function my_prefix_add_rest_orderby_params( $params ) {
$params['orderby']['enum'][] = 'menu_order';
return $params;
}
found here:
https://www.timrosswebdevelopment.com/wordpress-rest-api-post-order/
Following code do sort by menu_order when orderby is not in query string (for woocommerce):
add_filter('woocommerce_get_catalog_ordering_args', 'am_woocommerce_catalog_orderby');
function am_woocommerce_catalog_orderby( $args ) {
if(!$_GET['orderby']) {
$args['orderby'] = 'menu_order';
$args['order'] = 'asc';
}
return $args;
}
source

How to disable Yoast SEO adding article:author meta tags to pages

The excellent Yoast SEO plugin is adding some unwanted meta tags.
For example, I would like article:author to appear on posts, but not on pages or other content types.
Is there a way to adjust this globally?
I'm happy to edit functions.php, but I'm just unsure what I should be hooking in to.
I would be grateful for any pointers from those more familiar with the plugin.
I tried this:
function wpseo_show_article_author_only_on_posts() {
if ( !is_single() ) {
return false;
}
}
add_filter( 'xxxxxx', 'wpseo_show_article_author_only_on_posts' );
I need to know what hook should replace xxxxxx.
You're looking for the wpseo_opengraph_author_facebook filter, which ties into the article_author_facebook() method in frontend/class-opengraph.php of the plugin.
function wpseo_show_article_author_only_on_posts( $facebook ) {
if ( ! is_single() ) {
return false;
}
return $facebook;
}
add_filter( 'wpseo_opengraph_author_facebook', 'wpseo_show_article_author_only_on_posts', 10, 1 );
The article_author_facebook() method does a check for is_singular(), which checks that we're viewing single page, post or attachment:
This conditional tag checks if a singular post is being displayed, which is the case when one of the following returns true: is_single(), is_page() or is_attachment(). If the $post_types parameter is specified, the function will additionally check if the query is for one of the post types specified.
The additional filter for ( ! is_single() ) ensures that article:author is only added to posts.
If people are looking for a way to remove more yoast SEO tags, just lookup the file wordpress-seo/frontend/class-opengraph.php, and you can see which filters you can hook into to remove certain tags.
This is the code I use to remove these tags from pages: url, image, title, description and type:
function remove_yoast_og_tags( $ogTag ){
// Do a check of which type of post you want to remove the tags from
if ( is_page() ) {
return false;
}
return $ogTag;
}
$yoastTags = array(
"url",
"image",
"title",
"desc",
"type"
);
foreach ($yoastTags as $tag) {
add_filter( 'wpseo_opengraph_'.$tag, 'remove_yoast_og_tags');
}

Remove Yoast WordPress SEO on a page

I am trying to remove the Yoast WordPress SEO on a certain page because it is conflicting with another plugin.
I tried adding the code below to my functions.php but it does not seem to work, any help is appreciated.
Thank You
function remove_wpseo(){
if ( is_page(944)) {
global $wpseo_front;
remove_action( 'wp_head', array($wpseo_front, 'head'), 2 );
}
}
add_action('wp_enqueue_scripts','remove_wpseo');
Just in case someone is wondering why above methods are not working after the upgrade, this is the new method of disabling Yoast SEO output as of version 14.0
add_action( 'template_redirect', 'remove_wpseo' );
function remove_wpseo() {
if ( is_page ( 944 ) ) {
$front_end = YoastSEO()->classes->get( Yoast\WP\SEO\Integrations\Front_End_Integration::class );
remove_action( 'wpseo_head', [ $front_end, 'present_head' ], -9999 );
}
}
Hope this helps!
Enqueing is not the right moment to remove an action, use template_redirect instead:
add_action('template_redirect','remove_wpseo');
function remove_wpseo(){
if ( is_page(944)) {
global $wpseo_front;
remove_action( 'wp_head', array($wpseo_front, 'head'), 2 ); // <-- check priority
}
}
Check the priority that the plugin uses to add the wp_head action as the removal has to be the same and none if empty.
Just in case someone still needs this. This worked for me. Change 'page' to 'post' if it's a blog post. Instead of trying to throw out Yoast completely, just hide the meta box.
add_action( 'add_meta_boxes', 'remove_post_meta_boxes', 11 );
function remove_post_meta_boxes() {
if( isset( $_GET['post'] ) && $_GET['post'] == '22' ) {
remove_meta_box( 'wpseo_meta', 'page', 'normal' );
}
}
#jhashane answer is correct as a straight forward answer to the question as it is. However, this removes the <tite> tag as well, and other default worpdress meta, as long as Yoast is active and installed. It just kills the output handled by Yoast.
Disable Yoast components might be a better approach most of the time. Conflicts are often about Yoast taking over some meta, specially types or social open graphs.
We spend hours to understand the new 14.0 version. As of Yoast SEO 14.0 the plugin is more like Danish Lego and building up the head meta tags as "presenters".
EX: Remove all social media components output on page id 123:
function intervik_wpseo_frontend_presenters($presenters){
/* set your conditional(s) */
if(!is_singular(123)) return $presenters;
/* return all WITHOUT Open_Graph and Twitter presenters on $page_id = 123 */
if($matches = preg_grep('/Open_Graph|Twitter/', $presenters)) return array_diff($presenters, $matches);
else return $presenters;
}
add_filter('wpseo_frontend_presenter_classes', 'intervik_wpseo_frontend_presenters', 10, 1);
The filter in this example is very late. You can still use individual meta or schema etc etc filters to filter the content configuration and settings. And when you partial manually wanna disable your configuration, on page basis or so, remove "blocks" of Yoast do in your source code:
function intervik_wpseo_frontend_presenters($presenters){
/* REMOVE ONE exactly presenters (example: Canonical) */
if(($key = array_search('Yoast\WP\SEO\Presenters\Canonical_Presenter', $presenters)) !== false){
unset($presenters[$key]);
}
return $presenters;
}
add_filter('wpseo_frontend_presenter_classes', 'intervik_wpseo_frontend_presenters', 10, 1);
Remove everything except document title and description on pages:
function intervik_wpseo_frontend_presenters($presenters){
$keep[] = 'Yoast\WP\SEO\Presenters\Title_Presenter';
$keep[] = 'Yoast\WP\SEO\Presenters\Meta_Description_Presenter';
$keep[] = 'Yoast\WP\SEO\Presenters\Robots_Presenter';
/* remove ALL, except title, description and robots on PAGES */
if(is_page()) return $keep;
else return $presenters;
}
add_filter('wpseo_frontend_presenter_classes', 'intervik_wpseo_frontend_presenters', 10, 1);
In this case, you should use the wpseo_title etc etc filters to enable och disable Yoast content, and use Wordpress default content on certain selected post or pages.
Some meta still have the old filter(s) left to turn different "grouped" output on or off Like add_filter('wpseo_output_twitter_card', '__return_false' ); But Facebook for example, is part of the opengraph, shared by other social media. There is no explicit Facebook opengraph filter. And in the future, we will have more social media and other tags shared components.
Lets play with bricks and blocks instead.
Common default presenters: (dump of $presenters)
array(27) {
[0]=>
string(39) "Yoast\WP\SEO\Presenters\Title_Presenter"
[1]=>
string(50) "Yoast\WP\SEO\Presenters\Meta_Description_Presenter"
[2]=>
string(40) "Yoast\WP\SEO\Presenters\Robots_Presenter"
[3]=>
string(43) "Yoast\WP\SEO\Presenters\Googlebot_Presenter"
[4]=>
string(41) "Yoast\WP\SEO\Presenters\Bingbot_Presenter"
[5]=>
string(43) "Yoast\WP\SEO\Presenters\Canonical_Presenter"
[6]=>
string(42) "Yoast\WP\SEO\Presenters\Rel_Prev_Presenter"
[7]=>
string(42) "Yoast\WP\SEO\Presenters\Rel_Next_Presenter"
[8]=>
string(51) "Yoast\WP\SEO\Presenters\Open_Graph\Locale_Presenter"
[9]=>
string(49) "Yoast\WP\SEO\Presenters\Open_Graph\Type_Presenter"
[10]=>
string(50) "Yoast\WP\SEO\Presenters\Open_Graph\Title_Presenter"
[11]=>
string(56) "Yoast\WP\SEO\Presenters\Open_Graph\Description_Presenter"
[12]=>
string(48) "Yoast\WP\SEO\Presenters\Open_Graph\Url_Presenter"
[13]=>
string(54) "Yoast\WP\SEO\Presenters\Open_Graph\Site_Name_Presenter"
[14]=>
string(62) "Yoast\WP\SEO\Presenters\Open_Graph\Article_Publisher_Presenter"
[15]=>
string(59) "Yoast\WP\SEO\Presenters\Open_Graph\Article_Author_Presenter"
[16]=>
string(67) "Yoast\WP\SEO\Presenters\Open_Graph\Article_Published_Time_Presenter"
[17]=>
string(66) "Yoast\WP\SEO\Presenters\Open_Graph\Article_Modified_Time_Presenter"
[18]=>
string(50) "Yoast\WP\SEO\Presenters\Open_Graph\Image_Presenter"
[19]=>
string(54) "Yoast\WP\SEO\Presenters\Open_Graph\FB_App_ID_Presenter"
[20]=>
string(46) "Yoast\WP\SEO\Presenters\Twitter\Card_Presenter"
[21]=>
string(47) "Yoast\WP\SEO\Presenters\Twitter\Title_Presenter"
[22]=>
string(53) "Yoast\WP\SEO\Presenters\Twitter\Description_Presenter"
[23]=>
string(47) "Yoast\WP\SEO\Presenters\Twitter\Image_Presenter"
[24]=>
string(49) "Yoast\WP\SEO\Presenters\Twitter\Creator_Presenter"
[25]=>
string(46) "Yoast\WP\SEO\Presenters\Twitter\Site_Presenter"
[26]=>
string(40) "Yoast\WP\SEO\Presenters\Schema_Presenter"
}
Finally, here is an example of "conflicts with other plugin". We needed to remove open graphs when plugin "Groups" restricted a page. We don wanna share or give meta for sharing here. Either, Yoast should not add this page to the sitemap, and the robots must be set as noindex. All this is decided by a custom meta on the page we talking about:
/* Disable YOAST components output on selected pages by custom meta */
function intervik_wpseo_frontend_presenters($presenters){
if(is_singular()){
global $post;
$meta = get_post_meta($post->ID, 'example_custom_field', true);
if($meta){
add_filter('wpseo_json_ld_output', '__return_false');
add_filter('wpseo_robots', function(){
return 'noindex,nofollow';
}, 30, 1);
if($matches = preg_grep('/Open_Graph|Twitter/', $presenters)) $presenters = array_diff($presenters, $matches);
}
}
return $presenters;
}
add_filter('wpseo_frontend_presenter_classes', 'intervik_wpseo_frontend_presenters', 10, 1);
Sitemap case: We still need a separate filter process for the sitemap as it might be loaded by ajax or cron/ not rendered as head output:
/* -------------------- */
// DISABLE SITEMAP EXAMPLE
function intervik_wpseo_sitemap_entry_exclude($url, $type, $object){
/* Types can be = 'term', 'post', 'user' */
if($type == 'post'){
$meta = get_post_meta($object->ID, 'example_custom_field', true);
if($meta) return false;
}
return $url;
}
add_filter('wpseo_sitemap_entry', 'intervik_wpseo_sitemap_entry_exclude', 30, 3);
This example above shows how the filters and presenters works
together to control the output of Yoast. Adding modules like
YOAST woocommerce or YAOST Local gives you more presenters to play with/ add or remove. And the best part of 14 API, you can
provide your own presenter.
Please comment to add another approach or trix.

Disable caching in WordPress Feeds generation

i'm working on a plugin that adds another parameter to feeds, i want to add a numberOfItems on the url and the feed returns that number of articles. I dont want to use the builtin option from WP Admin because the feed will be added on other websites with different number of items, it's a little bit complicated, the point is i need this implementation. i've added something like
function _my_custom_option( $option )
{
global $wp_query, $wp_rewrite;;
remove_filter( 'pre_option_posts_per_rss', '_my_custom_option' );
//$number = get_query_var('number');
$number = $wp_query->query_vars['numberOfItems'];
if(isset($number))
$option = $number;
else
$option = 10;
//$wp_rewrite->flush_rules();
add_filter( 'pre_option_posts_per_rss', '_my_custom_option' );
return $option;
}
add_filter( 'pre_option_posts_per_rss', '_my_custom_option' );
It seems that the feed is cached somehow and doesnt generate with the number of items, because when i add paged=2, it works. But if i change on page=2 numberOfItems with another number, it doesnt change. Plus, i added some junk text in wp-includes >feed-rss2.php just to verify if it cached or not. And it doesnt show after the first 2-3 page refreshes.
To be honest, i'm stuck, i don't know how to approach this, i've looked on the wordpress code and i dont see where the caching is done.
What about this?
function do_not_cache_feeds(&$feed) {
$feed->enable_cache(false);
}
add_action( 'wp_feed_options', 'do_not_cache_feeds' );

How can I select books randomly in Now Reading wordpress plugin?

I am using 'Now Reading' plugin in a wordpress project. In plugin's sidebar template I am using this query:
while( have_books('status=read&orderby=finished&num=2') ) : the_book();
to select 2 books.
What parameter should I pass to make it random? I tried with 'order=rand' and 'rand=true' but it did not work.
Any help will be appreciated!
Thanks in advance..
A random function doesn't actually exist. I have used this code, in my themes functions.php to allow random order before - not sure if it'll work in this situation, but worth a try.
Add this to your themes functions.php file:
function query_random_posts($query) {
return query_posts($query . '&random=true');
}
class RandomPosts {
function orderby($orderby) {
if ( get_query_var('random') == 'true' )
return "RAND()";
else
return $orderby;
}
function register_query_var($vars) {
$vars[] = 'random';
return $vars;
}
}
add_filter( 'posts_orderby', array('RandomPosts', 'orderby') );
add_filter( 'query_vars', array('RandomPosts', 'register_query_var') );
Then try this in your sidebar file:
while( have_books('status=read&orderby=finished&num=2&random=true') ) : the_book();
If not, my only other suggestion would be to get the 10 latest books, add them all to a new array, and then shuffle that array. May be a bit bloated though.

Resources