Ado
view release on metacpan or search on metacpan
lib/Ado/Plugin/I18n.pm view on Meta::CPAN
$config->{default_language} ||= 'en';
#Supported languages by this system
$config->{languages} ||= ['en', 'de', 'bg'];
# Language will be guessed from one of these places in the order below.
# Specify/narrow your preferences in etc/plugins/i18n.conf.
$config->{language_from_route} //= 1;
$config->{language_from_host} //= 1;
$config->{language_from_param} //= 1;
$config->{language_from_cookie} //= 1;
$config->{language_from_headers} //= 1;
$config->{language_param} //= 'language';
#Allow other namespaces too
$config->{namespace} ||= 'Ado::I18n';
my $e = Mojo::Loader::load_class($config->{namespace});
$app->log->error(qq{Loading "$config->{namespace}" failed: $e}) if $e;
# Defaults for $c->stash so templates without controllers can be used
$app->defaults(language => '', language_from => '');
#Add helpers
$app->helper(language => \&language);
$app->helper(l => \&_maketext);
#default routes including language placeholder.
$app->load_routes($self->routes);
# Add hook around_action
$app->hook(around_action => \&around_action);
#Add to classes used for finding templates in DATA sections
push @{$app->renderer->classes}, __PACKAGE__;
#make plugin configuration available for later in the app
$app->config(__PACKAGE__, $config);
return $self;
}
#Mojolicious::around_action hook.
sub around_action {
my ($next, $c, $action, $last_step) = @_;
$c->language();
return $next->();
}
# Sets *once* and/or returns the current language - a controller attribute
sub language {
my ($c, $language) = @_;
state $config = $c->app->config(__PACKAGE__);
state $l_param = $$config{language_param};
my $stash = $c->stash;
#language('fr') should be used in very
#rare cases since it is called in around_action
if ($language) {
$stash->{i18n} =
$$config{namespace}->get_handle($language, $c, $config);
$c->debug("explicitly set by developer.");
return $stash->{$l_param} = $language;
}
#already set from route or called in an action as: $c->language()
if ($stash->{$l_param}) {
$stash->{i18n}
||= $$config{namespace}->get_handle($stash->{$l_param}, $c, $config);
$c->debug("already set in \$stash->{$l_param}:");
return $stash->{$l_param};
}
#bg.example.com
if ($$config{language_from_host}
&& (my ($l) = $c->req->headers->host =~ /^(\w{2})\./))
{
$stash->{i18n} =
$$config{namespace}->get_handle($l, $c, $config);
$stash->{language_from} = 'host';
return $stash->{$l_param} = $l;
}
#?language=de
if ($$config{language_from_param}
&& (my $l = ($c->param($l_param) // '')))
{
$stash->{$l_param} = $l;
$stash->{language_from} = 'param';
}
if ( !$stash->{$l_param}
&& $$config{language_from_cookie}
&& ($language = $c->cookie($l_param)))
{
$c->cookie($l_param => $language, {expires => time + ONE_MONTH});
$stash->{$l_param} = $language;
$stash->{language_from} = 'cookie';
}
#Accept-Language:"bg,fr;q=0.8,en-us;q=0.5,en;q=0.3"
elsif (!$stash->{$l_param} && $$config{language_from_headers}) {
my @languages =
I18N::LangTags::implicate_supers(
I18N::LangTags::Detect->http_accept_langs($c->req->headers->accept_language));
foreach my $l (@languages) {
$stash->{$l_param} = List::Util::first { $_ =~ /$l/ } @{$$config{languages}};
last if $stash->{$l_param};
}
$c->debug("language_from_headers:$stash->{$l_param}") if $stash->{$l_param};
}
#default
$stash->{$l_param} = $$config{default_language} unless $stash->{$l_param};
$stash->{i18n} =
$$config{namespace}->get_handle($stash->{$l_param}, $c, $config);
return $stash->{$l_param};
}
sub _maketext {
my $stash = $_[0]->stash;
return ref($stash->{i18n}) ? $stash->{i18n}->maketext($_[1], @_[2 .. $#_]) : $_[1];
}
1;
=pod
=encoding utf8
=head1 NAME
Ado::Plugin::I18n - Internationalization and localization for Ado
=head1 SYNOPSIS
This plugin just works. Nothing special needs to be done.
#Override the current language.
#you need to do this only in rare cases (like in an Ado::Command)
$c->language('bg');
#what is my language?
my $current_language = $c->language;
=head1 DESCRIPTION
L<Ado::Plugin::I18n> localizes your application and site.
It automatically detects the current UserAgent language preferences
and selects the best fit from the supported by the application languages.
The current language is detected and set in L<Mojolicious/around_action> hook.
Various methods for setting the language are supported.
=head1 OPTIONS
The following options can be set in C<etc/ado.conf> or in C<etc/plugins/i18n.conf>.
You have to create first C<etc/plugins/i18n.conf> so Ado can pick it up.
You can enable all supported methods to detect the language in your application.
The methods which will be used to detect and set the current
language are as follows:
1. language_from_route, eg. /bg/controller/action
2. language_from_host, eg. fr.example.com
3. language_from_param, eg. ?language=de
4. language_from_cookie, eg. Cookie: language=bg;
5. language_from_headers, eg. Accept-Language: bg,fr;q=0.8,en-us;q=0.5,en;q=0.3
Just be careful not to try to set the language in one request using two different
methods eg. C</bg/controller/action?language=de>.
lib/Ado/Plugin/I18n.pm view on Meta::CPAN
This is the underlying subroutine used in C<around_action> hook and c<language>
helper.
#Add helpers
$app->helper(language => \&language);
=head2 around_action
This method is passed as reference to be used as L<Mojolicious/around_action>.
# Add hook around_action
$app->hook(around_action => \&around_action);
=head1 TODO
Create a table with message entries which will be loaded by this plugin.
Create user interface to add/edit entries.
=head1 SEE ALSO
L<Locale::Maketext>, L<Ado::Plugin>, L<Ado::Manual::Plugins>,
L<Mojolicious::Plugins>,
L<Mojolicious::Plugin>, L<Mojolicious::Guides::Routing/Conditions>
=head1 SPONSORS
The original author
=head1 AUTHOR
ÐÑаÑÐ¸Ð¼Ð¸Ñ ÐеÑов (Krasimir Berov)
=head1 COPYRIGHT AND LICENSE
Copyright 2014 ÐÑаÑÐ¸Ð¼Ð¸Ñ ÐеÑов (Krasimir Berov).
This program is free software, you can redistribute it and/or
modify it under the terms of the
GNU Lesser General Public License v3 (LGPL-3.0).
You may copy, distribute and modify the software provided that
modifications are open source. However, software that includes
the license may release under a different license.
See http://opensource.org/licenses/lgpl-3.0.html for more information.
=cut
__DATA__
@@ partials/language_menu.html.ep
%# This template is inflated from Ado::Plugin::I18n.
%# It Displays menu items with flags.
%# You can experiment and make it as one dropdown menu item.
%# See http://localhost:3000/perldoc/Ado/Plugin/I18n#partialslanguage_menuhtmlep
% my $stash = $self->stash;
% my $conf = config('Ado::Plugin::I18n');
% my @languages = @{$conf->{languages}};
% $language_from ||= 'route';
% #$c->debug('$language_from:' . $language_from);
% $language ||= $conf->{default_language};
<!-- language_menu start -->
<!-- language_from: <%=$language_from%> -->
<% head_css([$sui_path.'/menu.min.css', $sui_path.'/dropdown.min.css',
$sui_path.'/item.min.css',$sui_path.'/icon.min.css',
$sui_path.'/button.min.css']);
head_javascript($sui_path.'/dropdown.min.js'); %>
<div class="right compact menu" id="language_menu">
<div class="ui simple dropdown item">
<i class="translate icon"></i><%=l('Translate') %>
<div class="menu">
% if($language_from eq 'route') {
% foreach my $l(@languages) {
% my $active = $l eq $language ? 'active ' : '';
% my $url = url_for(language => $l, ($$stash{id}?(id => $$stash{id}):()));
%= link_to $url,(class => "${active}button item", title => l($l) ), begin
%= l($l)
%= end
% }
% }
% elsif($language_from eq 'host'){
% foreach my $l(@languages){
% my $active = $l eq $language ? 'active ' : '';
% my $url = $self->req->url->to_abs->clone;
% my ($port, $host) = ($url->port,$url->host);
% $host =~ s|^\w{2}\.||;
<a class="<%= $active %>button item"
href="//<%= $l.'.'.$host .($port?':'.$port:'') %>"
data-content="<%= l($l) %>"><%=l($l)%></a>
% }
% }
% elsif($language_from eq 'param'){
% my $language_param = $conf->{language_param};
% foreach my $l(@languages){
% my $active = $l eq $language ? 'active ' : '';
<a class="<%= $active %>button item"
href="<%= url_with->query([$language_param => $l]); %>"
data-content="<%= l($l) %>"><%=l($l)%></a>
% }
% }
% elsif($language_from eq 'cookie'){
% my $language_param = $conf->{language_param};
% foreach my $l(@languages){
% my $active = $l eq $language ? 'active ' : '';
<a class="<%="$l $active" %>button item"
href="<%= url_for; %>" data-content="<%= l($l) %>"
data-language="<%= $l %>"><%=l($l)%></a>
% }
% my $languages_css_selectors = join(', ', map("#language_menu a.$_", @languages));
<script src="/js/jquery.cookie.js"></script>
<script>
$('<%=$languages_css_selectors%>').click(function(){
$.removeCookie('<%=$language_param%>', { path: '/' });
$.cookie('<%=$language_param%>',$(this).data('language'),{
expires: 30, path: '/' });
});
</script>
% }
( run in 1.214 second using v1.01-cache-2.11-cpan-e1769b4cff6 )