When to use filter, action and when normal function in WordPress?

I’ve been reading about actions and filters for the past hour and I still can’t find the answer I am looking for.

Let say I have a WP theme/site about 2 cities. London and Washington. These two are top parent pages to every other page. (about, what to visit, info etc) Certain content is different for each city.

Read More

For example:

  • in footer we display city name for every children page.
  • promoted content on front page in 3 divs (content loaded with WP_Query)
  • different header color for different city
  • etc

This content is not stored in database so I though I’d make a simple function in functions.php file, like this (simplified, also I left out part when I get the slug):

function cityData () {
    $currentCitySlug = 'xx';//code that finds top parent & returns 'london' or 'washington';
    switch ($currentCitySlug ) {
        case 'london':
        $smth['footer'] = 'London';
        $smth['frontpage-featured'] = array(190,200,201); //post IDs
            break;

        default: //washington
                $smth['footer'] = 'Washington';
                $smth['frontpage-featured'] = array(150,154,167);
            break;
    }
    return $smth;
}

So here is what I don’t get:

  1. Where should I call cityData() so the returned variable is available everywhere in my theme? Do I use some global variable array in let say index.php, then header.php etc or anywhere where I need it (and then let say in footer do echo $somecity['footer'])? I read we should avoid global variables.

  2. Should I make this function action? Almost all guides say actions do not return variable, however, the very example in https://codex.wordpress.org/Plugin_API#Create_an_Action_Function shows functions that Return variable. This confuses me. Where and why is this variable returned when actions don’t return variable? Also, hook it to what WordPress action? init? after_setup_theme? There are millions of these actions, how to know which one? If you can return variable from the action then why even use a filter?

  3. My guess is I need to use a filter. However, this is my main dilemma: should I use filter OR should I just use the ordinary function call like:

    $city = cityData();
    echo $city['footer'];
    

every time I need this array in my theme?

or should I use add_filter to this function in functions.php then call it with apply_filters function in my theme every time I need some data from an array? It is a very simple function, why use filters and not normal function?

  1. How do I call this function (or apply filters) and set this variable only once and then simply echo it like $city['somesubfield'] whenever I need it anywhere in my code? Is this better than applying filter or calling function every time I need it?

I have a feeling I am over complicating of doing it completely wrong. Maybe I should even add custom fields to top parent pages (London,Washington) then get this data directly from the database? But this just makes additional database calls when maybe not needed.

If you had to store some additional data for 2 cities where would you store it? Remember, this additional data is not only needed when these 2 pages are displayed but for EVERY child page of these two top pages. Manually in function? In the database, custom fields for these 2 pages then read from DB every time you need it? In some special database field, like options? There are no more than 5 different items needed to be stored for each city.

Related posts

1 comment

  1. I’m not sure I completely understand, but I’m going to try anyway to help with at least some of your concerns. For one, you don’t need global variables. It’s seeming to me like you can get what you want by passing parameters through a normal function. So, for example, you can give a function the parameters 'london' and 'footer' and have that function give you your footer value for London.

    And nope, functions don’t return variables, but they can return values. When you call this function…

    function hello_world() {
        $x = 'Hello world!';
        return $x;
    }
    

    …it’s returning whatever the value of what $x is. It will return the literal string 'Hello world!'—not $x as a variable to be used throughout your code on a global scope.

    Anyway, I think this is one way you can go about what you’re trying to do.

    /**
     * Find top parent and return 'london' or 'washington' (Based on what you said, this is sounding to me like this could/should be a function all on its own.)
     */
    function get_citySlug() {
        $slug = 'xx'; // Remember when you said you left out the part where you get the city slug? Well, you could put that here.
        return $slug;
    }
    
    /**
     * Return requested information based on specified city
     */
    function cityData($city, $output) {
        // $currentCitySlug = 'xx'; // This has been turned into its own function (see get_citySlug() above). I left this comment in here so you can see what's going on, but you can remove it.
    
        // Define data based on given city
        switch ($city) {
    
            case 'london':
                $footer    = 'London';
                $frontpage = array(190,200,201); //post IDs
                break;
    
            case 'washington':
                $footer    = 'Washington';
                $frontpage = array(150,154,167);
                break;
    
            // If there's no case for the given city, then there's no point in continuing this function. Leave the function and return with nothing.
            default:
                return;
        }
    
        // Rerturn data based on given output
        switch ($output) {
    
            case 'footer':
                return $footer;
                break;
    
            case 'frontpage-featured':
                return $frontpage;
                break;
    
            // If there's no case for the given output, return with nothing.
            default:
                return;
        }
    }
    

    Calling These Functions (vs Global Variables)

    Now, you can call cityData() and pass parameters through it. (You can use this anywhere in your code and you’d be doing it without the need of a global variable.)

    echo cityData('london','footer'); // echoes: London
    

    Keep in mind, if you set it up where get_citySlug() actually returns the city slug dynamically, you could pass get_citySlug() through cityData() like this (situations like this are good reasons to put that city slug as its own function like we did).

    echo cityData(get_citySlug(),'footer');
    

    Theme’s functions.php vs Plugin

    I’ll say this (even though it looks like you may already be aware of this) since it’s sounding like these functions are quite important to your site. While putting functions in functions.php will work, if you decide to deactivate your theme, these functions will also be deactivated. If these functions are strongly tied to the nature of your site as opposed to being simply for presentation, you may consider writing a plugin or installing a plugin for your custom site functions.

    Alternative Suggestions

    Just to maybe throw some more ideas your way, some things you might look into are custom post types or page templates.

    As for returning arrays from a function, I know you already touched on this approach, but I’m still going to list it anyway.

    If you need to, you could also use a class and pull a variable from there.


    Again, I’m not exactly sure what you’re trying to achieve specifically, so I might not have covered everything you were hoping for, and I can’t really speak to the filter/action part for your situation or give a specific “should” or “shouldn’t” for you, but I hope I’ve given you (or anyone) at least something useful to work with or a nudge in the right direction.

Comments are closed.