Is there a way where I can get the default output of the_content in WordPress post? Some of the plugin is using add_filter to the content to add their desired result like related post plugins where they add the result at the end of the content of a post. What I want to happen is to get the default formatting functions of WordPress core without any additional filters from other plugins.
You can use remove filter function.
remove_filter( $tag, $function_to_remove, $priority );
For more please refer below link
https://codex.wordpress.org/Function_Reference/remove_filter
You can use the_content filter itself to get the post object or the content , you can modify it or you can unhook it and again hook it as per your requirement .
If I have understood your requirement this link will help you, if you need something different please ask me.
Guys thanks for responding to my question I think I got it somehow but need to run more test. What I did was I replicate the process on how the_content() function of WordPress work. Base from my research there are 10 default filters coming from WordPress core you can see on this link: read here
I just created my own function like the_content() from WordPress and apply the default filters to my own function. Put this code in your functions.php
if(!function_exists(default_post_content)){
function default_post_content( $more_link_text = null, $strip_teaser = false) {
$content = get_the_content( $more_link_text, $strip_teaser );
$content = apply_filters( 'default_post_content', $content );
$content = str_replace( ']]>', ']]>', $content );
echo do_shortcode($content);
}
add_filter( 'default_post_content', array( $wp_embed, 'run_shortcode' ), 8 );
add_filter( 'default_post_content', array( $wp_embed, 'autoembed'), 8 );
add_filter ( 'default_post_content', 'wptexturize');
add_filter ( 'default_post_content', 'convert_smilies');
add_filter ( 'default_post_content', 'convert_chars');
add_filter ( 'default_post_content', 'wpautop');
add_filter ( 'default_post_content', 'shortcode_unautop');
add_filter ( 'default_post_content', 'prepend_attachment');
}
Then for example in your single page template(single.php) instead of using the usual the_content I can use my function default_post_content();. Now I don't need to worry about any of the plugins that create additional data to the_content() function.
Related
I need to output a certain product page on the homepage. add_rewrite_rule doesn't work for homepage for any reason (
there are actually no rewrite rules for the homepage in the database, WordPress seems to use some other functions to
query the homepage):
//works fine
add_rewrite_rule( 'certainproductpage/?$',
'index.php?post_type=product&name=certainproduct',
'top'
);
//does not work
add_rewrite_rule( '', //tried everything like "/", "/?$" etc
'index.php?post_type=product&name=certainproduct',
'top'
);
After spending way too much time looking through wp / wc core code and stackoverflow I came across an alternative. I can
simply add a shortcode in the content of the page I need to be the homepage and a product page at the same
time: [product_page id=815]. Indeed it works great, but only if the shortcode is added in the admin editor or is
stored in the database (post_content). If I try to call the shortcode manually on the page template (
page-certainproductpage.php) then it outputs the product page without some necessary stuff (PayPal, PhotoSwipe and
Gallery js). Weirdly enough, if I keep the shortcode in the content (via Gutenberg / Code Editor) but don't
call the_content and only echo the shortcode then everything works fine:
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
get_header( 'shop' );
//works fine only if the same shortcode is within the certainproductpage's content
echo do_shortcode("[product_page id='815']");
//the_content();
get_footer( 'shop' );
Also when I try to add the shortcode via the_content filter hook before the do_shortcode function is applied in core's
default-filters.php ($priority < 11), then I get only the error:
NOTICE: PHP message: PHP Fatal error: Maximum execution time of 30 seconds exceeded in /var/www/html/wp-includes/functions.php on line 5106
Unfortunately there is no stack trace logged. And the function around line 5107 is wp_ob_end_flush_all which is called on shutdown from default-filters.php
echo do_shortcode(apply_filters('the_content', "[product_page id=815]")); did not help either (same incomplete output as
with echo do_shortcode("[product_page id=815]");)
Also totally weird:
When I compare the string of the content from the editor and the string of the shortcode added programmatically it is
equal!:
add_filter( "the_content", function ( $content ){
$wtf = "<!-- wp:paragraph -->
<p>[product_page id=815]</p>
<!-- /wp:paragraph -->";
$result = $wtf === $content;
?><pre><?php var_dump($result)?></pre><?php
return $content;
}, 1 );
But if I replace return $content with return $wtf - I get the maximimum exucution time exceeded error.
So how can I properly output a product page on the homepage ("/") or how can I get the same result with the shortcode
when applied within the the_content filter as when just adding the shortcode in the (Gutenberg) editor?
Update
Tested it with a simple custom shortcode outputting only a heading tag and it works fine with the_content filter. Also tried it on an absolutely clean site with only WooCommerce and PayPal installed - with the same results. Seems to be a bug on the WooCommerce side. Gonna run it through xDebug some day this week.
Ok, found a bit of a hacky solution. I just check on every page load whether the homepage is currently queried or not. Then I get the page content and check if it already contains the shortcode. If not then the page content gets updated in the database with the shortcode appended.
//it has to be a hook which loads everything needed for the wp_update_post function
//but at the same time has not global $post set yet
//if global $post is already set, the "certainproductpage" will load content not modified by the following code
add_action( "wp_loaded", function () {
//check if homepage
//there seems to be no other simple method to check which page is currently queried at this point
if ( $_SERVER["REQUEST_URI"] === "/" ) {
$page = get_post(get_option('page_on_front'));
$product = get_page_by_path( "certainproduct", OBJECT, "product" );
if ( $page && $product ) {
$page_content = $page->post_content;
$product_id = $product->ID;
$shortcode = "[product_page id=$product_id]";
//add shortcode to the database's post_content if not already done
$contains_shortcode = strpos( $page_content, $shortcode ) > - 1;
if ( ! $contains_shortcode ) {
$shortcode_block = <<<EOT
<!-- wp:shortcode -->
{$shortcode}
<!-- /wp:shortcode -->
EOT;
$new_content = $page_content . $shortcode_block;
wp_update_post( array(
'ID' => $page->ID,
'post_content' => $new_content,
'post_status' => "publish"
) );
}
}
}
} );
I'd recommend one step at a time. First of all, does this work?
add_filter( "the_content", function ( $content ) {
$content .= do_shortcode( '[product_page id=815]' );
return $content;
}, 1 );
This should append a product page to every WordPress page/post.
If it works, then you need to limit it to the homepage only, by using is_front_page() conditional in case it's a static page:
add_filter( "the_content", function ( $content ) {
if ( is_front_page() ) {
$content .= do_shortcode( '[product_page id=815]' );
}
return $content;
}, 1 );
If this works too, then we'll see how to return a Gutenberg paragraph block, but not sure why you'd need that, so maybe give us more context
How to insert shortcode with more parameters and multiline into WordPress page?
Backslash used to work as a line separator:
[my_shorcode parameter_1=10 \
parameter_2=20 \
parameter_3="test"]
But it doesn't work in the latest WordPress version. I want to use more lines for better readability of the code.
Thanks for #Arvind K. for advice
This is not good idea since it breaks normal post editing behavior.
Rather you should try to keep shortcodes "short
I've been solving this problem by the way
1. I have used shortcode this way [my-shortcode id="1"]
2. I have created post type My Shortcodes
3. The id for step 1. is the My Shortcodes post id
4. In ACF (Custom fields) I have created fields for My Shortcodes
(Field - is shortcode param)
5. Then you could use your My Shortcodes post for getting fields.
add_shortcode( 'my-shortcode', function ( $atts, $content ) {
$custom_shortcode_id = $atts['id'];
$parameter_1 = get_field( 'parameter_1', $custom_shortcode_id );
$parameter_2 = get_field( 'parameter_2', $custom_shortcode_id );
return "Your shortcode content $parameter_1, $parameter_2";
} );
I removed 2 WordPress filters and it works fine now.
remove_filter( 'the_content', 'wpautop' );
remove_filter( 'the_excerpt', 'wpautop' );
On my woocommerce theme I get some errors on Google structured data such as:
I've found code into mytheme/woocommerce/loop/ratings.php
In this file there are only this method:
$product->get_average_rating();
The question is: there's a hook or action that implement this function?
I need to implement "ItemReviewed" props.
This is down to your product schema, option one is to remove the error but wont push the reviews is
/**
* Remove the generated product schema markup from Product Category and Shop pages.
*/
function wc_remove_product_schema() {
remove_action( 'woocommerce_shop_loop', array( WC()->structured_data, 'generate_product_data' ), 10, 0 );
}
add_action( 'woocommerce_init', 'wc_remove_product_schema' );
if you want to aggregate your reviews you will need to update your schema if you are using yoast and woocommerce this can be achieved by looking into the specific yoast woocoommerce plugin and the plugin docs to add the correct schema
https://developer.yoast.com/schema-documentation/woocommerce-seo/
I had the same problem - reviews were not validating and throwing an error
Managed to get it fixed by editing /wp-content/themes/YOURTHEME/woocommerce/single-product/review.php
I added the below code:
<p>Item Reviewed: <span itemprop="itemReviewed"><?php echo get_the_title(); ?></span></p>
That generated the itemReviewed markup in Structured Data Tool and my reviews validated.
Might want to place it in the child theme just in case :)
define the woocommerce_structured_data_review callback
function filter_woocommerce_structured_data_review( $markup, $comment ) {
global $product;
$markup['itemReviewed']['sku'] = $product->get_sku();
$markup['itemReviewed']['brand'] = $product->get_attribute( 'brand' ) ?? null;
$markup['itemReviewed']['description'] = wp_strip_all_tags( do_shortcode( $product->get_short_description() ? $product->get_short_description() : $product->get_description() ) );
$markup['itemReviewed']['image'] = wp_get_attachment_url( $product->get_image_id() );
$markup['itemReviewed']['isbn'] = $product->get_attribute( 'isbn' ) ?? null;
$markup['itemReviewed']['AggregateRating'] = $product->get_average_rating();
return $markup;
};
Woocommerce Reviews filter
add_filter( 'woocommerce_structured_data_review',
'filter_woocommerce_structured_data_review', 10, 2 );
I am using a custom post type for the slide in my theme. I'm trying to remove wpautop from the cpt using the_content filter hook, and it works using the following code, but it also removes it wpautop from the other queries on the same page. Here is the code:
add_filter( 'the_content', 'remove_autop_for_post_type', 0 );
function remove_autop_for_post_type( $content )
{
if('par2_slide' === get_post_type(get_the_ID())){
remove_filter( 'the_content', 'wpautop' );
return $content;
};
return $content;
};
Adding a second condition to include "! is_main_query() like so:
if('par2_slide' === get_post_type(get_the_ID()) && ! is_main_query()){
causes the script to stop working. The query for my cpt to which this is supposed to apply is as follows:
function par2_slides_query () {
$args = array( 'post_type' => 'par2_slide');
$slides_loop = new WP_Query( $args );
while ( $slides_loop->have_posts() ) : $slides_loop->the_post();
echo '<li class="slide">';
the_content();
echo '</li>';
endwhile;
};
wpauto messes with the slide layout so I really need to filter the content for that particular post type to turn it off without turning it off for the instances of the_content on the rest of the page. It doesn't affect other pages, on the_content on the same page.
Re add the filter after your IF statement.
add_filter('the_content', 'wpautoop');
It removes it and returns the content IF par2_slide is the post type, and if it's not it adds the filter if it doesn't exist.
I'm trying to understand Wordpress plugin like:
apply_filters( 'gettext', $translations->translate( $text ), $text, $domain );
I'm looking for all codes in Wordpress, I can't find:
add_filter( 'gettext', ....);
Why there is no add_filter for this plugin? Or I missed something? Same thing like:
do_action('wp_loaded');
I can't find:
add_action('wp_loaded', ....);
apply_filters is like, 'if there are any filters with this name, run the attached callbacks with these parameters'. So if there is no add_filter for that name, it means that there is no filter that's going to be run with the apply_filters call at the moment.
The same goes with do_action and add_action.
I am a beginner in PHP - WordPress stack as well, but this is from my understanding.
The plugins call apply_filters without having any add_filter in their codes is to allow the website users to add custom logic to their plugins. We - the users, can add our own function and use add_filter to register our functions.
For example, this piece of code is from the plugin. Normally, it shows all products but it provides us a way to not show a specific product.
// Plugin's
if (apply_filters( 'plugin_show_products', true, $product->get_id() ) ) {
$this->show_products();
}
So, if we - the users, want to customize a bit. We can add our own function as following (maybe in functions.php)
// Our custom changes
function my_own_changes($boolean, $product_id) {
if ( $product_id === 5 ) return false;
return true;
}
add_filter( 'plugin_show_products', 'my_own_changes', 10, 2 );
This translates to: The plugin will behave normally but for my own site, it will not show the product with ID of 5!
I have come across this type of code in a plugin or theme where the apply_filter is used without necessarily having an existing filter or add_filter
In this case, where the apply_filters is used without a filter you will have to call the function again where you want to run it. For example, in the header of a theme.
The following is an example of apply filters used in a function that is again called in the header.php
if ( ! function_exists( 'header_apply_filter_test' ) ) {
function header_apply_filter_test() {
$filter_this_content = "Example of content to filter";
ob_start();
echo $filter_this_content;
$output = ob_get_clean();
echo apply_filters( 'header_apply_filter_test', $output );//used here
}
}
Now in the header.php file, you would have to call this function since it is not hooked anywhere. So, in this case, to display the output in the header you would call the function like this :
<?php header_apply_filter_test(); ?>
You could as well write this code with a hook and it would do the same thing i.e display the output in the header.
add_filter('wp_head', 'header_apply_filter_test');
if ( ! function_exists( 'header_apply_filter_test' ) ) {
function header_apply_filter_test() {
$filter_this_content = "Example of content to filter";
ob_start();
echo $filter_this_content;
$output = ob_get_clean();
echo $output;
}
}
For this second option, you would still have the capability of using apply_filters anywhere else to call the callback function header_apply_filter_test() since the filter now exists.
So the bottom line in my view is a use case since either approach works!