How to properly use UTF-8-encoded data from Schema inside Catalyst app?

catalyst, dbix-class, perl, utf-8

Solution

In a typical Catalyst setup with Catalyst::View::TT and Catalyst::Model::DBIC::Schema you'll need several things for UTF-8 to work:

- add Catalyst::Plugin::Unicode::Encoding to your Catalyst app

- add `encoding => 'UTF-8'` to your app config

- add `ENCODING => 'utf-8'` to your TT view config

- add `<meta http-equiv="Content-type" content="text/html; charset=UTF-8"/>` to the `<head>` section of your html to satisfy old IEs which don't care about the `Content-Type:text/html; charset=utf-8` http header set by Catalyst::Plugin::Unicode::Encoding

- make sure your text editor saves your templates in UTF-8 if they include non ASCII characters

- configure your DBIC model according to DBIx::Class::Manual::Cookbook#Using Unicode

- if you use Catalyst::Authentication::Store::LDAP configure your LDAP stores to return UTF-8 by adding `ldap_server_options => { raw => 'dn' }`

According to Catalyst::Model::DBIC::Schema#connect_info:

The old arrayref style with hashrefs for DBI then DBIx::Class options is also supported.

But you are already using the 'new' style so you shouldn't nest the dbi attributes:

connect_info => {
     dsn               => 'dbi:mysql:test',
     user              => 'user',
     password          => 'password',
     AutoCommit        => 1,
     RaiseError        => 1,
     mysql_enable_utf8 => 1,
     on_connect_do     => [
         'SET NAMES utf8',
     ],      
}

Problem

Data defined inside Catalyst app or in templates has correct encoding and is diplayed well, but from database everything non-`Latin1` is converted to `?`. I suppose problem should be in model class, which is such: ``` use strict; use base 'Catalyst::Model::DBIC::Schema'; __PACKAGE__->config( schema_class => 'vhinnad::Schema::DB', connect_info => { dsn => 'dbi:mysql:test', user => 'user', password => 'password', { AutoCommit => 1, RaiseError => 1, mysql_enable_utf8 => 1, }, 'on_connect_do' => [ 'SET NAMES utf8', ], } ); 1; ``` I see no flaws here, but something must be wrong. I used my schema also with test scripts and data was well encoded and output was correct, but inside Catalyst app i did not get encoding right. Where may be the problem? EDIT For future reference i put solution here: i mixed in connect info old and new style. Old style is like `(dsn, username, passw, hashref_options, hashref_other options)` New style is `(dsn => dsn, username => username, etc)`, so right is to use: ``` connect_info => { dsn => 'dbi:mysql:test', user => 'user', password => 'password', AutoCommit => 1, RaiseError => 1, mysql_enable_utf8 => 1, on_connect_do => [ 'SET NAMES utf8', ], } ```

Original source