Using Wordpress you can add a hook to "the_content". In my code it looks like this.
add_filter("the_content", some_func);
So, in Wordpress every time there is a post "some_func" gets ran. So, let's say "some_func" looked like this.
function some_func( $content ) {
return $content . "<div id='my_div'></div>";
}
Using an ID attribute means there can only be one HTML element. What happens is, this function gets ran for every post there is in the database. That means if I had two posts then I have two divs with the ID "my_div" and if I have Javascript that relies on those IDs then the Javascript won't act correctly. Same for CSS.
So, what I need is a way to have this function ran once and no more than once. Anyone know of a way, maybe a wrapper, or a different filter I should be using?
I haven't tested this, but perhaps you can add this to the top of your some_func function:
remove_filter( 'the_content', 'some_func' );
In theory, it would call the filter once, and remove the filter after the first call.
Related
I have been searching and found a lot of various answers, however, I have not found a definitive answer.
I need to run a function right after a post is done saving to the database. This includes every aspect of the post including post metas. I have tried to hook into save_post but that seems to run my function before post metas are saved. I have also tried post_updated and updated_postmeta, but my function doesn't seem to run on either of them.
Another thing to note, I need to have access to the post ID inside my function.
Edit, My plugin uses the Advanced Custom Fields plugin and the function I have coded uses update_field to either create new post metas or update existing one based on some stuff. This code works. When I run the function at the post_updated hook the function seems to run but nothing happens. If I add die() to the end of my function my code works, but die kills the page and all I am left with is a blank white page at the url wp-admin/post.php. So adding die allows my function to work and I am not sure why it would not work without die.
I would comment your post, but I cannot because I dont have 50 rep.
Do you mean the_post?
https://codex.wordpress.org/Plugin_API/Action_Reference/the_post
function my_the_post_action( $post_object ) {
// modify post object here
}
add_action( 'the_post', 'my_the_post_action' );
it ought to have the post Id
https://developer.wordpress.org/reference/hooks/the_post/
Okay I found how to make publish_post work.
For custom post type you need to replace the "post" by the post type slug.
Example with the custom post type "Recipe" with "recipe" slug.
add_action('publish_recipe', 'test_publish_post', 10, 2);
function test_publish_post($post_id, $post){
wp_die($post_id);
}
Don't forget to wp_die() or die(); else you will be redirected and you won't see your var_dump();
I was able to
fix my issue. It turns out that save_post does seem to run after post metas are saved. My problem actually came from something else inside my code that I was able to fix by changing how I handled that part of my script.
In pure theory my question is whether it is possible to make one php function run twice taking a different variable each time and returning it as a result.
In practice, I'm tinkering with a child theme for WordPress (and learning some PHP basics). The original theme, twentysixteen, has a function to construct a link to Google fonts using several parameters and output the final URL, which is then taken by some other function and inserted in to the head template with added HTML markup - link, href, rel, type.
In my child theme I had to replace one of the default fonts completely, so instead of reconstructing the function, I simply minimized it to just contain and output the final font URL like so:
if ( ! function_exists( 'twentysixteen_fonts_url' ) ) :
function twentysixteen_fonts_url() {
$fonts_url = 'https://fonts.googleapis.com/css?family=Merriweather:400,700,900,400italic,700italic,900italic|Inconsolata&subset=latin,latin-ext,cyrillic,greek';
return $fonts_url;
}
endif;
What I'm trying to do now is get another URL (https://code.cdn.mozilla.net/fonts/fira.css) into this function to load a third font from Mozilla's CDN alongside the Google ones.
Can't put it into a separate function with a different name, because its output does not get picked up by the head template. Using an array puts both urls into one link href.
Can somebody please point me in the right direction?
Thank you.
Twentysixtee juste use one font, and the URL is generated with twentysixteen_fonts_url ()
If you look into Twentysixtee's function.php, twentysixteen_fonts_url () is use only 2 times. It's use to include font url in editor (line 144) and in front end (line 233).
Add an other font
If you want to add an other font you need to add it in your child theme.
You could do it by adding the following code in your function.php
function my_child_theme_font_url()
{
$fonts_url = 'https://code.cdn.mozilla.net/fonts/fira.css';
return $fonts_url;
}
function my_child_theme_enqueue_scripts()
{
wp_enqueue_style( 'my_child_font', my_child_theme_font_url(), array(), null );
}
add_action( 'wp_enqueue_scripts', 'my_child_theme_enqueue_scripts' );
As suggested by #MonkeyZeus the simplest way to achieve having another webfont enqueued in such cases is leaving the first function as it is and adding a different one right after it to enqueue the needed file like so:
add_action( 'wp_enqueue_scripts', 'register_custom_plugin_styles' );
function register_custom_plugin_styles() {
wp_register_style( 'fira', 'https://code.cdn.mozilla.net/fonts/fira.css' );
wp_enqueue_style( 'fira' );
}
As for the theoretical part of my question, I understand that somehow forcing a function to run a second time and produce a different output would not force the other function using this output to run a second time as well, producing a different result. For this to work, the calling function has to be modified, not the emitting one.
Thank you #MonkeyZeus and #Jordane-CURE for your help.
I'm trying to create and if() statement that works in accordance to the kind of post (i.e., page or article) and, if page, the title of such page.
The type of post can be obtained from its class function post_class() and the title from its title function the_title().
So I know where I can get the info I need but, then, no matter what, I cannot turn this info into a string I can test. Wherever I put any of these two functions I get an output onto the page.
First, I tried:
if(strpos(post_class(), 'page')) {
//DO SOMETHING
}
Didn't work. Just had the post_class() dumped onto the page.
Then, I tried calling the function as the value of a variable:
$this_class = post_class();
And had the same result.
I've since tried a couple of other dirtier ways of doing it but to no avail. It seems wherever these WP functions are placed, they will dump their values onto the page.
Perhaps somebody out there knows how I can successfully get the type of post and title and set them to if() statements in order to trigger whatever else.
Thanks!
According to Wordpress Docs:
post_class()
When the post_class function is added to a tag within the loop, for
example >, it will print out and add
various post-related classes to the div tag.
In case you would like to be able to retrieve the value you should use
the get_post_class() function which returns that value.
Retrieve the classes for the post div as an array.
I'm using a theme framework and am trying very hard to resist the temptation of editing core files. I want to add the functionality of post formats, but I need to be able to remove certain elements for specific post formats.
function thesis_teaser_headline($post_count, $post_image) {
thesis_hook_before_teaser_headline($post_count); #hook
if ($post_image['show'] && $post_image['y'] == 'before-headline')
echo $post_image['output'];
echo '<h2 class="entry-title">' . get_the_title() . "</h2>\n";
if ($post_image['show'] && $post_image['y'] == 'after-headline')
echo $post_image['output'];
thesis_hook_after_teaser_headline($post_count); #hook
}
What would be the most efficient way to go about removing headline data for a post format such as 'link' (for example)? This function is being called to generate the content for the teasers from the homepage loop. I could just make an entire custom loop, but it won't tie in with the Thesis backend which makes it much less flexible.
Thanks!
I'm not familiar with Thesis, but I see it is calling hooks, so you could possibly put one of your functions on these, that in case you don't want any content from original thesis_teaser_headline() would turn on output buffering (ob_start()) on before hook, and clean it (ob_end_clean() or $content = ob_get_clean() if you want to alter its content, not completely replace) on after hook.
You can use the /* */ control to make the function in comment. So it will not be executed. Or put just the section you want to delete between them...
What about tweaking the html with jquery? Check on the post classes (the list of css classes that's on the div that wraps each post) to see if you can select what you need from there.
On top of all, I recommend to avoid using that framework, it's pure nightmare when you need to tweak it.
I've been stuck on this for a while. I'm working on a wordpress site where I wrote the theme from scratch, I use php calls to get the wordpress functionality that I need in certain sections.
I'm trying to use a plugin, but calling it via
echo do_shortcode('[STORE-LOCATOR]');
just isnt working. Even when I switch to the default template and post that code, it still doesnt work. It simply echoes "[STORE-LOCATOR]"
Any help would be greatly appreciated.
[STORE-LOCATOR] is probably not a 'shortcode' in WordPress sense.
I encountered this on different plugin, Stream media player. They use the same syntax as shortcodes, but they are actually not.
Try using:
echo apply_filters( 'the_content',' [STORE-LOCATOR] ');
instead of do_shortcode, and see if it helps.
do_shortcode() returns a string.
I get it working by doing:
<?php echo do_shortcode(...); ?>
This is specific to the Store Locator plugin, not do_shortcode in general.
apply_filters can be an acceptable workaround for other plugins, but this does not work for Store Locator; you will only see an empty space and some controls. This is because it is looking for that shortcode in the page/post body to determine whether or not to include all of its js references at the top of the page. And without these references, nothing will work. See the sl_head_scripts function in sl-functions.php.
To change this behavior, simply modify that function to match based upon page title instead. In my instance I wanted it only on a "shop" page, so I commented out the entire $on_sl_page test and replaced it with this:
$on_sl_page = ( strpos($pagename, 'shop') === 0 );
I then called it from my page with apply_filters as indicated in the other answer:
echo apply_filters( 'the_content','[STORE-LOCATOR]');
And this appears to work perfectly.
echo do_shortcode('[STORE-LOCATOR][/STORE-LOCATOR]');
Try using shortcode after the WordPress environment has been set up.
function my_function() {
echo do_shortcode('[STORE-LOCATOR]');
}
add_action('wp', 'my_function');
If you're writing the whole thing from scratch, you'll want to make sure that the function you create is in the root php file of your plugin. The function might look something like this, but you'll have to sub in whatever logic you're using to arrive at the store location:
<?php
function doCoolStuff () {
$var1 = "value1";
$var2 = "value2";
$output = $var1+$var2;
}
return $output;
}
add_shortcode('SOTRE-LOCATIOR', 'doCoolStuff');
?>
Then in your template put the code:
<?php echo do_shortcode('[STORE-LOCATOR]');?>
Happy coding and good luck!