wordpress post the_content filter - wordpress

I want write function which add to my post content <!--nextpage--> tags, I write this function:
<?php
function output($content) {
$output = $content.'<!--nextpage-->'.$content;
return $output;
}
add_filter('the_content','output');
?>
Function add <!--nextpage--> tags, but this tags not works when I display posts, it are like html comments, maybe are some solution to solve this problem ?
Maybe I must use not the_content but wp_insert_post_data ?

The conversion from text with <!--nextpage--> into "pages" happens in setup_postdata. But the hook you use executes when the template tag with the same name, the_content is called. So what this means is you have to change the content before the loop starts. It can be a bit tricky. Off the top of my head I don't know of any suitable hooks but you can check the source code for setup_postdata and there might be one. In the theme, though, you can access $posts so if you put this in a template, it should work:
global $posts;
array_map( function( $apost ) {
$apost->post_content = $apost->post_content.'<!--nextpage-->'.$apost->post_content;
return $apost;
}, $posts );
If you don't have PHP version => 5.3 you can't use anonymous functions. In that case, this version will work:
global $posts;
function output( $apost ) {
$apost->post_content = $apost->post_content.'<!--nextpage-->'.$apost->post_content;
return $apost;
}
array_map( 'output', $posts );

Related

WordPress hook for changing excerpt content when excerpt not set

Title says pretty much all of it. I need a filter that I can use to change excerpt content for those posts that have no excerpt set.
Now, I've tried both the_excerpt and get_the_excerpt, they both pass one parameter, and in both cases said parameter is empty string.
That said, I will need to hook onto a filter that has access to the auto-generated except, and lets me change it.
Perhaps something like this (untested)?
function my_filter_the_excerpt( $excerpt ) {
global $post;
if( empty( $post->post_excerpt ) ) {
// Excerpt is auto-generated
$excerpt = 'Something else...';
}
return $excerpt;
}
add_filter( 'get_the_excerpt', 'my_filter_the_excerpt' );

How to build custom plugin to integrate with current theme

I am developing a plugin with a CPT and a CPT template. I would like the template to be able to integrate into any theme it is used with. I thought of calling the 'the_content' hook from my template but I have no idea how to do that as all I can find is calling it from the functions.php file. Please can you tell me how to code this in the CPT template file (like single-CPT.php) or maybe I am heading in the wrong direction so please redirect me. Thank you!
EDIT:
If you only want to add content to the_content function you can do something like that:
add_filter('the_content', "test_the_content");
function test_the_content($content){
if(is_singular('test')){
$content = $content.test_additional_content();
}
return $content;
}
function test_additional_content(){
ob_start(); ?>
<div class="test">
Here what you want to display after the_content
</div>
<?php
return ob_get_clean();
}
ORIGINAL ANSWER
If I understood your question correctly, here is how to define the templates of your custom post type in your plugin. This way it will also be possible to overwrite the plugin template from the theme.
The example below is for a CPT called "test", so you have to adapt the code according to the name of your CPT.
add_filter('template_include', 'my_plugin_templates');
function my_plugin_templates($template) {
$post_types = array('test');
if (is_post_type_archive($post_types) && !file_exists(get_stylesheet_directory() . '/archive-test.php')) {
$template = plugin_dir_path( __FILE__ ) . 'archive-test.php';
}
if (is_singular($post_types) && !file_exists(get_stylesheet_directory() . '/single-test.php')) {
$template = plugin_dir_path(__FILE__) . 'single-test.php';
}
return $template;
}
You can also take a look to this repo: https://github.com/zecka/cpt-in-plugin

Get post id inside shortcode used in loop

I feel like I'm missing something here. So I'm using visual composer masonry grid to show posts. I'm trying to create a shortcode to use in the Visual composer grid builder that shows the date timestamp but even though the shortcode is being used in a loop I can't get the post id or things like the_title or the_date in the shortcode. I can even use other shortcodes within this one to pull in the title and other meta info and it shows post specific info.
This is my attempt... it outputs nothing, no errors at least, but no result...
function lmi_features_time_ago_shortcode( $atts, $post ) {
global $post;
$output = '';
$timestamp = get_the_date('Y-m-d g:i:s', $post->id);
// $timestamp = time_elapsed_string($timestamp);
$output .= $timestamp;
return $output;
}
add_shortcode( 'social_feed_ago', 'lmi_features_time_ago_shortcode' );
Do a var_dump($post) and check if it's actually the post object. If the loop is set to return ids only then the $post variable will be the ID itself.

Wordpress skipping functions with apply_filters?

I'm using a translation plugin which creates a hook for the_title, the_content and other things.
All is working fine except one bit of code that does not display the title.
It uses this code:
$page_title = apply_filters('the_title',get_the_title());
If i try to use get_the_title() or the_title(), it breaks.
What does apply filters do, and how do i make it not skip the hook from the translation plugin?
the_title and the_content also exist in the Wordpress core. They are utilized for many things. Why a line like that is useful is apparent if you know what hooks are.
Filter hooks and Action hooks are essentially laundry lists. You can put functions on a hook, one after another so they form a queue, and when this hook is called on (by do_action and apply_filters respectively) Wordpress will unqueue one function after another. As it does, it will execute them.
add_action( 'test', 'func1' );
add_action( 'test', 'func2' );
do_action( 'test' ); // Executes func1 and then func2
The difference between actions and filters is that while they can both accept values, only filters will return a modified value. Actions do something that is important in and of itself; filters take a value and return a modified version of it that can be used later on. For example, to capitalize every title that's printed with the_title we can use the following piece of code:
add_filter( 'the_title', function( $title ) {
return strtoupper( $title );
});
Since we know that all functions hooked on the_title - the hook and not the function - will be executed only by apply_filters we expect to find it somewhere in function the_title. Actually that function is basically echo get_the_title and here's how get_the_title looks:
function get_the_title( $id = 0 ) {
$post = &get_post($id);
$title = isset($post->post_title) ? $post->post_title : '';
$id = isset($post->ID) ? $post->ID : (int) $id;
if ( !is_admin() ) {
if ( !empty($post->post_password) ) {
$protected_title_format = apply_filters('protected_title_format', __('Protected: %s'));
$title = sprintf($protected_title_format, $title);
} else if ( isset($post->post_status) && 'private' == $post->post_status ) {
$private_title_format = apply_filters('private_title_format', __('Private: %s'));
$title = sprintf($private_title_format, $title);
}
}
return apply_filters( 'the_title', $title, $id );
}
I'm posting the entire function because learning to look for hooks in the source code is of utmost importance for bourgeoning Wordpress developers. The source code is littered with hooks, and so they can be used to modify many aspects of the built-in functions of Wordpress. Now that you've located apply_filters( 'the_title', ... ) in the source code, you can appreciate its importance!
the_title simply echoes the value given to it by get_the_title and you can modify or even replace the value that get_the_title returns by attaching a filter to the hook the_title!
Now, I hope you don't think all that I've written so far is gratuitous. In fact, now we can easily answer your main question which was "why does it not work?"
First of all, you can never pass the_title to a function! It would be like writing somefunction( $var1, echo $var2, $var3 ). We cannot pass a value to a function by using echo, because echo sends its output to the browser.
The better attempt is the one you posted
$page_title = apply_filters('the_title',get_the_title());
But as we've seen, get_the_title has applied the_title to its return value already. You're simply applying all those functions a second time. It could result in strangeness if you have some custom filters attached to the_title or it could do nothing. So it either muddles the result or is gratuitous. Which is why you should simply do this:
$page_title = get_the_title();
Now, you also said
All is working fine except one bit of code that does not display the
title
This is confusing, because we would not expect a variable assignment to output anything! To output the title, you could do this
$page_title = get_the_title();
echo $page_title;
But as we've learned, this is really (look at the source code for the slight difference) the same as:
the_title();
So I wrote quite a lot just to come to the conclusion that you probably want to use the_title on its own. But I hope this can be a good resource on filter/action hooks as well.
Any questions are welcome.

Do I have to add_filter() before apply_filters() in Wordpress?

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!

Resources