.\" Automatically generated by Pod::Man 4.10 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "HTML::FormFu::Manual::Unicode 3pm" .TH HTML::FormFu::Manual::Unicode 3pm "2019-01-12" "perl v5.28.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Unicode.pod \- Working with unicode .SH "VERSION" .IX Header "VERSION" version 2.07 .SH "DESCRIPTION" .IX Header "DESCRIPTION" Working with unicode. .PP For a practical example, see the Catalyst application in the \&\f(CW\*(C`examples/unicode\*(C'\fR directory in this distribution. .SH "ASSUMPTIONS" .IX Header "ASSUMPTIONS" In this tutorial, we're assuming that all encodings are \s-1UTF\-8.\s0 It's relatively simple to combine different encodings from different sources, but that's beyond the scope of this tutorial. .PP For simplicity, we're also going to assume that you're using Catalyst for your web-framework, DBIx::Class for your database \s-1ORM,\s0 \&\s-1TT\s0 for your templating system, and \s-1YAML\s0 format \f(CW\*(C`HTML::FormFu\*(C'\fR configuration files, with \s-1YAML::XS\s0 installed. However, the principles we'll cover should translate to whatever technologies you chose to work with. .SH "BASICS" .IX Header "BASICS" To make it short and sweet: you must decode all data going into your program, and encode all data coming from your program. .PP Skip to \*(L"\s-1CHANGES REQUIRED\*(R"\s0 if you want to see what you need to do without any other explanation. .SH "INPUT" .IX Header "INPUT" .SS "Input parameters from the browser" .IX Subsection "Input parameters from the browser" If you're using \f(CW\*(C`Catalyst\*(C'\fR, Catalyst::Plugin::Unicode will decode all input parameters sent from the browser to your application \- see \&\*(L"Catalyst Configuration\*(R". .PP If you're using some other framework or, in any case, you need to decode the input parameters yourself, please take a look at HTML::FormFu::Filter::Encode. .SS "Data from the database" .IX Subsection "Data from the database" If you're using DBIx::Class, DBIx::Class::UTF8Columns is likely the best options, as it will decode all input retrieved from the database \- see \*(L"DBIx::Class Configuration\*(R". .PP In other cases (i.e. plain \s-1DBI\s0), you still need to decode the string data coming from the database. This varies depending on the database server. For MySQL, for instance, you can use the \f(CW\*(C`mysql_enable_utf8\*(C'\fR attribute: see DBD::mysql documentation for details. .SS "Your template files" .IX Subsection "Your template files" Set \s-1TT\s0 to decode all template files \- see \*(L"\s-1TT\s0 Configuration\*(R". .SS "HTML::FormFu's own template files" .IX Subsection "HTML::FormFu's own template files" Set \f(CW\*(C`HTML::FormFu\*(C'\fR to decode all template files \- see \&\*(L"HTML::FormFu Template Configuration\*(R". .SS "HTML::FormFu form configuration files" .IX Subsection "HTML::FormFu form configuration files" If you're using \f(CW\*(C`YAML\*(C'\fR config files, your files will automatically be decoded by \f(CW\*(C`load_config_file|HTML::FormFu/load_config_file\*(C'\fR and \&\f(CW\*(C`load_config_filestem|HTML::FormFu/load_config_filestem\*(C'\fR. .PP If you have Config::General config files, your files will automatically be decoded by \f(CW\*(C`load_config_file|HTML::FormFu/load_config_file\*(C'\fR and \&\f(CW\*(C`load_config_filestem|HTML::FormFu/load_config_filestem\*(C'\fR, which automatically sets Config::General's \f(CW\*(C`\-UTF8\*(C'\fR setting. .SS "Your perl source code" .IX Subsection "Your perl source code" Any perl source files which contain Unicode characters must use the utf8 module. .SH "OUTPUT" .IX Header "OUTPUT" .SS "Data saved to the database" .IX Subsection "Data saved to the database" With \f(CW\*(C`DBIx::Class\*(C'\fR, DBIx::Class::UTF8Columns will encode all data sent to the database \- see \*(L"DBIx::Class Configuration\*(R". .SS "\s-1HTML\s0 sent to the browser" .IX Subsection "HTML sent to the browser" With \f(CW\*(C`Catalyst\*(C'\fR, Catalyst::Plugin::Unicode will encode all output sent from your application to the browser \- see \*(L"Catalyst Configuration\*(R". .PP In other circumstances you need to be sure to output your Unicode (decoded) strings in \s-1UTF\-8.\s0 To do this you can encode your output before it's sent to the browser with something like: .PP .Vb 4 \& use utf8; \& if ( $output && utf8::is_utf8($output) ){ \& utf8::encode( $output ); # Encodes in\-place \& } .Ve .PP Another option is to set the \f(CW\*(C`binmode\*(C'\fR for \f(CW\*(C`STDOUT\*(C'\fR: .PP .Vb 1 \& bindmode STDOUT, \*(Aq:utf8\*(Aq; .Ve .PP However, be sure to do this \fBonly\fR when sending \s-1UTF\-8\s0 data: if you're serving images, \s-1PFD\s0 files, etc, \f(CW\*(C`binmode\*(C'\fR should remain set to \f(CW\*(C`:raw\*(C'\fR. .SH "CHANGES REQUIRED" .IX Header "CHANGES REQUIRED" .SS "Catalyst Configuration" .IX Subsection "Catalyst Configuration" Add Catalyst::Plugin::Unicode to the list of Catalyst plugins: .PP .Vb 1 \& use Catalyst qw( ConfigLoader Static::Simple Unicode ); .Ve .SS "DBIx::Class Configuration" .IX Subsection "DBIx::Class Configuration" Add DBIx::Class::UTF8Columns to the list of components loaded, for each table that has columns storing unicode: .PP .Vb 1 \& _\|_PACKAGE_\|_\->load_components( qw( UTF8Columns HTML::FormFu PK::Auto Core ) ); .Ve .PP Pass each column name that will store unicode to \f(CW\*(C`utf8_columns()\*(C'\fR: .PP .Vb 1 \& _\|_PACKAGE_\|_\->utf8_columns( qw( lastname firstname ) ); .Ve .SS "\s-1TT\s0 Configuration" .IX Subsection "TT Configuration" Tell \s-1TT\s0 to decode all template files, by adding the following to your application config in MyApp.pm .PP .Vb 3 \& package MyApp; \& use parent \*(AqCatalyst\*(Aq; \& use Catalyst qw( ConfigLoader ); \& \& MyApp\->config({ \& \*(AqView::TT\*(Aq => { \& ENCODING => \*(AqUTF\-8\*(Aq, \& }, \& }); \& \& 1; .Ve .SS "HTML::FormFu Template Configuration" .IX Subsection "HTML::FormFu Template Configuration" Make \f(CW\*(C`HTML::FormFu\*(C'\fR tell \s-1TT\s0 to decode all template files, by adding the following to your \f(CW\*(C`myapp.yml\*(C'\fR Catalyst configuration file: .PP .Vb 3 \& package MyApp; \& use parent \*(AqCatalyst\*(Aq; \& use Catalyst qw( ConfigLoader ); \& \& MyApp\->config({ \& \*(AqController::HTML::FormFu\*(Aq => { \& constructor => { \& tt_args => { \& ENCODING => \*(AqUTF\-8\*(Aq, \& }, \& }, \& }, \& }); \& \& 1; .Ve .PP These above 2 examples should be combined, like so: .PP .Vb 3 \& package MyApp; \& use parent \*(AqCatalyst\*(Aq; \& use Catalyst qw( ConfigLoader ); \& \& MyApp\->config({ \& \*(AqController::HTML::FormFu\*(Aq => { \& constructor => { \& tt_args => { \& ENCODING => \*(AqUTF\-8\*(Aq, \& }, \& }, \& }, \& \*(AqView::TT\*(Aq => { \& ENCODING => \*(AqUTF\-8\*(Aq, \& }, \& }); \& \& 1; .Ve .SH "AUTHORS" .IX Header "AUTHORS" Carl Franks \f(CW\*(C`cfranks@cpan.org\*(C'\fR Michele Beltrame \f(CW\*(C`arthas@cpan.org\*(C'\fR (contributions) .SH "COPYRIGHT" .IX Header "COPYRIGHT" This document is free, you can redistribute it and/or modify it under the same terms as Perl itself. .SH "AUTHOR" .IX Header "AUTHOR" Carl Franks .SH "COPYRIGHT AND LICENSE" .IX Header "COPYRIGHT AND LICENSE" This software is copyright (c) 2018 by Carl Franks. .PP This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.