wordpress: actions, filters & hooks - wordpress

I'm quite new to this (understanding the WP Guts), and I wanted to understand the Hooks and Filters better, I can't get it right from Codex.
I did a simple test,
the idea is to override the get_title() method in order to erase the "Protected: " sentence from the title if the page is protected, there is a protected_title_format filter, and I thought using it ...
that line in post-template.php specifies:
$protected_title_format = apply_filters('protected_title_format', __('Protected: %s'));
for what I could get from CODEX, I need to remove that filter and add my own, like
remove_action('protected_title_format');
apply_filters('protected_title_format', __('MY OWN PAGE Protected: %s'));
using, off course something like
// Removing action
function remove_title_action() {
remove_action('protected_title_format','get_the_title',3);
}
add_action('init','remove_title_action');
// Adding custom function
add_action('protected_title_format','fancy_title', 3, 4);
function fancy_title($id = 0) {
$post = &get_post($id);
$title = $post->post_title;
echo "I'm the king of the world!... >" . $title . "< & >" . $post . "<";
if ( !is_admin() ) {
if ( !empty($post->post_password) ) {
$protected_title_format = apply_filters('protected_title_format', __('MY OWN PAGE Protected: %s'));
$title = sprintf($protected_title_format, $title);
}
}
return apply_filters( 'the_title', $title, $post->ID );
}
I can get the echo to output, but I dont get the $id (and for that, no $title or $post), this method is a copy of get_title() stripping out everything but the protected part string.
Can anyone care to explain me how this works?
Thank you
P.S. I want to learn, this is the idea of this question, not someone to tell me "Hey, just go to post-template.php and change it", because then I would ask "How about when I update WP...?" !

You can actually do this much more simply than what you're trying. You're on the right track though.
Basically, what you want to do is create your own function that will strip out the "Protected: " part of the WordPress titles. The easiest way to do this is to simply create a function that uses preg_replace() to search for the "Protected: " text and strip it. You could just as easily have it auto-replace the string with your own text.
Here's a sample function that does that. We're taking the $title as a parameter and returning the modified version of it.
function remove_protected_text($title) {
$match = '/Protected: /';
$replacement = '';
$title = preg_replace($match, $replacement, $title);
return $title;
}
The next thing we want to do is actually add our function to a filter hook. The filter hook that we're interested in in this cases is 'the_title'. So, we add the following line below the function we just wrote:
add_filter( 'the_title', 'remove_protected_text', 10);
This adds our function remove_protected_text() to the 'the_title' filter. In this case I've used the third argument to give our filter a priority of 10. This is totally optional, but I figure this filter is a pretty low priority.
So all together our code should look like this:
function remove_protected_text($title) {
$match = '/Protected: /';
$replacement = '';
$title = preg_replace($match, $replacement, $title);
return $title;
}
add_filter( 'the_title', 'remove_protected_text', 10);
Adding that code to the functions.php file in your theme will allow it to work. You can write filters like this for most of the parts of WordPress that output text.
Update
Here's a revised version of the function that should get the translated string of "Protected: " and remove it:
function remove_protected_text($title) {
$protected = __('Protected: %s');
$protected = preg_replace('/ %s/', '', $protected);
$match = "/${protected}/";
$replacement = '';
$title = preg_replace($match, $replacement, $title);
return $title;
}
add_filter( 'the_title', 'remove_protected_text');
Basically the only change here is that we are using the __() function to translate the protected string and then striping out the extra bits. This is kind of hackish, and I'm sure there's a better way to do it, but it does work in my testing.
I tested this out on a Spanish version of WordPress and it worked, so let me know if it works for your project.

Related

Show shortcode for a given word only once

I'm trying to implement a custom functionality to a wordpress shortcode plugin that shows a tooltip for specified words by automatically calling for information from Wikipedia.
Currently my code snippet works fine, but it shows the tooltips for each occurrence of the word in an article. For example if I specified the word : "dessert" in an array it will show the tooltip for all 5 words "dessert" found in the post. I'm looking for a way to limit the tooltip shortcode to be applied only once per word ( in this case "dessert" which has been specified in the array).
Me code snippet is this:
function add_wikitips($content) {
if( is_single() && is_main_query() ) {
$arr = array('dessert');
for ($i = 0; $i < count($arr); $i++) {
$content = str_replace($arr[$i], '[wiki]'.$arr[$i].'[/wiki]', $content);
}
}
return $content;
}
add_filter('the_content', 'add_wikitips');
I tried adding ob_end_clean(); then
static $content = null;
if ($content === null) {
return $content;
}
, but these methods didn't work. Probably because I didn't implement them properly.
Thanks a lot in advance for any advice and suggestions.
Probably, you can try this: Using str_replace so that it only acts on the first match?
You want the first work to have Wiki link. So replace the first occurrence only when you are doing str_replace()
May be like:
function str_replace_first($from, $to, $content)
{
$from = '/'.preg_quote($from, '/').'/';
return preg_replace($from, $to, $content, 1);
}
echo str_replace_first('abc', '123', 'abcdef abcdef abcdef');
// outputs '123def abcdef abcdef'
Mentioned in Karim's amswer

Wordpress: add custom params to all URLS

I have an addition to url e.g. /products/myproduct/?v=iphone-x/transparent/*/Green
So what I need is for wordpress to add the ?v=iphone-x/transparent/*/Green to all links on the page (only '<a href="">'s, no 'img src=""' or others)
I have managed to do that, but it's a little "dirty". Is there any neat function to add the parameter to all links?
The code I have is as follows:
function callback($buffer) {
// modify buffer here, and then return the updated code
$temp = explode('href="', $buffer);
$buffer = $temp[0];
array_shift($temp);
foreach($temp as $t){
$tt = explode('"', $t, 2);
$buffer .= 'href="'.$tt[0].'?v='.$_GET['v'].'"'.$tt[1];
}
return $buffer;
}
function buffer_start() { ob_start("callback"); }
function buffer_end() { ob_end_flush(); }
add_action('wp_head', 'buffer_start');
add_action('wp_footer', 'buffer_end');
One way you can achieve this is to hook into "the_content" filter. By using regexp with preg_replace_callback function you can get decent results.
function add_para( $content ) {
$content = preg_replace_callback(
"/href=(?>'|\")([^\"']+)(?>'|\")/",
function($m) {
print_r($m);
return "href='".$m[1]."/additional-param'";
},
$content);
return $content;
}
add_filter( 'the_content', 'add_para', 0 );
However, you might run into some issues particularly if your content is not formatted probably (extra spaces, missing tags .. etc).
So the alternative is either to us a JS approach (jQuery for example), or using PHP DOM parser like: PHP Simple HTML DOM Parser

Wordpress shortcode linked to another DB

First thing first, this is my first shortcode attempt.
It is worthed mention that I'm also using woocommerce on my website.
Let's start:
I know that to add shortcodes into wordpress, you need to write something similar to the code below into the functions.php file: (this is just an example)
function myshortcode() {
return "This is a shortcode example!";
}
add_shortcode( 'mycode', 'myshortcode' );
and if i add [mycode] into the wordpress page editor, the preview shows my text correctly.
But what if i need to use a variable (in my case woocommerce order number) in the shortcode?
Let's say i need to compare woocommerce_order_number with my_custom_uid (inserted into another database, outside wordpress).
I usually use a db request like the one below, and usually it works fine (as before, this is only an example):
select 'my_custom_uid' from 'my_custom_database' where 'woocommerce_order_number' = '1234'
The problem is that i don't know the woocommerce_order_number (it changes everytime!), because this shortcode needs to go inside an html email body i need to send out to customers after they placed the order.
How can i get the customer woocommerce order (variable that changes everytime) so that i will be able to use it into my shortcode to link it to my custom_uid?
If the question is not clear enough, please feel free to ask for clarification!
thanks a lot
I don't see a reason to use a shortcode. If you want to add something to an email, you should use one of the hooks in the email. For example:
function kia_display_email_order_meta( $order, $sent_to_admin, $plain_text ) {
$some_field = get_post_meta( $order->id, '_some_field', true ),
$another_field = get_post_meta( $order->id, '_another_field', true ),
if( $plain_text ){
echo 'The value for some field is ' . $some_field . ' while the value of another field is ' . $another_field;
} else {
echo '<p>The value for <strong>some field</strong> is ' . $some_field. ' while the value of <strong>another field</strong> is ' . $another_field . '</p>';
}
}
add_action('woocommerce_email_customer_details', 'kia_display_email_order_meta', 30, 3 );
Note that the $order object is the first parameter available to the kia_display_email_order_meta function. So you'd be able to get the ID via $order->id. This should add the data after the customer address details, but there are other hooks available if woocommerce_email_customer_details isn't appropriate.
I finally managed to solve this, and here's what i did if someone is interested:
<?PHP
add_action('fue_before_variable_replacements', 'register_variable_replacements', 11, 4);
add_action('fue_email_variables_list', 'email_variables_list');
/**
* This gets called to replace the variable in the email with an actual value
* #param $var - Modify this: array key is the variable name, value is the replacement
*/
function register_variable_replacements($var, $email_data, $queue_item, $email){
global $wpdb;
// Look up UID from order number
$orderNumber = $var->get_variables()['order_number'];
$sql = " //Your sql statement here...//";
$results = $wpdb->get_results($sql);
$UID = $results[0]->meta_value;
$variables = array(
'uid' => $UID
);
$var->register($variables);
}
function email_variables_list($email)
{
global $woocommerce;
?>
<li class="var hideable var_subscriptions">
<strong>{uid}</strong>
<img class="help_tip" title="<?php _e('Order UID', 'follow_up_emails'); ?>" src="<?php echo $woocommerce->plugin_url(); ?>/assets/images/help.png" width="16" height="16"/>
</li>
<?php
}
Now on your follow up email plugin, you can use {uid} as a variable and this will be replaced with the correct value on every email.
I though the best way was to use short code, but then i discovered this filter and i think this is the best way to handle this. This code is also pretty flexible and you can add as many variables as you want.
Hope this can help someone.

hatom-entry errors on the Google snippet test

Almost sure that I'm not the first one that has this question but when I test my (WordPress) page on Google Snippet Test Tool I got hatom-enty errors like:
hatom-feed
hatom-entry:
Fout: At least one field must be set for HatomEntry.
Fout: Missing required field "entry-title".
Fout: Missing required field "updated".
Fout: Missing required hCard "author".
I found some tutorials about this but that is for standard WordPress themes. I'm using Inovado from ThemeForest and I can't figure out in which file I have to edit this data.
Someone familiar with this?
I also got problems with snippet review... Good in testresults but doesn't show up in de Google Search Results. Don't know why...
You can Add this code to the function.php file in your theme's directory and it will solve the problems.
//mod content
function hatom_mod_post_content ($content) {
if ( in_the_loop() && !is_page() ) {
$content = '<span class="entry-content">'.$content.'</span>';
}
return $content;
}
add_filter( 'the_content', 'hatom_mod_post_content');
//add hatom data
function add_mod_hatom_data($content) {
$t = get_the_modified_time('F jS, Y');
$author = get_the_author();
$title = get_the_title();
if(is_single()) {
$content .= '<div class="hatom-extra"><span class="entry-title">'.$title.'</span> was last modified: <span class="updated"> '.$t.'</span> by <span class="author vcard"><span class="fn">'.$author.'</span></span></div>';
}
return $content;
}
add_filter('the_content', 'add_mod_hatom_data');
The code contains 2 functions. The first function will use the WordPress filter hook for “the_content” to add the class of “entry-content” to the article. To add in the other essential hAtom fields, the second function will add a short sentence to the end of your post article, which contains updated time, post title and author, with required microdata.

Wordpress wp-post-image class remover

We use the_post_thumbnails to get our images displayed.
We want to use them with a specific class called "test" but we cant manage it!
We use this code:
<?php the_post_thumbnail('pin-photo-large', array('class' => 'test')); ?>
But the output of the image seems like this:
class="test wp-post-image"
How can we overcome this issue and get an output like this ?
class="test"
Update: Add this to your functions.php file:
remove_action( 'begin_fetch_post_thumbnail_html', '_wp_post_thumbnail_class_filter_add' );
Explanation: In media.php, the _wp_post_thumbnail_class_filter function adds the wp-post-image class to post thumbnails. By removing the begin_fetch_post_thumbnail_html action hook (located in default-filters.php), the function will no longer apply to the_post_thumbnail.
Old answer below:
I also searched for a proper way to filter out the wp-post-image class, alas to no avail. The only solution I figured out was to edit a (gasp!) core file: media.php and replace this:
function _wp_post_thumbnail_class_filter( $attr ) {
$attr['class'] .= ' wp-post-image';
return $attr;
}
by this:
function _wp_post_thumbnail_class_filter( $attr ) {
return $attr;
}
There's certainly a better way to do this than to patch a core file, but this can be a good temporary solution.
Add this to your functions.php file :
function remove_post_image_class($content) {
$post_string = $content;
$post_string = preg_replace('/<img class=".*?"/', '<img', $post_string);
return $post_string;
}
add_filter( 'the_content', 'remove_post_image_class' );
Enjoy

Resources