3

Inside functions.php:

add_action('init','my_action');

function my_action() {
    if($dontknow) {
        $passme = "yes";
    } else {
        $passme = "no";
    }
}

Inside index.php of the current theme:

echo $passme;

Is there a global to use for this purpose? Shall I use add_option (this is not a good idea for each request I guess)? Shall I use a custom global variable?

Is there a better / usual / standard way to do this?

10

Use an object to keep the value of the variable and a custom action to print it out.

In your theme’s functions.php, create a class, or better: move the class to a separate file.

class PassCheck
{
    private $passed = 'no';

    public function check()
    {
        if ( is_user_logged_in() )
            $this->passed = 'yes';
    }

    public function print_pass()
    {
        echo $this->passed;
    }
}

Then register the callbacks:

$passcheck = new PassCheck;
add_action( 'init',       [ $passcheck, 'check' ] );
add_action( 'print_pass', [ $passcheck, 'print_pass' ] );

And in your template just call the proper action:

do_action( 'print_pass' );

This way, the template has no static dependency on the class: if you ever decide to remove the class or to register a completely different callback for that action, the theme will not break.

You can also move the check() callback to another action (like wp_loaded) or separate it out into another class later.

As a rule of thumb: templates (views) should be decoupled from business logic as much as possible. They shouldn't know class or function names. This isn't completely possible in WordPress’ architecture, but still a good regulative idea.

  • Didnt know that one. A nice way to solve it thanks. – Blackbam Mar 17 '16 at 0:46
  • having a class just to temporary hold a value sounds so wrong. – Mark Kaplun Mar 17 '16 at 9:59
  • @MarkKaplun It's not "just to hold a value". The main idea is to keep the logic for that separated from the rest. You can test it, mock it or replace it entirely. – fuxia Mar 17 '16 at 10:00
  • that is not logic, that is a value. The question feels like an early optimization effort, why can't my_action be simply called to echo the value? – Mark Kaplun Mar 17 '16 at 10:03
  • Uhm, that's exactly what happens here: calling the custom action prints the value. There are sometimes good reasons to collect a value as early as possible in WordPress, because almost any information is global and can be changed by other code (plugins). The current blog ID is an example. Even the new code for WP_Site is not an immutable object, so it cannot be trusted. – fuxia Mar 17 '16 at 10:12
2

It really depends on the use case. Anything that writes to the DB is probably overkill. Globals are messy. You could set a constant. You could turn the function into a class method, and create an additional method to return the variable. You could only check $passme when it's needed, instead of init.

  • Hum what I actually need to pass is the result object of a newsletter registration API. Doing the request during the Theme is already loading feels wrong. Even if I make a class then I have to make the class instance global, right? – Blackbam Mar 16 '16 at 23:31
  • Right, so more context helps. What are you getting from the API? Are you checking if someone is registered or not? Are you registering them and then showing... what? – vancoder Mar 16 '16 at 23:37
  • Well I send some date like email, name, etc. to the mailchimp api and get back a response array. On success it contains id etc. on error it contains error message etc. In the them I want to display parts of the array to the user accordingly and ofc I want to show if it was successful or not. – Blackbam Mar 16 '16 at 23:42
  • Current solution is custom global variable global $cm_newsletter. However I wonder if there is not a better way to pass variables from action hooks? – Blackbam Mar 16 '16 at 23:43
  • why are you making it hard? there is really nothing wrong with a global here at all. (but do not use an option for this as it can break for multiple users.) – majick Mar 16 '16 at 23:48
1

Without more details it hard to judge, but it feels like you have written my_action wrong, and it tries to do too many things.

The init hook should be used just for initializing whatever you need, you should not precompute values in it. This should be done only when the need arises.

You should just have a function called print_pass and call it wherever you need it.

Doing too much on the init hook violates the principal of delaying code execution as much as possible. In this case the init hook will execute your passme logic even when handling admin in which that value is not needed.

As for @toshco's answer, yes if you have some logic that might be better described with objects then print_pass should probably be a method in the class, but the wordpress hook system is functional in nature, and there is no need to go OOP when functional approach will be good enough. Functional is just more readable in the way the wordpress hook system works.

  • I was actually watching this question and waiting for some kind of (actually this very same) response from you, lol. I agree with your statements, although the answer by @toscho is still miles better than a comment somewhere here that everybody is overthinking this and the answer is simply to create a global. – Pieter Goosen Mar 17 '16 at 10:48
  • 1
    @PieterGoosen, toscho answer is really just using a global, but decorating it enough to give the impression of something else. I assume toscho is as stubborn as me and will not admit his mistake, although if someone else would have posted that he would have spotted it in a glance. – Mark Kaplun Mar 17 '16 at 13:54
-1

Though you are asking about global variables, I think it worth adding that if you are just checking and setting this value once (as it seems like you might be) and it is not going to change later, it actually may make more sense just to use a constant instead of using a variable at all.

if ( ($thischeck) && ($thatcheck) ) {$dontknow = true;} else {$dontknow = false;}
define('DONTKNOW',$dontknow);

add_action('init','my_action');
function my_action() {
    if (DONTKNOW) {$passme = "yes";} 
    else {$passme = "no";}
}

Because really, a 'static variable' is a basically a constant anyway.

  • of course logically, lateral thinking should be downvoted. – majick Mar 22 '16 at 15:55
  • but then after writing this I applied this to reduce a number of unnecessary globals in own my theme code by replacing them with constants. :-) – majick Mar 22 '16 at 15:59

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.