7

Making my plugin extensible is the next way to solve most people's problems. And I know I can place plenty of filter and action hooks here and there to make things more dynamic. But to me, it's too messy.

Recently a user of my plugin asked to change tooltip text in their end, and in their case it's not that bad reason. There are 6-8 tooltips on that page. I know I can place filter hooks for each of 'em. But should I?

Is there any drawback, performance issue regarding placing many hooks?

  • 1
    Isn't that th same as How to create an API for my plugin? – fuxia Aug 24 '16 at 18:33
  • @toscho a kind of. But the answers here are good enough to be not marked as duplicate because they are pointing to something good too. BTW thanks for the powerhouse. Will help a lot to sorting my issue. – Mayeenul Islam Aug 25 '16 at 5:05
6

As long as hooks don't have anything hooked to them they are no-ops, that is do nearly nothing and have no considerable effect on runtime. It gets quite different when things are hooked and there are a lot of calls.

Since you talk about customizing strings the good example would be gettext hook in core. Every string that is localized passes through it.

So in theory this is a very flexible hook that allows to filter text nearly anywhere. In practice it can fire thousands of times and if you just hook into it unreservedly it will quickly slow down complex site to a halt.

You don't cover your use case in sufficient detail to recommend specific implementation. In general you have multiple choices on how to organize this:

  • apply_filters( 'prefix_tooltip', $text ) is basic case, the filter would have to figure out does the text match exactly to determine context, thus fragile.
  • apply_filters( 'prefix_tooltip', $text, 'type/location' ) additional argument allows you to specify type of tooltip, which filter can target; so even if text changes, the type still identifies it.
  • apply_filters( 'prefix_tooltip_' . $type, $text ) dynamic hook name, which changes with variable value; this is very flexible for cases of many/generated types, the issue mostly is that dynamic hooks are harder to discover in code and are much worse at self-documenting;
  • apply_filters( 'prefix_tooltips', $texts_array ) single filter for complete set of tooltips used.

At a count of 6–8 entries there won’t really be meaningful performance difference between these.

What is important for you to learn here is what approaches there are and that you need to carefully pick the most appropriate one for every case, to have it be meaningful and convenient for yourself and downstream developers.

3

There are really two questions here 1. what is the impact of having an hook? and 2. Should you just spread hooks everywhere

  1. The impact is close to zero. If there is nothing that hooked on on the action/filter the calls to do_action/apply_filters will return almost imidiatly, so there will not be any noticeable impact to people that do not use the hook, and therefor it is not technically bad to add them (if you give any semi reasonable reason to adding hooks to core, it will most likely be added by the core theme).

  2. But is it smart as a software development practice? No. Hooks are APIs and APIs means commitment on your part to maintain them in the long run. Therefor like any "official" API you create, you should think is it something that make sense for your plugin in the long run and you do not do it just to make one plugin user happy.

From your description, if you think that there is a text that needs customized, maybe you should consider using some kind of settings screen for that. This is obviously also some kind of API, but it is more visible accessible for the end users.

  • maybe you should consider using some kind of settings screen for that. Sorry Mark, that'd be way too messy for a situation like that I've described. Because that will generate a db query too where there's not a necessity to add more load (i.e. tooltip text). – Mayeenul Islam Aug 24 '16 at 19:39
  • 1. Forcing users to write code in order to make a change in a text is much more messier than having a setting. If you don't think that there is enough value for the user to change the text, then why do you think that bloating your code with functionality that users will not use is a good idea? 2. unless your plugin is very trivial it is unlikely you will need another DB query as all options of the site are loaded with one query @MayeenulIslam – Mark Kaplun Aug 24 '16 at 20:54
  • Thanks Mark, but I find no reason to go with settings API for a simple change to tooltip. BTW settings API is a dynamic way, that's obvious, I agree. – Mayeenul Islam Aug 25 '16 at 5:03
3

Customization is always a stone of stumbling (painful process). From one side we have a real requests (issues) from users which always matters. On other hand all of this additional options can turn your lovely theme, plugin or some abstract product to the hell. So what can we do as a developer?

First of all. Write extensible code with opportunity to change some of pieces of your code — reusable code. Classes, interfaces, traits and just splitting long-wrong code into small methods (functions). Some part of users can easily use them without changes in your product. For example, someone can create a widget with his own needs and use internal plugin function please_echo_the_plugin_awesome_stuff().

Adding the new filters and actions is not bad idea. Many popular plugins like Jetpack or bbPress have hundreds of filters inside their code. Sometimes even excessively. Each new filter (or action) without any handlers usually not doing a large overhead. It's a microseconds.

10^−3 s millisecond ms 10^−6 s microsecond µs

Much more important is what you're doing on this action by adding new handlers via add_action() or add_filter(). For example, requests to the database server (sometimes non-obvious, like getting non autoload option by get_option()). And you can measure it. The most simple example:

$start = microtime(true);
// Do some stuff here
$end = microtime(true);
echo $start, PHP_EOL, $end, PHP_EOL, $end - $start, PHP_EOL,

It is very simple and sometimes most suitable technique to profile your code. By the way WordPress have internal "stopwatch", checkout timer_start() and timer_stop().

Or you can use XDebug. It may seem very complex to configure. But you can use VVV or any other ready-to-go server. All of them already have properly configured Xdebug and you can just use it - sounds great, isn't it?. If you're using VVV just hit few commands:

vagrant ssh
xdebung_on

That's all! Switch to your IDE and profile your code. Or use VVV internal services like WebGrind. More about this techniques you can find at Code Debugging Wiki. It should be remembered that using Xdebug make effect on the performance, but you can find slow code (bottleneck).

And third. The last thing. WordPress philosophy is Decisions, not Options.

  • Thanks for the awesome answer. I wish I could accept multiple answer at once. But I's taught to accept the only the most acceptable one. Your one's too good, but it's not to be abandoned also. Good bunch of advises. Thank you so much. – Mayeenul Islam Aug 24 '16 at 19:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.