抱歉,我以為我在上一篇文章之后就到了那里,但是我只能從一個單獨的 PL 檔案訪問。我現在正試圖確保我可以使用模式加載來加載詞典,而不是每次我在結果/結果集類中呼叫方法時(這似乎是一個非常糟糕的想法)。
所以為了嘗試給出一個完整的畫面,這是我最終開始作業的腳本:
#!/usr/bin/perl
use strict;
use warnings;
use FindBin qw( $Bin );
use lib "$Bin/../lib";
use Data::Dumper::Concise;
use TopTable::Maketext;
use Config::ZOMG;
use Path::Class::Dir;
# Load the Catalyst config
my $tt_config = Config::ZOMG->new( name => "TopTable" );
my $config_hash = $tt_config->load;
# Load the locales from the config
my (@locales, %inheritance, $config);
$config = $config_hash->{I18N}{locales};
foreach my $locale (keys %$config) {
push(@locales, $locale);
$inheritance{$locale} = $config->{$locale}{inherits} if defined $config->{$locale}{inherits};
}
# Get the directory where the messages are defined
my $dir = Path::Class::Dir->new( "$Bin/..", "root", "locale" );
# Load the lexicon
TopTable::Maketext->load_lexicon(
locales => \@locales,
directories => [$dir],
gettext_style => 1,
inheritance => \%inheritance,
);
my $lang = TopTable::Maketext->get_handle( "en_GB" );
printf "%s\n", $lang->maketext( "menu.title.league-tables", "Division Three" );
1;
這是我的 TopTable::Maketext:
package TopTable::Maketext;
use strict;
use warnings;
use parent qw(CatalystX::I18N::Maketext);
1;
現在這是我的架構檔案:
use utf8;
package TopTable::Schema;
# Created by DBIx::Class::Schema::Loader
# DO NOT MODIFY THE FIRST PART OF THIS FILE
use Moose;
use MooseX::MarkAsMethods autoclean => 1;
extends 'DBIx::Class::Schema';
__PACKAGE__->load_namespaces;
# Created by DBIx::Class::Schema::Loader v0.07037 @ 2013-12-03 11:04:44
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:uMxbZipkwEqVJYByeZhY5Q
# You can replace this text with custom code or comments, and it will be preserved on regeneration
__PACKAGE__->meta->make_immutable(inline_constructor => 0);
1;
恐怕我是一個 Moose 新手,但我相信如果我添加了一個帶有構建器方法的“lang”屬性來設定所有這些,那么我可以從我的資料庫方法中訪問它:
use utf8;
package TopTable::Schema;
# Created by DBIx::Class::Schema::Loader
# DO NOT MODIFY THE FIRST PART OF THIS FILE
use Moose;
use MooseX::MarkAsMethods autoclean => 1;
extends 'DBIx::Class::Schema';
__PACKAGE__->load_namespaces;
# Created by DBIx::Class::Schema::Loader v0.07037 @ 2013-12-03 11:04:44
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:uMxbZipkwEqVJYByeZhY5Q
use FindBin qw( $Bin );
use TopTable::Maketext;
has "lang" => (
is => "ro",
isa => "TopTable::Maketext",
builder => "_set_maketext",
required => 1,
);
sub _set_maketext {
my ( $self ) = @_;
my $class = $self->class;
my $app = $self->_app;
my (@locales, %inheritance);
my $config = $app->config->{I18N}{locales};
$app->log->debug( sprintf( "app: %s, class: %s", $app, $class ) );
printf( "app: %s, class: %s", $app, $class );
foreach my $locale (keys %$config) {
push(@locales, $locale);
$inheritance{$locale} = $config->{$locale}{inherits} if defined $config->{$locale}{inherits};
}
my $dir = Path::Class::Dir->new( "$Bin/..", "root", "locale" );
TopTable::Maketext->load_lexicon(
locales => \@locales,
directories => [$dir],
gettext_style => 1,
inheritance => \%inheritance,
);
return TopTable::Maketext->get_handle( "en_GB" );
}
# You can replace this text with custom code or comments, and it will be preserved on regeneration
__PACKAGE__->meta->make_immutable(inline_constructor => 0);
1;
This however, doesn't work - the 'lang' method is accessible, but returns undef - I have added this as a test in one of my resultset methods:
$logger->( "debug", $self->result_source->schema->lang->maketext("menu.title.league-tables", "Division Three") );
But this gives an error:
[error] Caught exception in TopTable::Controller::Admin::Bans->process_form "Can't call method "maketext" on an undefined value at D:\Personal\Dev\Web\www.mkttl.co.uk\TopTable\lib/TopTable/Schema/ResultSet/Ban.pm line 88."
Grateful for any advice, thanks so much! I hope I've provided enough to see what's going on.
uj5u.com熱心網友回復:
在@simbabque 非常友善和耐心的幫助下,我設法解決了這個問題。
simbabque 建議我將 lang 屬性設定為lazy,這確實有效:
use FindBin qw( $Bin );
use TopTable::Maketext;
has "lang" => (
is => "ro",
isa => "TopTable::Maketext",
builder => "_set_maketext",
lazy => 1,
);
sub _set_maketext {
my ( $self ) = @_;
my $class = $self->class;
my $app = $self->_app;
my (@locales, %inheritance);
my $config = $app->config->{I18N}{locales};
$app->log->debug( sprintf( "app: %s, class: %s", $app, $class ) );
printf( "app: %s, class: %s", $app, $class );
foreach my $locale (keys %$config) {
push(@locales, $locale);
$inheritance{$locale} = $config->{$locale}{inherits} if defined $config->{$locale}{inherits};
}
my $dir = Path::Class::Dir->new( "$Bin/..", "root", "locale" );
TopTable::Maketext->load_lexicon(
locales => \@locales,
directories => [$dir],
gettext_style => 1,
inheritance => \%inheritance,
);
return TopTable::Maketext->get_handle( "en_GB" );
}
這有效,但產生了訊息Lexicon has already been loaded for TopTable::Maketext,這表明 Catalyst 加載詞典是一項全域操作,所以實際上我能夠將該_set_maketext方法歸結為:
sub _set_maketext {
return TopTable::Maketext->get_handle( "en_GB" );
}
到目前為止一切都很好,但是我必須弄清楚如何將用戶的語言環境放入對get_handle().
Again, with the help of simbabque, I have managed to get this working using an ACCEPT_CONTEXT sub in the model (note the if ref( $c ) eq "TopTable" check - as the comment says, the model seems to get called by Catalyst as part of the instantiation, before my code kicks in, and in these cases, $c is the string "TopTable", not a ref to the TopTable object so we can't call ->locale on it):
package TopTable::Model::DB;
use strict;
use base 'Catalyst::Model::DBIC::Schema';
__PACKAGE__->config(
schema_class => 'TopTable::Schema',
connect_info => {
dsn => 'dbi:mysql:toptable',
user => '',
password => '',
}
);
use TopTable::Maketext;
sub ACCEPT_CONTEXT {
my ( $self, $c ) = @_;
# We have to check the ref of $c here because this model seems to get called by Catalyst as part of the instantiation, before my code kicks in
# and in these cases, $c is the string "TopTable", not a ref to the TopTable object.
$self->schema->_set_maketext( TopTable::Maketext->get_handle( $c->locale ) ) if ref( $c ) eq "TopTable";
return $self;
}
1;
I've changed the schema thus:
use TopTable::Maketext;
has "lang" => (
is => "ro",
isa => "TopTable::Maketext",
writer => "_set_maketext",
);
This is now working as expected and simbabque's help was invaluable!
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/425573.html
標籤:perl internationalization moose catalyst
