Skip to content

Placeholders substitution in language strings

Derek Jones edited this page Jul 5, 2012 · 8 revisions

Category:Internationalization

From time to time is useful to have an ability to modify language string from language file dynamically. I'm using the following functions:

<?
$lang['user_logged_out'] = "User %s has been logged out";

#this functions takes variable number of parameters, calls second function
#which replaces %s placeholders with these parameters in appropriate order.
function lang($msg)
{
    $args = func_get_args();
    
    if(is_array($args)) array_shift($args);
    
    if(is_array($args) && count($args))
    {
        foreach($args as $arg)
        {
            $msg = str_replace_first('%s', $arg, $msg);
        }
    }
    return $msg;
}
function str_replace_first($search_for, $replace_with, $in)
{
    $pos = strpos($in, $search_for);
    if($pos === false)
    {
        return $in;
    }
    else
    {
        return substr($in, 0, $pos) . $replace_with . substr($in, $pos + strlen($search_for), strlen($in));
    }
}
?>

Example:

<?=lang($lang['user_logged_out'], $username);?>

Messages than sound more naturally. I believe this helps someone and it would by nice if something like this could be part of language class in standard CI distro.

Other solution is to extend CI_Language class and replace the original line() method:

   /**
     * Fetch a single line of text from the language array
     * Replace argument placeholders with values
     *
     * Usage:
     * # this msg is in your language file
     * $lang['hello_key'] = "Hello %s, you are visitor number %d";
     * ...
     * $this->lang->load('hello_language_file_name','english');
     * $msgvalues = array("Peter",21);
     * $msg = $this->lang->line('hello_key', $msgvalues);     
     *
     * @access    public
     * @param    string    the language line key
     * @param    mixed    argument or array of arguments
     * @return    string
     */

    function line( $line_key = '', $args = '' ) {
        if ($line_key == '' OR ! isset($this->language[$line_key])) {
            return FALSE;
        }
        $line_string = $this->language[$line_key];
        if ($args == '') {
            return $line_string;
        }
        else if (is_array($args)) {
            return vsprintf($line_string, $args);
        }
        else {
            return sprintf($line_string, $args);     
        }
    }
Clone this wiki locally