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
Related
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
I have migrated my contents from a Yii site to Wordpress and I have all my posts filled with div tags with all kind of styles and ids and class and I want to use a pattern to remove them all. I searched the internet and came with this function, yet it does remove the closing tag, but not the opening tags which contains other attributes like style id or class:
function remove_divs($data) {
$filteredContent = preg_replace(array('/<\s*div.*?>/', '</div>'), '', $data['post_content']);
$data['post_content'] = $filteredContent;
return $data;
}
add_filter('wp_insert_post_data', 'remove_divs', 99);
Can you help me figure what isn't working?
Being inspired by the previous answer, I edited my function and it worked just fine. Here is the code:
function remove_divs($data) {
$filteredContent = preg_replace(array('/<\s*div[^>]*>/', '</div>'), '', $data['post_content']);
$data['post_content'] = $filteredContent;
return $data;
}
add_filter('wp_insert_post_data', 'remove_divs', 99);
Thank you for your answer!
You can try this pattern
$pattern = "/<div[^>]*>(.*?)<\/div>/";
$content = '<div class="test">Alpha Beta Gamma</div>Test<div class="best">Delta Gamma Eta</div>';
preg_match_all($pattern, $content, $match);
var_dump($match);
The length of the excerpt in wordpress is 55 words by default.
I can modify this value with the following code:
function new_excerpt_length($length) {
return 20;
}
add_filter('excerpt_length', 'new_excerpt_length');
So, the following call will return just 20 words:
the_excerpt();
But I can't figure out how could I add a parameter to obtain different lengths, so that I could call, for example:
the_excerpt(20);
the_excerpt(34);
Any ideas? Thanks!
uhm, answering me again, the solution was actually quite trivial. it's not possible, as far as i know, to pass a parameter to the function my_excerpt_length() (unless you want to modify the core code of wordpress), but it is possible to use a global variable. so, you can add something like this to your functions.php file:
function my_excerpt_length() {
global $myExcerptLength;
if ($myExcerptLength) {
return $myExcerptLength;
} else {
return 80; //default value
}
}
add_filter('excerpt_length', 'my_excerpt_length');
And then, before calling the excerpt within the loop, you specify a value for $myExcerptLength (don't forget to set it back to 0 if you want to have the default value for the rest of your posts):
<?php
$myExcerptLength=35;
echo get_the_excerpt();
$myExcerptLength=0;
?>
There is no way to do this as far as I have found using the_excerpt().
There is a similar StackOverflow question here.
The only thing I have found to do is write a new function to take the_excerpt()'s place. Put some variation of the code below into functions.php and call limit_content($yourLength) instead of the_excerpt().
function limit_content($content_length = 250, $allowtags = true, $allowedtags = '') {
global $post;
$content = $post->post_content;
$content = apply_filters('the_content', $content);
if (!$allowtags){
$allowedtags .= '<style>';
$content = strip_tags($content, $allowedtags);
}
$wordarray = explode(' ', $content, $content_length + 1);
if(count($wordarray) > $content_length) {
array_pop($wordarray);
array_push($wordarray, '...');
$content = implode(' ', $wordarray);
$content .= "</p>";
}
echo $content;
}
(Function credit: fusedthought.com)
There are also "advanced excerpt" plugins that provide functionality like this you can check into.
Thanks for your answer, thaddeusmt.
I am finally implementing the following solution, which offers a different length depending on the category and a counter ($myCounter is a counter within the loop)
/* Custom length for the_excerpt */
function my_excerpt_length($length) {
global $myCounter;
if (is_home()) {
return 80;
} else if(is_archive()) {
if ($myCounter==1) {
return 60;
} else {
return 25;
}
} else {
return 80;
}
}
add_filter('excerpt_length', 'my_excerpt_length');
I have added a function to functions.php on my theme.
function insertAds($content) {
$content = $content.' add goes here';
return $content;}
add_filter('the_content_feed', 'insertAds');
add_filter('the_excerpt_rss', 'insertAds');
The problem is that I'm having the add displayed under each content, and not at the end of the rss page. How can I fix that?
WordPress doesn’t offer a hook for what you want to do. In which element would you place the ad?
The usual RSS-2-Feed has meta data and items (the content). There is no other element.
See wp-includes/feed-rss2.php for details.
Update
Adjust the following code to your needs and put the file into your plugin directory:
<?php
/*
Plugin Name: Last man adding
Description: Adds content to the last entry of your feed.
Version: 0.1
Author: Thomas Scholz
Author URI: http://toscho.de
Created: 31.03.2010
*/
if ( ! function_exists('ad_feed_content') )
{
function ad_feed_content($content)
{
static $counter = 1;
// We only need to check this once.
static $max = FALSE;
if ( ! $max )
{
$max = get_option('posts_per_rss');
}
if ( $counter < $max )
{
$counter++;
return $content;
}
return $content . <<<MY_ADDITIONAL_CONTENT
<hr />
<p>Place your ad here. Make sure, your feed is still
validating</p>
MY_ADDITIONAL_CONTENT;
}
}
add_filter('the_content_feed', 'ad_feed_content');
add_filter('the_excerpt_rss', 'ad_feed_content');
Is this the effect you had in mind? As you can see, adding content is rather easy. :)
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.