From: Mischa POSLAWSKY Date: Tue, 24 Jan 2006 19:55:34 +0000 (+0000) Subject: Lirama::Loc2 X-Git-Url: http://git.shiar.nl/perl/loc/.git/commitdiff_plain/0fc15cae405d8c2af2c9dc53eed4e03e2f5433da Lirama::Loc2 --- diff --git a/Lirama/Loc.pm b/Lirama/Loc.pm deleted file mode 100644 index cd3529f..0000000 --- a/Lirama/Loc.pm +++ /dev/null @@ -1,115 +0,0 @@ -package Lirama::Loc; - -use strict; -use warnings; -use utf8; - -require Exporter; -our @ISA = qw(Exporter); -our @EXPORT = qw(langpref); -our @EXPORT_OK = qw(@langpref loc); - -our @langpref = qw(en eo nl sv el hu de fr ru kr fi); - -sub langpref { - # @_ is order of languages (prefered language last) - for my $lang (@_) { - unshift @langpref, splice @langpref, $_, 1 # move to front - for grep $langpref[$_] eq $lang, 0..$#langpref; - } # find $lang and move to front of @langpref -} # langpref - -sub loc($) { - my $this = shift; - # localize to most preferred language - ref $_[0] eq "HASH" or return $_[0]; - defined $_[0]{$_} and return $_[0]{$_} for @langpref; -} # loc - -sub TIEHASH { - my $this = shift; - - my $node = {}; - while (my ($id, $langs) = each %{$_[0]}) { - $node->{$id} = $this->loc($langs); - } # add each element of i18n hash - - return bless $node, $this; -} # new - -sub FETCH { - my $this = shift; - # custom expand: get preferred language from given hash - return $this->loc($_[0]) if ref $_[0] eq "HASH"; # deprecated in favor of loc() - # array ref used for passing arguments - @_ = @{$_[0]} if ref $_[0] eq "ARRAY"; - # get localized string by identifier - local $_ = shift; - #todo: shouldn't occur - find out where this is done, then fix and remove this check - defined $_ or return ''; - $_ = $this->{$_} if exists $this->{$_}; - # static output if no arguments given - return $_ unless @_; # unnecessary but faster for common case - # adaptive string (code) - $_ = $_->(@_) if ref $_ eq "CODE"; - # dynamic output - return sprintf $_, @_; -} # FETCH - -sub EXISTS { - # true if identifier is localized; non-existing strings still return - # themselves, so in standard meaning everything would exist - return exists $_[0]->{$_[1]}; -} # EXISTS - -sub FIRSTKEY { - my $this = shift; - keys %$this; # reset iterator - return each %$this; -} # FIRSTKEY - -sub NEXTKEY { - my $this = shift; - return each %$this; -} # NEXTKEY - -1; - -__END__ - - -=head1 NAME - -Lirama::Loc - Localize strings - -=head1 SYNOPSIS - - use Lirama::Loc; - - langpref(qw/en eo/); # prefer esperanto texts - - tie my %loc, "Lirama::Loc", { - test => { - en => "this is a test", - eo => "cxi tio estas testo", - nl => "dit is een test", - }, - }; - - print $loc{test}; - -=head1 DESCRIPTION - -Returns a text in the preferred language. - -=head1 SEE ALSO - -L - -=head1 AUTHOR - -Mischa POSLAWSKY - -Copyright 2005 Mischa POSLAWSKY. All rights reserved. - -=cut diff --git a/Lirama/Loc2.pm b/Lirama/Loc2.pm new file mode 100644 index 0000000..0ea0410 --- /dev/null +++ b/Lirama/Loc2.pm @@ -0,0 +1,119 @@ +package Lirama::Loc2; + +use strict; +use warnings; +use utf8; #todo: does it even matter? + +our $VERSION = '2.00'; + +require Exporter; +our @ISA = qw(Exporter); +our @EXPORT = qw(langpref); +our @EXPORT_OK = qw(loc); + +our @langpref;# = qw(en eo nl sv el hu de fr ru kr); + +sub langpref { + @langpref = @_ if @_; # set order of languages (prefered language first) + return wantarray ? @langpref : $langpref[0]; +} + +sub loc($) { + my $this = shift; + # get one value from a hash of multiple options + # if it isn't, we're done already: + ref $_[0] eq "HASH" or return $_[0]; + # localize to most preferred language + defined $_[0]{$_} and return $_[0]{$_} for @langpref; +} + +sub TIEHASH { + return bless $_[1], $_[0]; # bless the l10n hash +} + +sub FETCH { + my $this = shift; + # custom expand: get preferred language from given hash + # return $this->loc($_[0]) if ref $_[0] eq "HASH"; # deprecated in favor of loc() + # array ref used for passing arguments + @_ = @{$_[0]} if ref $_[0] eq "ARRAY"; + # get localized string by identifier + local $_ = shift; + #todo: shouldn't occur - find out where this is done, then fix and remove this check + # defined $_ or return ''; + $_ = $this->loc($this->{$_}) if exists $this->{$_}; +# $_ = ref $this->{$_} eq "HASH" ? $this->loc($this->{$_}) : $this->{$_} if exists $this->{$_}; + # static output if no arguments given + return $_ unless @_; # unnecessary but faster for common case + # adaptive string (code) + $_ = $_->(@_) if ref $_ eq "CODE"; + # dynamic output + return sprintf $_, @_; +} + +# Same as found in Tie::StdHash + +sub EXISTS { exists $_[0]->{$_[1]} } +sub FIRSTKEY { my $a = scalar keys %{$_[0]}; each %{$_[0]} } +sub NEXTKEY { each %{$_[0]} } + +1; + +__END__ + + +=head1 NAME + +Lirama::Loc - Localize strings + +=head1 SYNOPSIS + + use Lirama::Loc; + + langpref(qw/nl en eo/); # prefer I (dutch) texts + + tie my %loc, "Lirama::Loc", { + test => { + en => "this is a test", + eo => "cxi tio estas testo", + }, + }; + + print $loc{test}; # "this is a test", since dutch is unavailable + +=head1 DESCRIPTION + +Returns a text in the most preferred language available. +Mainly intended for translation of different strings on a website. + +=over 4 + +=item C + +Shared so we only have to set one var to change all translations; +may yet be a very bad idea (does it work correctly in modperl?) + +=item C + +=item C + +=item C + +True if identifier is localized; non-existing strings still return +themselves, so in standard meaning everything would exist. + +=back + +=head1 SEE ALSO + +L + +L + +=head1 AUTHOR + +Mischa POSLAWSKY + +Copyright 2005 Mischa POSLAWSKY. All rights reserved. + +=cut diff --git a/Lirama/Loc2/Auto.pm b/Lirama/Loc2/Auto.pm new file mode 100644 index 0000000..f5a5340 --- /dev/null +++ b/Lirama/Loc2/Auto.pm @@ -0,0 +1,140 @@ +package Lirama::Loc2::Auto; + +use strict; +use warnings; +use utf8; + +use Lirama::Loc2; + +our $VERSION = '2.00'; + +sub optimize { + my $self = shift; + $self->[1]{optimize} = $_[0] if @_; + return $self->[1]{optimize}; +} # optimize + +sub TIEHASH { + my ($class, $path, @langpref) = @_; + + my $langs = @langpref>0; # languages specified + langpref(@langpref) if $langs; # set default language preference + + my $node = [ # array for faster access to common [0] + {}, # files + { # configuration + path => $path, + optimize => $langs, # assume langpref won't change if specified + } + ]; + return bless $node, $class; +} # new + +sub FETCH { + my ($self, $file) = @_; + + unless (exists $self->[0]{$file}) { + my $filename = $self->[1]{path}.'/'.$file; # perl file returning l10n hash + my $extlang = '.'.langpref(); # file tag for the preferred language + my $ext = ".pl"; # extension for $filename + + $filename .= $extlang # get language-optimized file + if $self->[1]{optimize} and -r $filename.$extlang.$ext; + + tie %{$self->[0]{$file}}, "Lirama::Loc2", do $filename.$ext; + } # initialize Loc for this file + + return $self->[0]{$file} +} # FETCH + +# Basically same as Tie::StdHash + +sub EXISTS { exists $_[0]->[0]{$_[1]} } +sub FIRSTKEY { my $a = scalar keys %{$_[0]->[0]}; each %{$_[0]->[0]} } +sub NEXTKEY { each %{$_[0]->[0]} } + +1; + +__END__ + + +=head1 NAME + +Lirama::Loc::Auto - Localize strings, initialize automatically + +=head1 SYNOPSIS + + use Lirama::Loc::Auto; + + tie my %L, "Lirama::Loc::Auto", "path/to/translation/files", "en"; + + print $L{numbers}{7}; # "seven" + +=head1 DESCRIPTION + +Setup a hash containing multiple L objects, which +open automatically on demand. + +=over 4 + +=item C + +Will setup a hash to automatically load data files from P<$path/*.pl>. +These files should only return an anonimous translation hash. + +If @languages is set, it will be taken as the default language preference. +[todo:optimize] + +=item C<$tie{$file}{$string}> + +The first time a translation is accessed from C<$tie{$file}{$string}>, it will +create a Lirama::Loc object from P<$path/$file.pl>. + +=item C + +=item C + +bla + +=back + +=head1 EXAMPLE + +We'll create P<./includes/loc/index.pl> with the following contents: + + { + welcome => { + en => "welcome", + eo => "bonvenon", + nl => "welkom", + }, + "%d visits" => { + en => sub { "%d user".($_[0]!=1 && "s")." have visited this site." }, + }, + } + +Setup a hash with user defined language preferences, and a fallback to English. + + my @langpref = split(',', $ENV{HTTP_ACCEPT_LANGUAGE}); + tie my %loc, "Lirama::Loc::Auto", "includes/loc", @langpref, "en"; + +And display the I string: + + print $loc{index}{welcome}; + +If the user wanted Dutch texts, it will show I. In case the user wanted +French for example, it will fallback to English. + + print $loc{index}{["%d visits", ++$counter]}; + +=head1 SEE ALSO + +L + +=head1 AUTHOR + +Mischa POSLAWSKY + +Copyright 2005 Mischa POSLAWSKY. All rights reserved. + +=cut