With a number of plugins under my belt, I’ve collected a number of theories on what you shouldn’t do. All of them are relevant, if light-hearted.
Don’t allow your plugin to rely on third party code
If you do and it doesn’t work (or doesn’t work as the users want) then you’ll be crucified. No matter how much you may argue to your users that it’s not your fault and there’s nothing you can do, that won’t prevent the poor reviews you’ll get as a result.
Take my YouTube Embed plugin – the majority of support queries I get are from people having issues with the way the YouTube Player API works. Not my plugin’s fault, but doesn’t stop me having to constantly answer questions on it.
My Feed List plugin displays RSS feeds by using the in-built WordPress feed parser. However, I regularly get complaints from users who say that their feed output is not updating. It’s not the fault of my plugin and there’s nothing I can do to fix it. Do you really want that hassle?
Don’t write a plugin on a subject that people will argue about
So, you have a great idea. A plugin that counts the number of words in a post. But then the complaints poor in – it’s not counting the words right. You finished the sentence with a word that was split onto the next sentence and it’s not counted it correctly. You get a user who writes in Afro-Spanglish and they count hyphenated words as 2. It’s never ending and you’ll never, ever, get it right.
Pick your plugin topic carefully – something fixed that people can’t argue with. What about a plugin that counts the words in 1 word posts (although if you do, you’ll probably still fall foul of the Afro-Spanglish)?
Pick a subject you actually care about
I will often decide to write a plugin simply because I’m after that functionality myself. That way I actually use it and care for it. Too many plugin developers create something and then leave it to rot.
Dead, useless plugins just give WordPress a bad name. And you don’t want that.
Be careful what words you use in your plugin title
Start your plugin title with “WordPress” or “WP” and you risk looking like an idiot. A WordPress plugin, available at the WordPress plugin repository at WordPress.org and you feel the need to indicate in the title that it’s for WordPress? Amazing.
Equally, and for different reasons, don’t use “Simple” in your title. I used to, and did so to indicate that they were basic plugins – no “singing and dancing”, it just did the job. However, you could also mean simple to suggest that the plugin is really, really easy to use. Both definitions don’t always work at the same time. Whichever reason you choose for using it yourself, you will be soundly berated for the other. In the case of my “Simple” plugins I had more than once occasion when a user angrily complained that they weren’t simple to use. Explaining that it didn’t mean that didn’t help. Multiple meanings = bad.
Don’t write plugin READMEs with next to no detail in it
Unless you link to a web site that covers everything. Unfortunately, there are a large number of plugins that have installation details and, after that, you’re on your own. Writing some instructions for use is not at all difficult and, to be honest, whenever I see such a plugin I’ll move away from it quickly. This is a perfect example.
Don’t use third party support
You’ve written a plugin, under the GPL licence, to be a caring, sharing kind of person. You cared for it, nurtured it and continue to make it better with regular updates. So why in the name of all that’s holey have you handed over support to some money-grabbing third party?
If you want to annoy users, or make them turn away right from the beginning, this is the way to go.
Don’t write a plugin unless you work for Automattic
Most people don’t realise that running this site and developing WordPress plugins is not a full time job for me. Therefore I have to find the time during lunchtimes and snatching time in the evenings. However, this week I’m off and have decided to tackle a big upgrade to my most popular WordPress plugin – Artiss YouTube Embed. As a bit of an experiment I thought I’d write a diary of how it goes – each day I’ll make regular updates to this article with details on what I’m doing. If I get it completed this week I’ll be astronished – I expect it to run into at least next week!
First of all, though, I need to bring you up to date with where I’ve got.
Today is Monday 7th, but in the UK it’s a public holiday. Therefore, my development hasn’t officially started as I have a family to keep entertained However, I did make a start so my diary starts on Sunday.
If you find this interesting, please come back for the latest update. For a complete list of my planned changes and where I’ve got to please view the roadmap.
Pulled the YouTube Embed files out my personal archive. Ensured the current version, 2.4.1, is safely stored and created version 2.5. At the moment this is an exact duplicate of 2.4.1, but I quickly changed that by updating the version number in the root file and the README.
Meantime, I’ve had a report from a user of problems with the URL embedding options1. By default, if you add a YouTube URL to a line of a post it will convert it to a video. There are few parameters available to the user and the end-result isn’t very configurable. So, I’d added an option to my plugin to override WP doing this and allow my own embedding instead. Sadly, it doesn’t appear to be working (something must have changed as I tested it when I originally implemented it).
My wife and youngest daughter were out at the park this morning and after I’d mowed my rather substantial lawn and done a few other jobs I took another look at the plugin changes.
First job – going through the list of changes that I have on MantisBT and ensuring that all my planned changes are there. Unfortunately the list is now bigger.
I also had an opportunity to do 2 things…
Start making some internationalisation changes. Basically, I’m ensuring that any text output goes through the appropriate WP filters and does so properly. WP has some great translation tools built in, but you need to ensure you’re using them properly.
Both of these items, both unfinished, took me an hour which, I guess, goes to show how much time it can take to make what are relatively insignificant changes.
Had some breakfast and time to make a start. My intention is to concentrate on 2 of the major issues initially – getting the aforementioned embedded URLs to work (or not) and updating the playlist code. There are a couple of things on the list that could potentially wait for a future release so I’ll do those last – otherwise everything else I’ll do in no particular order.
The URL embedding issue is causing WordPress to display the embedded URL instead of my own code and the following error is logged… “WARNING: wp-includes/media.php:1171 – preg_match() [function.preg-match]: Delimiter must not be alphanumeric or backslash”.
I’m bringing back a copy of media.php and will add some lines of code in to help me debug the situation. I’ll put that version back and re-try.
Got somewhere with the regular expression issue but I’ve hit an impasse. When outputting the expressions that WP is processing I came across another, which wasn’t one from my plugin. No, this isn’t causing the issue but I could see the format was different to mine – I believe mine is formatted incorrectly and hence the error. Unfortunately, my knowledge of regular expressions isn’t good enough to fix it so I’ve added my question to a forum – I’m hoping somebody will be able to assist.
Moving onto the playlist…
I’ve spent all this time trying to desperately understand how the new playlist function works. The documentation for it is poor and the penny has just dropped that it only supports the IFRAME player. This is a retrograde step from how it was. On the plus side I’ve since managed to get the old playlist method to work, so I’ll see if I can get it to work on new playlists!
Just realised actually that I can get new format playlists to appear in the current version of the code simply by removing the “PL” suffix from them. I could swear I’d already tried this and it hadn’t worked! I’ll have to do some more testing on that. Maybe the solution is to use the new method when using the IFRAME player and the old method for the Flash player.
Finally, the playlists are working correctly and I’ve taken the opportunity to tidy up some of the code in doing so. The code tidying means that I now generate the embed URL all in one section, rather than piecing it together later. This has also affected normal video embeds as well so they’ll need a thorough re-test later. The up-side of this (other than making the code easier for me to understand!) is that it’s given me an opportunity to bring it 100% up-to-date with the API examples.
If you use the IFRAME method then the new playlist parameter will be used, if you Flash then the older one will. The API also works too for the different formats too.
I’m going to have a little break now!
I’ve now completely re-written the contextual help and updated all the script file names (see my Monday comments!). The former took a while, but it’s now compatible with both the 3.3 updates to the help system and the previous version.
20% of all the planned changes are now done which is an excellent start.
I’m now off for a long lunch, including having a much-needed shower.
Back! One lunch, one level of Infamous on the PS3 and one shower later.
My aim now is to “rattle off” some of the smaller changes, starting with completing the internationalisation.
Okay, all code tidy-ups done – output appropriately internationalised and function names standardised.
I’ve now resolved an issue with the titles not appearing correctly – I was incorrectly calculating the position of the title in the XML if I was using the one from YouTube. That’s fixed and the title is now displaying correctly. Other small fixes done…
The option to display the README now picks up the one relevant to your installation and not the latest
Fixed assorted errors being reported in DEBUG (none were critical)
That’s it for now – Mantis shows 36% of the changes are done so I can rest for now. I may do some more later, but a new episode of CSI and popcorn beckons
Another early start. The first thing I’m going to look at is an enhancement for excerpts. Post excerpts have shortcodes removed from them which, if you have a YouTube embed included, doesn’t give a great output, especially if a post if not much more than a video. My intention is, in the case of excerpts, to replace the video with a line of text.
Thankfully I didn’t spend much time on it! The excerpt is edited BEFORE any plugin can edit it (unless you remove the excerpt filter and replace it entirely yourself).
I’ve now bought all the parameters up to date with current API documentation – some now work with a large number of player types so this has been reflected in the screens and README. I’ve also changed some of the wording to better reflect how Google differentiates between the different player types.
Lastly, I’ve added the ‘end’ parameter which allows you to specify when a video should end.
An update on the embedded URL issue – I’ve found out what I’d done wrong and the errors are gone. Unfortunately, the expression is simply not trapping YouTube URLs and I don’t have enough knowledge on regular expressions to correct it. I’ve therefore decided to remove the functionality from the plugin.
Wow, I’ve blitzed through the list of changes. I’ve removed a few because they weren’t actually issues – for example, someone requested that I remove the restriction on the number of lists and profiles I allow. In fact, there is no limit (should have realised that).
However, some changes have been made. One user reported that adding FRAMEBORDER to an IFRAME is not HTML5 compatible. I’ve therefore put this into the options as a selectable feature.
After all the changes I made I went for a break and I just ended up doing a lot of jobs around the house.
There are now just 2 changes to make – implement the new search facility and update the README with new FAQs. I’ll therefore call it a day and return to the code tomorrow – the search facility should be a bit more taxing.
A late start today as I had a lot of things to do this morning away from the computer. I updated the README last night so I just have the one (admittedly large) code change to make.
YouTube now allows you to specify a user name or search term and it will generate a playlist from the results. This is what I need to implement. My intention is that the search term or user will be specified between the shortcodes instead of the video ID.
One hour later and I’m now able to build a playlist based on user ID (more specifically my own). Excited!
I’ve now added the same options to the widget. I think that’s now about it for now – just some tidying up to do and some testing.
I’m out tomorrow so I’m not sure if they’ll be a diary entry – I’ll be back soon!
I’ve had 2 responses today from queries.
First of all, the forum where I asked about the regular expression they offered to construct what I needed. They asked me for some examples of what should match and what was needed to be extracted. At this point I realised that I didn’t know the latter – maybe this is why it didn’t work in the first place! If I ever work out what WordPress requires I’ll be able to work it out but, with my current knowledge, that may not be anytime soon.
On the more positive side I also heard from Jeff Posnick from the YouTube API Team. He has provided me with details on how to add the new playlist, search and user details to the Flash embed. Up until now I thought it only worked with the IFRAME and have coded it for that. So, I have more work to do after all!
Spent the morning at the shops, now raring to try and sort out the code.
Having thought about this further, this is a good opportunity for me to clean up some of the code further – at the moment I’m building the playlist separate to the new search/user features but I should, in fact, be doing it as one.
Before diving in, though, I need to do some planning. Paper and pencil are ready!
Code done (still neats neatening up, though). I’ve realised that I still don’t know if the new functions with the Chromeless player. I’ve had a play and can’t get it to work, but have fired another query off to Jeff Posnick to confirm it.
Meantime, I’ve (after some head-scratching) decided to get it to force the player to IFRAME if one of the new functions is requested in the Chromeless player.
Lots more testing and tweaking done and I’m struggling to break it. I therefore suspect I’ve cracked it, so will tidy my code up now and think about testing next week (and also some updates to the README!).
Am 30 minutes into my lunch break at work today. Have been testing, concentrating (so far) on the admin screens. After some modification, they now appear fine.
I’ve also updated the plugins’ screen icon. Am now going to whip through the plugin files and remove stray, redundant characters (tabs and spaces mainly).
Lunchtime over. Whilst testing MCE edit button and the link on the Admin Bar, I realised that the format (and action filter) of the bar has changed. I’ve therefore updated the code so that if using WP of 3.3 or greater it will add a new menu link to the Admin Bar with sub-menu links to all the main option pages. If the WP version is below this it will use the old style of adding a single link to the “Appearance” menu.
Back at home and have been working on the testing again since 4pm.
I realised the the positioning on the Admin Bar was wrong – instead of it being to the right of the site menu, it was to the left. A bit of tweaking and I found that a weight of 40 (passed via the admin_bar_menu action) resolved it.
Checked debug output to ensure I’m not creating any errors – all now cleared up (that I can find!). Finishing already, but will return later.
Testing again since sometime after 8pm.
Lots done including checking that the new “stop” parameter works – yes I coded it, but never checked it at the time. However, I’d made a school boy error – I didn’t allow it if using the IFRAME player. In fact, the API allows it in the IFRAME player, it just doesn’t work if it falls back to HTML5.
The same went with the switchable FRAMEBORDER code too – it all worked, except I was looking at the wrong parameter when generating the embed code FRAMEBORDER was never added. Ho hum.
Now finishing for today – more testing fun tomorrow lunchtime! I now only have the playlist, search and user upload features to test (so nothing major) along with general testing of other functions that I haven’t specifically changed. I then need to finalise the internationalisation text before creating the requisite translation files.
Nothing happened yesterday as I was feeling unwell. However, I hope to return to testing today.
However, something might hold up proceedings – I’ve been approached to add some advertising to the plugin administration screen. They haven’t said it will be this plugin but I’m guessing it may be. In which case I’ll add it to this release.
Tested existing features – they all work fine. Now moving to testing playlists (in all their flavours!).
Playlists all worked, so I moved onto the new search and user upload features which worked equally well. Yes, that was a fast test but when writing the code I’d already constructed some test posts with examples in so it was simply a case of checking I’d covered all examples and re-testing.
Internationalisation has now been implemented, with all the relevant translation files generated. I had to tweak some output to get it spot on but I’m happy with the results.
Basically, I’ve generated the translation files that list all of the text that my program outputs. If anybody then wishes to provide translation to another language they will use these files to do that.
That’s it for tonight – I’m busy tomorrow and out Friday night, so I’ll hopefully be able to do some further work Friday lunchtime. By then I hope to have heard from the potential advertisers.
The potential advertiser got back to me and an agreement has been made – I’ll therefore be adding a discrete advertisement to one of the plugins’ administration screens.
This might otherwise have held up for release if it wasn’t for something else that’s come along as well. I’ve had a 2nd user complain about having a database full of cache data generated by this plugin. Two doesn’t seem a lot but how many people are likely to be checking this? The thing is, I know the cause – it was a bug in an older version, which is now fixed. Both users have been instructed on how to clear down their database manually of this old data – however, I think is only fair that I implement a better solution for future. I’ll therefore add in an option to clear down the cache from the admin page.
I’ve spent my lunch today implementing the advert in the administration page. I’ve taken the chance to put some social links alongside which has produced a neat result.
Also implemented the caching clearing option and updated the FAQ to explain why this may be needed!
Finally, updated the demonstration video and added a more prominent bit of text to explain that the video can be sponsored
Tested all the changes and compressed all the images from the earlier updates.
Made final changes to the README and updated the translation files.
Voilà, it is done. However, I still need to put it in the WordPress repository – things may break and I don’t want to do this just before a weekend. So the next update should be on Monday when I launch it!
I have about half an hour before having to get ready for work. My intention was to get the new version uploaded, however I’ve had a report via the WordPress forum of something else that could lead to a change. They are attempting to use another plugin within the YouTube Embed shortcode to return the URL that they require. I’ve therefore taken the opportunity to add recursive shortcode functionality – essentially if you include other shortcodes within those in my plugin they will now be run too.
Ok, so with that done and a brief test to ensure all was still fine I then started to upload the changes to the WordPress SVN repository. I use TortoiseSVN for this purpose.
I also need to take the opportunity today to promote the release – I don’t do this for minor releases but like to for the more major ones. I’ll be doing this later
At 8:30 the code was completely uploaded and the WordPress.org page was showing version 2.5
Promotion is complete – I have contacted various WordPress sites that publish information about plugins.
So far, so good on the plugin – no issues reported yet. It’s still quite early in the US, though, so I suspect it may be some time before I have a better idea. None-the-less I’d say this diary has come to an end. I’ll update it if any issues are reported, but otherwise I hope you enjoyed this. Depending on the statistics for this article I’ll decide whether to do another in the future.
I have since had to make 2 minor revisions to the plugin to fix some reported issues – the link in the Admin Bar wasn’t appearing for those with a WordPress version between 3.1 and 3.3 and single video widgets weren’t displaying the correct video[/update]
in fact he’s been reporting it for a while but has never supplied me with enough detail to allow me to recreate it until now [↩]
Again, needing to provide information for a page for the press I created a shortcode that would output the number of posts that have been published. And it’s just 2 lines long!
Copy the code below into your theme’s functions.php file and then place the shortcode [post_count] wherever you wish the count of posts to appear. There is no caching as this information is being provided by WordPress itself.
If you want to change the shortcode name, simply change it on the final line.
If you have a need to add your site’s current PageRank to a page or post (for example, you may have a page for the media/PR on which you may wish to highlight it), the following piece of code, added to your theme’s functions.php file, will achieve just that.
All you have to add in a post or page is add [pagerank] wherever you wish the PageRank to appear.
To achieve this, the code uses the site Prapi.net to retrieve the information. The result is cached for 24 hours so as not to inflict on site performance.
You can change the caching time by modifying the number 86400 (which represents the number of seconds to cache for). If you wish to change the name of the shortcode, then simply change that on the final line.
This will add the Skimlinks script to your site’s footer – simply replace xxxx with your Skimlinks number. Additionally, this script is designed to only allow Skimlinks to be placed on single posts and pages – you can update this depending on your site’s requirements.
Lastly, you probably don’t want Skimlinks to appear on site parts of your site – e.g. the header, footer and sidebar. To suppress this you’ll need to have a bit more coding knowledge – identify the appropriate DIV that covers each area and add a class of “noskim” to it.
For example, say you have <div class="footer"> that covers the footer area of your site. If you change this to <div class="footer noskim"> then this will prevent any Skimlinks from appearing in the footer.