How to change content depending on the country (IP address)?

Hello all,
Today a client had a special request. He has a Kirby website in 2 languages (EN, FR).

For legal reasons, a few texts fields on the site need to be different in one specific country (Germany it is).

Any idea on how I could do this ?

The best would be : if user has a specific IP address corresponding to the country, PHP parses the content and replace the text strings.

Any hint ?

Thanks for your help

After a few googling, I found that there are some database for sale to match IP and country.

Let’s say I can find the user IP, find his country with the database. Now, how can I hook Kirby to replace some text string in the content before it’s sent to the client?

(I am probably totally on the wrong path here, if it’s the case, please tell me something)

This library might also be of interest: http://chir.ag/projects/geoiploc/

As regards replacing strings, might be helpful to see what it is that needs to be replaced, if it is some strings within one field or whatever. Maybe you can use custom kirbytags that render content based on the country?

1 Like

@textnixe GeoIpLoc looks interesting. thanks

The string to replace is just two words, but it could be in any fields (and maybe not kirbytext fields).

If its just two words, then you can probably do a simple string replacement.

<?php
    function replace_words_in_germany($text){
        return str_replace("two words", "other words",  $text);
    }
?>

and call this function on all fields if GeoIP = Germany. This should be called after kirbytext processing.

<?php 
    if $countrycode == "DE" {
       echo  replace_words_in_german($page->text()->kirbytext());
    }
    else {
      echo $page->text()->kirbytext(); 
    }
?>

Ok this is a really great solution already.

Is there a way to apply “replace_words_in_german()” on every fields, without having to modify every single templates ?

thank you

I have no idea, where to hook in to achieve this, without touching the templates. To replace the content on a completely rendered page you could probably use output buffering, but that would still mean touching the templates. I suppose using JavaScript is not an option?

Well, I guess sooner or later the smarter minds here will come around with a solution…

Yes, I would prefer to avoid JS.
What do you mean by ‘output buffering’ ?
How can I use the function replace_words_in_germany and $countrycode variable on every pages?
(I tried to make a file in the /plugin folder, but still the variable is not accessible from the template)

geoiploc.php is working fine btw!

How about Kirbytext filters? http://getkirby.com/docs/advanced/kirbytext#kirbytext-filters

1 Like

The Kirbytext filters would indeed be an option but only if you use Kirbytext. Another option is too modify the way Kirby renders templates. It’s super easy to create your custom Kirby class and overwrite the template method. Basically all you need to do is to create a site.php next to the index.php and in there do something like this:

<?php 

class CustomKirby extends Kirby {

  public function template(Page $page, $data = array()) {
    $template = parent::template($page, $data);
    $template = replace_words_in_german($template);
    return $template;
  }

}

$kirby = kirby('CustomKirby');

thank you Bastien!
where should the condition be? (if $countrycode == "DE")

in your replace_words_in_german method. I just put it in there as a placeholder for your own code, which would replace the text strings.

Here is the full working code of site.php:

<?php 
include('lib/geoiploc.php'); 
class CustomKirby extends Kirby {
    public function template(Page $page, $data = array()) {
         $countrycode = getCountryFromIP($_SERVER["REMOTE_ADDR"]);
  
        function replace_words($text, $cc){
            return ($cc == "DE") ? str_replace("Replaced", "Replacement",  $text) : $text; 
        }

        $template = parent::template($page, $data);
        $template = replace_words($template, $countrycode);
        return $template;
    }
}

$kirby = kirby('CustomKirby');

The GeoIpLoc file is inside a /lib directory.

It’s working fine.

  • Do you think this is the good way to do it?

  • Is it going to work with the cache?

Thanks for that @desgnl, I too wonder how the caching would react, especially the file cache.
I know that opcache / apc stores scripts in memory for faster loading and have mine setup to check every two seconds if the script has changed.