Separate handling of po translations and DDTP translations
authorFrank Lichtenheld <frank@lichtenheld.de>
Tue, 5 Feb 2008 21:15:59 +0000 (22:15 +0100)
committerFrank Lichtenheld <frank@lichtenheld.de>
Tue, 5 Feb 2008 21:52:54 +0000 (22:52 +0100)
This way we don't need to immediatly fall back to English
if people have more than one preferred language for which
only part of the page content is available.

If e.g. they would have "ca;q=0.9, de;q=0.5, en;q=0.1" in
their Accept-Language header (insert any DDTP-only language
for ca and any PO-available language for de), we can show the
description in Catalan if available, and the po contents in
German.

The code will usually try to fall back to $po_lang if a
description is not available in $ddtp_lang.

Not implemented (yet) is a DDTP language negotiation _after_
we actually know which DDTP translations are available.

The 'lang' query parameter overrides both values and has
only the fallback English (But you shouldn't use it
anyway ;).

bin/create_index_pages
lib/Packages/Dispatcher.pm
lib/Packages/DoIndex.pm
lib/Packages/Template.pm
templates/config.tmpl
templates/html/head.tmpl
templates/html/index.tmpl
templates/html/search.tmpl
templates/html/show.tmpl
templates/html/util.inc
templates/rss/newpkg.tmpl

index 4e094302746b131708f6af53223cafdaa4bbe4f2..05123e7355923197b194b6a040b43f8350e96abb 100755 (executable)
@@ -60,7 +60,8 @@ foreach my $s (@SUITES) {
        print "writing $key/index (lang=$lang)...\n";
 
        my %content = ( subsections => [], suite => $s,
-                       lang => $lang, charset => $charset, cat => $cat,
+                       po_lang => $lang, ddtp_lang => $lang,
+                       charset => $charset, cat => $cat,
                        used_langs => \@LANGUAGES, suites => \@SUITES );
        foreach my $ssec (sort (keys %{$subsections->{$s}}, 'virtual')) {
            next if $ssec eq '-';
@@ -200,7 +201,8 @@ sub write_files {
            my $cat = Packages::I18N::Locale->get_handle($lang)
                or die "get_handle failed for $lang";
 
-           my %lang_vars = ( lang => $lang, charset => $charset,
+           my %lang_vars = ( po_lang => $lang, ddtp_lang => $lang,
+                             charset => $charset,
                              cat => $cat, used_langs => \@LANGUAGES );
            print "writing $source$s/allpackages (lang=$lang)...\n";
            $template->page( 'index', { %lang_vars, packages => $pkgs->{$key},
index e6a9d5220dfe764fc607317c91953d861a5294d5..9f844f2e2d175240e4d5eb06887b59a6f08e1c4e 100755 (executable)
@@ -1,7 +1,7 @@
 #!/usr/bin/perl -T
 # Packages::Dispatcher -- CGI interface for packages.debian.org
 #
-# Copyright (C) 2004-2007 Frank Lichtenheld
+# Copyright (C) 2004-2008 Frank Lichtenheld
 #
 #    This program is free software; you can redistribute it and/or modify
 #    it under the terms of the GNU General Public License as published by
@@ -92,14 +92,16 @@ sub do_dispatch {
     &Packages::Config::init( $homedir );
     &Packages::DB::init();
 
-    my $acc = I18N::AcceptLanguage->new();
-    my %all_langs = map { $_ => 1 } (@LANGUAGES, @DDTP_LANGUAGES);
-    my @all_langs = sort keys %all_langs;
-    my $http_lang = $acc->accepts( $input->http("Accept-Language"),
-                                  \@all_langs ) || 'en';
-    debug( "LANGUAGES=@all_langs header=".
+    my %PO_LANGUAGES = map { $_ => 1 } @LANGUAGES;
+    my %DDTP_LANGUAGES = map { $_ => 1 } @DDTP_LANGUAGES;
+    my $acc = I18N::AcceptLanguage->new(defaultLanguage => 'en');
+    my $ddtp_lang = $acc->accepts( $input->http("Accept-Language"),
+                                  \@DDTP_LANGUAGES );
+    my $po_lang = $acc->accepts( $input->http("Accept-Language"),
+                                \@LANGUAGES );
+    debug( "LANGS=@LANGUAGES DDTP_LANGS=@DDTP_LANGUAGES header=".
           ($input->http("Accept-Language")||'').
-          " http_lang=$http_lang", 1 ) if DEBUG;
+          " po_lang=$po_lang ddtp_lang=$ddtp_lang", 1 ) if DEBUG;
 
     # backwards compatibility stuff
     debug( "SCRIPT_URL=$ENV{SCRIPT_URL} SCRIPT_URI=$ENV{SCRIPT_URI}" ) if DEBUG;
@@ -141,7 +143,7 @@ sub do_dispatch {
 
        push @components, 'index' if @components && $path =~ m,/$,;
 
-       my %LANGUAGES = map { $_ => 1 } @all_langs;
+       my %LANGUAGES = map { $_ => 1 } (@LANGUAGES, @DDTP_LANGUAGES);
        if (@components > 1 and $LANGUAGES{$components[0]}
            and !$input->param('lang')) {
            $input->param( 'lang', shift(@components) );
@@ -247,7 +249,7 @@ sub do_dispatch {
                                        replace => { all => \@ARCHIVES,
                                                     default => \@ARCHIVES} },
                       exact => { default => 0, match => '^(\w+)$',  },
-                      lang => { default => $http_lang, match => '^([\w-]+)$',  },
+                      lang => { default => undef, match => '^([\w-]+)$',  },
                       source => { default => 0, match => '^(\d+)$',  },
                       debug => { default => 0, match => '^(\d+)$',  },
                       searchon => { default => 'names', match => '^(\w+)$', },
@@ -272,9 +274,16 @@ sub do_dispatch {
     my %params = Packages::CGI::parse_params( $input, \%params_def, \%opts );
     Packages::CGI::init_url( $input, \%params, \%opts );
 
+    if (defined($opts{lang})) {
+       $opts{po_lang} = $PO_LANGUAGES{$opts{lang}} ? $opts{lang} : 'en';
+       $opts{ddtp_lang} = $DDTP_LANGUAGES{$opts{lang}} ? $opts{lang} : 'en';
+    } else {
+       $opts{po_lang} = $po_lang;
+       $opts{ddtp_lang} = $ddtp_lang;
+    }
     my $charset = "UTF-8";
-    my $cat = Packages::I18N::Locale->get_handle( $opts{lang}, "en" )
-       or die "get_handle failed for $opts{lang}";
+    my $cat = Packages::I18N::Locale->get_handle( $opts{po_lang}, 'en' )
+       or die "get_handle failed for $opts{po_lang}";
     $opts{cat} = $cat;
 
     $opts{h_suites} = { map { $_ => 1 } @suites };
@@ -299,8 +308,8 @@ sub do_dispatch {
     debug( "Parameter evaluation took ".timestr($petd) ) if DEBUG;
 
     my $template = new Packages::Template( $TEMPLATEDIR, $opts{format},
-                                          { lang => $opts{lang}, charset => $charset,
-                                            cat => $cat,
+                                          { po_lang => $opts{po_lang}, ddtp_lang => $opts{ddtp_lang},
+                                            charset => $charset, cat => $cat,
                                             debug => ( DEBUG ? $opts{debug} : 0 ) },
                                           ( $CACHEDIR ? { COMPILE_DIR => $CACHEDIR } : {} ) );
 
index a0cae2baf2f435cff7fa59f1f698d1d2ee19894c..3129b0b9c7fb950cc000cf0803485e6a65951af8 100644 (file)
@@ -46,12 +46,7 @@ sub send_file {
     $path .= "$opts->{archive}[0]/" if @{$opts->{archive}} == 1;
     $path .= "$opts->{subsection}[0]/" if @{$opts->{subsection}};
     $path .= "$opts->{priority}[0]/" if @{$opts->{priority}};
-
-    #FIXME: ugly hack
-    if ($opts->{lang} ne 'en' and !-f "$wwwdir/$path$file.$opts->{lang}.$opts->{format}") {
-       $opts->{lang} = 'en';
-    }
-    $path .= "$file.$opts->{lang}.$opts->{format}";
+    $path .= "$file.$opts->{po_lang}.$opts->{format}";
 
     unless (@Packages::CGI::fatal_errors) {
        my $buffer;
index a3268a35f046d5141003e1d6da5b6fffd7540010..c2919f1973de710a4f653fae67272f5a3edeee50 100644 (file)
@@ -85,8 +85,10 @@ sub page {
            sub { return Packages::I18N::Locale::g($page_content->{cat}, @_) };
     }
     $page_content->{used_langs} ||= \@LANGUAGES;
-    $page_content->{langs} = languages( $page_content->{lang}
-                                       || $self->{vars}{lang} || 'en',
+    $page_content->{langs} = languages( $page_content->{po_lang}
+                                       || $self->{vars}{po_lang} || 'en',
+                                       $page_content->{ddtp_lang}
+                                       || $self->{vars}{ddtp_lang} || 'en',
                                        @{$page_content->{used_langs}} );
 
     my $txt;
@@ -114,17 +116,17 @@ sub error_page {
 }
 
 sub languages {
-    my ( $lang, @used_langs ) = @_;
-    my $cat = Packages::I18N::Locale->get_handle($lang)
-       || Packages::I18N::Locale->get_handle('en');
+    my ( $po_lang, $ddtp_lang, @used_langs ) = @_;
+    my $cat = Packages::I18N::Locale->get_handle($po_lang, 'en');
 
     my @langs;
+    my $skip_lang = ($po_lang eq $ddtp_lang) ? $po_lang : '';
 
     if (@used_langs) {
 
        my @printed_langs = ();
        foreach (@used_langs) {
-           next if $_ eq $lang; # Never print the current language
+           next if $_ eq $skip_lang; # Don't print the current language
            unless (get_selfname($_)) { warn "missing language $_"; next } #DEBUG
            push @printed_langs, $_;
        }
index 1fee16b8b4a0245fc268afb4c50235cb96b5b32f..c99694e5c4f063bdf823e9c0b46e9b358c1ac910 100644 (file)
@@ -1,6 +1,7 @@
 [%- DEFAULT
    charset = 'UTF-8'
-   lang = 'en'
+   po_lang = 'en'
+   ddtp_lang = 'en'
 
    organisation = 'Debian'
    homepage = 'http://www.debian.org/'
index 362a32edf0a61d41d2267fee4d88116969952dca..866641cf4c7d40dbe088c600fdf326f98f4679d6 100644 (file)
@@ -1,5 +1,5 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html lang="[% lang %]">
+<html lang="[% po_lang %]">
 <head>
 <title>[% organisation %] -- [% title_tag %]</title>
 <link rev="made" href="mailto:[% admin.mail %]">
index cc209838c189b60d034bb2ac1a78acf741241f29..cac305c1d671a547a8988886dcf10c77079ed2d9 100644 (file)
     [% PROCESS marker text=p.section IF p.section != main_section %]
     [% PROCESS marker text=p.archive IF p.archive != main_archive %]
   [% END %]
-  [%- IF p.trans_desc.$lang;
-       sdesc = p.trans_desc.$lang;
+  [%- desclang = 'en';
+      IF p.trans_desc.$ddtp_lang;
+       sdesc = p.trans_desc.$ddtp_lang;
+       desclang = $ddtp_lang;
       ELSE;
        sdesc = p.desc;
       END -%]
        [%- ', ' UNLESS loop.last %][% END %]</dd>
     [% IF p.versions.length %]
       <dt><a href="[% p.name %]">[% p.name %]</a> ([% p.versions %])[% PROCESS markers %]</dt>
-         <dd>[% sdesc | html %]</dd>
+         <dd [% "lang=\"$desclang\"" IF desclang != po_lang %]>[% sdesc | html %]</dd>
     [% END %]
   [% ELSE %]
     <dt><a href="[% p.name %]" id="[% p.name %]">[% p.name %]</a> ([% p.versions %])[% PROCESS markers %]</dt>
-       <dd>[% sdesc | html %]</dd>
+       <dd [% "lang=\"$desclang\"" IF desclang != po_lang %]>[% sdesc | html %]</dd>
   [% END %]
 
   [% '</dl>' IF loop.last %]
index 452e80b169b9e8a3b0a67342334c34eebe95b7ee..41ca369cf1c3d6794f6b731155e4708f7d8261be 100644 (file)
@@ -27,6 +27,7 @@
     }
    navigation = [ { name => g('Package Search Results') } ]
 -%]
+[%- PROCESS 'html/util.inc' -%]
 
 <div id="psearchsug">
 [% UNLESS results %]
   [% FOREACH s IN suites;
        suite = s.suite %]
     <li class="[% suite %]"><a class="resultlink" href="[% make_url(pkg,'','suite',suite,'arch','','section','') %]">[% suite %]
-       [%- ' (' _ suite_aliases.$suite _ ')' IF suite_aliases.$suite %]</a>[% ' (' _ s.subsection _ ')' IF s.subsection %]: [% IF s.trans_desc.$lang; s.trans_desc.$lang | html; ELSE; s.desc | html; END %]  [%- IF s.section && s.section != main_section %] [<strong class="pmarker">[% s.section %]</strong>][% END %]
+       [%- ' (' _ suite_aliases.$suite _ ')' IF suite_aliases.$suite %]</a>[% ' (' _ s.subsection _ ')' IF s.subsection %]:
+       [% PROCESS desc_i18n trans_desc=s.trans_desc desc=s.desc %]
+       [%- PROCESS marker text=s.section IF s.section && s.section != main_section %]
     [% FOREACH s.versions %]
       <br>[% version %] [%- IF archive != main_archive %] [<strong class="pmarker">[% archive %]</strong>][% END %]: [% architectures.join(' ') %]
     [% END %]
      [% origin = (archive == main_archive) ? suite : "$suite/$archive";
        js_id = string2id("$pkg$suite$archive")  %]
     <li><a class="resultlink" href="[% make_url(pkg,'','source','source','suite',origin,'section','','arch','') %]">[% origin %]</a> ([% subsection %]): [% version %]
-      [%- IF section %] [<strong class="pmarker">[% section %]</strong>][% END %]
-      [%- IF real_archive %] [<strong class="pmarker">[% real_archive %]</strong>][% END %]
+      [%- PROCESS marker text=section IF section %] [%- PROCESS marker text=real_archive IF real_archive %]
     <br>[% g('Binary packages:') %] <span id="js_[% js_id %]" class="p_js_elem"></span> <span id="html_[% js_id %]" class="binaries">[% FOREACH binary IN binaries.sort %]<a href="[% make_url(binary,'','source','','suite',suite,'archive',archive,'arch','','archive','') %]">[% binary %]</a>[% ', ' UNLESS loop.last %][% END %]</span>
        [% IF binaries.size > 10 %]
        <script type="text/javascript">init_toggle_elem("[% js_id %]","[% g('show %u binary packages', binaries.size) %]","[% g('hide %u binary packages', binaries.size) %]")</script>
index ff589b916c9d7d139a37bccd8f9472e33f0fa4c6..048b7d0d6d72f62116b67dfa34b8672d8694ce69 100644 (file)
@@ -16,7 +16,8 @@
     nav_arr.push( { prefix=>g('Section:'), title=>g('All packages in this section'), url=>make_url("$subsection/"), name=>subsection } );
     nav_arr.push( { prefix=>g('Package:'), name=>pkg } ); -%]
 [% desclang = 'en';
-   SET desclang = lang IF desc.$lang.long %]
+   SET desclang = po_lang IF desc.$po_lang.long;
+   SET desclang = ddtp_lang IF desc.$ddtp_lang.long %]
 [%- PROCESS 'html/head.tmpl'
    title_tag = is_source ? g('Details of source package %s in %s', pkg, suite)
                         : g('Details of package %s in %s', pkg, suite)
 
 [% IF desc %]
 <div id="pdesctab">
-<div id="pdesc">
 [% UNLESS is_virtual %]
+<div id="pdesc" [% "lang=\"$desclang\"" IF desclang != po_lang %]>
        [% IF desc.$desclang.short %]
        <h2>[% desc.$desclang.short %]</h2>
        <p>[% desc.$desclang.long %]
        [% END %]
 [% ELSE %]
+<div id="pdesc">
        <p>[% g('This is a <em>virtual package</em>. See the <a href="%s">Debian policy</a> for a <a href="%sch-binary.html#s-virtual_pkg">definition of virtual packages</a>.',
                policy_url, policy_url) %]</p>
 [% END %]
     <div id="ptags"><p>
     <a href="[% tags_url %]edit.html?pkg=[% pkg | uri %]">[% g('Tags') %]</a>:
   [%- END %]
-  [% facet = tag.0; lfacet = "$facet-$lang"; 
+  [% facet = tag.0; lfacet = "$facet-$po_lang"; 
      facet_name = debtags_voc.$lfacet;
      SET facet_name = debtags_voc.$facet UNLESS facet_name;
-     tag_id = "$tag.0::$tag.1"; ltag = "$tag_id-$lang";
+     tag_id = "$tag.0::$tag.1"; ltag = "$tag_id-$po_lang";
      tag_name = debtags_voc.$ltag;
      SET tag_name = debtags_voc.$tag_id UNLESS tag_name;
    %]
 [% FOREACH p IN providers %]
   [% IF loop.first %]<div id="pdeps"><h2>[% g('Packages providing %s', pkg) %]</h2><dl>[% END %]
     <dt>[% IF p.available %]<a href="[% make_url(p.name,'','source','') %]">[% p.name %]</a>[% ELSE; p.name; END %]</dt>
-    <dd>[% IF p.trans_desc.$lang; p.trans_desc.$lang | html; ELSE; p.desc | html; END %]</dd>
+    [% PROCESS desc_i18n_dd trans_desc=p.trans_desc desc=p.desc %]
   [% '</dl></div>' IF loop.last %]
 [% END %]
 </div> <!-- pdesctab -->
 [% FOREACH b IN binaries %]
   [% IF loop.first %]<div id="pbinaries">[% g('The following binary packages are built from this source package:') %]<dl>[% END %]
     <dt>[% IF b.available %]<a href="[% make_url(b.name,'','source','') %]">[% b.name %]</a>[% ELSE; b.name; END %]</dt>
-    <dd>[% IF b.trans_desc.$lang; b.trans_desc.$lang | html; ELSE; b.desc | html; END %]</dd>
+    [% PROCESS desc_i18n_dd trans_desc=b.trans_desc desc=b.desc %]
   [% '</dl></div>' IF loop.last %]
 [% END %]
 
        [% ' (' _ version _ ')' IF version %]
         [% ' [' _ arch_str _ ']' IF arch_str %]</dt>
       [%- IF !is_old_pkgs -%]
-        <dd>[% IF trans_desc.$lang; trans_desc.$lang | html; ELSE; desc | html; END -%]
+        [% PROCESS desc_i18n_dd no_end_tag=1 trans_desc=trans_desc desc=desc -%]
         [%- IF providers.pkgs.size > 0 -%]
          [% IF providers.also;
                '<br>' _ g('also a virtual package provided by');
index aa9c43d98542151b30d5ff04c3ee7086ba07963c..731b8aec329800f3ce3263e202773dbee95cbe2b 100644 (file)
@@ -8,3 +8,25 @@
   &nbsp;]
 [%- END -%]
 [% BLOCK marker %] [<strong class="pmarker">[% text %]</strong>] [%- END %]
+[%- BLOCK desc_i18n;
+   IF trans_desc.$ddtp_lang;
+      trans_desc.$ddtp_lang | html;
+   ELSIF trans_desc.$po_lang;
+      trans_desc.$po_lang | html;
+   ELSE;
+      desc | html;
+   END;
+END -%]
+[%- BLOCK desc_i18n_dd;
+   IF trans_desc.$ddtp_lang;
+      '<dd lang="' _ ddtp_lang _ '">';
+      trans_desc.$ddtp_lang | html;
+   ELSIF trans_desc.$po_lang;
+      '<dd>';
+      trans_desc.$po_lang | html;
+   ELSE;
+      '<dd lang="en">';
+      desc | html;
+   END;
+   '</dd>' UNLESS no_end_tag;
+END -%]
index c95ee53f2b29c13809c25bbb5aac5a90d9d6d3de..378cca3f39b7e3d2fcdf8da1c4e69e225df3dd3b 100644 (file)
@@ -24,7 +24,7 @@
        suite, organisation);
     END; -%]
 </description>
-<dc:language>[% lang %]</dc:language>
+<dc:language>[% po_lang %]</dc:language>
 <dc:rights>[% g('Copyright ©') %] [% timestamp.year %], [% copyright.name %]</dc:rights>
 <dc:date>[% rss_timestamp %]</dc:date>
 <dc:publisher>[% contact.mail %]</dc:publisher>