Theme/Plugin Dependencies
In trying to figure out what to talk about at WordCamp Atlanta, I remembered a question put to me in WordCamp Birmingham. The question was how can a theme developer easily make a plugin-dependency in their theme?
I wrote some code to do this sort of thing, just as an example/test/demonstration, but then after looking over the schedule, I found that Thomas Griffin had beat me to it. After looking over his slides and having him walk me through his code, I realized that his solution was much more fully featured than mine, so I’m glad I didn’t present anything on this topic. (I ended up just doing an answer session where I tried to answer any question put to me, and frankly that was much more fun than having slides, so I’m probably just going to do that from now on.)
You can find his cool library here, BTW: tgmpluginactivation.com/
However, his solution is highly complex. The class he came up with is well done and fully-featured. He has capabilities for making notifications in the header space on the admin section, lightbox popups, bulk installs, forced activation, custom skinning, etc. It’s a big thing. While that’s great for a lot of people in terms of having code you can just drop-in and use, I thought that it doesn’t do much to teach how one can DIY it.
See, the code I wrote was tiny. It basically just provides some minor functionality to show a theme author how to detect installed plugins, how to detect when they’re active, how to build install and activate links, etc. It doesn’t do any pretty stuff. No custom skinning. No lightbox popups. All these things are possible, but if somebody hands you a hunk of library code to do them, then you know how to use that library, not how it works. I dislike using libraries for this reason.
So here’s the small class I wrote to do the same sort of thing, but in a very bare-bones style.
/* Simple class to let themes add dependencies on plugins in ways they might find useful Example usage: $test = new Theme_Plugin_Dependency( 'simple-facebook-connect', 'ottopress.com/wordpress-plugins/simple-facebook-connect/' ); if ( $test->check_active() ) echo 'SFC is installed and activated!'; else if ( $test->check() ) echo 'SFC is installed, but not activated. <a class="'.$test->activate_link().'">Click here to activate the plugin.</a>'; else if ( $install_link = $test->install_link() ) echo 'SFC is not installed. <a class="'.$install_link.'">Click here to install the plugin.</a>'; else echo 'SFC is not installed and could not be found in the Plugin Directory. Please install this plugin manually.'; */ if (!class_exists('Theme_Plugin_Dependency')) { class Theme_Plugin_Dependency { // input information from the theme var $slug; var $uri; // installed plugins and uris of them private $plugins; // holds the list of plugins and their info private $uris; // holds just the URIs for quick and easy searching // both slug and PluginURI are required for checking things function __construct( $slug, $uri ) { $this->slug = $slug; $this->uri = $uri; if ( empty( $this->plugins ) ) $this->plugins = get_plugins(); if ( empty( $this->uris ) ) $this->uris = wp_list_pluck($this->plugins, 'PluginURI'); } // return true if installed, false if not function check() { return in_array($this->uri, $this->uris); } // return true if installed and activated, false if not function check_active() { $plugin_file = $this->get_plugin_file(); if ($plugin_file) return is_plugin_active($plugin_file); return false; } // gives a link to activate the plugin function activate_link() { $plugin_file = $this->get_plugin_file(); if ($plugin_file) return wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin='.$plugin_file), 'activate-plugin_'.$plugin_file); return false; } // return a nonced installation link for the plugin. checks wordpress.org to make sure it's there first. function install_link() { include_once ABSPATH . 'wp-admin/includes/plugin-install.php'; $info = plugins_api('plugin_information', array('slug' => $this->slug )); if ( is_wp_error( $info ) ) return false; // plugin not available from wordpress.org return wp_nonce_url(self_admin_url('update.php?action=install-plugin&plugin=' . $this->slug), 'install-plugin_' . $this->slug); } // return array key of plugin if installed, false if not, private because this isn't needed for themes, generally private function get_plugin_file() { return array_search($this->uri, $this->uris); } } }
Obviously, for theme authors wanting to do something, they’re going to want to make much prettier means of displaying things and installing things. Thus, this code is meant as an example, to show the basics of how to detect such things.
So, use it directly if you like (it works), but more importantly, if you want to put plugin dependancies in your theme, then I suggest reading it and figuring out how it works instead. Then you can see how plugins can be detected and how to build simple install and activation links.
(BTW, note that I used the slug and the PluginURI for a reason. Plugins should be using a unique URL for the plugin in their code, and that URL is very likely to be the most unique thing about the plugin, and therefore the best way to check for a plugin already being there or not. Slugs can be duplicated by accident or design, but URLs are generally going to be unique and specific to a particular plugin.)
Category: Code, WordPress | 10 Comments
Using SFC? Got an email from Facebook?
Some people have been forwarding me this email message that they received from Facebook:
We currently detect that your app is using the old JavaScript SDK (FeatureLoader.js). This library will no longer work for authentication on February 1st, 2012 since it does not support OAuth 2.0. In May, we announced that all apps on Facebook need to support OAuth 2.0 by October 1st, 2011. Please upgrade to the new JavaScript SDK by February 1st, 2012 to avoid any disruption of service to your app.
The Simple Facebook Connect plugin has not used the FeatureLoader.js script since before version 1.0, which was released 5 months ago. Version 1.2 of SFC fully integrated OAuth 2.0 authentication, and it was released 5 weeks ago.
So if you’re getting this email from Facebook, upgrade SFC to the latest version. Problem solved.
Category: Code, Other | Comment
Comment Form Autocomplete Snippet
Google came out with an experimental specification for websites to provide “hints” on forms, to allow things like autocomplete to work better and be more standardized. Seems useful.
Here’s a quick plugin snippet you can use to make your comments form use this specification. Only Chrome 15 and up is using this at the moment, but in the long run I think most browsers will be implementing something similar to this, since filling out forms is just one of those endless pieces of drudgery that we could all stand to do away with.
Note that your theme will need to be using the comment_form() function call for this to work, otherwise you’ll just have to edit your comment form in the theme manually.
<?php /* Plugin Name: Add X-Autocomplete Fields to Comment Form */ add_filter('comment_form_default_fields','add_x_autocompletetype'); function add_x_autocompletetype($fields) { $fields['author'] = str_replace('<input', '<input x-autocompletetype="name-full"', $fields['author']); $fields['email'] = str_replace('<input', '<input x-autocompletetype="email"', $fields['email']); return $fields; }
Simple little bit of code, really. Should work with any theme using the normal comment_form() function call.
Category: Code, WordPress | 2 Comments