0

I am learning WordPress Plugin Development. My Code is like below.

class Admin
{
    
    public function __construct()
    {        
        add_action( 'admin_menu', [$this,'news_meta_boxes'] );
    }

    public function news_meta_boxes()
    {
        add_meta_box('news_settings', 'News Settings', [ $this, 'post_settings_html' ], 'news', 'normal', 'default');
        add_meta_box('display_settings', 'Display Settings', [ $this, 'display_settings_html' ], 'news', 'normal', 'default');
        add_meta_box('style_settings', 'Color Settings', [ $this, 'style_settings_html' ], 'news', 'normal', 'default');
    }
    

    public function post_settings_html($post)
    {
        $stored_meta = get_post_meta($post->ID); // I would like to use it globally as like member variable

        // more code here
    }


    public function display_settings_html($post)
    {
        $stored_meta = get_post_meta($post->ID); // I would like to use it globally as like member variable
        
        // more code here
    }

    public function style_settings_html($post)
    {
        $stored_meta = get_post_meta($post->ID); // I would like to use it globally as like member variable

        // more code here
    }
}

How can I use $stored_meta = get_post_meta($post->ID); globally like member variable ?

2 Answers 2

1

You shouldn’t.

To get the data for the correct post you should be using the $post variable passed to the callback function. This represents the post being edited. Therefore to get the metadata for the correct post you should call get_post_meta() inside the callback function.

5
  • Thanks @Jacob Peattie. Actually I am learning Plugin development. I am using Same Post in three callback functions. That's why I would like to use globally. Thanks.
    – Foysal
    Jul 13 at 8:42
  • 1
    That’s the point. You shouldn’t do it that way. You should be using the post variable passed to the callback and there’s no sensible way to share that variable between callbacks. Jul 13 at 10:13
  • Thanks @Jacob Peattie. That means I have to use Post Variable in every callback function sperately.
    – Foysal
    Jul 13 at 10:19
  • 1
    Yes. Exactly. That’s what you’re supposed to do. Jul 13 at 12:15
  • Thanks @Jacob Peattie. Is it the right approach ? I am confused.
    – Foysal
    Jul 13 at 12:22
0

First thing you can do is to switch to using add_meta_boxes_{$post_type} action to register your metaboxes. This way the register method only fires for your custom post type. This action also gives you the current post as a parameter and can be used to fetch the post meta data.

Another thing is to pass custom callback args to the add_meta_box() function as the last argument. This data is then available in the render callback. The callback argument could be used to pass the meta data to the render function. Alternatively get the meta data in the render method by getting the current post ID from the post object that is passed as the first parameter to the method.

The following example demonstrates these improvements. In my example I've also split the metabox configuration to its own method and assume the metabox html is located in a separate template file (to keep the render method cleaner).

Note the metakey usage in the get_post_meta(). If you happen to save the data from the metabox as an array, then you can do this to only pass the needed data to the specific metabox.

class Admin
{

    public function __construct()
    {
        add_action( 'add_meta_boxes_news', [$this,'register_news_metaboxes'] );
    }

    public function register_news_metaboxes(WP_Post $post)
    {
        foreach ($this->metaboxes() as $metabox_id => $metabox) {
            add_meta_box(
                $metabox_id,
                $metabox['title'],
                [$this, 'render_metabox'],
                $post->post_type,
                $metabox['context'],
                $metabox['priority'],
                [
                    'post_meta' => get_post_meta(
                        $post->ID,
                        $metabox['metakey'] ?: $metabox_id,
                        true
                    ), // get meta by key maybe?
                    'template' => $metabox['template'],
                ]
            );
        }
    }

    public function render_metabox(WP_Post $post, array $metabox)
    {
        // $metabox array keys: id, title, callback, args
        // var_dump($metabox);
        $callbackArgs = $metabox['args'];
        $postMeta = $callbackArgs['post_meta'];
        $templateFile = $callbackArgs['template'];

        if ( file_exists($templateFile) ) {
            // the declared variables and function parameters
            // are available in the included file
            // e.g. $postMeta
            include_once $templateFile;
        }
    }

    protected function metaboxes()
    {
        return [
            'news_settings' => [
                'title' => 'News Settings',
                'context' => 'normal',
                'priority' => 'default',
                'metakey' => '',
                'template' => 'path/to/template.php',
            ],
            'display_settings' => [
                'title' => 'Display Settings',
                'context' => 'normal',
                'priority' => 'default',
                'metakey' => '',
                'template' => 'path/to/template.php',
            ],
            'style_settings' => [
                'title' => 'Color Settings',
                'context' => 'normal',
                'priority' => 'default',
                'metakey' => '',
                'template' => 'path/to/template.php',
            ],
        ];
    }
}

Modify as needed.

2
  • Thanks @Antti Koshkinen. Your solution is awesome. You created an array of Metabox Values. It is good for code maintainability. But isn't problematic for Resource Usage ? Thanks.
    – Foysal
    Jul 13 at 9:52
  • 1
    @Foysal, I don't know, I've never really given a thought to that as I haven't faced any issues with this kind of config arrays containing only few items. It might, if the array was really big I think, but it is something you need to measure to find out. The config could probably be stored in a separate PHP file, which returns the array, and included / read only when needed. Jul 13 at 10:03

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.