RSS
Arrays in language files (deel 2)

Arrays in language files (deel 2)

Deze post is een vervolg op de post ‘Arrays in language files‘ die ik enkele dagen geleden publiceerde. Op het einde gaf ik enkele suggesties voor uitbreidingen op de code in die post.

Als fervente PHPer kon ik me natuurlijk niet inhouden om die uitbreidingen zelf ook eens te maken, al was het maar om de uitdaging aan te gaan. Bovendien heb ik van elke mensen al vragen gehad over hoe ze eraan moeten beginnen. Daarom heb ik besloten om dit vervolg te schrijven en een woordje uitleg te geven bij deze uitbreidingen.

Meerdimensionale arrays

De uitbreiding die ik heb geschreven ziet er als volgt uit:

function line ($keys, $vals = array())
{
    $return = '';
 
    if (count($vals) === 0)
    {
        // Er zijn geen waardes opgegeven
        // We gebruiken dan een echo
        $return .= 'return $this->language';
    }
    else
    {
        // Er zijn wel waardes opgegeven
        // We gebruiken dan een sprintf
        $return .= 'return sprintf($this->language';
    }
 
    // De volledige key samenstellen aan de hand van de array
    // Dit wordt iets als ['error']['username']['minLength']
    if (is_array($keys) === true)
    {
        // Als $keys een array is halen we alle delen op
        foreach ($keys as &$key)
        {
            $return .= '[\'' . $key . '\']';
        }
    }
    else
    {
        // Anders is er maar één key meegegeven aan de functie
        $return .= '[\'' . $keys . '\']';
    }
 
    // Daarna doen we ongeveer hetzelfde voor de waardes
    // Als die er zijn, maken we gebruik van een sprintf (zie bovenaan)
    if (is_array($vals) === true)
    {
        // Als er een array werd meegegeven, doorlopen we deze
        foreach ($vals as &$val)
        {
            $return .= ', \'' . $val . '\'';
        }
    }
    else
    {
        // Anders is er maar één waarde
        $return .= ', \'' . $vals . '\'';
    }
 
    // Op het einde nog even de functie (echo of sprint) juist afsluiten
    if (count($vals) === 0)
    {
        $return .= ';';
    }
    else
    {
        $return .= ');';
    }
 
    // En het geheel teruggeven
    return eval($return);
}

Deze functie staat uiteraard in het MY_Language.php bestand. Aangezien de naam van de functie die hierboven staat ‘line’ is, zal de functie van CI_Language overschreven worden. Dit is echter geen probleem, omdat onze eigen functie dezelfde en meer functionaliteiten biedt dan de originele. Om dit even te demonstreren, maak ik gebruik van dutch_lang.php in de map language/dutch/:

<?php
$lang['een'] = 'Dit is een voorbeeld';
$lang['twee'] = 'Dit is voorbeeld %s';
$lang['drie']['a'] = 'Dit is voorbeeld a';
$lang['drie']['b'] = 'Dit is voorbeeld b met als gegevens: %s en %s';

De code om dit te testen is redelijk makkelijk te schrijven. Dit zijn enkele van de tests, maar er zijn er natuurlijk nog meer mogelijk. Zo is er bijvoorbeeld geen test voorzien voor een array van keys met één waarde.

<?php
class Home extends Controller
{
    function index()
    {
        $this->lang->load('dutch', 'dutch');
 
        echo $this->lang->line(
            'een'
        );
 
        echo '<br />';
 
        echo $this->lang->line(
            'twee',
            2
        );
 
        echo '<br />';
 
        echo $this->lang->line(
            array('drie', 'a')
        );
 
        echo '<br />';
 
        echo $this->lang->line(
            array('drie', 'b'),
            array('1', '2')
        );
    }
}

Bovenstaande code geeft als resultaat:

Dit is een voorbeeld
Dit is voorbeeld 2
Dit is voorbeeld a
Dit is voorbeeld b met als gegevens: 1 en 2

Dat werkt allemaal heel mooi, maar er is nog een tweede uitdaging.

Alle language file rechtstreeks in de language/ map

Nu staat alle taalbestanden nog in mappen. Zo staat dutch_lang.php in language/dutch/ en english_lang.php in language/english/. Dit heeft als gevolg dat we steeds deze map moeten meegeven met de $this->lang->load functie.

De enige manier om dit op te lossen is om de load functie van CI_Language te overschrijven. Dit kan door de load functie te kopiëren vanuit Language.php (te vinden in system/libraries/) en te plakken in MY_Language.php. Het enige dat je nu nog moet doen is een stuk code in commentaar zetten, of volledig te verwijderen als je dat liever doet. Het gaat om de if structuur die begint op regel 8 van de functie:

if ($idiom == '')
{
    $CI =& get_instance();
    $deft_lang = $CI->config->item('language');
    $idiom = ($deft_lang == '') ? 'english' : $deft_lang;
}

Wanneer je bovenstaande code in commentaar zet kan je in je controllers

$this->lang->load('dutch', 'dutch');

vervangen door

$this->lang->load('dutch');

Je moet natuurlijk ook dutch_lang.php verplaatsen van language/dutch/ naar language/.

En klaar is kees

Voila, beide ideeën die ik en de vorige post voorstelde zijn bij deze gemaakt. Als er nog vrage zijn, je weet ondertussen wel waar je ze kan zetten…

Delen

Facebook Facebook     Twitter Twitter     TinyUrl: http://tinyurl.com/r4wdlv

Reageer zelf!