package Catalyst::Model::Data::Localize; use Moose; use Data::Localize; extends 'Catalyst::Model'; with 'Catalyst::Component::InstancePerContext'; __PACKAGE__->meta->make_immutable(inline_constructor => 0); no Moose; our $VERSION = '0.00007'; our $AUTHORITY = 'cpan:DMAKI'; sub build_per_context_instance { my ($self, $c) = @_; my $localize = $self->{localize}; if (! $localize) { $self->__init_localizer($c); $localize = $self->{localize} || die "Could not create a Data::Localize instance"; } if (my $language = $self->{languages}) { $localize->set_languages(@$language); } else { # if we're being called at the beginning of the context, then # we won't have have access to $c->req... eval { my @langs = $localize->detect_languages_from_header( $c->req->header('Accept-Language') ); $localize->set_languages(@langs); }; } return $localize; } sub __init_localizer { my ($self, $c) = @_; my $config = $c->config->{'Model::Data::Localize'} || $c->config->{'Model::Localize'} || {} ; # by default, set "auto" to true if (! exists $config->{auto}) { $config->{auto} = 1; } my $localizers = $config->{localizers} ||= []; if (ref $localizers ne 'ARRAY') { $localizers = [ $localizers ]; $config->{localizers} = $localizers; } if (scalar (@$localizers) <= 0) { # attempt to auto-detect common paths my $modpath = ref $c || $c; $modpath =~ s/::/\//g; $modpath .= '.pm'; my $path = $INC{ $modpath }; $path =~ s/\.pm$//; # find in MyApp::I18N, and possibly (for those of us using a setup # like MyApp::Catalyst or MyApp::Web), one level above my @paths = # map { File::Spec->canonpath($_) } ( ( File::Spec->catdir($path, 'I18N'), File::Spec->catdir($path, File::Spec->updir(), 'I18N'), ); foreach my $curpath (@paths) { my $gettext = File::Spec->catfile($curpath, '*.po'); $c->log->debug("Looking for gettext-based localization files under\n\t$gettext") if $c->log->is_debug; if (defined glob($gettext)) { push @{ $localizers }, { class => 'Gettext', paths => [ $gettext ] } } my $namespace = File::Spec->catfile($path, '*.pm'); $c->log->debug("Looking for namespace-based localization files under\n\t$namespace") if $c->log->is_debug; if (defined glob($namespace)) { push @{ $localizers }, { class => 'Namespace', namespaces => [ join('::', ref($c) || $c, 'I18N' ) ] } } } } if ($config->{languages}) { if (ref $config->{languages} ne 'ARRAY') { $config->{languages} = [ $config->{languages} ]; } } $self->{localize} = Data::Localize->new(%$config); $self->{languages} = $config->{languages}; } 1; __END__ =head1 NAME Catalyst::Model::Data::Localize - Catalyst Model Over Data::Localize =head1 SYNOPSIS $c->model('Data::Localize') # or Localize. whatever ->localize($key, @args); =head1 DESCRIPTION WARNING: Data::Localize, which this module is based on, is still in alpha quality. This module should also be treated as such. This is a thin wrapper around Data::Localize. The only thing it does that a plain Catalyst::Model::Adaptor + Data::Localize can do is the automatic discovery of I18N files (if they are placed under likely locations). For example, these files will automatically be found: # suppose our Catalyst app is at lib/MyApp.pm lib/MyApp/I18N/ja.pm lib/MyApp/I18N/ja.po Also, for those like me that don't like to put a catalyst app at the project's top namespace, we look for one level above, too: # suppose our Catalyst app is at lib/MyApp/Web.pm lib/MyApp/I18N/ja.pm lib/MyApp/I18N/ja.po The default behavior is to detect the language setting from the HTTP headers. If you want to override it, simply place an explicit call somehwere in your action chain: my $loc = $c->model('Data::Localize'); $loc->set_languages('ja'); # or whatever you prefer $loc->localize($key, @args); =head1 CONFIGURATION Configuration can be done via the 'Model::Data::Localize' slot: auto 1 class Gettext path /path/to/gettext/files/*.po If you want Catalyst::Plugin::I18N compatible style method generation on the context object, look at Catalyst::Plugin::Data::Localize, which is just a really thin wrapper over this module. C parameter is a bit special, as it overrides the default behavior to detect the desired language from HTTP headers. # Always use ja languages ja =head1 TODO Tests. Yes, I know. =head1 AUTHOR Daisuke Maki C<< >> =head1 LICENSE This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See http://www.perl.com/perl/misc/Artistic.html =cut