I am creating tooltips that I will use throughout my site.

Each individual tooltip is created as an object, all of these tooltips need to be ingested with these rules:

  1. I should be able to hold an array with all the tooltips.

  2. Given my array, I should be able to loop through each and call a method to output that tooltip as simple HTML.

Here's how I create a tooltip:

interface Tooltip_Interface {
    public function get_attribute( $attribute );

class Tooltip implements Tooltip_Interface {

    public $data;

    public $is_data_processed = false;

    public function __construct( array $data ) {
        $this->data = $data;

    protected function process_data() {

        if( $this->is_data_processed ) {

        $this->is_data_processed = true;

        $this->data = array_merge([
                'id'        => '',
                'title'     => '',
                'body'      => '',
                'meta'      => ''
        ], $this->data);

        $this->data['id'] = stripslashes($this->data['id']);
        $this->data['title'] = stripcslashes($this->data['title']);
        $this->data['body']  = stripslashes($this->data['body']);
        $this->data['meta']  = stripslashes($this->data['meta']);

    public function get_attribute( $attribute ) {
        return $this->data[$attribute];

interface Tooltip_Style_Interface {
    public function get_markup();

class Style_1 implements Tooltip_Style_interface {

    public $tooltip;

    public function __construct( Tooltip_Interface $tooltip ){
        $this->tooltip = $tooltip;

    public function get_markup() {
        return sprintf(
            '<div class="nice-tooltip" id=%s><div class="main-body"><h4>%s</h4>%s</div></div><!--%s-->',

Which, in order to output the HTML, I need to call the get_markup method:

echo (new Style_Video
        new Tooltip_Video([
            'id' => 'instagram-help',
            'title' => 'Need help with Instagram?',
            'body' => 'See Our Instagram Help Support Articles.',
            'video'=> 'https://www.youtube.com/watch?v=_Jc-Xcw1nJI',
            'meta' => 'Last update: last year'

But this is somewhat hard-coded. I decided then to turn this into a singleton due to the need to have the shared array of tooltips (shared resource) at hand:

class Tooltip_Register {

    protected $tooltips = [];

    private static $instance;

    private function __construct() {

    public static function get_instance() {
        if (null === self::$instance) {
            self::$instance = new self();
        return self::$instance;

    final function register_tooltip( Tooltip_Style_Interface $tooltip ) {
        $this->tooltips[] = $tooltip;

And then have a handler to output all of the tooltips:

final class Tooltip_Handler extends Tooltip_Register {

    public $is_render_finished = false;

    public function __construct() {

    final public function render_tooltips() {
        if( $this->is_render_finished ) {

        foreach( parent::get_instance()->tooltips as $tooltip ) {
            echo $tooltip->get_markup();

        $this->is_render_finished = true;

Which now allows me to add as many Tooltips as I want with this piece of code:

    ( new Style_1
            new Tooltip([
                'id' => 'instagram-help',
                'title' => 'This widget is not working?',
                'body' => 'See Our Widgets Videos',
                'meta' => 'Last update: last year'

My problems are that I have to use a singleton which doesn't fare well with dynamicism due to its nature.

Concretely, how can I rewrite this so that I:

  1. Have a nice way to register a tooltip just as I did with Tooltip_Register::get_instance()->register_tooltip().

  2. Have "shared variables" such as Tooltip_Register's $this->tooltips.

  • \$\begingroup\$ How do you render the template in your application? Do you use a template engine at any point? When exactly is the render_tooltips method called? \$\endgroup\$ Mar 9, 2018 at 7:53
  • \$\begingroup\$ @insertusernamehere Merely with an echo. The "render tooltips" is the last call of the whole miriad of classes. \$\endgroup\$ Mar 9, 2018 at 13:17
  • \$\begingroup\$ @insertusernamehere pastebin.com/bs0k0caM This is the full code, just for reference. Can ignore "load scripts" and add_action (they're just hooks within WordPress). \$\endgroup\$ Mar 9, 2018 at 16:55


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.