5

I'm making a plugin for a website, which methods I'd like to use in a few different places, such as page templates, shortcodes etc.

I don't want to make the plugin class global or create more than one instance (I'm creating one instance of it on plugin activation).

What's the best approach to do it? Should I make shortcodes that use those functions? Or is there a better way?

3

I'm not entirely sure what you want to do exactly. But basically you just create one instance and then add functions like public static function FunctionName() to be used anywhere you want after the plugin got activated. To fire your hooks simply use the public function __construct().

Taking the Sample Plugin from below, the FooBar method can be called in any template like that:

<div class="foobar">
  <?php echo MyPlugin::FooBar(); ?>
</div>

And to call FooBar inside its class in another function you'd do:

self::FooBar();

Sample Plugin

<?php
/*
Plugin Name: My Plugin
Description: Lorem ipsum dolor sit amet.
Version: 1.0
Author: You
Author URI: https://example.com
*/

class MyPlugin {

  // Fire your hooks from here.
  public function __construct() {

    add_action('wp_enqueue_scripts', [$this, 'scripts']);
  }

  // Use any generic function to be used for hooks.
  function scripts() {

    wp_enqueue_script('abc_snippets', plugin_dir_url(__FILE__) . 'js/scripts.js', ['jquery'], NULL, TRUE);
  }

  // Use static public functions to also be used outside of this class.
  public static function FooBar() {

    return 'Hello World';
  }

}

new MyPlugin();
3

One way is to use static methods from class itself, as @leymannx explained in his answer.

I prefer a little bit different approach, which is a little bit nicer/cleaner (but it's only my opinion, so feel free to argue with that statement). I do it like so:

  1. If some function should be available for use in templates, then I register is as a template tag (so I call it the same way WordPress does - get_X for getting something and the_X for printing something.
  2. If some function should be available for use as a shortcode, then I register such shortcode.
  3. I then register my own filters/actions hooks for the functions/shortcodes above and in my class I use these hooks and write proper code - this way the code is encapsulated in class properly.

And some (very basic) example:

In file template-tags.php I'll add this code:

function the_wpse_hello_world_message( $name = '' ) {
    echo get_wpse_hello_world_message( $name );
}

function get_wpse_hello_world_message( $name = '' ) {
    return apply_filters( 'get_wpse_hello_world_message', 'Hello World', $name );
}

So anyone can easily use both of these functions anywhere in the code, and it's pretty easy to find out what is the "public API" of my plugin.

And later in my class I do something like this:

class My_WPSE_Super_Plugin {

    protected function initHooks() {
        add_filter( 'get_wpse_hello_world_message', array( $this, 'get_wpse_hello_world_message_filter' ), 10, 2 );
    }

    ...

    protected get_wpse_hello_world_message_filter( $result, $name ) {
        if ( trim($name) ) {
            return 'Hello, ' . $name . '!';
        }

        return $result;  // or return 'Hello world!'.
    }
}

The pros for this method are (IMHO):

  • it's easier to learn the "public API" of a plugin (which is important if the team is bigger, or if you will work with given site for a long time)
  • the real code inside the class gets properly encapsulated
  • the "public API" is separated from real implementation, so it's easy to document (write some comments for users) and to do refactoring later someday... Let's say the class gets to big and you want to divide it to smaller classes? What then? Will all users have to change all their templates?
  • it allows to modify these parts using filters/actions (and we all love WP exactly for that, right?)

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.