Hi
I have an issue with an I18N routine that's calling Locale::Maketext::Lexicon. The routine that's being called (from CatalystX::I18N::Maketext) is below:
sub load_lexicon {
my ( $class, %params ) = @_;
my $locales = $params{locales} || [];
my $directories = $params{directories};
my $gettext_style = defined $params{gettext_style} ? $params{gette
+xt_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_R
+E } @$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->strin
+gify);
} elsif ($filename =~ m/^$locale\.m$/i) {
push(@locale_lexicon,'Msgcat',$content->string
+ify);
} 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;
}
The problem, I think, comes from the fact I'm trying to load multiple files in directories named after the locales (i.e., the en_GB directory will have multiple files with translation messages in it). I believe this is causing the push(@locale_lexicon,'Slurp',$content->stringify) to execute.
When I temporarily altered the die message at the bottom to add in the value of $@, I got the following:
"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.
I'm at a loss as to why this message is stopping it; the perl process is running under my logged in session and I can access the directory and the files in it without an issue; I've also (temporarily) given 'Everyone' modify access to the directory (although I'm sure it should only need to read) and that hasn't had any effect.
Does anyone have any suggestions? It works if I keep all my translations in one en_gb.po file, but it's getting extremely unwieldy and I'd like to separate out the messages if I can.
Edit:I should have mentioned this originally, but the fact I have it running in the Apache directory is just because that tends to be where I put my web stuff - this is just running on my laptop and the outside world has no access (I'm developing a Catalyst web site that will eventually run on CentOS). At the moment it's running via the Catalyst built-in web server (using HTTP::Server::PSGI). I'm running this directly under my own username, so no services are running under separate accounts.
Many thanks
Chris