How to show content/data based on visitor country

Maybe you have specific content/section/data you want show based on visitor location in your WordPress Blog/Site. Here is how you can do it.

First write a function to get location data of visitor. For simplicity sake, I take this function from this SO accepted answer.

function ip_info($ip = NULL, $purpose = "location", $deep_detect = TRUE) {
    $output = NULL;
    if (filter_var($ip, FILTER_VALIDATE_IP) === FALSE) {
        $ip = $_SERVER["REMOTE_ADDR"];
        if ($deep_detect) {
            if (filter_var(@$_SERVER['HTTP_X_FORWARDED_FOR'], FILTER_VALIDATE_IP))
                $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
            if (filter_var(@$_SERVER['HTTP_CLIENT_IP'], FILTER_VALIDATE_IP))
                $ip = $_SERVER['HTTP_CLIENT_IP'];
        }
    }
    $purpose    = str_replace(array("name", "\n", "\t", " ", "-", "_"), NULL, strtolower(trim($purpose)));
    $support    = array("country", "countrycode", "state", "region", "city", "location", "address");
    $continents = array(
        "AF" => "Africa",
        "AN" => "Antarctica",
        "AS" => "Asia",
        "EU" => "Europe",
        "OC" => "Australia (Oceania)",
        "NA" => "North America",
        "SA" => "South America"
    );
    if (filter_var($ip, FILTER_VALIDATE_IP) && in_array($purpose, $support)) {
        $ipdat = @json_decode(file_get_contents("http://www.geoplugin.net/json.gp?ip=" . $ip));
        if (@strlen(trim($ipdat->geoplugin_countryCode)) == 2) {
            switch ($purpose) {
                case "location":
                    $output = array(
                        "city"           => @$ipdat->geoplugin_city,
                        "state"          => @$ipdat->geoplugin_regionName,
                        "country"        => @$ipdat->geoplugin_countryName,
                        "country_code"   => @$ipdat->geoplugin_countryCode,
                        "continent"      => @$continents[strtoupper($ipdat->geoplugin_continentCode)],
                        "continent_code" => @$ipdat->geoplugin_continentCode
                    );
                    break;
                case "address":
                    $address = array($ipdat->geoplugin_countryName);
                    if (@strlen($ipdat->geoplugin_regionName) >= 1)
                        $address[] = $ipdat->geoplugin_regionName;
                    if (@strlen($ipdat->geoplugin_city) >= 1)
                        $address[] = $ipdat->geoplugin_city;
                    $output = implode(", ", array_reverse($address));
                    break;
                case "city":
                    $output = @$ipdat->geoplugin_city;
                    break;
                case "state":
                    $output = @$ipdat->geoplugin_regionName;
                    break;
                case "region":
                    $output = @$ipdat->geoplugin_regionName;
                    break;
                case "country":
                    $output = @$ipdat->geoplugin_countryName;
                    break;
                case "countrycode":
                    $output = @$ipdat->geoplugin_countryCode;
                    break;
            }
        }
    }
    return $output;
}

Then we use the function above into our WordPress system. We will use it in init action hooks.

add_action('init', 'set_user_country');
function set_user_country(){
    //start the session only it is not started, becuase other plugins might have already did it. 
    if (!session_id()) {
         session_start();
    }
    if(!isset($_SESSION["user_country"]) || empty($_SESSION["user_country"]) ){
        $_SESSION["user_country"] = ip_info("Visitor", "Country Code");
        //I put the country code into the "user_country" session for later use
        //I use the country code for this example, you can use other details as well based on the function above such as "Region", "State"..etc. 
    } 
}

Since the user location data already in session, then you can use it wherever you like. Like in content, widget, header, or footer. You get the idea.

For example, use shortcode to display custom content by country.

add_shortcode('country_base_content', 'country_base_content_func');
function country_base_content_func(){
  if( isset($_SESSION["user_country"]) && $_SESSION["user_country"] == "US" ){//if vistor is from United State
        return "This is the content for United State";
  }else{
        return "This is the content for rest of the world";
  }
}

So when you insert shortcode `country_base_content` into your content, then it will automatically display the content based on visitor country code.

Note:

The `ip_info` function above is fetching data from `http://www.geoplugin.net/` which is a free Webservice API. It can’t guarantee the accuracy of the data. If accuracy is what you concern, you might want to use a premium service like maxmind GeoIP2 Precision Services

Also, note that if you are using Caching Plugin this method will not work as desired because most cache plugin will store the generated html once visitor first visited the page, and used it to serve to other visitor afterward, which mean the functions above only will run once on the first visitor visit the page.

If you can’t get rid the cache plugin, one of the solution is use Javascript Ajax to fetch the country based content. That’s another topic which maybe I will cover up in the future.

Leave A Comment