Wordpress apply get_excerpt formatting to a string - php

I would like to apply wordpress' get_excerpt format to a string I pass to it.
I know the standard excerpt only works within the loop - but I'm hoping there is a function or something I'm missing that generates the excerpt when you don't manually define one.

Fixed answer:
You need wp_trim_words(). Yes - you're right. wp_trim_excerpt() doesn't play nice with passed strings.
http://codex.wordpress.org/Function_Reference/wp_trim_words
wp_trim_words( "I would like to apply wordpress' get_excerpt format to a string I pass to it. I know the standard excerpt only works within the loop - but I'm hoping there is a function or something I'm missing that generates the excerpt when you don't manually define one.", 5, '[...]' ); returns "I would like to apply[...]"
Previous answer:
WordPress uses wp_trim_excerpt() to generate excerpts.
http://codex.wordpress.org/Function_Reference/wp_trim_excerpt
You probably want some filtering on there too before you output (depending on the source of your text).

Related

WordPress esc_attr returns empty string

I have a form with an input name="title" and in functions.php I'm simply getting all the data from that form
Here's the code:
$title = $_POST['title'];
print_r($_POST);
var_dump($title);
var_dump(esc_attr($title));
The expected outcome would be the same string, but, I have no idea why, WordPress shows an empty string on the esc_attr one
Here's the output:
Array ( [title] => Swedish House Mafia – Doooon\'t You Worry Child ft. John Martin )
string(63) "Swedish House Mafia – Doooon\'t You Worry Child ft. John Martin"
string(0) ""
It's not related to the input field being called title or the variable being called $title and conflicting with other stuff in WordPress, I have no idea why the escape functions are not working.
Let's walk through the thought process of what might be a contributor to this problem.
With the code as presented, nothing in your code is affecting the variable or $_POST. You are just echoing out each variable one after the other (as you presented above).
That means something is wonky with esc_attr. What could the possibilities be:
The function is not available yet.
Something is overriding the returned value and behavior.
Possibility 1 is not feasible because you are working in the theme's function.php file. WordPress has loaded the escaping functions by the time the theme is called. To check that, you can do:
echo function_exists( 'esc_attr' ) ? 'yes, loaded' : 'whoops, not loaded';
That leaves us with Possibility 2. Let's look at the function in WordPress Core.
function esc_attr( $text ) {
$safe_text = wp_check_invalid_utf8( $text );
$safe_text = _wp_specialchars( $safe_text, ENT_QUOTES );
/**
* Filters a string cleaned and escaped for output in an HTML attribute.
*
* Text passed to esc_attr() is stripped of invalid or special characters
* before output.
*
* #since 2.0.6
*
* #param string $safe_text The text after it has been escaped.
* #param string $text The text prior to being escaped.
*/
return apply_filters( 'attribute_escape', $safe_text, $text );
}
There are 3 functions that interact with the text. I don't see anything in the first two. However, look at the filter event attribute_escape. Any other plugin or theme can register to that event and change the returned text, including returning an empty string.
That sounds like a highly probable candidate.
Next Steps
Something is stepping on (filtering) the text when it's passed through esc_attr(). You need to eliminate all variables, strip the site down to the bare bones basics, and then see if the problem resolves itself.
The following steps are a process to discover where the problem lies. It's an elimination methodology. As you walk through it, it'll help you to pinpoint what component (theme, plugin, or even core) is affecting it.
Step 1: Deactive ALL plugins
Step 2: Move your code to the top of the theme's functions.php file. Why? It eliminates anything in the theme from affecting the text as the functions.php file loads first.
Step 3: Manually add the title to $_POST['title']. Put as the first line in functions.php: $_POST['title'] = "Swedish House Mafia – Doooon't You Worry Child ft. John Martin";.
Step 4: Refresh the browser.
Is it working properly, meaning esc_attr() returns the string?
Nope, the problem is still happening.
Hum, that means something then in WordPress Core is not playing nice. You could investigate by digging into Core and finding what is causing the conflict. Or reload a fresh version of it.
Yes, the problem is gone
Add in one plugin at a time. Refresh the browser. Check if the problem reappears. If yes, then you found the plugin that is causing it.
Now what?
Once you find the culprit, you can take steps to fix the problem. Then you can remove the code from functions.php file that I had you add.
This might be edge case, but I had the same issue and the problem was with multibyte characters.
My code looked something like this: esc_attr( substr( $desc, 0, 152 ) )
Without esc_attr() it worked but I sometimes got the �-character. When running it through esc_attr() I got nothing back.
So my solution was to replace substr() with mb_substr(). Read about the difference in this answer.
Retrieve data with this code
echo esc_attr( $title );

Tag Array Sorting issue

10/25/2012 - Still Not solved! Please see below:
My client has a WordPress Tag Cloud (tag array) with tags which include ["] character as well as [The] prefix for some tags. I.e:
"rose"
"autumn"
The Abby
The Cloud
The Elephant
Obviously all the tags enclosed in the quotations marks ["] are sorted on the top of the list and all the words starting with [The] prefix are sorted somewhere around the letter [T] (following the logical ASC order).
It was sprinkled on me that: "All tags (in the WP tag cloud) have to be ordered Ascending but those which contain the [" "] or [The] characters have to be sorted with all other tags in the chronological order, ignoring the ["] and [The] prefix.
I looked into the WP core function:
**function wp_generate_tag_cloud**
but I have no idea where to start. In the raw SQL statement, I could probably use the trim() to filter out the [" "] and [The] characters form the tag cloud array but that is only a thought which I have no idea how to apply.
wp_generate_tag_cloud() invokes a filter named tag_cloud_sort, which can override the sort order specified in the $args parameter. The tag_cloud_sort filter receives an array of tags and the actual $args parameter passed to wp_generate_tag_cloud(), so it can inspect the full settings of the wp_generate_tag_cloud() invocation and adjust its behavior accordingly.
You could try something like this:
function custom_tag_sort($tags, $args) {
if ($args['orderby'] != 'name') {
// do not reorder if sort order is not by name.
// wp_generate_tag_cloud() is smart enough to notice order
// is not changed and will proceed with its regular sort logic.
return $tags;
}
uasort($tags, 'custom_tag_sort_compare');
}
function custom_tag_sort_compare($a, $b) {
return strnatcasecmp(
custom_tag_sort_normalize($a->name),
custom_tag_sort_normalize($b->name)
);
}
function custom_tag_sort_normalize($tag) {
// strip quote marks
$tag = trim($tag, '"');
// strip leading definitive article
$tag = preg_replace('/^\s*the\s+/i', '', $tag);
return $tag;
}
add_filter('tag_cloud_sort', 'custom_tag_sort');
Disclaimer: I've written this after only a cursory inspection of the wp_generate_tag_cloud() function. I haven't tested it on a live WordPress installation; I have only verified that the sorting function works correctly on your sample tag cloud:
The Abby
"autumn"
The Cloud
The Elephant
"rose"
ok so you want to avoid modifying the core code of wordpress... when your client hits the update button after you told him not to, then your going to have to go in and mess with it again.. use action hooks instead. there is conveniently one for hooking into the output for the tag cloud function. add this to your themes functions file
function tagCloudFilter($tagCloudString, $args)
{
$tagCloudString = str_replace('The','', $tagCloudString);
$tagCloudString = str_replace('"','', $tagCloudString);
}
add_filter('wp_tag_cloud', 'tagCloudFilter', 10, 2);
That will atleast get rid of the stuff you dont want. as far as sorting it im not to sure but this should get you on your way. it may be easier to sort it with jquery
If you really want to modify the core code run a foreach loop in the tag array before its formatted and use the str_replaces from above in that loop.. The just run sort() on that array and you should be good. But if it were me i would go with the half solution and not have it alphabetized than to modify the wordpress core
Here's a thought:
you could copy the original tag_cloud function and create your own on your functions.php.
You make the changes you want to make and add this filter inside the function:
$return = apply_filters( 'YOUR_tag_cloud_function', $return, $args );
And then create the previous filter to add your function to the hook:
add_filter('wp_tag_cloud', 'YOUR_tag_cloud_function');
I don't know if it works, I didn't test it. What do you think?

Smarty Postfilters / Prefilters how to apply on template before output

I am rather confused about how to use post / pre filters with smarty.
What I need to do, is to search and replace certain elements in the page before it is displayed. I would rather like to do this right before $smarty->display is called. That means, before it gets saved to disk, but after it has been compiled (so, postfilter).
Example postfilter function:
function smarty_postfilter_replace($tpl_output, $search, $replace)
{
return str_replace($search, $replace, $tpl_output);
}
How do I apply this right before smarty output. I have tried after looking at the Smarty documentation ( http://www.smarty.net/docsv2/de/advanced.features.postfilters.tpl ) and some other examples, but none seems to be working.
can someone give me an example code on how to do this, and how to pass parameters to the filter ($search, $replace).
Thanks
The post-filter is probably the most misunderstood filter. While the pre-filter runs on the uncompiled template source code, and the output-filter runs on the evaluated output (y'know, the generated HTML), the post-filter is run as part of the compiler - it's fed the PHP produced by the compiler. I'm not sure what anyone would do with this. In any case, it's not what you're looking for.
Use the output-filter to replace your content. If you're using caching, it is run before writing to cache, if you don't have any non-caching elements. If you have non-caching elements (like {nocache} or variables with nocache flag), the output filter is run after the cache has been evaluated (pretty much on every request).

How do I get the_time as one string of numbers in wordpress?

I'm using wordpress. I remember messing with the code of <?php the_time('d.m.y') ?> and getting something like "2011161457" (2011 16-1 4:57) I don't remember how I did it. I want just the numbers anyone knows how to do it?
Look at the PHP date() man page. Wordpress's time_time() is basically just a wrapper around that and uses the exact same formating options.

How does gettext handle dynamic content?

In php (or maybe gettext in general), what does gettext do when it sees a variable to dynamic content?
I have 2 cases in mind.
1) Let's say I have <?=$user1?> poked John <?=$user2?>. Maybe in some language the order of the words is different. How does gettext handle that? (no, I'm not building facebook, that was just an example)
2) Let's say I store some categories in a database. They rarely, but they are store in a database. What would happen if I do <?php echo gettext($data['name']); ?> ? I would like the translators to translate those category names too, but does it have to be done in the database itself?
Thanks
Your best option is to use sprintf() function. Then you would use printf notation to handle dynamic content in your strings. Here is a function I found on here a while ago to handle this easily for you:
function translate()
{
$args = func_get_args();
$num = func_num_args();
$args[0] = gettext($args[0]);
if($num <= 1)
return $args[0];
return call_user_func_array('sprintf', $args);
}
Now for example 1, you would want to change the string to:
%s poked %s
Which you would input into the translate() function like this:
<?php echo translate('%s poked %s', $user1, $user2); ?>
You would parse out all translate() functions with poEdit. and then translate the string "%s poked %s" into whatever language you wanted, without modifying the %s string placeholders. Those would get replace upon output by the translate() function with user1 and user2 respectively. You can read more on sprintf() in the PHP Manual for more advanced usages.
For issue #2. You would need to create a static file which poEdit could parse containing the category names. For example misctranslations.php:
<?php
_('Cars');
_('Trains');
_('Airplanes');
Then have poEdit parse misctranslations.php. You would then be able to output the category name translation using <?php echo gettext($data['name']); ?>
To build a little on what Mark said... the only problem with the above solution is that the static list must be always maintained by hand and if you add a new string before all the others or you completely change an existing one, the soft you use for translating might confuse the new strings and you could lose some translations.
I'm actually writing an article about this (too little time to finish it anytime soon!) but my proposed answer goes something like this:
Gettext allows you to store the line number that the string appears in the code inside the .po file. If you change the string entirely, the .po editor will know that the string is not new but it is an old one (thanks to the line number).
My solution to this is to write a script that reads the database and creates a static file with all the gettext strings. The big difference to Mark's solution is to have the primary key (let's call it ID) on the database match the line number in the new file. In that case, if you completely change one original translation, the lines are still the same and your translator soft will recognize the strings.
Of course there might be newer and more intelligent .po editors out there but at least if yours is giving you trouble with newer strings then this will solve them.
My 2 cents.
If you have somewhere in your code:
<?=sprintf(_('%s poked %s'), $user1, $user2)?>
and one of your languages needs to swap the arguments it is very simple. Simply translate your code like this:
msgid "%s poked %s"
msgstr "%2$s translation_of_poked %1$s"

Categories