Archive for the ‘Code’ Category.

For those of you helping me with testing out SFC trunk, there’s a new one in there for you.

[fb-activity]

The activity feed widget is one of Facebook’s recent addition to their social widgets. Basically, it shows who’s liked and shared your posts recently. The idea is to encourage liking, I suppose.

The latest plugin adds this to WordPress as a sidebar widget, as a shortcode (fb-activity), and enables it for direct theme usage with the sfc_activity_feed() function.

As always, this is trunk beta code here, so if you do use it, don’t expect it to be 100% yet. Still, it works well enough. 🙂

Get it here: http://plugins.svn.wordpress.org/simple-facebook-connect/trunk/.

Shortlink:

I sort of snuck this into Simple Facebook Connect 0.18 for you all.

If you go to http://facebook.com/insights, then one of the new things they have is “Insights for your Domain”. Basically, this lets you hook the Facebook Insights system up to your own domain.

They give you meta info to add to your site so as to define who has control over that site. This lets them know who should be able to see the insights and such.

Well, if you use SFC, that information is already there for you. Just go over to the insights page, put in your domain, then “Link With” your SFC Application. No need to add anything else to your site, the base SFC plugin is adding that fb:app-id meta tag for you automatically (once you’ve configured SFC itself, of course).

Note that you may have to link it a few times before it actually takes. Facebook has to retrieve your webpage to verify the connection, and it seems to time out rather easily. Took me several tries and I kept getting messages like “Bad Domain” and such. But it finally worked.

Since I just added it, I don’t have any data yet to show you, but basically it will keep track of the “Shares” from your site, so those Share buttons will now give you some useful information and feedback on the Insights page.

Enjoy.

Additional: Note that since I wrote this post, Insights never actually updated or worked at all. Facebook basically dropped the ball and never actually finished this code or turned it on or something. I seriously wonder exactly WTF they are doing over there sometimes. Anyway, here’s the bug if you want to track it: http://bugs.developers.facebook.com/show_bug.cgi?id=10174

Shortlink:

Took a look at @anywhere a little while ago. With my experience working with the Facebook javascript methods, it was rather trivial to incorporate the new javascript functionality from Twitter into Simple Twitter Connect, so that was exactly what I did.

Simple Twitter Connect 0.7 now automatically enables your site to run the new @anywhere code. With zero extra configuration steps.

All the example javascript code they give on the @anywhere documentation site will work immediately.

I even added an example plugin (STC-Linkify) to demonstrate how it works. Activate that plugin and it will automatically link any Twitter usernames on your page to Twitter. So when I type @ottodestruct or @otto42, they’re automatically linked. Neat, eh?

I’ll be adding several more @anywhere plugins to the package soon, but those will be in the next update. If you want them in advance, then you can see the trunk version of the plugin and pick and choose which you want. I’ve already added the Follow Button widget to there, so you can go get it now if you like. I’m already using it here in my sidebar. 🙂

Shortlink:


I’m working on a Simple Google Connect for the future. But for now, here’s a simple Buzz Button using the functionality they announced today.

sgc-buzz.php

<?php
/*
Plugin Name: SGC - Buzz Button  
Plugin URI: http://ottopress.com/wordpress-plugins/simple-google-connect
Description: Adds a Google Buzz button to your content.
Author: Otto
Version: 0.1
Author URI: http://ottodestruct.com
License: GPL2

    Copyright 2010  Samuel Wood  (email : otto@ottodestruct.com)

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License version 2, 
    as published by the Free Software Foundation. 
    
    You may NOT assume that you can use any other version of the GPL.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
    
    The license for this software can likely be found here: 
    http://www.gnu.org/licenses/gpl-2.0.html
    
*/

wp_enqueue_script( 'google-buzz-button', 'http://www.google.com/buzz/api/button.js', array(), '1', true );

/**
 * Simple GB button
 *
 * @param int $post_id An optional post ID.
 */
function get_buzz_button($id = 0) {
	$url = get_permalink($id);
	$out = '<a title="Post on Google Buzz" class="google-buzz-button" href="http://www.google.com/buzz/post" data-button-style="normal-count" data-url="';
	$out .= $url;
	$out .= '"></a>';
	return $out;
}

function buzz_button($source = '', $id = 0) {
	echo get_buzz_button($id);
}

/**
 * Simple buzz button as a shortcode
 *
 * Example use: buzz id="123"
 */
function buzz_button_shortcode($atts) {
	extract(shortcode_atts(array(
		'id' => 0,
	), $atts));
	return get_buzz_button($id);
}

add_shortcode('buzz', 'buzz_button_shortcode');

function buzz_button_automatic($content) {
	$button = get_buzz_button();
	$content = $content . $button;
	return $content;
}
add_filter('the_content', 'buzz_button_automatic', 30);
Shortlink:

The Custom Background screen

The Custom Background screen is easy to add to any theme

Quick and simple way to add the new custom background selector to your WordPress 3.0 theme.

add_custom_background();

Seriously. That’s it. Just add that to the theme’s functions.php file.

Details

Okay, so your theme does need to have the normal wp_head() call in it. For those of you more CSS inclined, this basically creates CSS code for the body and adds that code to the head output directly. Voila, your theme gets styled.

Note that you will need to also not define your own background stuff in the theme for this to work. If the user tries to put in a solid color background and you define an image background, then the color won’t work or be visible over your image. Best to not put anything background related onto the body at all, in fact.

Customization

For those more inclined to customize things, there’s actually three parameters you can use:

function add_custom_background($header_callback = '', $admin_header_callback = '', $admin_image_div_callback = '')

Each of these are references to a callback function. If you use them, then you need to define your own callback functions to replace the default ones.

The header_callback function is what builds and outputs the CSS. The function takes no parameters, but it can use get_background_image() and get_background_color() to retrieve the necessary information. From this information, the function should produce and output (echo) the necessary <style> block to show the image.

The admin_header_callback function is called in the head section of the admin side of things; in the Background section to be specific. The admin_image_div_callback is similar, called immediately after displaying “This is your current background” on that page, where the image is displayed. If used, the admin_image_div_callback replaces the display of the current background image, so you custom callback should produce that instead.

These two admin callbacks can be used to modify the Background admin page, to add custom text or information, etc.

But generally, most themes won’t need this level of customization. Just add the basic code to the theme and the defaults are good to go. 🙂

Shortlink:

Seems that some people don’t know much about kses. It’s really not all that complicated, but there doesn’t seem to be a lot of documentation around for it, so what the hell.

The kses package is short for “kses strips evil scripts”, and it is basically an HTML filtering mechanism. It can read HTML code, no matter how malformed it is, and filter out undesirable bits. The idea is to allow some safe subset of HTML through, so as to prevent various forms of attacks.

However, by necessity, it also includes a passable HTML parser, albeit not a complete one. Bits of it can be used for your own plugins and to make things a bit easier all around.

Note that the kses included in WordPress is a modified version of the original kses. I’ll only be discussing it here, not the original package.

Filtering

The basic use of kses is as a filter. It will eliminate any HTML that is not allowed. Here’s how it works:

$filtered = wp_kses($unfiltered, $allowed_html, $allowed_protocols);

Simple, no?

The allowed html parameter is an array of HTML that you want to allow through. The array can look sorta like this:

$allowed_html = array(
	'a' => array(
		'href' => array (),
		'title' => array ()),
	'abbr' => array(
		'title' => array ()),
	'acronym' => array(
		'title' => array ()),
	'b' => array(),
	'blockquote' => array(
		'cite' => array ()),
	'cite' => array (),
	'code' => array(),
	'del' => array(
		'datetime' => array ()),
	'em' => array (), 'i' => array (),
	'q' => array(
		'cite' => array ()),
	'strike' => array(),
	'strong' => array(),
);

As you can see, it’s rather simple. The main array is a list of HTML tags. Each of those points to an array of allowable attributes for those tags. Each of those points to an empty array, because kses is somewhat recursive in this manner.

Any HTML that is not in that list will get stripped out of the string.

The allowed protocols is basically a list of protocols for links that it will allow through. The default is this:

array ('http', 'https', 'ftp', 'ftps', 'mailto', 'news', 'irc', 'gopher', 'nntp', 'feed', 'telnet')

Anything else goes away.

That $allowed_html I gave before may look familiar. It’s the default set of allowed HTML in comments on WordPress. This is stored in a WordPress global called $allowedtags. So you can use this easily like so:

global $allowedtags;
$filtered = wp_kses($unfiltered, $allowedtags);

This is so useful that WordPress 2.9 makes it even easier:

$filtered = wp_kses_data($unfiltered);
$filtered = wp_filter_kses($unfiltered); // does the same, but will also slash escape the data

That uses the default set of allowed tags automatically. There’s another set of defaults, the allowed post tags. This is the set that is allowed to be put into Posts by non-admin users (admins have the “unfiltered_html” capability, and can put anything they like in). There’s easy ways to use that too:

$filtered = wp_kses_post($unfiltered);
$filtered = wp_filter_post_kses($unfiltered); // does the same, but will also slash escape the data

Note that because of the way they are written, they make perfect WordPress filters as well.

add_filter('the_title','wp_kses_data');

This is exactly how WordPress uses them for several internal safety checks.

Now, this is all very handy, but what if I’m not filtering? What if I’m trying to get some useful information out of HTML? Well, kses can help you there too.

Parsing

As part of the filtering mechanism, kses includes a lot of functions to parse the data and to try to find HTML in there, no matter how mangled up and weird looking it might be.

One of these functions is wp_kses_split. It’s not something that is useful directly, but it is useful to understand how kses works. The wp_kses_split function basically finds anything that looks like an HTML tag, then passes it off to wp_kses_split2.

The wp_kses_split2 function takes that tag, cleans it up a bit, and perhaps even recursively calls kses on it again, just in case. But eventually, it calls wp_kses_attr. The wp_kses_attr is what parses the attributes of any HTML tag into chunks and then removes them according to your set of allowed rules. But here’s where we finally find something useful: wp_kses_hair.

The wp_kses_hair function can parse attributes of tags into PHP lists. Here’s how you can use it.

Let’s say we’ve got a post with a bunch of images in it. We’d like to find the source (src) of all those images. This code will do it:

global $post;
if ( preg_match_all('/<img (.+?)>/', $post->post_content, $matches) ) {
        foreach ($matches[1] as $match) {
                foreach ( wp_kses_hair($match, array('http')) as $attr)
                	$img[$attr['name']] = $attr['value'];
                echo $img['src'];
        }
}

What happened there? Well, quite a bit, actually.

First we used preg_match_all to find all the img tags in a post. The regular expression in preg_match_all gave us all the attributes in the img tags, in the form of a string (that is what the “(.+?)” was for). Next, we loop through our matches, and pass each one through wp_kses_hair. It returns an array of name and value pairs. A quick loop through that to set up a more useful $img array, and voila, all we have to do is to reference $img[‘src’] to get the content of the src attribute. Equally accessible is every other attribute, such as $img[‘class’] or $img[‘id’].

Here’s an example piece of code, showing how kses rejects nonsense:

$content = 'This is a test. <img src="test.jpg" class="testclass another" id="testid" fake fake... / > More';
if ( preg_match_all('/<img (.+?)>/', $content, $matches) ) {
        foreach ($matches[1] as $match) {
                foreach ( wp_kses_hair($match, array('http')) as $attr)
                	$img[$attr['name']] = $attr['value'];
                print_r($img); // show what we got
        }
}

The resulting output from the above:

Array
(
    [src] => test.jpg
    [class] => testclass another
    [id] => testid
    [fake] =>
)

Very nice and easy way to parse selected pieces of HTML, don’t you think?

Overriding kses

Want to apply some kind of filter of your own to things? WordPress kindly adds a filter hook to all wp_kses calls: pre_kses.

function my_filter($string) {
	// do stuff to string
	return $string;
}
add_filter('pre_kses', 'my_filter');

Or maybe you want to add your own tags to the allowed list? Like, what if you wanted comments to be able to have images in them, but (sorta) safely?

global $allowedtags;
$allowedtags['img'] = array( 'src' => array () );

What if you want total control? Well, there’s a CUSTOM_TAGS define. If you set that to true, then the $allowedposttags, $allowedtags, and $allowedentitynames variables won’t get set at all. Feel free to define your own globals. I recommend copying them out of kses.php and then editing them if you want to do this.

And of course, if you only want to do a small bit of quick filtering, this sort of thing is always a valid option as well:

// only allow a hrefs through
$filtered = wp_kses($unfiltered, array( 'a' => array( 'href' => array() ) ));

Hopefully that answers some kses questions. It’s not a complete HTML parser by any means, but for quick and simple tasks, it can come in very handy.

Note: kses is NOT 100% safe. It’s very good, but it’s not a full-fledged HTML parser. It’s just safer than not using it. There’s always the possibility that somebody can figure out a way to sneak bad code through. It’s just a lot harder for them to do it.

Shortlink:

For ages, theme authors have been adding code like this to their theme’s header.php files:

<link rel="alternate" type="application/rss+xml" title="<?php bloginfo('name'); ?> RSS Feed" href="<?php bloginfo('rss2_url'); ?>" />

No need for that any more. Remove that stuff, make sure you’ve got the wp_head() call in the header (like you should anyway), then add this to the theme’s functions.php file instead:

add_theme_support( 'automatic-feed-links' );

This automatically adds the relevant feed links everywhere on the whole site. Standard feed, comments links, category and tag archives, everything as it should be.

Shortlink:

If you subscribe to the Twitter account that is hooked up to my blog entries, then you might have saw a test tweet earlier. That’s because I was testing. Now I’m not, and I just pushed Simple Twitter Connect 0.5 out for release.

New features:

– Made the comments plugin smarter. The Settings page allows the “Send to Twitter” button on comments to be disabled. Just leave the field blank and voila, no more checkbox.

– The Tweetmeme script now uses HTML comments properly. This prevents the tweetmeme javascript stuff from showing up in weird places, like in the feed and in the Simple Facebook Connect Publish/Share sections.

– And the big one: Automatic Tweeting on Post Publish. It supports auto-tweeting to an alternate Twitter account than your own (useful if you have a multi-user blog). Manual publishing will be coming soon, but I suspect it will not support the alternate account functionality, for simplicity. It would be confusing and hard to use.

Note: that last one is a bit beta. Don’t be surprised by bugs and odd behavior. Don’t rely on it working every time, because it probably won’t. But when it does work, it works great. Here’s this post, auto-tweeted: http://twitter.com/ottodestruct/status/10934354229 🙂

Shortlink:

For you people who do your own theme work:

<?php if (function_exists('wp_get_shortlink')) { ?>
<div><span class="post-shortlink">Shortlink: 
<input type='text' value='<?php echo wp_get_shortlink(get_the_ID()); ?>' onclick='this.focus(); this.select();' />
</span></div>
<?php } ?>

Basically that adds a little Shortlink: input box with the shortlink in it. Click the box, and the shortlink becomes selected for easy copy and paste.

It’ll also work with any shortlink plugin that uses the “get_shortlink” filter to override the shortlink properly (like WordPress.com Stats).

Put it somewhere in The Loop or on the Single Post pages or what have you.

Shortlink:

I updated Simple Twitter Connect to version 0.4. New stuff:

Login message

The Login plugin now correctly displays an error message when somebody attempts to login as a user that isn’t recognized yet. This should prevent confusion about why “login doesn’t work” after activating the plugin.

Tweetmeme button

New Tweetmeme button plugin added. STC was already perfectly compatible with the existing TweetMeme plugins, but for completeness (and because it was easy), I added this. It’s much like the SFC Share plugin, really.

Note: In the future, an actual STC Share plugin will be created, which will send tweets directly from your own Twitter Application, instead of through TweetMeme. That will be a sorta replacement for this, in that it will have the same basic functionality.

Shortlink support (or lack thereof)

I made the plugin give more information about shortlinks and how they work. Basically, I’m not going to support shortlinks directly. There’s just too many of them. Instead, I have put in support for generic shortlink plugins. The idea here is that anybody can make a plugin to do some form of shortlink support, and this plugin can then use it automatically.

How this idea works:
1. A shortlink plugin author implements this function: “get_shortlink($post_id)”.
2. That’s it. Do that and the plugin will use it.

Any plugin author creating a shortlink plugin should be able to easily do this. In fact, one already has. If you use the WordPress.com Stats plugin, then you automatically get “wp.me” style shortlinks. STC will use them because they implement this function in a pluggable way.

This is also the best solution for people who prefer to implement their own shortlinks in some custom manner. All they need to do is to create a get_shortlink function that returns the shortlink string, and voila, it’ll be used.

So, there you go. Enjoy.

Shortlink: