А я делаю так:
1. у меня есть класс шаблонизатора, который по большому счёту состоит из одного метода и приватного свойства, в которое пишется кэш. Этот метод принимает на вход имя файла и массив и заменяет в HTML-шаблоне все <%переменная%> на значения массива с ключём "переменная".
2. В самом коде формируется этот массив.
3. Перед вызовом Parser::parse($skin, $values) достаточно проинклюдить соответствующий языковой файл и сделать $values = array_merge($LANG, $values)
В результате: код чист от представления, представление чисто от языко-зависимых данных, размер кода минимален, логика отделена от представления (нет всяческих богомерзких {section name=user_loop loop=$users})
Для меня превосходство было в том, что не вызывались какие-то ф-ции smarty для вывода надписей, а. так как надписей было много - такая реализация помогла немного снизить нагрузку. Возможно стоит провести тестирование скорости различных способов что бы сравнить
Моя реализация локализации интерфейса в PHP