Locale::Maketext::Lexiconを呼び出している I18N ルーチンに問題があります。( CatalystX::I18N::Maketextから) 呼び出されているルーチンは次のとおりです。
sub load_lexicon {
my ( $class, %params ) = @_;
my $locales = $params{locales} || [];
my $directories = $params{directories};
my $gettext_style = defined $params{gettext_style} ? $params{gettext_style} : 1;
my $inheritance = $params{inheritance} || {};
$directories = [ $directories ]
if defined $directories
&& ref $directories ne 'ARRAY';
$directories ||= [];
$locales = [ $locales ]
unless ref $locales eq 'ARRAY';
die "Invalid locales"
unless defined $locales
&& scalar @$locales > 0
&& ! grep { $_ !~ $CatalystX::I18N::TypeConstraints::LOCALE_RE } @$locales;
{
no strict 'refs';
my $lexicon_loaded = ${$class.'::LEXICON_LOADED'};
if (defined $lexicon_loaded
&& $lexicon_loaded == 1) {
warn "Lexicon has already been loaded for $class";
return;
}
}
my $lexicondata = {
_decode => 1,
};
$lexicondata->{_style} = 'gettext'
if $gettext_style;
my %locale_loaded;
# Loop all directories
foreach my $directory (@$directories) {
next
unless defined $directory;
$directory = Path::Class::Dir->new($directory)
unless ref $directory eq 'Path::Class::Dir';
next
unless -d $directory->stringify && -e _ && -r _;
my @directory_content = $directory->children();
# Load all avaliable message files
foreach my $locale (@$locales) {
my $lc_locale = lc($locale);
$lc_locale =~ s/-/_/g;
my @locale_lexicon;
foreach my $content (@directory_content) {
if ($content->is_dir) {
push(@locale_lexicon,'Slurp',$content->stringify)
if $content->basename eq $locale;
} else {
my $filename = $content->basename;
if ($filename =~ m/^$locale\.(mo|po)$/i) {
push(@locale_lexicon,'Gettext',$content->stringify);
} elsif ($filename =~ m/^$locale\.m$/i) {
push(@locale_lexicon,'Msgcat',$content->stringify);
} elsif($filename =~ m/^$locale\.db$/i) {
push(@locale_lexicon,'Tie',[ $class, $content->stringify ]);
} elsif ($filename =~ m/^$lc_locale\.pm$/) {
$locale_loaded{$locale} = 1;
require $content->stringify;
# TODO transform maketext -> gettext syntax if flag is set
# Locale::Maketext::Lexicon::Gettext::_gettext_to_maketext
}
}
}
$lexicondata->{$locale} = \@locale_lexicon
if scalar @locale_lexicon;
}
}
# Fallback lexicon
foreach my $locale (@$locales) {
next
if exists $inheritance->{$locale};
next
if exists $locale_loaded{$locale};
$lexicondata->{$locale} ||= ['Auto'];
}
eval qq[
package $class;
our \$LEXICON_LOADED = 1;
Locale::Maketext::Lexicon->import(\$lexicondata)
];
while (my ($locale,$inherit) = each %$inheritance) {
my $locale_class = lc($locale);
my $inherit_class = lc($inherit);
$locale_class =~ s/-/_/g;
$inherit_class =~ s/-/_/g;
$locale_class = $class.'::'.$locale_class;
$inherit_class = $class.'::'.$inherit_class;
no strict 'refs';
push(@{$locale_class.'::ISA'},$inherit_class);
}
die("Could not load Locale::Maketext::Lexicon") if $@;
return;
}
問題は、ロケールにちなんで名付けられたディレクトリに複数のファイルをロードしようとしていることにあると思います (つまり、en_GB ディレクトリには、翻訳メッセージを含む複数のファイルがあります)。これが push(@locale_lexicon,'Slurp',$content->stringify) を実行させていると思います。
$@ の値を追加するために下部の die メッセージを一時的に変更すると、次のようになりました。
"Could not load Locale::Maketext::Lexicon: Cannot read D:\WAMP\Apache\Apache2\htdocs\TopTable\Test\TopTable\root\locale\en_GB (called by TopTable::Maketext): Permission denied at D:/WAMP/Perl/perl/site/lib/Catalyst/ScriptRunner.pm line 50.
このメッセージが停止している理由がわかりません。ログインしたセッションで perl プロセスが実行されており、ディレクトリとその中のファイルに問題なくアクセスできます。また、(一時的に)「Everyone」にディレクトリへの変更アクセス権を付与しました(ただし、読み取りのみが必要なはずです)が、何の効果もありませんでした。
誰か提案はありますか?すべての翻訳を 1 つの en_gb.po ファイルに保存すれば機能しますが、非常に扱いにくくなっており、できればメッセージを分離したいと考えています。
注意してください、私が Apache ディレクトリで実行しているという事実は、それが私の Web のものを置く傾向があるという理由だけです - これは私のラップトップで実行されているだけで、外の世界はアクセスできません最終的には CentOS で実行されます)。現時点では、(HTTP::Server::PSGI を使用して) Catalyst 組み込み Web サーバー経由で実行されています。これを自分のユーザー名で直接実行しているため、別のアカウントで実行されているサービスはありません。
どうもありがとう