How to use multiple pre_get_posts on functions.php? - php

I will try to explain as good as I can (sorry if my english is bad, this is not my native):
I have two custom post types and two custom post type archive pages for each of them.
To filter posts which are displayed in those pages I created two different functions inside functions.php file with "pre_get_posts" function as you can see in code below.
My functions.php:
add_action('pre_get_posts', 'my_pre_get_posts');
function my_pre_get_posts( $query ) {
some code here...
}
add_action('pre_get_posts', 'my_pre_get_posts_2');
function my_pre_get_posts_2( $query ) {
some code here...
}
The problem is that second function (my_pre_get_posts_2) is overwriting first one (my_pre_get_posts) and first function is not working on custom post type archive page.
I tried to use is_post_type_archive( 'custom_post_type' ) but first function still is not working.
What I need to do to assign first function only to specific custom post type archive page and not to call it on any other pages?

This is covered in the Codex. You should use a single callback:
function my_pre_get_posts( $query ){
if ( is_post_type_archive('cpt_1') ) {
// Do stuff for a custom post type
} elseif ( is_post_type_archive('cpt_2') ) {
// Do stuff for a different custom post type
}
}
add_action('pre_get_posts', 'my_pre_get_posts');

Related

Using current post ID in Wordpress shortcode

I'm using an event management plugin, and I want to display some specific event details via shortcodes.
I've found this very useful guide regarding this plugin's shortcodes:
https://urjtechhelp.zendesk.com/hc/en-us/articles/115002801594-Embedding-Single-Events-with-the-tribe-event-inline-Shortcode
But I have one problem. As stated in the guide you must always supply an event’s ID via the id shortcode attribute, like this:
[tribe_event_inline id="167"]
What I'm trying to achieve is for the shortcode to always use the ID of the post it's placed in.
I've tried adding additional shortcode
add_shortcode( 'return_post_id', 'the_dramatist_return_post_id' );
function the_dramatist_return_post_id() {
return get_the_ID();
}
And then nest the shortcode in the original one, but apparently it doesn't work that way.
Any idea on how to achieve this?
Thank you in advance for any ideas.
Maybe it's help:
add_shortcode( 'return_post_id', 'the_dramatist_return_post_id' );
function the_dramatist_return_post_id() {
global $post;
return $post->ID ?? '';
}
This would not work using the WP text editor. It would also not be a clean implementation.
I would recommend going straight to the problem and edit the function responsible for the "tribe_event_inline" shortcode.
Try searching for add_shortcode('tribe_event_inline' in your source code files.
Here is one my function what I use time to time. I simplify it for you but with small work can be expanded to more levels.
function current_ID($post_id=NULL){
global $product, $page;
if(is_numeric($post_id) && $post_id == intval($post_id)) {} else {
// Get ID from the current object
if(!is_object($post_id)) {} else if(property_exists($post_id, 'ID')) {
$post_id = $post_id->ID;
}
// Woocommerce product page
if(empty($post_id) && property_exists($product, 'ID')) $post_id = $product->ID;
// Standard page/post ID
if(empty($post_id)) $post_id = get_the_ID();
// Get ID from the $page global
if(empty($post_id) && property_exists($page, 'ID')) $post_id = $page->ID;
// GET request
if(isset($_GET['post']) && is_numeric($_GET['post']) && $_GET['post'] > 0 && intval($_GET['post']) == $_GET['post']) $post_id = intval($_GET['post']);
if(isset($_GET['p']) && is_numeric($_GET['p']) && $_GET['p'] > 0 && intval($_GET['p']) == $_GET['p']) $post_id = intval($_GET['p']);
// Get ID from the get_queried_object_id() function
if(empty($post_id) && function_exists('get_queried_object_id')) $post_id = get_queried_object_id(); // Need tests
}
// The end
return $post_id;
}
It support also Woocommerce.
Now you need to include it into your project and add it to shortcode or combine with some other function to accept it.
Idea:
Use a template for your shortcode like [tribe_event_inline id="ZXZX"]
Add filter for the_content.
Use your filter to replace ZXZX with post ID.

How to get_the_date() of post inside an action hook function?

Trying to get current post date inside an action hook function for custom post type. How to get all the details of the current post inside there. Or at least the post date? I have tried many things. Sorry if it's easy, I am a beginner in Wordpress.
add_action('init', 'Theme2035_lyric_register');
function Theme2035_lyric_register() {
echo get_the_date();
---other code below---
}
I see you're looking for the_post action hook:
function my_the_post_action( $post_object ) {
$post_date = $post_object->post_date;
// do something with $post_date
}
add_action( 'the_post', 'my_the_post_action' );
If you want to get more attribute of $post_object, you may want to take a look at WP_Post class reference.

Woocommerce | If page_id= .. { }

I am trying to apply specific functions to a certain page ID in Woocommerce.
However, it does not seem to apply. I have looked at both Wordpress and Woommerce conditional tags (https://docs.woocommerce.com/document/conditional-tags/).
The simple code I am testing is shown below, but even that is not working.
if ( is_product()) {
echo ' HALLO sdfdsfsdfsdfsdf ';
}
I have also tried with page_id and post_id but cannot get this to work.
I have added this code to my functions.php in my child theme.
Does anybody know to to write a specific function only for a specific product page (I know the value).
Method - 1
is_page() relies on a complete global $wp_query object. If you call it before the action template_redirect has been fired, it might be impossible to get that data.
add_filter( 'template_include', function( $template ) {
if ( is_product() )
echo 'HELLO';
return $template;
});
Method - 2
The WordPress/WooCommerce conditional tags won’t work until after the wp action is fired, making it the earliest point at which you can use the tags. You can view the entire list, and the order of the core WordPress actions at the Action Reference page.
add_action( 'wp', 'init' );
function init() {
if ( is_shop() ) {
echo 'HELLO, this works!';
}
}

WooCommerce how to check if page is_shop() in functions.php?

In WooCommerce, My Category Listing page and product listing page are rendered from archieve-product.php ( By Default) . How to check if page is_shop() in functions.php? As is_shop function does not work in functions.php. I simply want to remove my sidebar from Category listing page not from product listing page.
When placed inside a hook, is_shop will work in functions.php
add_action( 'template_redirect', 'custom_template_redirect' );
function custom_template_redirect() {
if( is_shop() ) :
// code logic here
endif;
}
Here is a list of all WooCommerce conditionals
You can write a condition into "archive-product.php" for category page like,
$cate = get_queried_object();
if(is_product_category() && $cate->parent != 0 ){
// Write code here
//include sidebar here
}
By using this code this will check the page for product_category and also check for a parent.
call it using WordPress Hook pre get posts
add_action('pre_get_posts','nameTheFunction');
function nameTheFunction(){
if(is_shop()){
// your code here
}
}// function end here
Read more about pre get posts Hook
https://developer.wordpress.org/reference/hooks/pre_get_posts/
You can use function_exists
if( function_exists("is_shop") ) {
// call it or do something else
}
else {
// load it from somewhere
}
Official docs: https://secure.php.net/function_exists

How to modify page title in shortcode?

How do I modify a page title for specific pages in shortcode?
The following will change the title but it executes for every page. I need more control over where it executes.
function assignPageTitle(){
return "Title goes here";
}
add_filter('wp_title', 'assignPageTitle');
Is there a way to call the above in a shortcode function? I know how to use do_shortcode() but the above is a filter.
My goal is to modify the page title based on a URL parameter. This only happens for specific pages.
Although WordPress shortcodes was not designed to do this, it can be done. The problem is shortcodes are processed AFTER the head section is sent so the solution is to process the shortcode BEFORE the head section is sent.
add_filter( 'pre_get_document_title', function( $title ) {
global $post;
if ( ! $post || ! $post->post_content ) {
return $title;
}
if ( preg_match( '#\[mc_set_title.*\]#', $post->post_content, $matches ) !== 1 ) {
return '';
}
return do_shortcode( $matches[0] );
} );
add_shortcode( 'mc_set_title', function( $atts ) {
if ( ! doing_filter( 'pre_get_document_title' ) ) {
# just remove the shortcode from post content in normal shortcode processing
return '';
}
# in filter 'pre_get_document_title' - you can use $atts and global $post to compute the title
return 'MC TITLE';
} );
The critical point is when the filter 'pre_get_document_title' is done the global $post object is set and $post->post_content is available. So, you can find the shortcodes for this post at this time.
When the shortcode is normally called it replaces itself with the empty string so it has no effect on the post_content. However, when called from the filter 'pre_get_document_title' it can compute the title from its arguments $atts and the global $post.
Taken from the WordPress Codex
Introduced in WordPress 2.5 is the Shortcode API, a simple set of
functions for creating macro codes for use in post content.
This would suggest that you can't control page titles using shortcodes as the shortcode is run inside the post content at which point the title tag has already been rendered and is then too late.
What is it exactly that you want to do? Using the Yoast SEO Plugin you can set Post and Page titles within each post if this is what you want to do?
You could create your custom plugin based on your URL parameters as so:
function assignPageTitle(){
if( $_GET['query'] == 'something' ) { return 'something'; }
elseif( $_GET['query'] == 'something-else' ) { return 'something-else'; }
else { return "Default Title"; }
}
add_filter('wp_title', 'assignPageTitle');

Categories