TPAC: Implement a locale picker
authorDan Scott <dscott@laurentian.ca>
Tue, 17 Jul 2012 21:37:54 +0000 (17:37 -0400)
committerDan Scott <dscott@laurentian.ca>
Tue, 24 Jul 2012 12:18:59 +0000 (08:18 -0400)
In situations in which more than a single locale is configured, display
a locale picker in the TPAC header based on the registered locales. We
set the eg_locale cookie if passed a set_eg_locale GET param. Default
the selection to the currently selected locale (if any) and resubmit the
current page request.

Grabs the localized locale names, if available, from the database;
otherwise falls back to the en-US version of the locale names.

The locale picker form resubmits the current page with any variables
that were present in the current page request, so that switching locales
should still maintain state.

Signed-off-by: Dan Scott <dscott@laurentian.ca>
Open-ILS/src/perlmods/lib/OpenILS/WWW/EGWeb.pm
Open-ILS/src/sql/Pg/upgrade/XXXX.function.get_locale_name.sql [new file with mode: 0644]
Open-ILS/src/templates/opac/parts/locale_picker.tt2 [new file with mode: 0644]
Open-ILS/src/templates/opac/parts/topnav.tt2
Open-ILS/web/css/skin/default/opac/style.css

index 66fb47e..34bb486 100644 (file)
@@ -8,14 +8,14 @@ use Encode;
 use Apache2::Const -compile => qw(OK DECLINED HTTP_INTERNAL_SERVER_ERROR);
 use Apache2::Log;
 use OpenSRF::EX qw(:try);
-use OpenILS::Utils::CStoreEditor;
+use OpenILS::Utils::CStoreEditor q/:funcs/;
 
 use constant OILS_HTTP_COOKIE_SKIN => 'eg_skin';
 use constant OILS_HTTP_COOKIE_THEME => 'eg_theme';
 use constant OILS_HTTP_COOKIE_LOCALE => 'eg_locale';
 
 # cache string bundles
-my @registered_locales;
+my %registered_locales;
 
 sub handler {
     my $r = shift;
@@ -152,7 +152,22 @@ sub load_context {
     my %locales = $r->dir_config->get('OILSWebLocale');
     load_locale_handlers($ctx, %locales);
 
-    $ctx->{locale} = 
+    $ctx->{locales} = \%registered_locales;
+
+    # Set a locale cookie if the requested locale is valid
+    my $set_locale = $cgi->param('set_eg_locale');
+    if (!(grep {$_ eq $set_locale} keys %registered_locales)) {
+        $set_locale = '';
+    } else {
+        my $slc = $cgi->cookie({
+            '-name' => OILS_HTTP_COOKIE_LOCALE,
+            '-value' => $set_locale,
+            '-expires' => '+10y'
+        });
+        $r->headers_out->add('Set-Cookie' => $slc);
+    }
+
+    $ctx->{locale} = $set_locale ||
         $cgi->cookie(OILS_HTTP_COOKIE_LOCALE) || 
         parse_accept_lang($r->headers_in->get('Accept-Language')) || 'en_us';
 
@@ -228,6 +243,7 @@ sub load_locale_handlers {
     my $ctx = shift;
     my %locales = @_;
 
+    my $editor = new_editor();
     my @locale_tags = sort { length($a) <=> length($b) } keys %locales;
 
     # always fall back to en_us, the assumed template language
@@ -236,7 +252,17 @@ sub load_locale_handlers {
     for my $idx (0..$#locale_tags) {
 
         my $tag = $locale_tags[$idx];
-        next if grep { $_ eq $tag } @registered_locales;
+        next if grep { $_ eq $tag } keys %registered_locales;
+
+        my $res = $editor->json_query({
+            "from" => [
+                "evergreen.get_locale_name",
+                $tag
+            ]
+        });
+
+        my $locale_name = $res->[0]->{"name"} if exists $res->[0]->{"name"};
+        next unless $locale_name;
 
         my $parent_tag = '';
         my $sub_idx = $idx;
@@ -272,7 +298,7 @@ sub load_locale_handlers {
         if ($@) {
             warn "$@\n" if $@;
         } else {
-            push(@registered_locales, $tag);
+            $registered_locales{"$tag"} = $locale_name;
         }
     }
 }
diff --git a/Open-ILS/src/sql/Pg/upgrade/XXXX.function.get_locale_name.sql b/Open-ILS/src/sql/Pg/upgrade/XXXX.function.get_locale_name.sql
new file mode 100644 (file)
index 0000000..793621a
--- /dev/null
@@ -0,0 +1,37 @@
+CREATE OR REPLACE FUNCTION evergreen.get_locale_name(
+    IN locale TEXT,
+    OUT name TEXT,
+    OUT description TEXT
+) AS $$
+DECLARE
+    eg_locale TEXT;
+BEGIN
+    eg_locale := LOWER(SUBSTRING(locale FROM 1 FOR 2)) || '-' || UPPER(SUBSTRING(locale FROM 4 FOR 2));
+        
+    SELECT i18nc.string INTO name
+    FROM config.i18n_locale i18nl
+       INNER JOIN config.i18n_core i18nc ON i18nl.code = i18nc.translation
+    WHERE i18nc.identity_value = eg_locale
+       AND code = eg_locale
+       AND i18nc.fq_field = 'i18n_l.name';
+
+    IF name IS NULL THEN
+       SELECT i18nl.name INTO name
+       FROM config.i18n_locale i18nl
+       WHERE code = eg_locale;
+    END IF;
+
+    SELECT i18nc.string INTO description
+    FROM config.i18n_locale i18nl
+       INNER JOIN config.i18n_core i18nc ON i18nl.code = i18nc.translation
+    WHERE i18nc.identity_value = eg_locale
+       AND code = eg_locale
+       AND i18nc.fq_field = 'i18n_l.description';
+
+    IF description IS NULL THEN
+       SELECT i18nl.description INTO description
+       FROM config.i18n_locale i18nl
+       WHERE code = eg_locale;
+    END IF;
+END;
+$$ LANGUAGE PLPGSQL COST 1 STABLE;
diff --git a/Open-ILS/src/templates/opac/parts/locale_picker.tt2 b/Open-ILS/src/templates/opac/parts/locale_picker.tt2
new file mode 100644 (file)
index 0000000..c3943a6
--- /dev/null
@@ -0,0 +1,23 @@
+[%- IF ctx.locales.keys.size > 1;
+    set_locale = CGI.param('set_eg_locale') || CGI.cookie('eg_locale');
+%]
+<form id="locale_picker_form" action="[% mkurl() %]">
+    <label for="locale_picker">[% l("Language:") %]</label>
+    [%- FOREACH param IN CGI.params(); -%]
+        [%- NEXT IF param.key == 'set_eg_locale'; -%]
+        <input type="hidden" name="[% param.key %]" value="[% param.value %]" />
+    [%- END; -%]
+    <select id="locale_picker" name="set_eg_locale">
+    [%- FOREACH locale IN ctx.locales.keys %]
+        [%- IF set_locale == locale;
+                selected = 'selected="selected"';
+            ELSE;
+                selected = '';
+            END;
+        %]
+        <option value="[% locale | html %]" [% selected %]>[% ctx.locales.$locale | html %]</option>
+    [%- END %]
+    </select>
+    <input type="submit" value="[% l("Change") %]" />
+</form>
+[%- END %]
index beaccb8..832205d 100644 (file)
@@ -53,6 +53,7 @@
         </div>
         [% END %]
     </div>
+    [%- INCLUDE "opac/parts/locale_picker.tt2" %]
     <div class="common-no-pad"></div>
 </div>
 </div>
index a8fb879..d34df2e 100644 (file)
@@ -1466,6 +1466,7 @@ a.preflib_change {
 .ac_tab_selected a { color: #FFF; }
 #ac_content { clear: both; width: 100%; margin-top: 10px; }
 
+<<<<<<< HEAD
 /* Popmenu styles used for making css menus. */
 .popmenu {
     margin: 0;
@@ -1537,3 +1538,15 @@ a.preflib_change {
     border-bottom-style: solid;
 }
     
+#locale_picker_form {
+    float: right;
+    padding: 0.5em 1em 0.5em 0;
+    border-right: thin #69A088 solid;
+}
+
+#locale_picker_form * {
+    margin: 0;
+    padding: 0;
+    vertical-align: middle;
+    font-size: 1em;
+}