将 CatalystX::I18N::Maketext 添加到我的 DBIC 模式
Adding CatalystX::I18N::Maketext to my DBIC schema
抱歉,我以为我是在 之后到达那里的,但是我只能从一个单独的 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;
然而,这不起作用 - 'lang' 方法是可访问的,但 returns undef - 我已将此作为测试添加到我的结果集方法之一中:
$logger->( "debug", $self->result_source->schema->lang->maketext("menu.title.league-tables", "Division Three") );
但这给出了一个错误:
[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."
感谢任何建议,非常感谢!我希望我已经提供了足够的信息来了解发生了什么。
在@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()
的调用中。
再次,在 simbabque 的帮助下,我已经设法在模型中使用 ACCEPT_CONTEXT
sub(注意 if ref( $c ) eq "TopTable"
检查 - 正如评论所说,模型似乎在我的代码开始之前,作为实例化的一部分被 Catalyst 调用,在这些情况下,$c 是字符串“TopTable”,而不是 TopTable 对象的引用,因此我们不能在其上调用 ->locale
):
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;
我这样更改了架构:
use TopTable::Maketext;
has "lang" => (
is => "ro",
isa => "TopTable::Maketext",
writer => "_set_maketext",
);
现在一切正常,simbabque 的帮助非常宝贵!
抱歉,我以为我是在
因此,为了尝试给出一个完整的画面,这是我最终开始工作的脚本:
#!/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;
然而,这不起作用 - 'lang' 方法是可访问的,但 returns undef - 我已将此作为测试添加到我的结果集方法之一中:
$logger->( "debug", $self->result_source->schema->lang->maketext("menu.title.league-tables", "Division Three") );
但这给出了一个错误:
[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."
感谢任何建议,非常感谢!我希望我已经提供了足够的信息来了解发生了什么。
在@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()
的调用中。
再次,在 simbabque 的帮助下,我已经设法在模型中使用 ACCEPT_CONTEXT
sub(注意 if ref( $c ) eq "TopTable"
检查 - 正如评论所说,模型似乎在我的代码开始之前,作为实例化的一部分被 Catalyst 调用,在这些情况下,$c 是字符串“TopTable”,而不是 TopTable 对象的引用,因此我们不能在其上调用 ->locale
):
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;
我这样更改了架构:
use TopTable::Maketext;
has "lang" => (
is => "ro",
isa => "TopTable::Maketext",
writer => "_set_maketext",
);
现在一切正常,simbabque 的帮助非常宝贵!