Make WordPress Plugins

Updates from Samuel Wood (Otto) Toggle Comment Threads | Keyboard Shortcuts

  • Samuel Wood (Otto) 9:36 pm on July 14, 2016 Permalink |  

    Known issues with pre-commit to the plugins SVN 

    Have you seen this recently?

    $ svn ci -m 'commit first version of plugin'
    Adding trunk/readme.txt
    Adding trunk/my-cool-plugin.php
    Transmitting file data .......svn: E165001: Commit failed (details follow):
    svn: E165001: Commit blocked by pre-commit hook (exit code 1) with output:

    PHP error in: my-cool-plugin/my-cool-plugin.php:
    Errors parsing my-cool-plugin/my-cool-plugin.php

    A couple weeks ago, the PHP “lint” part of the SVN pre-commit check was changed from using PHP 5.4 to using PHP 7.0. Somewhere in that process, something got broken with regards to the output of the error messages resulting from this check. So, none of the errors show up.

    This can be confusing, especially if you’re not running PHP 7.0 yet, because PHP 7 is actually a lot more strict about this sort of thing. You can run the PHP lint process yourself on your own files all day long and not see what the issue is, because it *only* comes up in PHP 7.

    My advice: Grab a copy of PHP 7 for your machine, and run “php -l” on the file you’re getting an error message about. There is a valid error, you’re just not seeing it on older PHP versions, which were not quite so picky.

    One known case that seems to be cropping up a lot:

    The “break” and “continue” keywords are only valid inside a for, foreach, while, do-while, or switch structure. You’ll get the error message of “Fatal error: ‘break’ not in the ‘loop’ or ‘switch’ context in my-cool-plugin.php on line 123”

    We’ve been seeing code that has something like this in it:

    if ( is_thing() ) {

    And that is invalid in PHP unless that if is inside a loop. But, previous versions of PHP didn’t show the problem in their lint processes. Not so with PHP 7.

    So, make sure to check your code with PHP 7. It’s no fun for people using the newest systems, like we always recommend, to be running into syntax errors. Note that these were actually syntax errors in previous versions of PHP as well (using break and continue makes no sense outside of a loop structure), but now you’re getting told about them by the lint process.

    We’re still working on finding the bug not showing you these errors in the pre-commit checks too. 🙂

    Edit: Any plugins uploaded to the directory should still be PHP 5.2 compatible. Just because we’re allowing PHP 7 code doesn’t mean this is a free-for-all.

    Look at https://wordpress.org/about/stats/ . This isn’t complicated. Your main plugin file can be installed and activated on any of those sites. If you have even 5.3-only code in that main file, then you are responsible for breaking that person’s website, and *you* will get the appropriate review from them for doing so. And we are not going to delete that review just because you ask nicely…

    Make your plugin handle failure cases properly. If you want to limit your userbase, then you’re welcome to do so. But do it right. Add code to the plugin to fail gracefully on older systems.

  • Samuel Wood (Otto) 10:26 pm on February 12, 2016 Permalink |
    Tags: , plugins, selling, spam   

    On the Topic of Selling Your Plugins… 

    Unlike the title might suggest, this post is not about buying a plugin from a commercial author, or the viability of “freemium” plugins in the directory, or app stores, or anything of that sort.

    This post is directed squarely at plugin authors.

    Question: Who owns your plugin?

    The answer is simple: You do. You wrote it. You hold the copyrights on it.

    Now hold on a minute (one might say), everything in our directory is GPL or compatible. Isn’t that copyleft? Well, yes, and I’m not going to go into excessive amounts of legalese here (IANAL), but the GPL is built on top of copyright. It actually requires it. So yes, you do own the copyrights to your plugin, even when it’s available for free in the WordPress.org plugin directory.

    And yes, that totally means you can sell those rights to somebody else. We won’t stop you. Heck, if you ask, we’ll even help you perform the transfer correctly.

    Now, while we’ve talked about this before, it’s worth re-iterating because it has come up a lot recently: your name is on that plugin. If you sell it to some scummy spammer, then your name is likely to get dragged through the mud. Not by us, of course, we don’t name names. But other people do notice bad things happening, and they tell other people, and make posts in our forums, and leave bad reviews… and before you know it, you can get a bad rap for something you didn’t even do.

    There have been a lot of reports of various unsolicited emails recently asking plugin authors if they would sell their plugins. Sometimes these are legitimate offers. Not often. Usually it’s from marketing agencies looking to add backlinks.

    In a couple of notable cases, some of those plugin authors asked what the person was planning on doing to change the plugin. Surprisingly they responded and told them. Let’s just say that these plans are very much against our guidelines.

    In at least one case, the plugin author told this prospective purchaser as much, and the person responded by asking how long it would be in the directory before we shut it down, and how many sites could he get the code to before getting this noticed and thus removed from the directory. He even asked whether it was a manual or automatic process (hint: it’s both).

    Yes, this guy was actually that blunt about his plans.

    While my evidence is slim, I believe this particular person is a Russian spammer or hacker looking to add malware into the plugins and get this code onto as many sites as possible before we put a stop to him.

    What can I say? WordPress is a big target. Some are going to try to abuse the system. We’re used to that. Now you plugin authors will need to get used to it too, because you can be a target for this sort of thing as well.

    People offering to buy your plugin are generally spammers. They’re probably using fake email accounts, and offering you false information as well. They may be able to pay you, but understand that what they’re looking for is to buy heaps of unrelated plugins, modify them all with SEO spam like backlinks or potentially even malware, and get our systems to push those things to as many sites as possible before we notice and shut them down hard.

    Do you really want to sell your plugin to somebody like that? Do you want your hard work to be abused and to have your good name tarnished?

    Think twice before selling your plugin. Know the person you’re selling it to very well. Ignore unsolicited emails from people you don’t know. If they are going to pay you based on the number of “Active Installs”, then just don’t even consider it.

    Don’t worry about the plugin review team too much though. We can find and shut these things down very quickly, even in real-time. But it does help us quite a bit if you ignore these types of scammers too. 🙂

    But if you do decide to give your plugin to somebody responsible and real and who actually cares about it, make sure they know about the Plugin Directory Guidelines. Because hosting a plugin in the WordPress.org Plugin Directory is a privilege, not a right. We can and will act to remove and stop plugins in our systems from doing bad things, no matter who “owns” them.

    • Eric Amundson 12:17 am on February 13, 2016 Permalink | Log in to Reply

      Great post, Otto!

      I’ve received at least a few unsolicited emails asking to buy plugins and I figured they were up to no good as their company had nothing to do with WP development. Like you said, they were marketing agencies.

      Glad to know there are some automated ways to spot and remove bad, or compromised plugins.

    • FolioVision 12:44 am on February 13, 2016 Permalink | Log in to Reply

      Good post Otto. I’m just curious about why you said the person is a Russian spammer or hacker. Do you have specific grounds or is this just kneejerk MSM “blame the Russians” for everything?

      There are plenty of American spammers and scammers. I in specific had contact from some agency in New York, David something or another (can’t find the email now or I’d name names). They said they just wanted to stick advertising in one of our plugins.

      • Ipstenu (Mika Epstein) 12:55 am on February 13, 2016 Permalink | Log in to Reply

        It’s based on the evidence in the emails (header information, urls provided, etc). He has specific grounds.

        • FolioVision 2:37 am on February 13, 2016 Permalink | Log in to Reply

          Well at least he was honest about his dark plans for world domination via underhanded plugin purchases! Good luck with the automated tools to suss out these issues when they happen. I suppose you are running a filter on outbound links added to plugins when updated, both in documentation and PHP, as well as particular patterns in the PHP (which will catch most of the lightweights). An account used once this way is lost forever. Most such buyers would have plugins arriving on accounts with very limited previous WordPress.org participation.

          Thanks for fighting the good fight!

    • JasWSInc 12:58 am on February 13, 2016 Permalink | Log in to Reply

      > Yes, this guy was actually that blunt about his plans.
      Crazy. Thanks for passing this along 🙂 Appreciated.

    • Maeve Lander 1:10 am on February 13, 2016 Permalink | Log in to Reply

      Good post, thanks Otto. I’ve received emails like this and sent them straight to spam but they can look quite convincing on first read.

      Another disturbing thing I’ve noticed recently is marketing/dev companies going through the wordpress.org plugin support threads collecting URLs and email addresses of users having difficuclties, then contacting those users privately with offers of paid assistance. Poor form. And extremely anoying when the user then contacts me as the plugin dev saying “is this you guys or some other chancer” or “can I get some support for this privately cos I don’t want to post my link in the forum”.

    • Arnan de Gans 3:23 am on February 13, 2016 Permalink | Log in to Reply

      I’ve had people approach me over the last 2 years with stupid offers of buying my AdRotate plugin (https://wordpress.org/plugins/adrotate/) from me.
      Some even had the audacity to offer me as little as $5000 for it. Some were willing to go up to $50-70k.

      All appeared to be from India or had names that suggested they were from India.

      The plugin would be “repurposed for marketing goals” or they wanted it because of the user base and they would take the plugin in a “different direction”. All the while crediting me for the original code. As if that is doing me a favour. Hah.

      But… Another thing I noticed from a few of those dudes. They were just after my financial details.
      Trying to find out how rich I am. Who I used to process money. How much income I generate from plugins.Things like that…
      While not irrelevant when selling a plugin, the way they went about these questions made me wonder if they wanted the plugin at all or were just looking for a “best practise” business model to use for whatever they were up to.

      So also beware of people asking about how you run your business 🙁

      Does WordPress/Moderators have a mechanic to report people like this?
      If not, is it an idea to have this? We authors could send suspicious stuff to plugins@wordpress.org for example and after a quick examination of the email exchange the WP team could build a blacklist or something. Such a list can be simple enough. Something like a list; Name, Company, Category, last received report, how many reports received.

    • Milap 7:18 am on February 13, 2016 Permalink | Log in to Reply

      Very useful post Otto. I have my own plugin with more then 60k+ active installs, and i got 3 offers in last 3 months to sell it. They tried to trap me with their healthy money offer, but i denied them every times as i found something wrong with their offer, and i am happy & proud of that decision. WordPress and all related repositories must be remain clean and we developers will always try our best to achieve that.

    • Rene Hermenau 11:53 am on February 13, 2016 Permalink | Log in to Reply

      I ignore such mails, especially when there is no full contact address in their mails. These guys are using freemail address without any other contact data. In 99% of the inquiries you can be sure they are with a bad taste, especially when these guys are entirely unknown in the developer community.

    • George Notaras 7:06 pm on February 13, 2016 Permalink | Log in to Reply

      Great post! Yet another one in a series of great posts lately in the plugins make site!

      As far as I can remember, I haven’t received any such emails. (Or maybe I sent them to the spam box before reading far enough to know what they were about..)

      Trying to think about this for a while from the user perspective and how users could feel safe about their web site after the change of ownership of one of the plugins they use, I always come to the same conclusion: Currently such a change could go unnoticed by the user, but this would not be ideal for most of them as they would possibly want to re-evaluate this new plugin status and make a decision whether to continue using it or not. An ownership change may mean a lot of things, as it has already been mentioned in the post and the other comments, and I think the burden of a decision about whether the plugin should continue to be used is too big and complicated to be taken by wordpress org alone, but the user should also have to decide.

      An idea about chaining all these events together would be the following:

      1. The plugin guidelines could force the previous owner of the plugin to make one last release after having changed the author field name to that of the new owner. This would be just to trigger a notification in WP.
      2. A mechanism could be implemented in wordpress, which (on every plugin update) could compare the author field of the currently installed version of the plugin to the respective field of the updated version. In case these differed, a pop up could be displayed or a notification could be sent (in case of automatic plugin updates) indicating that extra user action should be taken before the update of the plugin could continue. That extra action could just be the acceptance of a confirmation dialog.

      Of course this is not to exclude all the automated or manual testing that takes place at wordpress org.

      This is too simplistic, but I’m sure you get the idea of what I’m trying to say with this example, which is to transfer the final decision of continuing using the plugin to the end user.

    • Jacob N. Breetvelt 9:10 am on April 18, 2016 Permalink | Log in to Reply

      I am the autor of plugin wp-photo-album-plus https://wordpress.org/plugins/wp-photo-album-plus/ and i received an email from Mohammad Noman who wants to buy all the rights of my plugin.
      Does anyone of you know him and/or how do i have to act upon this? He ‘looks’ to be seriously interested to me, but i do not have experience with this kind of things. Can anybody advise me?

  • Samuel Wood (Otto) 8:20 pm on January 23, 2016 Permalink |  


    Same issues that were happening two weeks ago are happening again right now. I have alerted relevant parties to the problem.

    For now, new plugin authors won’t be able to commit, and some plugin readme.txt files won’t get processed correctly until this is corrected.

    Sorry for the inconvenience.

    Edit: This seems to be fixed for the moment, we’re working on preventing future recurrences.

    ETA2: If your plugin is still missing, we know and we’re working on it.

    • Ipstenu (Mika Epstein) 3:40 am on January 24, 2016 Permalink | Log in to Reply

      Please note this means we will not be approving new plugins until it’s fixed. There’s no point if I have to loop back with you all to explain why you can’t access things.

  • Samuel Wood (Otto) 3:53 pm on December 6, 2015 Permalink |
    Tags: , i18n, language packs, slack,   

    Plugin Translations for All Plugins 

    We have not mentioned this here yet, but since Matt mentioned it in his State of the Word talk yesterday…

    The WordPress.org plugins directory has the translations import mechanism currently enabled for all plugins. The update will happen for the plugin at the time of the next commit.

    To break down what this means into details:

    • When you commit the plugin, it will get read by the translations system.
    • All the strings for the plugin will be imported into the GlotPress install at https://translate.wordpress.org.
    • The plugin will become available for translators and language packs.
    • A message detailing the import will be posted into the #meta-language-packs channel on Slack.

    That last part has not been widely mentioned, but that is there for debugging and so you can find out what has happened or gone wrong.

    Here is an example of a problem: (I picked this at random, I’m not judging anybody here 🙂 )

    Import of ewz-rating
    ​_Time: Sun, 06 Dec 2015 15:23:20 +0000, Development Log_​
    Code for stable (ewz-rating/tags/1.0.0/) in process...
    This plugin has no text domain declaration in the file header.
    This plugin doesn't use `load_plugin_textdomain()`.
    Code for stable was processed.
    Readme for stable (ewz-rating/tags/1.0.0/) in process...
    The GlotPress projects were created.
    Result of the POT import: 57 new strings added, 0 updated, 0 fuzzied, and 0 obsoleted.
    Readme for stable was processed.

    The problem for this one is simply that the plugin is missing the proper Text Domain header, as well as not having any calls to load the plugin text domain. So, obviously, for this plugin, language packs will not work.

    Here’s one that worked fine:

    Import of docu
    ​_Time: Sun, 06 Dec 2015 13:45:53 +0000, Development Log_​
    Code for stable (docu/tags/1.5/) in process...
    The GlotPress projects were created.
    Result of the POT import: 37 new strings added, 0 updated, 0 fuzzied, and 0 obsoleted.
    Results of the inital translations import:
    Code for stable was processed.
    Readme for stable (docu/tags/1.5/) in process...
    The GlotPress projects were updated.
    Result of the POT import: 26 new strings added, 0 updated, 0 fuzzied, and 0 obsoleted.
    Readme for stable was processed.
    Import of docu
    ​_Time: Sun, 06 Dec 2015 13:46:38 +0000, Development Log_​
    Readme for dev (docu/trunk/) in process...
    The GlotPress projects were updated.
    Result of the POT import: 21 new strings added, 0 updated, 0 fuzzied, and 0 obsoleted.
    Readme for dev was processed.

    This one updated both the trunk and tagged version of the code, so it processed everything successfully. There’s a color coding indicator in the Slack channel as well. Red for a big error of some kind, orange for issues with missing headers or function calls, and green for good-to-go. 🙂

    So, if you’re having trouble with the translations for your plugin, check there for your plugin’s slug. If you have updated recently, then you probably have translation access already and might just be missing a header or something.

    Now, if you don’t want to get everything sent to you about all the plugins on the Slack, then you don’t actually need to join the #meta-language-packs channel. Instead, just add your plugin’s slug to your highlight keywords, and Slack will ping you when your plugin gets mentioned. This will let you see just the info about your plugin and can be a bit easier to manage.

    And again, if you already have translators for your plugin, but they don’t know how to contribute, point them to the Polyglots handbook, and consider asking the polyglots team to make them Translation Editors for your plugin. This will give them access to translate the plugin easily and to approve translations to get out the language packs to your users quickly.

    • Emil Uzelac 5:47 pm on December 6, 2015 Permalink | Log in to Reply


    • Jon (Kenshino) 7:42 pm on December 6, 2015 Permalink | Log in to Reply


    • Rami Yushuvaev 10:02 pm on December 6, 2015 Permalink | Log in to Reply

      We need to create a tutorial for plugin developers with all the common errors and how to avoid them.

    • webaware 10:32 pm on December 6, 2015 Permalink | Log in to Reply

      OK, so what happened to the bit about emailing the plugin author before that happens? I have my own installation of GlotPress through which translators submit their translations, and I received a set just this morning for a plugin… and I see that the plugin has already been imported into the wordpress.org GlotPress.

      If I’d known that the svn commit had already become the trigger for importing into the new world, I’d have also updated all my links for translators and changed my GlotPress installation to reflect that also. Now I have to rush that through for all my plugins somehow while also juggling my real job.

      Uh, thanks for the heads up… 🙁

      • Samuel Wood (Otto) 11:41 am on December 7, 2015 Permalink | Log in to Reply

        If you want to continue to use your own methods, you can do so. If you want to use the language packs, then your existing translations can be imported as well. Just mention something about it in the #meta-i18n channel on slack and we can look into it for you.

        • webaware 2:54 am on December 8, 2015 Permalink | Log in to Reply

          Thanks Otto. I’m happy to move translations across, but was expecting a heads-up as happened with two of my plugins already. I mean, it’s not like I can flag a plugin to *not* get imported into translate.wordpress.org, so really I don’t have a choice anyway (people will submit translations there whether I want them to or not!)

          I’ve hit #meta-i18n, hope to get caught up soon.

    • Brian Hogg 10:42 pm on December 6, 2015 Permalink | Log in to Reply

      How do we actually switch plugins to using the hosted translations vs the local ones? I tried removing the languages/ folder in the latest version as alluded to in the “Plugin Translations on WordPress.org” post in September, but the German translation doesn’t appear to pull through when the plugin is installed or come through in the downloaded zip.

      • Samuel Wood (Otto) 11:42 am on December 7, 2015 Permalink | Log in to Reply

        Once the translations on translate.w.org are at 100%, then you can remove the existing .mo files from your plugin and the language packs will be used instead.

        • pepe 12:08 pm on December 8, 2015 Permalink | Log in to Reply

          Is there a time delay? I got a “language pack ready” message via #meta-language-packs yesterday, so tried deleting the translations locally for the previous release (3.0.2) of wp-Typography (https://wordpress.org/plugins/wp-typography/), but then the German translation would not load. I assumed that maybe the language packs were only shipped with new installs, so I made a new release. However, the translations still do not load and I don’t remember getting a “Translations updated. Click to download.” notice in the backend of my site, either.

    • pepe 10:47 am on December 7, 2015 Permalink | Log in to Reply

      Unfortunately, existing translations don’t seem to have been imported for either of my plugins (https://wordpress.org/plugins/media-credit/ and https://wordpress.org/plugins/wp-typography/). For wp-Typography I assume because the original import happened while the plugin didn’t have translations yet (before I took over), butt for Media Credit it’s a bit strange, because I added translations according to the specs months ago, long before it was imported into GlotPress.

    • sLa NGjI's 12:18 pm on January 1, 2016 Permalink | Log in to Reply


      GlotPress or Translation inclusion, on code of plugins or themes, is contition necessary for approve it (for new plugins or themes) or is not necessary?

      On detail:

      1 – My new plugin or theme – not include translation or GlotPress – rejected from repository
      2 – My previous approved plugin or theme – not include translation or GlotPress – deleted from repository

      Thanks! !!

  • Samuel Wood (Otto) 9:53 pm on November 11, 2015 Permalink |

    Making Better Banners for your Plugins 

    With the plugin directory now being converted to use language packs, it’s more and more likely that your plugin will be translated by others and available in our various international plugin directories. But banners are kind of a problem for a few of those directories.

    Compare the Hebrew plugin directory to the English plugin directory. One thing you’ll probably notice right away is that the icons are on the other side. Hebrew is a Right to Left language, so the design for it is flipped. Click through to any of the plugin and you’ll notice something else: The banner image is the same, but the title is now on the opposite side of the page.

    For some plugins, especially those who designed banners thinking that the title was in a fixed place, this can present a problem.

    Probably the best solution is simply to make your banner work with either method. Compare Ninja Forms old banner vs. their new banner:





    For another example, take a look at Yoast’s SEO plugin.





    It’s an interesting stylistic difference, but the point is that they simply made the banner work for either case of title positioning. That’s honestly the best solution, IMO, because it also eliminates something from the banner that shouldn’t be there to begin with: Text.

    Text in images is bad. It’s non-accessible. Screen-readers can’t read it. It’s non-translatable to other languages. It’s a pain. Avoid it.

    However, sometimes people really like their designs. The design of a banner says a lot about the plugin, even though it’s just a big image. Some authors may want to be able to adjust their banner designs to adapt to the RTL language pages.

    For this reason, a couple of weeks ago, we added RTL support to the banners. I’ve been holding off on announcing this here to make sure it worked okay, and it appears to work fine, so, here’s the announcement. 🙂

    How to do it? There’s no magic to it. Just make your new banner, and name it with -rtl at the end of the name. Banner images live in the same directory as always, /assets. Nothing else changes.

    An example if you want to see how this looks in the SVN: https://plugins.svn.wordpress.org/pluginception/assets/

    And how it looks on the plugin page:





    Strictly speaking, the banner on Pluginception didn’t need to be reversed. I only did so as a demonstration, to show you how it’s done. Nothing tricky to it.

    In the future, adding support for specific locales may or may not happen. It is undecided if it is necessary, because, frankly, there’s a LOT of locales we have. Who wants to make individual banner images for 80+ languages? Best to just leave the text out of the banner instead.

    Note that while the RTL banners are now active for WordPress.org, they have not yet made their way into core, so the banners won’t yet show up properly in WordPress installations. Working on it. 🙂

    • Joost de Valk 10:08 pm on November 11, 2015 Permalink | Log in to Reply

      Honestly the solution we chose is…. Far from optimal. I’d prefer having the option to make RTL and LTR banners. We do similar things in CSS in WP core.

      • Samuel Wood (Otto) 10:08 pm on November 11, 2015 Permalink | Log in to Reply

        Joost: Keep reading. 🙂

      • Joost de Valk 10:08 pm on November 11, 2015 Permalink | Log in to Reply

        (Ugh, hit enter too early): so we’ll actually update ours.

        • Samuel Wood (Otto) 10:10 pm on November 11, 2015 Permalink | Log in to Reply

          If you’re interested, this is entirely implemented with CSS, and the data is available to the core installs via the API, so getting this in core should not be difficult. Might be a bit late for 4.4 though. Oh well, it can wait for 4.4.1 or what have you.

          • Ahmad Awais 6:59 pm on November 12, 2015 Permalink | Log in to Reply

            That’s true! Would be fun, though. I think this is a much better way to deal with this problem. Thanks for implementing it Samuel.

      • FolioVision 1:11 pm on December 3, 2015 Permalink | Log in to Reply

        Two banners is certainly aesthetically offers much more scope for creativity and design. Last time I checked WordPress was not by programmers for programmers product (functionalism only). Design questions matter.

    • Rami Yushuvaev 10:30 pm on November 11, 2015 Permalink | Log in to Reply

      In other words, plugin authors has two options:

      1. Create one bidirectional banner – https://GenerateWP.com/how-to-improve-your-plugin-header-image/

      2. Create two banners for LTR and RTL views.

    • jeffmcneill 2:12 am on November 12, 2015 Permalink | Log in to Reply

      > The design of a banner says a lot about the plugin

      No, it doesn’t. The design of a banner should convey something about the plugin, the author, or a brand, but it doesn’t “say a lot” about it. There are crap plugins with good banners, and good plugins with crap banners. there is no essential link between banner quality and plugin quality, banner functionality and plugin functionality, or any other aspect. The tail should not try and wag the dog.

      • Samuel Wood (Otto) 2:59 pm on November 12, 2015 Permalink | Log in to Reply

        > there is no essential link between banner quality and plugin quality

        Sure there is: The author. A spammy looking banner probably has a spammy plugin behind it. Not saying this is always true, but hey, take a closer look at some of the banners on what you might consider to be “bad” plugins.

    • Rene Hermenau 9:08 am on November 12, 2015 Permalink | Log in to Reply

      I love the new banner RTL feature. Thanks for this!

    • dartiss 9:55 am on November 12, 2015 Permalink | Log in to Reply

      Brilliant solution Otto, thanks. I hadn’t considered this when designing my banners. Making alternative RTL banners is going to work best for me, so I have some work to do!

    • Torsten Landsiedel 12:22 pm on November 12, 2015 Permalink | Log in to Reply

      Great work! Thanks Rami for bringing this up and Otto for this solution!

    • Alex Mills (Viper007Bond) 1:11 am on November 13, 2015 Permalink | Log in to Reply

      One problem I see with Yoast’s SEO plugin’s solution is that in some languages the title could be very long and go on top of the center logo. Just something to keep in mind.

  • Samuel Wood (Otto) 10:51 pm on November 6, 2015 Permalink |
    Tags: ,   

    Creative Commons Licenses in the Plugin Directory 

    Back in February, the Creative Commons organization began taking steps to introduce compatibility between their licenses and the GPL. At that time, we took notice and started discussing the problems we’ve had with CC licenses in the directory in the past.

    Part of the problem is that the Creative Commons licenses are so fragmented. It’s very much a choose-your-own adventure landscape for CC licenses, and many people don’t understand licensing very well in the first place (it can be confusing, I admit).

    Since we require everything in our directory to be GPL Compatible, then it’s something we have to constantly scan for when even an accidental violation occurs.

    Then, things became even more interesting in March, when gnu.org silently changed their compatibility page to state that CC-BY 4.0 was now considered compatible with all versions of the GPL. So, at that time, we started trying to ignore that particular case. It isn’t easy, because a lot of CC licensed code is licensed under version 3.0 of their licenses, which is not GPL Compatible. And the issue of CC-BY-SA was still very much up in the air.

    However, last month, Creative Commons finally stepped up. CC-BY-SA 4.0 is now compatible with the GPLv3.

    Accordingly, you can now use CC-BY 4.0 and CC-BY-SA 4.0 licensed code or images or anything else in the WordPress.org plugin and theme directories.

    A few points of note:

    • Only version 4.0 is acceptable. Check before using third party code which may still be licensed using 3.0.
    • Only the Attribution (BY) and Share-Alike (SA) clauses are acceptable. The No-Derivs (ND) and Non-Commercial (NC) clauses are definitely not GPL-Compatible. Code or images using them cannot be used.
    • If the code you’re wanting to use has the Share-Alike (SA) clause, then it is only compatible with the GPLv3, not GPLv2. This means your plugin and all the other code in it must be licensed under the GPLv3. The GPLv2 is not compatible with the GPLv3.

    The license compatibility page does mention that the compatibility is one-way. This is important, but probably not relevant for the most common cases we’re concerned with. The cases for plugins is likely that they want to use CC licensed code such as javascripts. The cases for themes is likely that they want to use images or other artistic work in the themes. Well, now you can do that. Just mention in the readme.txt for either where the work you’re using was obtained from, and the license that work is available under. Since you’re not relicensing the work, then one-way compatibility is not really an issue.

    If you need it in simpler terms:

    • CC0 – This is equivalent to a public domain declaration, essentially, compatible with everything, and we have always allowed it.
    • CC-BY 4.0 – Compatible with any version of the GPL.
    • CC-BY-SA 4.0 – Compatible with the GPLv3 only.
    • Previous versions of CC licenses (like 3.0) – not compatible.
    • Any CC license containing “NC” or “ND” terms – not compatible.

    So, if you have a favorite library or image that we’ve had to push back on you in the past for, take another look at it. The license might be compatible now. Also, if something is CC 3.0, consider asking the author of the work to bump that up to 4.0, so you can use it. It’s nicer for everybody to have more things out there compatible with each other.

    (Note: everything above applies to themes too. I just don’t want to write two posts. 🙂 )

  • Samuel Wood (Otto) 6:57 am on April 7, 2014 Permalink |

    MySQL in WordPress 3.9 – Implications for Plugin Authors 

    If you’re a plugin developer and you have a plugin using any of the php mysql functions directly, then you might start to see breakage in WordPress 3.9.

    See, the php mysql extension is very old. As of PHP 5.5, it’s also deprecated and will very likely not be receiving further updates.

    So starting in WordPress 3.9, if PHP 5.5 is being used, the built in WPDB class will switch to using the mysqli extension instead.

    What this means for your plugin is that if you’re using any mysql_* functions directly, and somebody tries to use your plugin on a WordPress 3.9 + PHP 5.5 system, then all your database code will no longer work properly. Since the mysql functions are no longer being used in such a case by WordPress, then there is no longer an implicit database connection available to these function calls.

    Instead of using a direct database connection, you can switch to using the global $wpdb instance of the WPDB class to access the database. @pento gives a great rundown on what functions to use as drop-in replacements on this make/core post: https://make.wordpress.org/core/2014/04/07/mysql-in-wordpress-3-9/

    Now, as this is currently limited to PHP 5.5 and up only, the amount of breakage will likely be very minor. Our stats currently show that PHP 5.5 is being used on less than 1% of installations. Nevertheless, hosts are starting to upgrade PHP versions more and more frequently. This number is thus expected to grow over the next year or two. So before your users start having broken sites, please, take the time to switch your plugins over to the WPDB based methods. This will ensure future compatibility and minimal breakage.

    WordPress will always maintain backward compatibility in its own functions, so using them ensures that you’ll be good for the forseeable future, no matter what database methods are being used internally.

    • rahul286 7:27 am on April 7, 2014 Permalink | Log in to Reply

      Glad to hear this. mysqli is much better.

      We use PHP 5.5 and mysqli on all sites. I hope WordPress site’s running PHP 5.5 and mysqli will run faster soon. 🙂

  • Samuel Wood (Otto) 4:14 pm on April 16, 2013 Permalink |

    Be the Author… 

    So, I’ve had this working for a while, but not a lot of people noticed, so I figured I’d spell it out explicitly.

    WordPress.org plugin pages have special magic Google markup. This is what allows many of the Google tricks we do for plugin pages to work. If you’ve ever searched for one of our plugins on Google, you may have noticed that it says it’s “free” as well as showed the rating as stars and such. This is all using Google’s Rich Snippets functionality with markup from the schema.org specifications.

    One of the magic tricks we do is to point to your WordPress.org Profiles page as the “author” of the plugin. It’s your plugin, after all, and you deserve the credit. But promoting the authorship is only half the picture, it helps if Google also knows who you are as an author. Then they can do something clever too:


    This is a sample entry for one of my plugins from the Rich Snippets Testing tool. The photo and authorship info may not show up on every search result that gets my plugin up on Google’s search results, but it certainly doesn’t hurt. But to get this information to be capable of showing, Google needs to connect your profile and user information on WordPress.org with a profile and user information from Google+. To do this, there’s two steps:

    Step 1: Edit your WordPress.org profile to include a link to your Google+ account. You can do this yourself, and you can see how I did it on my Profiles page. I included this link in my “About Me” section: https://plus.google.com/100201852715113506716?rel=author

    Note that the ?rel=author bit is important, that’s what tells Google that you are the author here and links your G+ account to this page.

    Step 2: Tell Google that you contribute to WordPress.org. To do this, go to your Google+ Profile. In the “Links” section you will find a “Contributor To” area. You need to add two links to this area:

    • The first link will be a link to your own profile page, on http://profiles.wordpress.org. This completes the connection and tells Google that you and the profile are the same person. Because your plugin page automatically links to your profile with the author information, making this connection creates an indirect authorship connection to all your plugins.
    • The second link you need to make is a link to http://wordpress.org itself. This is because Google wants there to be an explicit connection on the same domain name (not a subdomain), and so this link is required. And hey, you’re contributing to WordPress.org every time you update your plugin or theme, so well done there! 🙂

    After doing both these steps, you can try your plugin’s URL in the Rich Snippets tool yourself, and voila, you’ll see the magic. Note that you may not see it in the actual Google search results for weeks, and it may never appear. Google shows snippets like these on terms of their own choosing. All you’re doing here is to give them the data that lets their engine do the magic, if it can.

    • Gabriel Reguly 4:24 pm on April 16, 2013 Permalink | Log in to Reply

      Wonderful Otto! Thanks for sharing this.

    • Charleston Software Associates 4:28 pm on April 16, 2013 Permalink | Log in to Reply

      Coolness! Thanks for the step-by-step guide, Otto. Works great!

    • myatu 5:39 pm on April 16, 2013 Permalink | Log in to Reply

      I didn’t even know you could use HTML in the “About Me” section. Learn something new everyday! 🙂

    • Peter 6:14 pm on April 16, 2013 Permalink | Log in to Reply

      +1 for Otto!

    • Chuck Reynolds 6:26 pm on April 16, 2013 Permalink | Log in to Reply

      never had my about section filled out. html ftw. thx – good setup.

    • realloc 7:50 pm on April 16, 2013 Permalink | Log in to Reply

      +1 Excellent!!

    • Syed Balkhi 8:43 pm on April 16, 2013 Permalink | Log in to Reply

      Sweet. I just added authorship on my profile 🙂

    • Crunchify 8:52 pm on April 16, 2013 Permalink | Log in to Reply

      Great Tips. I’ve just updated my profiles..

    • Andrey "Rarst" Savchenko 9:13 pm on April 16, 2013 Permalink | Log in to Reply

      Had you considered implementing `link rel=”author” url=”[g+ profile]”` in plugin pages header? It will simplify setup and won’t need that “indirect” connection through profile page.

      • Samuel Wood (Otto) 9:17 pm on April 16, 2013 Permalink | Log in to Reply

        That would require us to set up a special field somewhere for a G+ account, and if that social-network, then why not add others too, and yadda-yadda..

        This was a freebie, basically. I didn’t have to make any code changes to do it. We’ve had rel=author in there pointing to profiles forever, and the schema.org markup has been there for at least a year or more.

        I just noticed that I seemed to have been the only one to have done this already when I was looking through some search results today, so I felt like a post to show people how was in order. I did fiddle with the markup a bit today for other reasons, but not for this post.

    • Marcel Brinkkemper 9:14 pm on April 16, 2013 Permalink | Log in to Reply

      This is great stuff. +1 for @rarst suggestion

    • Jon Brown 1:32 am on April 17, 2013 Permalink | Log in to Reply

      This is fantastic Otto, Thanks for the detailed write up. Would have taken way longer than I have patience to figure it all out on my own.

    • takien 2:45 am on April 17, 2013 Permalink | Log in to Reply

      Done, thank you 🙂

    • toddhalfpenny 9:35 am on April 17, 2013 Permalink | Log in to Reply

      Absolutely brilliant… lovely work… thanks.

    • Eric Amundson 2:26 pm on April 17, 2013 Permalink | Log in to Reply

      Thanks for the write-up, Otto.

      Looks like the WP.org plugin repo alphabetizes plugin contributors, correct?

      In trying to connect my profile, I found that the Rich Snippet Testing Tool, I get an error saying:

      “Note: The testing tool currently only checks the first rel=author link listed on a webpage for a link to a Google+ profile”

      Issue is that a former contributor has a name that starts earlier in the alphabet, so it’s always finding his author link first, but since he’s not linking to Google +, his avatar isn’t showing in results.

      Any ideas on how to force Google to see the profile of the correct user?

      • Samuel Wood (Otto) 2:36 pm on April 17, 2013 Permalink | Log in to Reply

        I don’t think it is sorted, actually. I think it shows up in the order in the Contributors line in the readme.txt file. But if you have an example I can see, I can track the code down.

        • Aaron D. Campbell 8:10 pm on April 17, 2013 Permalink | Log in to Reply

          Google “WordPress Twitter Widget” and you’ll see Sara’s pretty face, and she’s the last contrib in the list. However, check the Rich Snippet Tool and it shows me. I’m the first contrib in the list. I’d prefer it to show Range, but that one’s in the middle.

          I’m not certain this is the pattern, but that seems to be what’s happening now. I’ll try to tweak the contrib list on a few plugins and see what happens.

          • Samuel Wood (Otto) 8:17 pm on April 17, 2013 Permalink | Log in to Reply

            The readme.txt for that plugin has the people in the same order as the author listing on the sidebar does:


            I have no idea how/why Google shows faces or chooses between them. The rich snippets tool says first one wins, but this is neither the first nor the last time that Google has given me false or contradictory information.

            • Aaron D. Campbell 8:22 pm on April 17, 2013 Permalink

              Yeah, the rich snippets tool says the first wins (and displays the first person), but actual Google searches seem to be showing the last. Since you’re right about the order of contribs matching the readme, I’m going to try reording some to see what happens.

            • Aaron D. Campbell 6:33 pm on April 18, 2013 Permalink

              I gave it a little over 24 hours after the change, and as best as I can tell, Google just likes Sara better. She seems to be listed no matter the order. It may still be cached, but either way it’s still really cool.


            • Samuel Wood (Otto) 6:37 pm on April 18, 2013 Permalink

              24 hours isn’t enough time. Those things likely won’t alter for weeks or more. I know WordPress.org is well-indexed by Google, but seriously, their snippets logic is confounding sometimes. Best to just set it the way you want and let it do its own thing. You can’t force it.

              Mine didn’t start showing up until I changed my G+ pic to be a “recognizable headshot”. Guess they don’t like my scuba avatar. It’s a shame too, I like the blue one.

            • Samuel Wood (Otto) 6:20 pm on April 20, 2013 Permalink

              After screwing around with this for a while, and reading up on the topic, Google seems to get very, very confused with multiple rel=authors. So I just now changed it to only have one rel=author on the plugin page, and that will be the first person listed.

              Hopefully, this should eliminate the ambiguity and cause more predictable results.

    • Brad Dalton 8:56 pm on April 17, 2013 Permalink | Log in to Reply

      Been using this link on my profile for a while already but didn’t add the ?rel=author to the end of the Google url which does make a difference.

    • Mert Yazicioglu 9:31 am on April 20, 2013 Permalink | Log in to Reply

      Before doing this, my plugin WordPress Move was the second result in Google when you searched for “wordpress move”. Now, however, it’s on the third page.

      Not sure if it’s a coincidence.

  • Samuel Wood (Otto) 4:43 pm on September 13, 2012 Permalink |  

    Last December, we added header images to the top of plugin screens. Since then, we’ve made more changes to the plugin directory and started supporting HiDPI images for those plugin headers as well.

    As part of that original header update, one thing that was added which I always meant to do more with was the addition of a new “assets” directory at the top level of the plugin SVNs. This is an optional directory that sits alongside the /tags and /trunk directories, and was just used to hold the banner images. Creating a place to put plugin assets which didn’t need to be included in the plugin itself simply made sense to me.

    It also never made sense to me that the plugin screenshots, which are rarely used by the plugin, needed to be included in the plugin’s ZIP file. Some plugins can use these themselves, certainly, but the majority don’t and it’s just really inflating the size of the plugin to include them.

    So, starting today, you can put your screenshot files in the assets directory instead of in the main plugin directory.

    A few notes, for the technically minded:

    • Screenshot naming conventions have not changed, nor have the readme.txt requirements for their captioning. The naming and behavior is exactly the same, the file can just go into a new place.
    • The old way still works too. If you have your screenshots in the plugin’s “stable” directory, then it will find them there just fine.
    • Screenshots in the assets directory take precedence over screenshots in the plugin’s directory. If you have both, then the assets directory wins. Of course, there’s really no reason to have both, this is just for backwards compatibility.
    • Like everything else in the assets directory, we are serving them through a separate static caching system, and so it may take a few minutes to update when you change them. What this means is that when you put the screenshots in there for the very first time, they may not show up on your page for a few minutes and you’ll just see the captions with no images above them. Please give the proxy some time to retrieve your screenshots and cache them before telling me it’s buggy. It should only take a few minutes. 🙂

    The ultimate goal, of course, is to reduce the size of the plugin ZIP files being served. By not including the screenshots in the plugin, files are smaller and upgrades are thus speedier for everybody.

    In the future, if we have a need for more “directory only” files, I expect them all to be in the assets directory as well, for just this sort of reason.

    • Pippin Williamson 4:48 pm on September 13, 2012 Permalink | Log in to Reply


    • logikal16 5:00 pm on September 13, 2012 Permalink | Log in to Reply

      That’s great news, thanks!

    • Brad Touesnard 5:03 pm on September 13, 2012 Permalink | Log in to Reply


    • Chuck Reynolds 5:04 pm on September 13, 2012 Permalink | Log in to Reply

      This is great. Shouldn’t we also do the same for readme files? With the recent security talks concerning the version number being in the readme’s in each plugin dir.

      • Otto 5:15 pm on September 13, 2012 Permalink | Log in to Reply

        I don’t know what talks you speak of in particular, but a) no and b) knowing the version of code being used is not an inherent security risk.

        A security risk is caused by running insecure code. The solution is not to attempt to hide the version, but to update the code to eliminate the security risk. This sort of thinking is along the same lines of hiding the WordPress version number from public view. Hiding your version number doesn’t improve security in the slightest. Fixing security related issues does.

        • Chuck Reynolds 10:46 pm on September 13, 2012 Permalink | Log in to Reply

          true, i can’t find the specific thing I read the other day but… whatever. just thinking out loud.

          Moved all my plugins’ screenshots to /assets/ from trunk and latest tag.

        • Ian Dunn 7:54 pm on September 14, 2012 Permalink | Log in to Reply

          I think that’s only half true. Obviously, fixing security bugs is the most important thing, but security-through-obscurity isn’t inherently bad, if you understand it correctly.

          Security shouldn’t be thought of as a binary thing — you’re either “secure” of “insecure” — and there are no silver bullets. Instead, it should be thought of in layers. Security-through-obscurity is a good first layer. It keeps the script kiddies away, so that you can focus your time on defending against real attackers.

          It’d be stupid to rely on obscurity as your only layer, but it’s a good practice to employ it as the first layer among many.

    • Ben Lobaugh (blobaugh) 5:12 pm on September 13, 2012 Permalink | Log in to Reply

      Thanks Otto

      @Chuck – good point, you would lose the tagged readme files though. Maybe the readme.txt file should just be blocked from serving?

    • scribu 5:53 pm on September 13, 2012 Permalink | Log in to Reply

      This makes sense. I just moved the screenshots over for all of my plugins.

      I noticed that the readme.txt example doesn’t point to the new /assets/ dir yet.

    • Thomas_Michaela 6:40 pm on September 13, 2012 Permalink | Log in to Reply

      Is there any discussion / ideas how to redesign the “popular plugins” section, so authors don’t need to fake their download numbers anymore?


      • Otto 7:18 pm on September 13, 2012 Permalink | Log in to Reply

        That doesn’t appear to be faked to me, just a bad development practice.

        Edit: Note that if you have hard evidence other than a one-time-thing, then that’s different. I’ll burn and salt the earth with the ashes if you can find a real case of somebody gaming our systems, but this does not appear to be such a case.

    • Jon Brown 7:36 pm on September 13, 2012 Permalink | Log in to Reply

      This all sounds great, nice work!

      Since I’m still a little slow when it comes to SVN though… Am I correct that /Assets is outside of version control? If that’s that case, I think that alone is reason to keep the readme files inside trunk, but even if that is not the case I’d still prefer seeing readme files in the zips.

      • Otto 7:45 pm on September 13, 2012 Permalink | Log in to Reply

        No, you’re not correct, and I’m not sure I understand the question.

        SVN is a version control system. Everything in it is “in version control”. So… yeah, you’ve left me confused.

        And there’s no plan (nor reason) to put readme.txt files anywhere that isn’t part of the plugin and isn’t in the ZIP file. That’s not under discussion nor up for debate, really. Readme’s should be sent with the plugin files.

    • Edward Caissie 8:03 pm on September 13, 2012 Permalink | Log in to Reply

      I must be slow or its not enough coffee today … to implement this new ‘assets’ directory the plugin author needs to send a commit with it included, correct? In other words, the assets directory is not being (has not been?) populated into the existing repository plugins (nor is it part of new plugin repositories).

      • Otto 8:13 pm on September 13, 2012 Permalink | Log in to Reply

        Correct, the /assets directory is not created for you. You can create it at the root of your plugin directory, alongside the trunk and tags and branches directories, and use “svn add” to add it and any files inside it to your next commit.

        • Edward Caissie 8:29 pm on September 13, 2012 Permalink | Log in to Reply

          Thanks. I had tested that with an existing plugin as well as checking out a newly created plugin repository as well. Just been having SVN client issues recently and wanted to make sure I was not _doing_it_wrong().

        • Matt Mullenweg 6:46 pm on September 14, 2012 Permalink | Log in to Reply

          Can we add it to the script that sets up directories for new plugins?

          • Otto 6:50 pm on September 14, 2012 Permalink | Log in to Reply

            We could, just haven’t seen the need to do so. Not everybody needs it, in the same way that uber-simple plugins don’t really need a readme.txt file.

            I’ll go ahead and add it though.

        • RobertPHeller 6:31 pm on June 15, 2013 Permalink | Log in to Reply

          ‘svn mkdir assets’ will both make the directory AND add it to the svn version control all in one step. Then doing a ‘svn mv trunk/screeshot*.png assets/’ moves the screenshots over.

          • Samuel Wood (Otto) 6:47 pm on June 15, 2013 Permalink | Log in to Reply

            The assets directory is automatically created for all new plugins now. You only need to do this if you got your plugin approved before last September.

    • elfin 8:58 pm on September 13, 2012 Permalink | Log in to Reply

      excellent – one reason why I never included any to begin with was because of the file size issue. Nice work again Otto.

    • shazdeh 10:38 pm on September 13, 2012 Permalink | Log in to Reply

      Totally makes sense!

    • Greenweb 1:30 pm on September 14, 2012 Permalink | Log in to Reply

      Great update to the system !

    • XYZScripts 6:08 am on September 15, 2012 Permalink | Log in to Reply

      Good move. Really saves on zip size.
      Next we should separate out readme.txt from folder as Chuck said.
      I think right now readme.txt is parsed from trunk until stable tag is found and then it starts parsing stable tag readme.
      So we have put this file in both trunk and tag which is simply duplicate.
      I dont think readme.txt is needed in s wordpress installation as it reads info from plugin main file (Correct me if an wrong)
      So why not move it to assets?

      • Otto 2:13 pm on September 15, 2012 Permalink | Log in to Reply

        No, the readme.txt file belongs with the plugin file itself and should be in the ZIP file. Moving it to assets makes no sense.

        The readme.txt will remain where it is.

    • Lance Cleveland 1:28 pm on September 17, 2012 Permalink | Log in to Reply

      Great decision. It is smart thinking like this that keeps WordPress ahead of all others and why I continue to recommend it as the best-of-breed for web publishing for my clients.

    • Aaron D. Campbell 2:08 pm on September 17, 2012 Permalink | Log in to Reply

      This was a great change. One of my plugins went from a 168k download to 52k. Thanks Otto.

    • wiredimpact 9:26 pm on September 28, 2012 Permalink | Log in to Reply

      This is a welcome change. It will greatly decrease the size of plugins. Thanks.

    • Aman 8:43 am on October 4, 2012 Permalink | Log in to Reply

      A very great decision 🙂
      Less size more downloads

    • Ben 7:50 pm on October 14, 2012 Permalink | Log in to Reply

      Awesome news!
      I was wondering if you guys where thinking about doing something for the languages files as well?
      I know that means also adapting the way a plugin is installed as well, but the more translations the heavier your plugins gets. Just leaving the .mo files it can be about 100k per language depending on the plugin’s size. Translate your plugin in 10 languages and Bam you get 1Mo extra.

      • Otto 5:42 pm on October 16, 2012 Permalink | Log in to Reply

        No particular plans for languages, but that would be pretty cool. I was thinking more along the lines of having core support for language packs. Like, we could have a big GlotPress install somewhere to allow community translations of plugins and themes, then have an API to serve up-to-date .mo files, then serve them directly to users that request them, and let the core put them in the right place, etc.

        Would be neat, but obviously that’s a big job there, with a lot of moving parts.

        • Ben 8:59 am on October 17, 2012 Permalink | Log in to Reply

          Sounds good, if we’re aiming to this kind of solution, that’s just perfect. But as you said it feels like a lot of changes and work involved.

      • Milan Dinić 6:34 pm on October 23, 2012 Permalink | Log in to Reply

        Still in works.

      • Milan Dinić 6:36 pm on October 23, 2012 Permalink | Log in to Reply

        How about displaying “Screenshots” tab only when there are screenshots, not always when “Screenshots” section of readme.txt has any content?

    • Joe Dolson 7:29 pm on October 22, 2012 Permalink | Log in to Reply

      The recent changes to the plug-in directory have been great — I noticed something today that I’m hoping would be a pretty quick fix: you can’t do a search on the words ‘accessibility’ or ‘accessible’. You can visit the tags, of course, but I don’t think it’s really the right response to send searches for these two terms to the results for ‘access’ — those are definitely two very distinct searches, and really should be giving different results.

      • Otto 7:40 pm on October 22, 2012 Permalink | Log in to Reply

        There’s no limitation on what you can search for. But the search engine considers similar words to be similar for the purposes of searching.

        • Joe Dolson 8:42 pm on October 22, 2012 Permalink | Log in to Reply

          Well, it’s definitely a problem — is there any way to tweak what the search engine considers to be similar? “access” and “accessibility” may be similar from a programming standpoint, but in terms of the search intent, they’re radically different – and I think it’s a serious limitation to the repository that you can’t easily find plug-ins that are intended to support accessibility.

    • RobertPHeller 6:20 pm on June 15, 2013 Permalink | Log in to Reply

      My plugin has a PDF user manual. This adds to the ‘bloat’ of the plugin. The plugin is complex enough to need this level of documentation. I am wondering: if I were to put the PDF manual in the assets directory, how would I link to it from the plugin’s contexual help screens? Right now, with the PDF file embedded in the plugin’s ZIP file, it is just a relative link.

      • Samuel Wood (Otto) 6:35 pm on June 15, 2013 Permalink | Log in to Reply

        You don’t. Files in the assets directory do not go into the plugin itself. You need to have the file in the plugin to be able to use it on people’s sites.

    • TC.K 4:51 pm on June 27, 2013 Permalink | Log in to Reply

      Hi, I added a header image into the assests/ directory, but some how the image does not show up in my plugin page. I checked on my plugin svn assests/ directory, I can see the files is in there, but it is not showed up. what is the problem?

      I don’t know whether here is the right place to ask, if there is another way to report this problem, please let me know.


    • TC.K 5:48 pm on June 27, 2013 Permalink | Log in to Reply

      Sorry, I spell it wrong here. But in the directiory is corret. Here is the link:

      • Samuel Wood (Otto) 5:58 pm on June 27, 2013 Permalink | Log in to Reply

        You named the file wrong, probably from copy and pasting the name. The letter between the 772 and the 250 needs to be an “x”, not that multiplication symbol you have there.

    • TC.K 11:54 am on June 30, 2013 Permalink | Log in to Reply

      Yes, you are right!! Thank you very much!

    • Lars Schenk 11:35 pm on November 27, 2013 Permalink | Log in to Reply

      Looks like the /assets makes a problem for git-svn. Question asked here:
      Not answered since 1y.

      Also found in other words: ” Does anyone have any insight on using this (updated) commit workflow along with the SVN assets folder? I have my git and SVN repositories synced up, but now I need to update the screenshots. I assume that if I do a pure SVN commit to update these then everything will get out of sync. I don’t see a way to update the assets folder via git-svn either. Any help would be appreciated!”

  • Samuel Wood (Otto) 6:12 pm on June 9, 2012 Permalink |
    Tags: , ,   

    The Plugins directory and readme.txt files 

    Every once in a while, somebody pings me to say that their plugin isn’t showing up properly in the directory. Almost always it’s a problem with the plugin itself having incorrect information somehow. So I thought I’d do a quick post to explain some aspects of the plugin directory, and explain some of the more obvious stuff which a lot of people miss.


    First, let’s briefly go over the layout of your plugin in the SVN repository. There’s three directories created by default, and an optional fourth one that you can create yourself.

    Trunk: The /trunk directory is where your plugin code should live. The trunk can be considered to be the latest and greatest code. It’s the development version. Hopefully, the code in trunk should always be working code, but it may be buggy from time to time because it’s not necessarily the “stable” version. For simple plugins, the trunk may be the only version of the code that exists, and that’s fine as well.

    Tags: The /tags directory is where you can put versions of the plugin at some specific point in time. Usually, you’ll use version numbers for the subdirectories here. So version 1.0 of the plugin would be in /tags/1.0, version 1.1 would be in /tags/1.1, and so forth. Again, not every plugin uses tags for versioning.

    Branches: The /branches directory is a place that you can use to store branches of the plugin. Perhaps versions that are in development, or test code, etc. The WordPress.org system does not use the branches directory for anything at all, it’s considered to be strictly for developers to use as they need it.

    Assets: The last optional directory doesn’t exist by default (Edit: It does now, older plugins may be missing it, but all newly added plugins will get it by default.) You can create it yourself though. Just make a directory called “assets” next to those other three directories. Assets currently only has one use, which is to store the banner image to be displayed on your plugin page. We may use it for more things in the future. For now, you can just make an image, name it banner-772x250.png or banner-772x250.jpg, and put it in there. Easy.

    Additional Info: Since creating this post, some new files have been added to the assets folder. You can create a banner-1544x500.png or banner-1544x500.jpg now too. This high-resolution banner will be shown to users with high-resolution displays, such as phones or tablets or certain newer laptops. Additionally, screenshots which once lived in the plugin’s own directory can now be moved from there into the assets directory. This allows the screenshots to be shown on the plugin page, but not included in the download of the plugin, reducing file size. It’s recommended to put screenshot files in /assets.

    Parsing the plugin information

    All plugins contain a main PHP file, and almost all plugins have a readme.txt file as well. The readme.txt file is intended to be written using a subset of markdown.  The example readme.txt explains most everything pretty well, but there’s a few little tidbits that are worth pointing out.

    First is the concept of the “Stable Tag”. When WordPress.org parses the readme.txt, the very first thing it does is to look at the readme.txt in the /trunk directory, and then read that “Stable Tag” line. If the Stable Tag is missing, or is set to “trunk”, then the version of the plugin in /trunk is considered to be the stable version. If the Stable Tag is set to anything else, then it will go and look in /tags/ for the referenced version. So a Stable Tag of “1.2.3” will make it look for /tags/1.2.3/.

    Important bit: Everything else is read from this new location. If the Stable Tag is 1.2.3 and /tags/1.2.3/ exists, then nothing in trunk will be read any further for parsing by any part of the system. If you try to change the description of the plugin in /trunk/readme.txt, and Stable Tag isn’t trunk, then your changes won’t do anything on your plugin page. Everything comes from the readme.txt in the file being pointed to by the Stable Tag.

    Now let’s get to the plugin information itself. The WordPress.org directory reads the main plugin PHP file to get things like the Name of the plugin, the Plugin URI, and most importantly, the version number. On the plugin page, you’ll see the download button which reads “Download Version 1.2.3” or similar. That version number comes from the plugin’s main PHP file.

    Some people get this versoning confused due to the tags system. The Stable Tag points to a subdirectory in the /tags directory. But the version of the plugin is not actually that, it’s the version that is listed in the plugin’s PHP file itself. If you have changed Stable Tag to 1.4 and the plugin still says 1.3 in the PHP file, then the version listed will be 1.3.

    Readme.txt pieces that everybody gets wrong

    Back to the readme.txt. There’s a line called “Contributors”. This line has always been expected to be WordPress.org usernames only. WordPress reads those, gets information about that user, gets their gravatar, name, etc, and makes the authors listing. If you put anything here that’s not a WordPress.org username, then it doesn’t look nearly as good. No picture, no link, just text.

    Other information in the readme.txt is read and used at various points on the Plugin listing. The Donate link makes a “Donate to this plugin” link in the sidebar. The “Requires at least” and “Tested up to” fields are used for compatibility checking, even on the WordPress installation itself. Few people get these wrong.

    One thing a lot of people get wrong is this line:
    “Here is a short description of the plugin.  This should be no more than 150 characters.  No markup here.”

    That bit is serious, and you should read it again. That one line people get wrong more often than anything else. That line of text is the single line description of the plugin which shows up in big letters right under the plugin name, and if it’s longer than 150 characters, it gets cutoff and makes your plugin page look silly.

    Markdown allows for easy linking in your readme.txt as well. Just write like this to link a word to a URL:


    Videos can be put into your readme.txt too. A YouTube or Vimeo link on a line by itself will be auto-embedded. It’s also possible to embed videos hosted on VideoPress using the wpvideo shortcode. More on that topic here: http://wpdevel.wordpress.com/2010/02/20/plugins-can-now-include-videos-in-their-readme-txt-files/


    I don’t think I covered everything, but hopefully that will explain some of the more obscure features of the directory and how it works. If it reduces the number of times people send me the question “why didn’t my version change show up in the directory”, then I think this post was time well spent. 🙂

    • Marcus 7:32 am on June 10, 2012 Permalink | Log in to Reply

      I must admit, I’ve made one or two of these mistakes starting off 🙂

      Useful article, it would go great linked somewhere in the developer center, as I’m sure that’s where people starting would look first.

    • Lance Cleveland 2:37 pm on July 12, 2012 Permalink | Log in to Reply

      Don’t forget about the new “high definition” banners for the header image. If memory serves this is twice the resolution of the standard banner in the assets directory at 1444×500.

    • Mike Schinkel 7:16 pm on August 3, 2012 Permalink | Log in to Reply

      Just replying so I can get subscribed to this blog (might be another way, but can’t figure out how.)

    • Brad Touesnard 3:53 pm on August 17, 2012 Permalink | Log in to Reply

      @Otto Would it be possible to start supporting the filename README.md in addition to readme.txt? A lot of developers host their plugins on GitHub as well but the filename readme.txt isn’t run through the markdown parser at GitHub. It would be nice if .org supported the README.md filename as well.

    • Gwyneth Llewelyn 10:12 pm on November 18, 2012 Permalink | Log in to Reply

      Ok, I’m a bit confused now.

      “If the Stable Tag is 1.2.3 and /tags/1.2.3/ exists, then nothing in trunk will be read any further for parsing by any part of the system. If you try to change the description of the plugin in /trunk/readme.txt, and Stable Tag isn’t trunk, then your changes won’t do anything on your plugin page. Everything comes from the readme.txt in the file being pointed to by the Stable Tag.”

      So if I understand this correctly, the best way to deal with this scheme is simply to have a single file under /trunk/, which is readme.txt, and that needs only to hold 9-10 lines or so with the headers — and just point to the “Stable Tag”? Then the *rest* of the readme.txt *which is under the tag, not trunk* will be read & parsed instead? I don’t need to have a full copy of readme.txt both under /trunk/ *and* /tags/X.Y.Z/ ?

      You see, I hate unnecessary file duplication 🙂 I love the idea of having a super-small, 9-line only, readme.txt file under /trunk/ which just points to the correct place. Also, it makes this far easier to revert to earlier versions in case something goes seriously wrong!

      Sorry if all of this sounds incredible obvious to you seasoned plugin developers 🙂

      • Gwyneth Llewelyn 10:44 pm on November 18, 2012 Permalink | Log in to Reply

        Maybe all that’s needed on trunk/readme.txt is 2 lines after all:

        === Plugin Name ===
        Stable tag: X.Y.Z

        Is that right? The remaining readme.txt will come from tags/X.Y.Z instead? If so, this is just awesome!

      • Samuel Wood (Otto) 4:38 am on November 19, 2012 Permalink | Log in to Reply

        Yes, that works.

        No, you absolutely should not do it that way.

        There is a *convention* in place here. People expect trunk to contain the latest development code of your plugin. In other words, the latest and greatest code, unstable changes and all, belongs in trunk. The latest stable, versioned, tagged code, will be in a tags directory.

        The directory is based around this concept. There are beta-tester plugins which assume this to be true. Forget about “duplicated files”, do it the way everybody else does it so that you don’t mess up the friggin’ system. 🙂

        Put your development code in trunk. Tag the ready-for-release versions of the code in the tags directory. This is the best way to manage things. Even repository systems such as git and github have the concept of a main trunk for development and tags for versioning. The goal isn’t to make things easier for you to manage, the goal is to make the code accessible to everybody else in a sane way.

        • Gwyneth Llewelyn 4:42 pm on November 19, 2012 Permalink | Log in to Reply

          Thanks for the clarification and I do apologise if I have understood you wrongly. Maybe you should clarify that duplication of everything continues to be mandatory, and not optional, to stick to conventions. Your article, read in a certain light, seemed to convey the idea that the convention was changed exactly for the benefit of keeping things simple.

          I’m not here to discuss what is better and what is not — I’ve just asked the question on how to do things from now on because the article lead to believe me that the convention had changed, or, if it hadn’t, that “beginners were always making mistakes and can do things in much simpler ways if they understand the directory structure better”. And I appreciate your answer: no, nothing has changed.

          “The goal isn’t to make things easier for you to manage”. Why not? KISS is always a good philosophy, IMHO.

          • Samuel Wood (Otto) 4:59 pm on November 19, 2012 Permalink | Log in to Reply

            It’s not really duplication though. SVN doesn’t store files that way, it really just stores changesets. The trunk/tags/branches convention is SVN’s, not ours. You can tag things using an svn copy operation, and that’s not making new files in svn, just marking copies of the files at a specific point in time.

            The Stable Tag and readme.txt stuff is indeed ours, simply for the purpose of keeping things in the directory sane.

    • brasofilo 2:08 pm on December 18, 2012 Permalink | Log in to Reply

      Finally I got the /tags/ concept and am correcting a wrongful use of the “Stable Tag” (I had it declared, but the version was not present in the tags folder), although the system was kind enough to make it work.

      Now, I’m looking for articles on how to use the /trunk/ when developing a new version of the plugin.
      I mean, is it possible to install and update from there?

      • Samuel Wood (Otto) 5:56 pm on December 18, 2012 Permalink | Log in to Reply

        Trunk should be the “beta” version, and have its version numbers indicating such. So if my Stable Tag was like 1.0, and I had a /tags/1.0 directory, then I could make trunk’s version into 1.1-beta or something like that, and make all the changes I liked, then when it was ready for release, change it to 1.1 and tag it and update the Stable Tag field in the readme.txt to point to the new one.

        If you use this sort of structure, with trunk containing the latest beta code, then you can easily use a plugin like https://wordpress.org/extend/plugins/plugin-beta-tester/ to update to that beta version on a site.

        • brasofilo 7:29 pm on December 18, 2012 Permalink | Log in to Reply

          Perfecto, Otto, gracias!

        • Hinjiriyo 1:56 pm on January 31, 2014 Permalink | Log in to Reply

          Now I got the concept of the trunk dir! Thank you very much for your explanation.

          There are other informations about the way the readme file and tag files are processed by the WP plugin repo. I wish someone would extend the Plugin Developer FAQ with that article and the role of the trunk.

    • amineoujda 10:09 am on July 16, 2013 Permalink | Log in to Reply

      I want to change the line description that appears below the plugin name

    • bendoh 4:44 pm on January 22, 2014 Permalink | Log in to Reply


      Is there any sort of documentation as to the exact subset of Markdown that’s being used on these readme.txt files, or could you perhaps point me to the code that’s actually producing the rendered markup?

      I just submitted a plugin with standard Markdown list formatting, (e.g., * Item 1\n*Item 1) in the readme.txt, and it was not rendered correctly on the plugin page: it just appeared all together in one paragraph without any markup.

    • duck__boy 9:32 am on April 14, 2014 Permalink | Log in to Reply

      A very will written post, but I must admit, I’m still struggling with the `readme.txt` file. I suspect I’m just missing something, but I’m hoping you are able to help.

      I have both a version of my plugin with the `readme.txt` file, in the `/trunk` and `/tag/1.2.4` folders, but none of the details from `readme.txt` seem to be read, including the Stable Tag. This also means that the `Installation`, `FAQ` and `Changelog` sections are not available on the plugins `Details` page).

      So taking the above in to account, if I change the version number of the main PHP file in `/trunk` to say `1.3-beta`, that version number is shown when you search for my plugin, and my `/tag/1.2.4` file is ignored.

      The plugin in question is https://wordpress.org/plugins/admin-bar-button/

      • duck__boy 3:31 pm on April 22, 2014 Permalink | Log in to Reply

        Just in case anyone ever runs in to this, my issue was that my `readme.txt` file was not encoded as ANSI for some reason. I simply recreated the file using the correct encoding and all is now good with the world (well, my plugin anyway…).

    • Chip Bennett 5:02 pm on April 22, 2014 Permalink | Log in to Reply

      @Otto42 is there any chance that the readme parser could be changed so that it reads “Tested up to” and “Requires” from the trunk copy of readme.txt? It would sure make it a lot easier for Plugin developers to update this information in the Plugin directory. As it is right now, we either have to update the readme.txt in the stable tag readme.txt, or else bump the version number just to indicate that the Plugin has been tested and works with the latest WordPress version.

      • Samuel Wood (Otto) 5:03 pm on April 22, 2014 Permalink | Log in to Reply

        You can edit the readme.txt file in a tagged version. SVN isn’t like Git, it doesn’t have a restriction preventing you from editing tagged versions.

        I’ll think about using the trunk readme for other things though, some of this seems like it might be a candidate for a refactoring.

    • Raghunath Gurjar 1:37 pm on June 17, 2014 Permalink | Log in to Reply

      I have released my plugin two version but still on plugin download page its show first release version 1.0 while when you will download my plugin , you will get all latest code.

      You can also find developer log from here https://wordpress.org/plugins/simple-testimonial-rutator/developers/

      Can you someone help me please?
      I don’t know why this happening , i have updated the Stable tag in readme.txt file to 1.2

      • Samuel Wood (Otto) 5:25 pm on June 17, 2014 Permalink | Log in to Reply

        All information in the system is gathered directly from your plugin. If the displayed information is wrong, then your plugin is wrong.

        In this case, notice that the version number in the plugin itself is 1.0:

        Fix the plugin to have the correct information.

        • Natallya 7:21 pm on August 22, 2014 Permalink | Log in to Reply

          Hi, does anyone know how to get feedback for a plugin published?
          It’s more then month we sent it for review but no information at all. How can I know if it was declined ?

          Thank you!

          • Samuel Wood (Otto) 7:24 pm on August 22, 2014 Permalink | Log in to Reply

            We don’t have any plugins in the queue that have been there for more than a month. You would have received an email about it, and if we got no answer for 7 days, then it would be automatically rejected and you would receive an email about that too.

            Make sure that your email system is set up to never spam any emails coming from WordPress.org. We send emails for lots of things, but we cannot control what your end does with them.

          • Samuel Wood (Otto) 7:26 pm on August 22, 2014 Permalink | Log in to Reply

            Looking closer, it appears that your plugin was approved and you never continued on and did anything with it. Again, check your emails, your plugin was approved on the 11th of last month.

    • Natallya 5:46 pm on September 4, 2014 Permalink | Log in to Reply

      Thanks a lot, email had gone to junk… Setting up all further things. Thank you again for a good news! 🙂

    • JayDeep Nimavat 12:34 pm on October 4, 2014 Permalink | Log in to Reply

      Hello wordpress friend,

      I have created new version of “JDs Portfolio” plugin,

      I have done change,

      • deleted all folder and files from Repository trunk directory and uploaded new files and folder of new plugin version.
      • Created new directory 1.1 in Tags directory where 1.0 is already available and I uploaded all new files and folder of new plugin version in 1.1.

      The duration of uploaded new version plugin is more than one day.

      The problem is that it still give old version of plugin when anyone download it, and shows in Developer option as other version, as current version it display me old version 1.0.1 of JDs Portfolio plugin.

      Please help me to solve :
      How can I apply new version of plugin as current version?

      your good suggestion most appreciate,
      Thanks a Lot’s,

    • salescart 4:45 pm on October 8, 2015 Permalink | Log in to Reply

      Ok, I’m sorry but I’ve read this and I’m still confused. We tried to make our first revision at https://plugins.svn.wordpress.org/e-commerce-by-salescart/tags/1.1.0/

      1.) So are you saying it still looks at the readme.txt file in the /trunk folder to find the stable tag, and based on that that, it then goes to that /tags folder for the plugin content and will ignore the rest of the content in the /trunk folder?

      2.) Or, are you saying the only released version is ALWAYS the version at the trunk? (This would be despite the readme.txt file’s stable tag saying 1.1.0 instead of trunk and that the tags folders is just for historical reference). Therefore, the /trunk version must be the most up-to-date version… ?

    • webbistro 9:29 am on January 10, 2016 Permalink | Log in to Reply


      I’ve read this carefully, and I uploaded new versions many times, but I am afraid I need help now. I am sure that all data is correct in my tag and trunk readme-s and in the main php, but I still see the old description, changelog, everything below readme’s header. The significant differences from the previous updates is that I am not receiving email notifications any more.
      Please help https://wordpress.org/plugins/enhanced-media-library/ (I know, too many actions… but I hoped I just did something wrong).


compose new post
next post/next comment
previous post/previous comment
show/hide comments
go to top
go to login
show/hide help
shift + esc
Skip to toolbar