Using current post ID in Wordpress shortcode - php

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.

Related

How to change displaying wordpress post title

i need a trick about wordpress.
i want replace a word from my displaying post title at whole website.(not permantly or not on database. only show temporary at browser.)
for example: i want change post word to text
here is list my post titles:
1- This is first post title
2- This is second post title
3- This is third post title
4- This is fourth post title
here is my new post title list:
1- This is first text title
2- This is second text title
3- This is third text title
4- This is fourth text title
How can i do this?
in your functions.php:
function title_changer($title) {
global $post;
$title = str_replace('text','post',$post->post_title);
return $title;
}
add_action('the_title','title_changer');
go to your single.php in your theme path
find get_the_title or the_title, for each one you may change the title_changer function with the specific functions used in the single.php
you can do using Jquery, but you've to change few things as according to your HTML tags
h2.entry-title HERE you've to change your post title CSS class and I'm hoping there is an anchor tag inside heading, so I'm replacing the HTML of anchor tag, Please change accordingly and add in your functions.php file.
add_action( 'wp_footer', 'replace_title' );
function replace_title() { ?>
<script>
(function($) {
jQuery('h2.entry-title').each(function(index, value) {
let text = jQuery(this).find("a").html();
let result = text.replace("post", "W3Schools");
jQuery(this).find("a").html(result);
});
})(jQuery);
</script>
<?php
}
This is my approach I don't know how good it is but it works.
function menuarray() {
if ( ( $locations = get_nav_menu_locations() ) && isset( $locations[ "primary" ] ) && !is_admin() ) {
$menu = wp_get_nav_menu_object($locations[ "primary" ]);
$menuitems = wp_get_nav_menu_items( $menu->term_id );
$idCats = array_column($menuitems, 'title');
return $idCats;
}
}
global $menutem;
$menutem = menuarray();
First I create this function globally in functions.php to I don't repeat it inside the function.
After that I create
add_filter('the_title', 'remove_header_metis', 10,2);
function remove_header_metis($title, $id) {
global $menutem;
if ( !is_admin() && ('post' == get_post_type($id) || 'page' == get_post_type($id) ) && !in_array($title, $menutem) ) {
$title = "";
}
return $title;
}
In this way, my menu stays ok and I change what I needed. You can tweak this for your needs.

Wordpress $_GET['post'] in admin returns NULL

I want to modify a custom field in my WordPress edit post page and I will need the post ID to do this. I have a function in functions.php and it works fine when I manually enter the post ID. The issue comes up when I try getting the post ID from the URL but the $_GET['post'] is proving to be useless. var_dump($_GET['post']) returns NULL, $global $post; var_dump($post->ID) returns NULL. The URL is the normal post edit link
URL: http://mywebsite.com/wp-admin/post.php?post=435&action=edit
I have been able to get the post ID via the admin_head hook but can't get it to work in my other function suing set_query_var(). Have a look below at my modified code:
add_action( 'admin_head', 'get_post_ID' );
function get_post_ID() {
global $post;
$thePostID = 0;
$pagenow = isset($GLOBALS['pagenow']) ? $GLOBALS['pagenow'] : null;
if ( $pagenow == 'post.php' ) {
$thePostID = $post->ID;
set_query_var('my_post_id', $thePostID);
}
return $post->ID;
}
function get_admin_post_ID() {
var_dump(get_query_var('my_post_id'));
}
add_action( 'template_redirect', 'get_admin_post_ID' );
What could be the issue here? Is there something I am missing? Kindly assist.
So, what $_GET return instead?
Are you using some plugin that edit posts, and that do not use/pass this var?
As said before, the browser address url, return something like this or not?
https://subdomain.w3host.com/wordpress/wp-admin/post.php?post=100&action=edit
PS: var_dump that return NULL on $_GET['post'], simply mean that there is so, a php
Notice: Undefined index:
the post var do not exist

Excluding posts on WooCommerce 'shop order' archive page based on meta key/value

I am trying to exclude certain posts from the Shop Order page e.g. '/wp-admin/edit.php?post_type=shop_order' if don't have a certain meta_key/meta_value combination present.
I have tried two approaches and neither seems to work properly:
Option 1: Pre Get Posts
add_action( 'pre_get_posts', 'so_filter_shop_order' );
function so_filter_shop_order($query) {
global $typenow;
/** #var $query WP_Query */
if ($query->is_main_query() && $typenow === 'shop_order' && is_admin()) {
$query->set( 'meta_key', '_method_created' );
$query->set( 'meta_value', 'booking' );
}
}
Limitations of Option 1 The problem with this option is that it doesn't seem to target other queries on this page (e.g. the count of different post statuses). I am also worried that this code will be targeting other queries elsewhere.
Option 2: Filter 'request'
This was an idea I got from WooCommerce CSV Export Plugin (as they filter this loop too).
add_filter( 'request', 'so_order_filters');
function so_order_filters( $vars ) {
global $typenow;
if ( 'shop_order' === $typenow ) {
$vars['meta_key'] = '_method_created';
$vars['meta_value'] = 'booking';
}
return $vars;
}
Limitations of Option 2 This approach also does not target other things on the page and it also conflicts with the CSV Export plugin because only one 'meta_key' can be added to the $vars array. I am also 95% sure this is not the right way to do it.
Where I would like help
It would be great to get some feedback on if either approach is worth pursuing or a suggested alternative please.
It would also be good to know if there are other things I can add to Option 1 to make sure it is only targeting the correct queries
Finally, any advice on how to target the other things on the other related queries on the page would be extremely useful.
Thanks in advance.
Here is another approach.
To get all post ID-s which has certain metakey+metavalue combination via SQL.
To include it with post__in parameter.
add_action( 'pre_get_posts', 'so_filter_shop_order' );
function so_filter_shop_order($query) {
global $wpdb;$excluded_results=array();
$excluded_results=$wpdb->query("select post_id from $wpdb->postmeta where meta_key='_method_created' and meta_value='booking' ");
foreach ($variable as $key => $value) {$excluded_results[]=$value;}
if (strpos($_SERVER["REQUEST_URI"],'post_type=shop_order') && is_admin()) {
$query->set( 'post__in', $excluded_results);
}
}
To affect table header part which shows the number of posts can't be done with pre_get_posts. It works through wp_count_posts filter. So you need to create a filter for this. Here is sample boilerplate for that:
add_filter('wp_count_posts','changenumbers',0,3);
function changenumbers ($counts, $type, $perm){
if (strpos($_SERVER["REQUEST_URI"],'post_type=product') && is_admin()) {
$counts->publish=0;
//var_dump($counts);
//you need to write some wp_query there which would get the number of posts by their status. Then you will only need to return those values.
}
return $counts;
}

hide password protected posts from wordpress loop

I found this in the codex:
// Filter to hide protected posts
function exclude_protected($where) {
global $wpdb;
return $where .= " AND {$wpdb->posts}.post_password = '' ";
}
// Decide where to display them
function exclude_protected_action($query) {
if( !is_single() && !is_page() && !is_admin() ) {
add_filter( 'posts_where', 'exclude_protected' );
}
}
// Action to queue the filter at the right time
add_action('pre_get_posts', 'exclude_protected_action');
But it didn't work. Perhaps because I've customised my loop. I was hoping to do something simple, along these lines:
<?php $postsLatest = get_posts('numberposts=10&passwordproteced=false'); foreach($postsLatest as $post) { ?>
Is that possible?
The has_password and post_password parameters in WordPress 3.9+
You wrote:
I was hoping to do something simple, along these lines:
passwordproteced=false
You're pretty close, because you can use the boolean has_password parameter:
$postsLatest = get_posts( 'has_password=false' );
to fetch posts without passwords.
You can read more about this parameter in the Codex for WP_Query(), since get_posts just a wrapper for WP_Query(), and shares the input parameters.
Notice that this will only work on WordPress 3.9+:
has_password (bool) - true for posts with passwords ; false for posts
without passwords ; null for all posts with and without passwords
(available with Version 3.9).
There's also another new post_password parameter with possible values:
null (ignore)
false (only posts without passwords)
true (only posts with passwords)
a string (posts with this exact password)
You can check this Trac Ticket.
Using pre_get_posts filter with get_posts:
The reason why you didn't succeed with the pre_get_posts filter, is that get_posts() suppresses all pre_get_posts filters by default. Use the suppress_filters=false parameter to apply it.
You can do this inside your custom loop.
<?php
if ( post_password_required() ) {
continue;
} else {
echo 'normal post';
}
?>

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