WordPress How to Keep the_content filter for my cpt from affecting other posts on the same page - wordpress

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.

Related

Output certain product page on homepage / WooCommerce shortcode not working properly

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 disable <p> tags without disable <br> tags in wordpress

I want to remove only <p> tags without remove <br> tags in pages wordpress, i only found remove <br> tags and keep <p>, every i use remove_filter still remove <br> tags.
You can use strip_tags php function which removes php and html tags from a string.
This is for displaying the content: the_content()
https://developer.wordpress.org/reference/functions/the_content/
And this to retrieve the post content: get_the_content()
https://developer.wordpress.org/reference/functions/get_the_content/
(1) First way doing this: Change the page template of your theme
So in your page template, you normally will find the function call the_content().
But we need to retrieve the post content, remove the paragraph tags, and then display the "cleaned" content.
For that we will not use the_content() but use get_the_content().
<?php
$my_content = get_the_content();
$clean_content = strip_tags($my_content , '<p>');
echo $clean_content;
?>
We saved the post content in a variable (get_the_content is returning a string) and then used strip_tags to remove the tags. We just need to echo the "cleaned" content.
(2) Alternative way doing this: Change the output of the_content() function
If you want to use the_content() function or do not have the possibility to change the theme files, you can make use of the_content filter in wordpress.
function remove_tags_from_the_content( $content ) {
return strip_tags( $content, '<p>' );
}
add_filter( 'the_content', 'remove_tags_from_content' );
This way everytime your the_content() function is called, the filter will be applied so the function returns your cleaned version.
(3) Another way: Remove auto paragraphs in wordpress content
Wordpress adds paragraph tags to the content by default. You can disable this behaviour (remove the filter) by putting the follwing code in the functions.php file of your theme:
// Prevent wordpress from adding paragraph tags on pages
function disable_pages_wpautop( $content ) {
if ( is_singular( 'page' ) ) {
remove_filter( 'the_content', 'wpautop' );
}
return $content;
}
add_filter( 'the_content', 'disable_pages_wpautop', 0 );
You can replace the if condition with the post type you like:
if ( is_singular( 'your-post-type' ) )
If you want to remove the paragraphs in the content and excerpt in pages, posts and other post-types, you can get rid of the if-clause:
function disable_wpautop_all( $content ) {
remove_filter( 'the_content', 'wpautop' );
remove_filter( 'the_excerpt', 'wpautop' );
return $content;
}
add_filter( 'the_content', 'disable_wpautop_all', 0 );

How can I get the default content of WordPress post?

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.

Wordpress: map existing page content instead of a copy

I have a page with several subpages in wordpress. The page should display the same content as the second subpage. When I edit the page, there is an option to copy the content from the subpage into it, but then I would have to maintain two instances of the text. Is there a possibility to map existing page content into a page? I'm using Wordpress.com so I cannot edit any files/links on the server.
You could use a shortcode that fetches the content of a page specified. In functions.php:
add_action( 'init', 'so20477735_init', 11 );
function so20477735_init()
{
add_shortcode( 'duplicate_page', 'so20477735_shortcode_callback' );
}
function so20477735_shortcode_callback( $atts, $content = null )
{
extract( shortcode_atts( array(
'page_id' => 0
), $atts ) );
$page_data = get_page( $page_id );
$return = '';
if( ! is_null( $page_data ) )
$return .= $page_data->post_content;
return $return;
}
Example usage:
[duplicate_page page_id="12"]
EDIT
I missed the fact you're using wp.com. You should be able to do something similar with the display posts shortcode:
http://en.support.wordpress.com/display-posts-shortcode/

Wordpress Gallery Shortcode Pregreplace

Basically I need to remove the gallery shortcode from the Wordpress content, I'm using
echo preg_replace('/\[gallery ids=[^\]]+\]/', '', get_the_content() );
It is removing the gallery shortcode successfully, but also the paragraph tags which I need to keep. The idea is that I want to output everything in the content except the gallery.
You could use Wordpress strip_shortcode function.
Look at the example in the Codex.
You can create a filter that strips shortcodes:
function remove_shortcode_from($content) {
$content = strip_shortcodes( $content );
return $content;
}
and call it when you need (in your template):
add_filter('the_content', 'remove_shortcode_from');
the_content();
remove_filter('the_content', 'remove_shortcode_from')
EDIT 1
Another way to get that (and answering you comment) you can use Wordpress apply_filters function in the content after remove the undesirables shortcodes.
//within loop
$content = get_the_content();
$content = preg_replace('/\[gallery ids=[^\]]+\]/', '', $content );
$content = apply_filters('the_content', $content );
echo $content;
But I would not recommend to you to do that. I think forcing your site to modify the content of a post could make that hard to understanding. Maybe you should work with Wordpress Excerpt and avoid any problem.
A link that helped me
to remove a shortcode or a particular list of shortcode you can use this code.
global $remove_shortcode;
/**
* Strips and Removes shortcode if exists
* #global int $remove_shortcode
* #param type $shortcodes comma seprated string, array of shortcodes
* #return content || excerpt
*/
function dot1_strip_shortcode( $shortcodes ){
global $remove_shortcode;
if(empty($shortcodes)) return;
if(!is_array($shortcodes)){
$shortcodes = explode(',', $shortcodes);
}
foreach( $shortcodes as $shortcode ){
$shortcode = trim($shortcode);
if( shortcode_exists($shortcode) ){
remove_shortcode($shortcode);
}
$remove_shortcode[$shortcode] = 1;
}
add_filter( 'the_excerpt', 'strip_shortcode' );
add_filter( 'the_content', 'strip_shortcode' );
}
function strip_shortcode( $content) {
global $shortcode_tags, $remove_shortcode;
$stack = $shortcode_tags;
$shortcode_tags = $remove_shortcode;
$content = strip_shortcodes($content);
$shortcode_tags = $stack;
return $content;
}
dot1_strip_shortcode( 'gallery' );
Accepts single, comma seprated shortcode string or array of shortcodes.

Resources