3 # Copyright (C) 2010 Tamil s.a.r.l.
5 # This file is part of Koha.
7 # Koha is free software; you can redistribute it and/or modify it under the
8 # terms of the GNU General Public License as published by the Free Software
9 # Foundation; either version 2 of the License, or (at your option) any later
12 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14 # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License along
17 # with Koha; if not, write to the Free Software Foundation, Inc.,
18 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 # WARNING: Any other tested YAML library fails to work properly in this
26 use YAML::Syck qw( Dump LoadFile );
28 use FindBin qw( $Bin );
30 $YAML::Syck::ImplicitTyping = 1;
33 my ($self, $lang) = @_;
35 $self->{lang} = $lang;
36 $self->{po_path_lang} = $self->{context}->config('intrahtdocs') .
37 "/prog/$lang/modules/admin/preferences";
42 my ($class, $lang, $pref_only) = @_;
46 my $context = C4::Context->new();
47 $self->{context} = $context;
48 $self->{path_pref_en} = $context->config('intrahtdocs') .
49 '/prog/en/modules/admin/preferences';
50 set_lang( $self, $lang ) if $lang;
51 $self->{pref_only} = $pref_only;
52 $self->{translator_path} = $Bin;
53 $self->{path_po} = $self->{translator_path} . "/po";
56 # Get all .pref file names
57 opendir my $fh, $self->{path_pref_en};
58 my @pref_files = grep { /.pref/ } readdir($fh);
60 $self->{pref_files} = \@pref_files;
62 # Get all available language codes
63 opendir $fh, $self->{path_po};
64 my @langs = map { ($_) =~ /(.*)-i-opac/ }
65 grep { $_ =~ /.*-opac-/ } readdir($fh);
67 $self->{langs} = \@langs;
69 # Map for both interfaces opac/intranet
70 $self->{interface} = {
72 dir => $context->config('opachtdocs') . '/prog',
73 suffix => '-i-opac-t-prog-v-3002000.po',
76 dir => $context->config('intrahtdocs') . '/prog',
77 suffix => '-i-staff-t-prog-v-3002000.po',
88 my $context = C4::Context->new;
89 my $trans_path = $Bin . '/po';
90 my $trans_file = "$trans_path/" . $self->{lang} . "-pref.po";
96 my ($self, $id, $comment) = @_;
100 $p->comment( $p->comment . "\n" . $comment );
103 $po->{$id} = Locale::PO->new(
104 -comment => $comment,
113 my ($self, $comment, $prefs) = @_;
115 for my $pref ( @$prefs ) {
117 for my $element ( @$pref ) {
118 if ( ref( $element) eq 'HASH' ) {
119 $pref_name = $element->{pref};
123 for my $element ( @$pref ) {
124 if ( ref( $element) eq 'HASH' ) {
125 while ( my ($key, $value) = each(%$element) ) {
126 next unless $key eq 'choices';
127 next unless ref($value) eq 'HASH';
128 for my $ckey ( keys %$value ) {
129 my $id = $self->{file} . "#$pref_name# " . $value->{$ckey};
130 $self->po_append( $id, $comment );
134 elsif ( $element && $pref_name ) {
135 $self->po_append( $self->{file} . "#$pref_name# $element", $comment );
143 my ($self, $id) = @_;
145 my $po = $self->{po}->{$id};
147 return Locale::PO->dequote($po->msgstr);
151 sub update_tab_prefs {
152 my ($self, $pref, $prefs) = @_;
154 for my $p ( @$prefs ) {
157 for my $element ( @$p ) {
158 if ( ref( $element) eq 'HASH' ) {
159 $pref_name = $element->{pref};
163 for my $i ( 0..@$p-1 ) {
164 my $element = $p->[$i];
165 if ( ref( $element) eq 'HASH' ) {
166 while ( my ($key, $value) = each(%$element) ) {
167 next unless $key eq 'choices';
168 next unless ref($value) eq 'HASH';
169 for my $ckey ( keys %$value ) {
170 my $id = $self->{file} . "#$pref_name# " . $value->{$ckey};
171 my $text = $self->get_trans_text( $id );
172 $value->{$ckey} = $text if $text;
176 elsif ( $element && $pref_name ) {
177 my $id = $self->{file} . "#$pref_name# $element";
178 my $text = $self->get_trans_text( $id );
179 $p->[$i] = $text if $text;
186 sub get_po_from_prefs {
189 for my $file ( @{$self->{pref_files}} ) {
190 my $pref = LoadFile( $self->{path_pref_en} . "/$file" );
191 $self->{file} = $file;
192 # Entries for tab titles
193 $self->po_append( $self->{file}, $_ ) for keys %$pref;
194 while ( my ($tab, $tab_content) = each %$pref ) {
195 if ( ref($tab_content) eq 'ARRAY' ) {
196 $self->add_prefs( $tab, $tab_content );
199 while ( my ($section, $sysprefs) = each %$tab_content ) {
200 my $comment = "$tab > $section";
201 $self->po_append( $self->{file} . " " . $section, $comment );
202 $self->add_prefs( $comment, $sysprefs );
211 # Write .po entries into a file put in Koha standard po directory
212 Locale::PO->save_file_fromhash( $self->po_filename, $self->{po} );
213 print "Saved in file: ", $self->po_filename, "\n";
217 sub get_po_merged_with_en {
220 # Get po from current 'en' .pref files
221 $self->get_po_from_prefs();
222 my $po_current = $self->{po};
224 # Get po from previous generation
225 my $po_previous = Locale::PO->load_file_ashash( $self->po_filename );
227 for my $id ( keys %$po_current ) {
228 my $po = $po_previous->{Locale::PO->quote($id)};
230 my $text = Locale::PO->dequote( $po->msgstr );
231 $po_current->{$id}->msgstr( $text );
238 print "Update '", $self->{lang},
239 "' preferences .po file from 'en' .pref files\n";
240 $self->get_po_merged_with_en();
248 unless ( -r $self->{po_path_lang} ) {
249 print "Koha directories hierarchy for ", $self->{lang}, " must be created first\n";
253 # Get the language .po file merged with last modified 'en' preferences
254 $self->get_po_merged_with_en();
256 for my $file ( @{$self->{pref_files}} ) {
257 my $pref = LoadFile( $self->{path_pref_en} . "/$file" );
258 $self->{file} = $file;
259 # First, keys are replaced (tab titles)
262 $self->get_trans_text( $self->{file} ) || $_ => $pref->{$_}
266 while ( my ($tab, $tab_content) = each %$pref ) {
267 if ( ref($tab_content) eq 'ARRAY' ) {
268 $self->update_tab_prefs( $pref, $tab_content );
271 while ( my ($section, $sysprefs) = each %$tab_content ) {
272 $self->update_tab_prefs( $pref, $sysprefs );
275 for my $section ( keys %$tab_content ) {
276 my $id = $self->{file} . " $section";
277 my $text = $self->get_trans_text($id);
278 my $nsection = $text ? $text : $section;
279 $ntab->{$nsection} = $tab_content->{$section};
281 $pref->{$tab} = $ntab;
283 my $file_trans = $self->{po_path_lang} . "/$file";
284 print "Write $file\n";
285 open my $fh, ">", $file_trans;
286 print $fh Dump($pref);
295 "Install templates\n";
296 while ( my ($interface, $tmpl) = each %{$self->{interface}} ) {
298 " Install templates '$interface\n",
299 " From: $tmpl->{dir}/en/\n",
300 " To : $tmpl->{dir}/$self->{lang}\n",
301 " With: $self->{path_po}/$self->{lang}$tmpl->{suffix}\n";
302 my $lang_dir = "$tmpl->{dir}/$self->{lang}";
303 mkdir $lang_dir unless -d $lang_dir;
305 "$self->{translator_path}/tmpl_process3.pl install " .
306 "-i $tmpl->{dir}/en/ " .
307 "-o $tmpl->{dir}/$self->{lang} ".
308 "-s $self->{path_po}/$self->{lang}$tmpl->{suffix} -r"
317 "Update templates\n";
318 while ( my ($interface, $tmpl) = each %{$self->{interface}} ) {
320 " Update templates '$interface'\n",
321 " From: $tmpl->{dir}/en/\n",
322 " To : $self->{path_po}/$self->{lang}$tmpl->{suffix}\n";
323 my $lang_dir = "$tmpl->{dir}/$self->{lang}";
324 mkdir $lang_dir unless -d $lang_dir;
326 "$self->{translator_path}/tmpl_process3.pl update " .
327 "-i $tmpl->{dir}/en/ " .
328 "-s $self->{path_po}/$self->{lang}$tmpl->{suffix} -r"
336 $self->get_po_from_prefs();
345 "Create templates\n";
346 while ( my ($interface, $tmpl) = each %{$self->{interface}} ) {
348 " Create templates .po files for '$interface'\n",
349 " From: $tmpl->{dir}/en/\n",
350 " To : $self->{path_po}/$self->{lang}$tmpl->{suffix}\n";
352 "$self->{translator_path}/tmpl_process3.pl create " .
353 "-i $tmpl->{dir}/en/ " .
354 "-s $self->{path_po}/$self->{lang}$tmpl->{suffix} -r"
361 return unless $self->{lang};
362 $self->install_tmpl() unless $self->{pref_only};
363 $self->install_prefs();
369 opendir( my $dh, $self->{path_po} );
370 my @files = grep { $_ =~ /-i-opac-t-prog-v-3002000.po$/ }
372 @files = map { $_ =~ s/-i-opac-t-prog-v-3002000.po$//; $_ } @files;
378 my @langs = $self->{lang} ? ($self->{lang}) : $self->get_all_langs();
379 for my $lang ( @langs ) {
380 $self->set_lang( $lang );
381 $self->update_tmpl() unless $self->{pref_only};
382 $self->update_prefs();
389 return unless $self->{lang};
390 $self->create_tmpl() unless $self->{pref_only};
391 $self->create_prefs();
401 LangInstaller.pm - Handle templates and preferences translation
405 my $installer = LangInstaller->new( 'fr-FR' );
406 $installer->create();
407 $installer->update();
408 $installer->install();
409 for my $lang ( @{$installer->{langs} ) {
410 $installer->set_lang( $lan );
411 $installer->install();
418 Create a new instance of the installer object.
422 For the current language, create .po files for templates and preferences based
423 of the english ('en') version.
427 For the current language, update .po files.
431 For the current langage C<$self->{lang}, use .po files to translate the english
432 version of templates and preferences files and copy those files in the
433 appropriate directory.
437 =item translate create F<lang>
439 Create 3 .po files in F<po> subdirectory: (1) from opac pages templates, (2)
440 intranet templates, and (3) from preferences.
444 =item F<lang>-opac.po
446 Contains extracted text from english (en) OPAC templates found in
447 <KOHA_ROOT>/koha-tmpl/opac-tmpl/prog/en/ directory.
449 =item F<lang>-intranet.po
451 Contains extracted text from english (en) intranet templates found in
452 <KOHA_ROOT>/koha-tmpl/intranet-tmpl/prog/en/ directory.
454 =item F<lang>-pref.po
456 Contains extracted text from english (en) preferences. They are found in files
457 located in <KOHA_ROOT>/koha-tmpl/intranet-tmpl/prog/en/admin/preferences
462 =item pref-trans update F<lang>
464 Update .po files in F<po> directory, named F<lang>-*.po.
466 =item pref-trans install F<lang>