Data::Localize::MultiLevel - Fetch Data From Multi-Level Data Structures


Data-Localize documentation Contained in the Data-Localize distribution.

Index


Code Index:

NAME

Top

Data::Localize::MultiLevel - Fetch Data From Multi-Level Data Structures

SYNOPSIS

Top

    use Data::Localize;

    my $loc = Data::Localize->new();

    $loc->add_localizer(
        Data::Localize::MultiLevel->new(
            paths => [ '/path/to/lexicons/*.yml' ]
        )
    );

    $loc->localize( 'foo.key', { arg => $value, ... } );

    # above is internally...
    $loc->localize_for(
        lang => 'en',
        id => 'foo.key',
        args => [ { arg => $value } ]
    );
    # which in turn looks up...
    # $lexicons->{foo}->{key};

DESCRIPTION

Top

Data::Localize::MultiLevel implements a "Rails"-ish I18N facility. Namely it uses a multi-level key to lookup data from a hash, and uses the NamedArgs formatter.

METHODS

Top

get_lexicon

set_lexicon

load_from_path


Data-Localize documentation Contained in the Data-Localize distribution.

package Data::Localize::MultiLevel;
use Any::Moose;
use Config::Any;

extends 'Data::Localize::Localizer';
with 'Data::Localize::Trait::WithStorage';

has paths => (
    is => 'ro',
    isa => 'ArrayRef',
    trigger => sub {
        my $self = shift;
        $self->load_from_path($_) for @{$_[0]};
    },
);

after register => sub {
    my ($self, $loc) = @_;
    $loc->add_localizer_map('*', $self);
    $loc->add_localizer_map( $_, $self )
        for keys %{ $self->lexicon_map }
};

around get_lexicon => sub{
    my ($next, $self, $lang, $key) = @_;

    my ($storage_key, @key_path) = split /\./, $key;
    my $lexicon = $self->$next($lang, $storage_key);

    return _rfetch( $lexicon, 0, \@key_path )
        if @key_path;

    return $lexicon;
};

around set_lexicon => sub {
    my ($next, $self, $lang, $key, $value) = @_;

    my ($storage_key, @key_path) = split /\./, $key;

    if ( @key_path ) {
        my $lexicon = $self->get_lexicon($lang, $storage_key);
        _rstore( $lexicon, 0, \@key_path, $value );
        $self->$next( $storage_key, $lexicon );
    }
    else {
        $self->$next( $storage_key, $value );
    }

    return;
};

no Any::Moose;

sub _build_formatter {
    Any::Moose::load_class('Data::Localize::Format::NamedArgs');
    return Data::Localize::Format::NamedArgs->new();
}

sub load_from_path {
    my ($self, $path) = @_;

    my @files = glob( $path );
    my $cfg = Config::Any->load_files({ files => \@files, use_ext => 1 });

    foreach my $x (@$cfg) {
        my ($filename, $lexicons) = %$x;
        # should have one root item
        my ($lang) = keys %$lexicons;

        if (Data::Localize::DEBUG()) {
            printf STDERR ("[%s] Loaded %s for languages %s\n",
                Scalar::Util::blessed($self),
                $filename,
                $lang,
            );
        }

        $self->merge_lexicon($lang, $lexicons->{$lang});
        $self->_localizer->add_localizer_map($lang, $self) if $self->_localizer;
    }
}

sub _rfetch {
    my ($lexicon, $i, $keys) = @_;

    return unless $lexicon;

    my $thing = $lexicon->{$keys->[$i]};
    return unless defined $thing;

    my $ref   = ref $thing;
    return unless $ref || length $thing;

    if (@$keys <= $i + 1) {
        return $thing;
    }

    if ($ref ne 'HASH') {
        if (Data::Localize::DEBUG()) {
            printf STDERR ("%s does not point to a hash\n",
                join('.', map { $keys->[$_] } 0..$i)
            );
        }
        return ();
    }

    return _rfetch( $thing, $i + 1, $keys )
}

sub _rstore {
    my ($lexicon, $i, $keys, $value) = @_;

    return unless $lexicon;

    if (@$keys <= $i + 1) {
        $lexicon->{ $keys->[$i] } = $value;
        return;
    }

    my $thing = $lexicon->{$keys->[$i]};

    if (ref $thing ne 'HASH') {
        if (Data::Localize::DEBUG()) {
            printf STDERR ("%s does not point to a hash\n",
                join('.', map { $keys->[$_] } 0..$i)
            );
        }
        return ();
    }

    return _rstore( $thing, $i + 1, $keys, $value );
}

1;

__END__