From dd6a94b186e73a630657c07061ebe8c72422052a Mon Sep 17 00:00:00 2001 From: intrigeri Date: Sat, 4 Oct 2008 16:10:39 +0200 Subject: fix --- doc/ikiwiki/subpage/linkingrules.mdwn | 33 --------------------------------- 1 file changed, 33 deletions(-) delete mode 100644 doc/ikiwiki/subpage/linkingrules.mdwn diff --git a/doc/ikiwiki/subpage/linkingrules.mdwn b/doc/ikiwiki/subpage/linkingrules.mdwn deleted file mode 100644 index e547f3090..000000000 --- a/doc/ikiwiki/subpage/linkingrules.mdwn +++ /dev/null @@ -1,33 +0,0 @@ -[[!meta robots="noindex, follow"]] -To link to or from a [[SubPage]], you can normally use a regular -[[WikiLink]] that does not contain the name of the parent directory of -the [[SubPage]]. Ikiwiki descends the directory hierarchy looking for a -page that matches your link. - -For example, if FooBar/SubPage links to "OtherPage", ikiwiki will first -prefer pointing the link to FooBar/SubPage/OtherPage if it exists, next -to FooBar/OtherPage and finally to OtherPage in the root of the wiki. - -Note that this means that if a link on FooBar/SomePage to "OtherPage" -currently links to OtherPage, in the root of the wiki, and FooBar/OtherPage -is created, the link will _change_ to point to FooBar/OtherPage. On the -other hand, a link from BazBar to "OtherPage" would be unchanged by this -creation of a [[SubPage]] of FooBar. - -You can also specify a link that contains a directory name, like -"FooBar/OtherPage" to more exactly specify what page to link to. This is -the only way to link to an unrelated [[SubPage]]. - -You can use this to, for example, to link from BazBar to "FooBar/SubPage", -or from BazBar/SubPage to "FooBar/SubPage". - -You can also use "/" at the start of a link, to specify exactly which page -to link to, when there are multiple pages with similar names and the link -goes to the wrong page by default. For example, linking from -"FooBar/SubPage" to "/OtherPage" will link to the "OtherPage" in the root -of the wiki, even if there is a "FooBar/OtherPage". - -Also, if the wiki is configured with a userdir, you can link to pages -within the userdir without specifying a path to them. This is to allow for -easy linking to a user's page in the userdir, to sign a comment. These -links are checked for last of all. -- cgit v1.2.3 From 219cb94841518ba938d5761c5d613a7aadb9c47c Mon Sep 17 00:00:00 2001 From: intrigeri Date: Sat, 4 Oct 2008 16:11:08 +0200 Subject: Revert "fix" This reverts commit 40757bfa154d816f0843af468c9085d5b041c95b. --- doc/ikiwiki/subpage/linkingrules.mdwn | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 doc/ikiwiki/subpage/linkingrules.mdwn diff --git a/doc/ikiwiki/subpage/linkingrules.mdwn b/doc/ikiwiki/subpage/linkingrules.mdwn new file mode 100644 index 000000000..e547f3090 --- /dev/null +++ b/doc/ikiwiki/subpage/linkingrules.mdwn @@ -0,0 +1,33 @@ +[[!meta robots="noindex, follow"]] +To link to or from a [[SubPage]], you can normally use a regular +[[WikiLink]] that does not contain the name of the parent directory of +the [[SubPage]]. Ikiwiki descends the directory hierarchy looking for a +page that matches your link. + +For example, if FooBar/SubPage links to "OtherPage", ikiwiki will first +prefer pointing the link to FooBar/SubPage/OtherPage if it exists, next +to FooBar/OtherPage and finally to OtherPage in the root of the wiki. + +Note that this means that if a link on FooBar/SomePage to "OtherPage" +currently links to OtherPage, in the root of the wiki, and FooBar/OtherPage +is created, the link will _change_ to point to FooBar/OtherPage. On the +other hand, a link from BazBar to "OtherPage" would be unchanged by this +creation of a [[SubPage]] of FooBar. + +You can also specify a link that contains a directory name, like +"FooBar/OtherPage" to more exactly specify what page to link to. This is +the only way to link to an unrelated [[SubPage]]. + +You can use this to, for example, to link from BazBar to "FooBar/SubPage", +or from BazBar/SubPage to "FooBar/SubPage". + +You can also use "/" at the start of a link, to specify exactly which page +to link to, when there are multiple pages with similar names and the link +goes to the wrong page by default. For example, linking from +"FooBar/SubPage" to "/OtherPage" will link to the "OtherPage" in the root +of the wiki, even if there is a "FooBar/OtherPage". + +Also, if the wiki is configured with a userdir, you can link to pages +within the userdir without specifying a path to them. This is to allow for +easy linking to a user's page in the userdir, to sign a comment. These +links are checked for last of all. -- cgit v1.2.3 From fc299df955879bf958aa78338ba64d56a7df17a9 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Sun, 5 Oct 2008 04:05:24 +0200 Subject: added the targetpage hook Signed-off-by: intrigeri --- IkiWiki.pm | 15 +++++++++++++-- IkiWiki/Plugin/skeleton.pm.example | 5 +++++ doc/plugins/write.mdwn | 9 +++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/IkiWiki.pm b/IkiWiki.pm index edee8aacb..28ee882cf 100644 --- a/IkiWiki.pm +++ b/IkiWiki.pm @@ -647,8 +647,19 @@ sub newpagefile ($$) { #{{{ sub targetpage ($$) { #{{{ my $page=shift; my $ext=shift; - - if (! $config{usedirs} || $page eq 'index') { + + my $targetpage=''; + run_hooks(targetpage => sub { + $targetpage=shift->( + page => $page, + ext => $ext, + ); + }); + + if (defined $targetpage && (length($targetpage) > 0)) { + return $targetpage; + } + elsif (! $config{usedirs} || $page eq 'index') { return $page.".".$ext; } else { diff --git a/IkiWiki/Plugin/skeleton.pm.example b/IkiWiki/Plugin/skeleton.pm.example index f844ddb91..af22b3406 100644 --- a/IkiWiki/Plugin/skeleton.pm.example +++ b/IkiWiki/Plugin/skeleton.pm.example @@ -34,6 +34,7 @@ sub import { #{{{ hook(type => "formbuilder_setup", id => "skeleton", call => \&formbuilder_setup); hook(type => "formbuilder", id => "skeleton", call => \&formbuilder); hook(type => "savestate", id => "skeleton", call => \&savestate); + hook(type => "targetpage", id => "skeleton", call => \&targetpage); } # }}} sub getopt () { #{{{ @@ -204,4 +205,8 @@ sub savestate () { #{{{ debug("skeleton plugin running in savestate"); } #}}} +sub targetpage () { #{{{ + debug("skeleton plugin running in targetpage"); +} #}}} + 1 diff --git a/doc/plugins/write.mdwn b/doc/plugins/write.mdwn index daf70c8e2..6d2622272 100644 --- a/doc/plugins/write.mdwn +++ b/doc/plugins/write.mdwn @@ -428,6 +428,15 @@ describes the plugin as a whole. For example: and undef if a rebuild could be needed in some circumstances, but is not strictly required. +### targetpage + + hook(type => "targetpage", id => "foo", call => \&targetpage); + +This hook can be used to override the name of the file a page should +be compiled into. + +It should return the target filename. + ## Plugin interface To import the ikiwiki plugin interface: -- cgit v1.2.3 From 50f1fd43daf98cbd296dbb51bd6519ab7e97ee9a Mon Sep 17 00:00:00 2001 From: intrigeri Date: Sun, 5 Oct 2008 04:11:02 +0200 Subject: po plugin: initial work - .po is a new supported wiki page type - PO files are rendered verbatim into HTML - override targetpage to ease Content Negotiation Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 IkiWiki/Plugin/po.pm diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm new file mode 100644 index 000000000..58e184b9b --- /dev/null +++ b/IkiWiki/Plugin/po.pm @@ -0,0 +1,71 @@ +#!/usr/bin/perl +# .po as a wiki page type +package IkiWiki::Plugin::po; + +use warnings; +use strict; +use IkiWiki 2.00; +use Encode; + +sub import { + hook(type => "getsetup", id => "po", call => \&getsetup); + hook(type => "targetpage", id => "po", call => \&targetpage); + hook(type => "filter", id => "po", call => \&filter); + hook(type => "htmlize", id => "po", call => \&htmlize); +} + +sub getsetup () { #{{{ + return + plugin => { + safe => 0, + rebuild => 1, # format plugin + }, + po_supported_languages => { + type => "string", + example => { 'fr' => { 'name' => 'Français' }, + 'es' => { 'name' => 'Castellano' }, + 'de' => { 'name' => 'Deutsch' }, + }, + safe => 1, + rebuild => 1, + }, +} #}}} + +sub targetpage (@) { #{{{ + my %params = @_; + my $page=$params{page}; + my $ext=$params{ext}; + + my ($origpage, $lang) = ($page =~ /(.*)[.]([a-z]{2}$)/); + + if (defined $origpage && defined $lang + && (length($origpage) > 0) && (length($lang) > 0) + && defined $config{po_supported_languages}{$lang}) { + if (! $config{usedirs} || $page eq 'index') { + return $origpage.".".$ext.".".$lang; + } + else { + return $origpage."/index.".$ext.".".$lang; + } + } +} #}}} + +# We use filter to convert PO to HTML, since the other plugins might do harm to it. +sub filter (@) { #{{{ + my %params = @_; + my $content = decode_utf8(encode_utf8($params{content})); + + if (defined $pagesources{$params{page}} && $pagesources{$params{page}} =~ /\.po$/) { + $content = "
" . $content . "
"; + } + + return $content; +} #}}} + +# We need this to register the .po file extension +sub htmlize (@) { #{{{ + my %params=@_; + return $params{content}; +} #}}} + +1 -- cgit v1.2.3 From 75fc44ce2fa43c984a1920f40d97631ace84d4f6 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Sun, 5 Oct 2008 17:14:30 +0200 Subject: po plugin: factorize most checks into a new match_istranslation PageSpec Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 55 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 44 insertions(+), 11 deletions(-) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 58e184b9b..fb4741cd4 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -36,17 +36,16 @@ sub targetpage (@) { #{{{ my $page=$params{page}; my $ext=$params{ext}; - my ($origpage, $lang) = ($page =~ /(.*)[.]([a-z]{2}$)/); - - if (defined $origpage && defined $lang - && (length($origpage) > 0) && (length($lang) > 0) - && defined $config{po_supported_languages}{$lang}) { - if (! $config{usedirs} || $page eq 'index') { - return $origpage.".".$ext.".".$lang; - } - else { - return $origpage."/index.".$ext.".".$lang; - } + if (! IkiWiki::PageSpec::match_istranslation($page, $page)) { + return; + } + + my ($masterpage, $lang) = ($page =~ /(.*)[.]([a-z]{2})$/); + if (! $config{usedirs} || $page eq 'index') { + return $masterpage.".".$ext.".".$lang; + } + else { + return $masterpage."/index.".$ext.".".$lang; } } #}}} @@ -68,4 +67,38 @@ sub htmlize (@) { #{{{ return $params{content}; } #}}} +package IkiWiki::PageSpec; + +sub match_istranslation ($;@) { #{{{ + my $page=shift; + my $wanted=shift; + + my %params=@_; + my $file=exists $params{file} ? $params{file} : $IkiWiki::pagesources{$page}; + if (! defined $file) { + return IkiWiki::FailReason->new("no file specified"); + } + + if (! IkiWiki::pagetype($page) eq 'po') { + return IkiWiki::FailReason->new("is not a PO file"); + } + + my ($masterpage, $lang) = ($page =~ /(.*)[.]([a-z]{2})$/); + if (! defined $masterpage || ! defined $lang + || ! (length($masterpage) > 0) || ! (length($lang) > 0)) { + return IkiWiki::FailReason->new("is not named like a translation file"); + } + + if (! defined $IkiWiki::pagesources{$masterpage}) { + return IkiWiki::FailReason->new("the master page does not exist"); + } + + if (! defined $IkiWiki::config{po_supported_languages}{$lang}) { + return IkiWiki::FailReason->new("language $lang is not supported"); + } + + return IkiWiki::SuccessReason->new("page $page is a translation"); + +} #}}} + 1 -- cgit v1.2.3 From 1b5f610a974bedd98b4feeaf566f6ad2eeb6acab Mon Sep 17 00:00:00 2001 From: intrigeri Date: Sun, 5 Oct 2008 19:42:43 +0200 Subject: po plugin: convert PO to master page's type in filter hook Master page's type htmlize hook should also be run in po's htmlize hook, but let's proceed step by step. Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 40 +++++++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index fb4741cd4..62632e1df 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -1,11 +1,15 @@ #!/usr/bin/perl # .po as a wiki page type +# inspired by the GPL'd po4a-translate, +# which is Copyright 2002, 2003, 2004 by Martin Quinson (mquinson#debian.org) package IkiWiki::Plugin::po; use warnings; use strict; use IkiWiki 2.00; use Encode; +use Locale::Po4a::Chooser; +use File::Temp; sub import { hook(type => "getsetup", id => "po", call => \&getsetup); @@ -49,22 +53,48 @@ sub targetpage (@) { #{{{ } } #}}} -# We use filter to convert PO to HTML, since the other plugins might do harm to it. +# We use filter to convert PO to the master page's type, +# since other plugins should not work on PO files sub filter (@) { #{{{ my %params = @_; + my $page = $params{page}; my $content = decode_utf8(encode_utf8($params{content})); - if (defined $pagesources{$params{page}} && $pagesources{$params{page}} =~ /\.po$/) { - $content = "
" . $content . "
"; + # decide if this is a PO file that should be converted into a translated document, + # and perform various sanity checks + if (! IkiWiki::PageSpec::match_istranslation($page, $page)) { + return $content; } + my ($masterpage, $lang) = ($page =~ /(.*)[.]([a-z]{2})$/); + my $file=srcfile(exists $params{file} ? $params{file} : $IkiWiki::pagesources{$page}); + my $masterfile = srcfile($pagesources{$masterpage}); + my (@pos,@masters); + push @pos,$file; + push @masters,$masterfile; + my %options = ( + "markdown" => (pagetype($masterfile) eq 'mdwn') ? 1 : 0, + ); + my $doc=Locale::Po4a::Chooser::new('text',%options); + $doc->process( + 'po_in_name' => \@pos, + 'file_in_name' => \@masters, + 'file_in_charset' => 'utf-8', + 'file_out_charset' => 'utf-8', + ) or error("[po/filter:$file]: failed to translate"); + my ($percent,$hit,$queries) = $doc->stats(); + my $tmpfh = File::Temp->new(TEMPLATE => "/tmp/ikiwiki-po-filter-out.XXXXXXXXXX"); + my $tmpout = $tmpfh->filename; + $doc->write($tmpout) or error("[po/filter:$file] could not write $tmpout"); + $content = readfile($tmpout) or error("[po/filter:$file] could not read $tmpout"); return $content; } #}}} -# We need this to register the .po file extension sub htmlize (@) { #{{{ my %params=@_; - return $params{content}; + my $content = $params{content}; + # FIXME: run master page's type htmlize hook + return $content; } #}}} package IkiWiki::PageSpec; -- cgit v1.2.3 From 575d4021e3a2da519f20d83be4916cb172ec5e2f Mon Sep 17 00:00:00 2001 From: intrigeri Date: Sun, 5 Oct 2008 19:56:53 +0200 Subject: po plugin: htmlize translated content as if it was the same type as the master page Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 62632e1df..dbeb0b481 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -92,9 +92,13 @@ sub filter (@) { #{{{ sub htmlize (@) { #{{{ my %params=@_; + my $page = $params{page}; my $content = $params{content}; - # FIXME: run master page's type htmlize hook - return $content; + my ($masterpage, $lang) = ($page =~ /(.*)[.]([a-z]{2})$/); + my $masterfile = srcfile($pagesources{$masterpage}); + + # force content to be htmlize'd as if it was the same type as the master page + return IkiWiki::htmlize($page, $page, pagetype($masterfile), $content); } #}}} package IkiWiki::PageSpec; -- cgit v1.2.3 From b90f8397f6f0c9c9e9de85ef04c32dba998c31a6 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Sun, 5 Oct 2008 21:34:43 +0200 Subject: po plugin: reworked available options - renamed po_supported_languages to po_slave_languages - added po_master_language option, which will soon be useful Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index dbeb0b481..351b9c155 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -24,12 +24,23 @@ sub getsetup () { #{{{ safe => 0, rebuild => 1, # format plugin }, - po_supported_languages => { + po_master_language => { type => "string", - example => { 'fr' => { 'name' => 'Français' }, + example => { + 'code' => 'en', + 'name' => 'English' + }, + description => "master language (non-PO files)", + safe => 1, + rebuild => 1, + }, + po_slave_languages => { + type => "string", + example => {'fr' => { 'name' => 'Français' }, 'es' => { 'name' => 'Castellano' }, 'de' => { 'name' => 'Deutsch' }, }, + description => "slave languages (PO files)", safe => 1, rebuild => 1, }, @@ -127,7 +138,7 @@ sub match_istranslation ($;@) { #{{{ return IkiWiki::FailReason->new("the master page does not exist"); } - if (! defined $IkiWiki::config{po_supported_languages}{$lang}) { + if (! defined $IkiWiki::config{po_slave_languages}{$lang}) { return IkiWiki::FailReason->new("language $lang is not supported"); } -- cgit v1.2.3 From fae57e807a6367708b8137109d79d75c5b2c75e6 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Mon, 6 Oct 2008 03:42:26 +0200 Subject: po plugin: initial documentation, along with huge TODO list Signed-off-by: intrigeri --- doc/plugins/po.mdwn | 168 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 doc/plugins/po.mdwn diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn new file mode 100644 index 000000000..6690e5dea --- /dev/null +++ b/doc/plugins/po.mdwn @@ -0,0 +1,168 @@ +[[!template id=plugin name=po core=0 author="[[intrigeri]]"]] +[[!tag type/format]] + +This plugin adds support for multi-lingual wikis, translated with +gettext, using [po4a|http://po4a.alioth.debian.org/]. + +It depends on the Perl `Locale::Po4a::Po` library (`apt-get install po4a`). + +Introduction +============ + +A language is decided to be the "master" one, and any other supported +language is a "slave" one. A page written in the "master" language is +a "master" page, and is written in any supported format but PO. + +Example: `bla/page.mdwn` is a "master" Markdown page written in +English; if `usedirs` is enabled, it is rendered as +`bla/page/index.html`, else as `bla/page.html`. + +Translations of a "master" page into a "slave" language are called +"slave" pages, and is a in gettext PO format. PO is thus promoted to +the wiki page type status. + +Example: `bla/page.fr.po` is the PO "message catalog" used to +translate `bla/page.mdwn` into French; if `usedirs` is enabled, it is +rendered as `bla/page/index.html.fr`, else as `bla/page.html.fr` + + +Configuration +============= + +`po_master_language` is used to set the master language in +`ikiwiki.setup`, such as: + + po_master_language => { 'code' => 'en', 'name' => 'English' } + +`po_slave_languages` is used to set the list of supported "slave" +languages, such as: + + po_slave_languages => { 'fr' => { 'name' => 'Français', }, + 'es' => { 'name' => 'Castellano', }, + 'de' => { 'name' => 'Deutsch', }, + }, + + +Server support +============== + +Apache +------ + +Using `mod_negotiation` makes it really easy to have Apache serve the +page in the client's preferred language, if available. This is the +default Debian Apache configuration. + +When `usedirs` is enabled, one has to set `DirectoryIndex index` for +the wiki context. + +Setting `DefaultLanguage LL` for the wiki context can be needed, to +ensure `bla/page/index.html` is served as `Content-Language: LL` +(replace `LL` with your default MIME language). + +lighttpd +-------- + +lighttpd unfortunately does not support content negotiation. + + +TODO +==== + +Display available translations +------------------------------ + +The [[linguas|plugins/contrib/linguas]] plugin has some code that can +be used as a basis to display the existing translations, and allow to +navigate between them. + +View translation status +----------------------- + +One should be able to view some freshness information about the +translation status, either for a given page or for the whole wiki. + +This should not be too hard using gettext tools. If this is +implemented as a +[[HTML::Template|http://search.cpan.org/search?mode=dist&query=HTML%3A%3ATemplate]] +loop, a page using it should depend on any "master" and "slave" pages +whose status is being displayed. + +Decide which pages are translatable +----------------------------------- + +The subset of ("master") pages supporting translation must be +configurable: + +- a `[[!translatable ]]` directive, when put on a page, makes it + translatable +- this [[ikiwiki/directive]] can be used with an optional `match=PageSpec` + argument, to render translatable a bunch of pages at once + +Automatic PO files update +------------------------- + +Committing changes to a "master" page must: + +1. update the POT file, the PO files for the supported languages, and + put them under version control +2. trigger a refresh of the corresponding HTML slave pages + +The former can be implemented as a `needsbuild` hook, which is the +first type of hook to run after the list of files that need to be +built is known: that is, at a time when we know which "master" page +was modified, and thus, which POT/PO files have to be updated. + +The latter can be implemented by making any "slave" page depend on the +corresponding "master" page. The `add_depends` function can achieved +this, if used in a FIXME hook. + +UI consistency: rename "Edit" button on slave pages +--------------------------------------------------- + +It may be surprising to some, after having pressed *Edit* on a wiki +page, to end up editing a strange PO file. The *Edit* button must then +be be renamed to *Improve translation* on "slave" pages. + +Translation quality assurance +----------------------------- + +Modifying a PO file via the CGI must only be allowed if the new +version is a valid PO file. As a bonus, check that it provides a more +complete translation than the existing one. + +A new `cansave` type of hook would be needed to implement this. + +Note: committing to the underlying repository is a way to bypass +this check. + +Translating online +------------------ + +As PO is a wiki page type, we already have an online PO editor, that +is ikiwiki's CGI. + +A message-by-message interface could be implemented later, providing +a nice way to translate offline (without VCS access) is provided. + +Translating offline without VCS access +-------------------------------------- + +The following workflow should be made possible for translators without +VCS access who need to edit the PO files in another editor than a web +browser: + +- download the PO file for the page +- use any PO editor to update the translation +- upload the updated PO file + +A generic mechanism to download and upload a page's source is needed. +It's only an alternative way to do Edit/edit/Save. + +### Short-term workflow + +- pretend to edit the PO file online +- copy the PO file content from the textarea +- cancel the edit +- paste the content into a local file. + -- cgit v1.2.3 From 45d08022bbb97f1731951402997fa343f82c1494 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Tue, 7 Oct 2008 22:08:28 +0200 Subject: po plugin: name rendered master pages like slave ones (page.html.LL) Apache's content negotiation transparently redirects any old URL (page.html) to the new one, depending on the client preferred language (i.e. a German browser will be fed with page.html.de). Transition to this naming convention is then really smooth. This naming convention allows one to deliberately display the master page, even if her browser is configured for another language. Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 22 ++++++++++++++-------- doc/plugins/po.mdwn | 9 +++++---- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 351b9c155..941f5629d 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -51,16 +51,22 @@ sub targetpage (@) { #{{{ my $page=$params{page}; my $ext=$params{ext}; - if (! IkiWiki::PageSpec::match_istranslation($page, $page)) { - return; - } - - my ($masterpage, $lang) = ($page =~ /(.*)[.]([a-z]{2})$/); - if (! $config{usedirs} || $page eq 'index') { - return $masterpage.".".$ext.".".$lang; + if (IkiWiki::PageSpec::match_istranslation($page, $page)) { + my ($masterpage, $lang) = ($page =~ /(.*)[.]([a-z]{2})$/); + if (! $config{usedirs} || $page eq 'index') { + return $masterpage . "." . $ext . "." . $lang; + } + else { + return $masterpage . "/index." . $ext . "." . $lang; + } } else { - return $masterpage."/index.".$ext.".".$lang; + if (! $config{usedirs} || $page eq 'index') { + return $page . "." . $ext . "." . $config{po_master_language}{code}; + } + else { + return $page . "/index." . $ext . "." . $config{po_master_language}{code}; + } } } #}}} diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index 6690e5dea..326a6f39f 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -15,7 +15,7 @@ a "master" page, and is written in any supported format but PO. Example: `bla/page.mdwn` is a "master" Markdown page written in English; if `usedirs` is enabled, it is rendered as -`bla/page/index.html`, else as `bla/page.html`. +`bla/page/index.html.en`, else as `bla/page.html.en`. Translations of a "master" page into a "slave" language are called "slave" pages, and is a in gettext PO format. PO is thus promoted to @@ -56,9 +56,10 @@ default Debian Apache configuration. When `usedirs` is enabled, one has to set `DirectoryIndex index` for the wiki context. -Setting `DefaultLanguage LL` for the wiki context can be needed, to -ensure `bla/page/index.html` is served as `Content-Language: LL` -(replace `LL` with your default MIME language). +Setting `DefaultLanguage LL` (replace `LL` with your default MIME +language) for the wiki context can be needed, to ensure +`bla/page/index.html.en` is served as `Content-Language: LL`. +**FIXME**: is it still needed with the new `.html.en` naming convention? lighttpd -------- -- cgit v1.2.3 From 968106cc80c4f24ae02a3e54877939cd00e33258 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Tue, 7 Oct 2008 22:20:07 +0200 Subject: po plugin: enhance documentation Signed-off-by: intrigeri --- doc/plugins/po.mdwn | 82 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 54 insertions(+), 28 deletions(-) diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index 326a6f39f..fddfe5c41 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -2,14 +2,14 @@ [[!tag type/format]] This plugin adds support for multi-lingual wikis, translated with -gettext, using [po4a|http://po4a.alioth.debian.org/]. +gettext, using [po4a](http://po4a.alioth.debian.org/). It depends on the Perl `Locale::Po4a::Po` library (`apt-get install po4a`). Introduction ============ -A language is decided to be the "master" one, and any other supported +A language is chosen as the "master" one, and any other supported language is a "slave" one. A page written in the "master" language is a "master" page, and is written in any supported format but PO. @@ -17,9 +17,9 @@ Example: `bla/page.mdwn` is a "master" Markdown page written in English; if `usedirs` is enabled, it is rendered as `bla/page/index.html.en`, else as `bla/page.html.en`. -Translations of a "master" page into a "slave" language are called -"slave" pages, and is a in gettext PO format. PO is thus promoted to -the wiki page type status. +Any translation of a "master" page into a "slave" language is called +a "slave" page; it is written in the gettext PO format. PO is now +a page type supported by ikiwiki. Example: `bla/page.fr.po` is the PO "message catalog" used to translate `bla/page.mdwn` into French; if `usedirs` is enabled, it is @@ -39,8 +39,8 @@ languages, such as: po_slave_languages => { 'fr' => { 'name' => 'Français', }, 'es' => { 'name' => 'Castellano', }, - 'de' => { 'name' => 'Deutsch', }, - }, + 'de' => { 'name' => 'Deutsch', } + } Server support @@ -66,6 +66,9 @@ lighttpd lighttpd unfortunately does not support content negotiation. +**FIXME**: does `mod_magnet` provide the functionality needed to + emulate this? + TODO ==== @@ -80,8 +83,8 @@ navigate between them. View translation status ----------------------- -One should be able to view some freshness information about the -translation status, either for a given page or for the whole wiki. +One should be able to view some information about the translation +completeness, either for a given page or for the whole wiki. This should not be too hard using gettext tools. If this is implemented as a @@ -92,38 +95,54 @@ whose status is being displayed. Decide which pages are translatable ----------------------------------- -The subset of ("master") pages supporting translation must be +The subset of "master" pages subject to translation must be configurable: - a `[[!translatable ]]` directive, when put on a page, makes it translatable -- this [[ikiwiki/directive]] can be used with an optional `match=PageSpec` - argument, to render translatable a bunch of pages at once +- to set at once a bunch of pages as being translatable, use this + [[ikiwiki/directive]] with the `match=PageSpec` argument. Automatic PO files update ------------------------- Committing changes to a "master" page must: -1. update the POT file, the PO files for the supported languages, and - put them under version control +1. update the POT file and the PO files for the supported languages, + before putting them under version control 2. trigger a refresh of the corresponding HTML slave pages -The former can be implemented as a `needsbuild` hook, which is the -first type of hook to run after the list of files that need to be -built is known: that is, at a time when we know which "master" page -was modified, and thus, which POT/PO files have to be updated. +The former is to be done at a time when: + +- we know which "master" page was modified, and thus, which POT/PO + files have to be updated: the `needsbuild` hook is the first one to + run that provides us with the necessary information +- we can modify the list of pages needing a refresh; this is + `needsbuild` hook's job The latter can be implemented by making any "slave" page depend on the -corresponding "master" page. The `add_depends` function can achieved -this, if used in a FIXME hook. +corresponding "master" page. The `add_depends` function can achieve +this, if used in a **FIXME** hook. UI consistency: rename "Edit" button on slave pages --------------------------------------------------- It may be surprising to some, after having pressed *Edit* on a wiki -page, to end up editing a strange PO file. The *Edit* button must then -be be renamed to *Improve translation* on "slave" pages. +page, to end up editing a strange looking PO file. The *Edit* button +displayed on "slave" pages must therefore be renamed *Improve +translation* . + +Pages selection depending on language +------------------------------------- + +To improve user navigation in a multi-lingual wiki, site developers +must be enabled to write: + + \[[!map pages="dev/* and preferredlang()" feeds="no"]] + + \[[!map pages="dev/* and currentlang()" feeds="no"]] + +Some new [[ikiwiki/pagespec]] functions have to be written. Translation quality assurance ----------------------------- @@ -143,8 +162,9 @@ Translating online As PO is a wiki page type, we already have an online PO editor, that is ikiwiki's CGI. -A message-by-message interface could be implemented later, providing -a nice way to translate offline (without VCS access) is provided. +A message-by-message interface could also be implemented at some +point; a nice way to do offline translation work (without VCS access) +still has to be offered, though. Translating offline without VCS access -------------------------------------- @@ -153,17 +173,23 @@ The following workflow should be made possible for translators without VCS access who need to edit the PO files in another editor than a web browser: -- download the PO file for the page +- download the page's PO file - use any PO editor to update the translation - upload the updated PO file -A generic mechanism to download and upload a page's source is needed. -It's only an alternative way to do Edit/edit/Save. +Implementation note: a generic mechanism to upload a page's source is +needed: it's only an alternative way to allow saving a the modified +page's source with the CGI. ### Short-term workflow +A possible workaround is: + - pretend to edit the PO file online - copy the PO file content from the textarea - cancel the edit - paste the content into a local file. - +- edit the local file in any PO editor +- pretend to edit the PO file online +- paste the modified local file's content into the edit textarea +- save -- cgit v1.2.3 From bd50ba3e8392db13c584b4166783ee4794b20365 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Tue, 7 Oct 2008 22:39:17 +0200 Subject: po plugin: switch to page.LL.html naming convention Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 8 ++++---- doc/plugins/po.mdwn | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 941f5629d..b33d4dc1b 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -54,18 +54,18 @@ sub targetpage (@) { #{{{ if (IkiWiki::PageSpec::match_istranslation($page, $page)) { my ($masterpage, $lang) = ($page =~ /(.*)[.]([a-z]{2})$/); if (! $config{usedirs} || $page eq 'index') { - return $masterpage . "." . $ext . "." . $lang; + return $masterpage . "." . $lang . "." . $ext; } else { - return $masterpage . "/index." . $ext . "." . $lang; + return $masterpage . "/index." . $lang . "." . $ext; } } else { if (! $config{usedirs} || $page eq 'index') { - return $page . "." . $ext . "." . $config{po_master_language}{code}; + return $page . "." . $config{po_master_language}{code} . "." . $ext; } else { - return $page . "/index." . $ext . "." . $config{po_master_language}{code}; + return $page . "/index." . $config{po_master_language}{code} . "." . $ext; } } } #}}} diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index fddfe5c41..e7a93469c 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -15,7 +15,7 @@ a "master" page, and is written in any supported format but PO. Example: `bla/page.mdwn` is a "master" Markdown page written in English; if `usedirs` is enabled, it is rendered as -`bla/page/index.html.en`, else as `bla/page.html.en`. +`bla/page/index.en.html`, else as `bla/page.en.html`. Any translation of a "master" page into a "slave" language is called a "slave" page; it is written in the gettext PO format. PO is now @@ -23,7 +23,7 @@ a page type supported by ikiwiki. Example: `bla/page.fr.po` is the PO "message catalog" used to translate `bla/page.mdwn` into French; if `usedirs` is enabled, it is -rendered as `bla/page/index.html.fr`, else as `bla/page.html.fr` +rendered as `bla/page/index.fr.html`, else as `bla/page.fr.html` Configuration @@ -58,8 +58,8 @@ the wiki context. Setting `DefaultLanguage LL` (replace `LL` with your default MIME language) for the wiki context can be needed, to ensure -`bla/page/index.html.en` is served as `Content-Language: LL`. -**FIXME**: is it still needed with the new `.html.en` naming convention? +`bla/page/index.en.html` is served as `Content-Language: LL`. +**FIXME**: is it still needed with the new `.en.html` naming convention? lighttpd -------- -- cgit v1.2.3 From d9b9022c13af3aa6c469df05beaa293fcf33cafc Mon Sep 17 00:00:00 2001 From: intrigeri Date: Wed, 8 Oct 2008 00:50:10 +0200 Subject: added hook urlpath This hook can be used to modify the internal urls generated by ikiwiki. Signed-off-by: intrigeri --- IkiWiki.pm | 4 ++++ IkiWiki/Plugin/skeleton.pm.example | 5 +++++ doc/plugins/write.mdwn | 10 ++++++++++ 3 files changed, 19 insertions(+) diff --git a/IkiWiki.pm b/IkiWiki.pm index 28ee882cf..e75175a8d 100644 --- a/IkiWiki.pm +++ b/IkiWiki.pm @@ -927,6 +927,10 @@ sub beautify_urlpath ($) { #{{{ $url =~ s!/index.$config{htmlext}$!/!; } + run_hooks(urlpath => sub { + $url=shift->(url => $url); + }); + # Ensure url is not an empty link, and # if it's relative, make that explicit to avoid colon confusion. if ($url !~ /^\//) { diff --git a/IkiWiki/Plugin/skeleton.pm.example b/IkiWiki/Plugin/skeleton.pm.example index af22b3406..ecf2a2407 100644 --- a/IkiWiki/Plugin/skeleton.pm.example +++ b/IkiWiki/Plugin/skeleton.pm.example @@ -35,6 +35,7 @@ sub import { #{{{ hook(type => "formbuilder", id => "skeleton", call => \&formbuilder); hook(type => "savestate", id => "skeleton", call => \&savestate); hook(type => "targetpage", id => "skeleton", call => \&targetpage); + hook(type => "urlpath", id => "skeleton", call => \&urlpath); } # }}} sub getopt () { #{{{ @@ -209,4 +210,8 @@ sub targetpage () { #{{{ debug("skeleton plugin running in targetpage"); } #}}} +sub urlpath () { #{{{ + debug("skeleton plugin running in urlpath"); +} #}}} + 1 diff --git a/doc/plugins/write.mdwn b/doc/plugins/write.mdwn index 6d2622272..15f6c8a20 100644 --- a/doc/plugins/write.mdwn +++ b/doc/plugins/write.mdwn @@ -437,6 +437,16 @@ be compiled into. It should return the target filename. +### urlpath + + hook(type => "urlpath", id => "foo", call => \&urlpath); + +This hook can be used to modify the internal urls generated by +ikiwiki; it is run just after ikiwiki has removed the trailing +`index.html`, in case `usedirs` is enabled. + +It should return the modified url. + ## Plugin interface To import the ikiwiki plugin interface: -- cgit v1.2.3 From a926f9840ef8abf18ea2ca4a35a2ee2e2f815bf1 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Wed, 8 Oct 2008 11:47:37 +0200 Subject: po plugin: linking behavior specification (no implementation yet) Signed-off-by: intrigeri --- doc/plugins/po.mdwn | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index e7a93469c..0cb510dce 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -73,6 +73,29 @@ lighttpd unfortunately does not support content negotiation. TODO ==== +Links +----- + +Choice between two behaviors must be possible in `ikiwiki.setup`; +a `po_link_to_current_language` option must allow switching +between them. + +If `po_link_to_current_language` is disabled, `[[page]]` links to the +negotiated preferred language, i.e.: + +- `usedirs` enabled: `bla/page/` +- `usedirs` disabled: `bla/page` + +This obviously does not work in case Content Negotiation is not +supported by the web server, hence one can enable +`po_link_to_current_language` to make `[[page]]` link to the current +page's language, i.e.: + +- `usedirs` enabled: `bla/page/index.LL.html` +- `usedirs` disabled: `bla/page.LL.html` + +**FIXME**: should `po_link_to_current_language` be enabled by default? + Display available translations ------------------------------ @@ -138,11 +161,7 @@ Pages selection depending on language To improve user navigation in a multi-lingual wiki, site developers must be enabled to write: - \[[!map pages="dev/* and preferredlang()" feeds="no"]] - - \[[!map pages="dev/* and currentlang()" feeds="no"]] - -Some new [[ikiwiki/pagespec]] functions have to be written. + \[[!map pages="dev/* and lang(LL)" feeds="no"]] Translation quality assurance ----------------------------- -- cgit v1.2.3 From 24726f283627dabcb397ede32e46e5ead12efcee Mon Sep 17 00:00:00 2001 From: intrigeri Date: Wed, 8 Oct 2008 14:30:50 +0200 Subject: po plugin: add one more pagespec function to the specification (not implemented yet) Signed-off-by: intrigeri --- doc/plugins/po.mdwn | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index 0cb510dce..9e9ba1fd8 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -163,6 +163,8 @@ must be enabled to write: \[[!map pages="dev/* and lang(LL)" feeds="no"]] + \[[!map pages="dev/* and currentlang()" feeds="no"]] + Translation quality assurance ----------------------------- -- cgit v1.2.3 From cc4736d9eef4fba7ec39afe1aa6782142befc3d0 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Wed, 8 Oct 2008 14:37:43 +0200 Subject: po plugin: clearer file naming specs i.e. clarify that master pages do not have to obey a special naming convention, so that migration from/to this plugin is smooth Signed-off-by: intrigeri --- doc/plugins/po.mdwn | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index 9e9ba1fd8..fd8a50e0b 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -10,8 +10,12 @@ Introduction ============ A language is chosen as the "master" one, and any other supported -language is a "slave" one. A page written in the "master" language is -a "master" page, and is written in any supported format but PO. +language is a "slave" one. + +A page written in the "master" language is a "master" page, and is +written in any supported format but PO. It does not have to be named +a special way: migration from/to this plugin does not imply heavy +renaming work. Example: `bla/page.mdwn` is a "master" Markdown page written in English; if `usedirs` is enabled, it is rendered as -- cgit v1.2.3 From 258c49ae55b96bb8dcc779f4c61b5ae6cdd280a5 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Wed, 8 Oct 2008 15:02:30 +0200 Subject: po plugin: added [[!translatable]] directive Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index b33d4dc1b..3546bef88 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -15,6 +15,7 @@ sub import { hook(type => "getsetup", id => "po", call => \&getsetup); hook(type => "targetpage", id => "po", call => \&targetpage); hook(type => "filter", id => "po", call => \&filter); + hook(type => "preprocess", id => "translatable", call => \&preprocess_translatable); hook(type => "htmlize", id => "po", call => \&htmlize); } @@ -107,6 +108,17 @@ sub filter (@) { #{{{ return $content; } #}}} +sub preprocess_translatable (@) { #{{{ + my %params = @_; + my $match = exists $params{match} ? $params{match} : $params{page}; + + $pagestate{$params{page}}{po_translatable}{$match}=1; + + return "" if ($params{silent} && IkiWiki::yesno($params{silent})); + return sprintf(gettext("pages %s set as translatable"), $params{match}); + +} #}}} + sub htmlize (@) { #{{{ my %params=@_; my $page = $params{page}; -- cgit v1.2.3 From 1975d4d35fa47a9f6846d2b4f9c8d1b6fc04ebbf Mon Sep 17 00:00:00 2001 From: intrigeri Date: Wed, 8 Oct 2008 20:31:46 +0200 Subject: po plugin: use pagespec_match() instead of direct match_istranslation calls Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 3546bef88..933f4d26e 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -52,7 +52,7 @@ sub targetpage (@) { #{{{ my $page=$params{page}; my $ext=$params{ext}; - if (IkiWiki::PageSpec::match_istranslation($page, $page)) { + if (pagespec_match($page,"istranslation()")) { my ($masterpage, $lang) = ($page =~ /(.*)[.]([a-z]{2})$/); if (! $config{usedirs} || $page eq 'index') { return $masterpage . "." . $lang . "." . $ext; @@ -80,7 +80,7 @@ sub filter (@) { #{{{ # decide if this is a PO file that should be converted into a translated document, # and perform various sanity checks - if (! IkiWiki::PageSpec::match_istranslation($page, $page)) { + if (! pagespec_match($page, "istranslation()")) { return $content; } -- cgit v1.2.3 From c8330da6c050918eaea4a441ba2ed59258f49494 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Fri, 10 Oct 2008 13:57:48 +0200 Subject: po plugin: add po_link_to_current_language option, check config Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 933f4d26e..fea4ca6eb 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -13,6 +13,7 @@ use File::Temp; sub import { hook(type => "getsetup", id => "po", call => \&getsetup); + hook(type => "checkconfig", id => "po", call => \&checkconfig); hook(type => "targetpage", id => "po", call => \&targetpage); hook(type => "filter", id => "po", call => \&filter); hook(type => "preprocess", id => "translatable", call => \&preprocess_translatable); @@ -45,6 +46,25 @@ sub getsetup () { #{{{ safe => 1, rebuild => 1, }, + po_link_to_current_language => { + type => "boolean", + example => 1, + description => "internal links point to pages in the current language (useful if Content Negotiation is not supported)", + safe => 1, + rebuild => 1, + }, +} #}}} + +sub checkconfig () { #{{{ + foreach my $field (qw{po_master_language po_slave_languages}) { + if (! exists $config{$field} || ! defined $config{$field}) { + error(sprintf(gettext("Must specify %s"), $field)); + } + } + if (! exists $config{po_link_to_current_language} || + ! defined $config{po_link_to_current_language}) { + $config{po_link_to_current_language}=0; + } } #}}} sub targetpage (@) { #{{{ -- cgit v1.2.3 From e51089e11fc1093a253fc13ebfbd5d55912eba59 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Fri, 10 Oct 2008 14:30:31 +0200 Subject: added the tweakbestlink hook Signed-off-by: intrigeri --- IkiWiki.pm | 27 +++++++++++++++++++-------- doc/plugins/write.mdwn | 11 +++++++++++ 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/IkiWiki.pm b/IkiWiki.pm index e75175a8d..f2b50e77a 100644 --- a/IkiWiki.pm +++ b/IkiWiki.pm @@ -807,6 +807,7 @@ sub will_render ($$;$) { #{{{ sub bestlink ($$) { #{{{ my $page=shift; my $link=shift; + my $res=undef; my $cwd=$page; if ($link=~s/^\/+//) { @@ -821,25 +822,35 @@ sub bestlink ($$) { #{{{ $l.=$link; if (exists $links{$l}) { - return $l; + $res=$l; } elsif (exists $pagecase{lc $l}) { - return $pagecase{lc $l}; + $res=$pagecase{lc $l}; } - } while $cwd=~s{/?[^/]+$}{}; + } while ($cwd=~s{/?[^/]+$}{} && ! defined $res); - if (length $config{userdir}) { + if (! defined $res && length $config{userdir}) { my $l = "$config{userdir}/".lc($link); if (exists $links{$l}) { - return $l; + $res=$l; } elsif (exists $pagecase{lc $l}) { - return $pagecase{lc $l}; + $res=$pagecase{lc $l}; } } - #print STDERR "warning: page $page, broken link: $link\n"; - return ""; + if (defined $res) { + run_hooks(tweakbestlink => sub { + $res=shift->( + page => $page, + link => $res); + }); + return $res; + } + else { + #print STDERR "warning: page $page, broken link: $link\n"; + return ""; + } } #}}} sub isinlinableimage ($) { #{{{ diff --git a/doc/plugins/write.mdwn b/doc/plugins/write.mdwn index 15f6c8a20..e7656b299 100644 --- a/doc/plugins/write.mdwn +++ b/doc/plugins/write.mdwn @@ -447,6 +447,17 @@ ikiwiki; it is run just after ikiwiki has removed the trailing It should return the modified url. +### tweakbestlink + + hook(type => "tweakbestlink", id => "foo", call => \&tweakbestlink); + +This hook can be used to modify the page returned by `bestlink`. It is +passed named parameters `page` and `link`. These are, respectively, +the page where the link will appear and the link ikiwiki would choose +as the best one, if no `tweakbestlink` hook was in effect. + +It should return the modified link. + ## Plugin interface To import the ikiwiki plugin interface: -- cgit v1.2.3 From 39d44d443d2271ec8787e6192b8b5811bee41ebf Mon Sep 17 00:00:00 2001 From: intrigeri Date: Fri, 10 Oct 2008 14:46:48 +0200 Subject: rename urlpath hook into tweakurlpath for consistency's sake Signed-off-by: intrigeri --- IkiWiki.pm | 2 +- doc/plugins/write.mdwn | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/IkiWiki.pm b/IkiWiki.pm index f2b50e77a..36e85d413 100644 --- a/IkiWiki.pm +++ b/IkiWiki.pm @@ -938,7 +938,7 @@ sub beautify_urlpath ($) { #{{{ $url =~ s!/index.$config{htmlext}$!/!; } - run_hooks(urlpath => sub { + run_hooks(tweakurlpath => sub { $url=shift->(url => $url); }); diff --git a/doc/plugins/write.mdwn b/doc/plugins/write.mdwn index e7656b299..884c7eefb 100644 --- a/doc/plugins/write.mdwn +++ b/doc/plugins/write.mdwn @@ -437,9 +437,9 @@ be compiled into. It should return the target filename. -### urlpath +### tweakurlpath - hook(type => "urlpath", id => "foo", call => \&urlpath); + hook(type => "tweakurlpath", id => "foo", call => \&tweakurlpath); This hook can be used to modify the internal urls generated by ikiwiki; it is run just after ikiwiki has removed the trailing -- cgit v1.2.3 From e82c6b1908b21b5e4246767d6a87fe46245e5e29 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Fri, 10 Oct 2008 15:16:04 +0200 Subject: po plugin: implement linking specification in one of the main cases i.e. in case usedirs is enabled and po_link_to_current_language is disabled Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index fea4ca6eb..63be0e389 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -15,6 +15,7 @@ sub import { hook(type => "getsetup", id => "po", call => \&getsetup); hook(type => "checkconfig", id => "po", call => \&checkconfig); hook(type => "targetpage", id => "po", call => \&targetpage); + hook(type => "tweakurlpath", id => "po", call => \&tweakurlpath); hook(type => "filter", id => "po", call => \&filter); hook(type => "preprocess", id => "translatable", call => \&preprocess_translatable); hook(type => "htmlize", id => "po", call => \&htmlize); @@ -91,6 +92,15 @@ sub targetpage (@) { #{{{ } } #}}} +sub tweakurlpath ($) { #{{{ + my %params = @_; + my $url=$params{url}; + if (! $config{po_link_to_current_language} && $config{usedirs}) { + $url =~ s!/index.$config{po_master_language}{code}.$config{htmlext}$!/!; + } + return $url; +} #}}} + # We use filter to convert PO to the master page's type, # since other plugins should not work on PO files sub filter (@) { #{{{ -- cgit v1.2.3 From 9c25f5cfe93899f6ac7da3c8c8d0939cff9a20b6 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Fri, 10 Oct 2008 15:35:55 +0200 Subject: po plugin: rewrite internal linking specification (not implemented yet) Signed-off-by: intrigeri --- doc/plugins/po.mdwn | 43 +++++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index fd8a50e0b..d2f572706 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -77,28 +77,39 @@ lighttpd unfortunately does not support content negotiation. TODO ==== -Links ------ +Internal links +-------------- -Choice between two behaviors must be possible in `ikiwiki.setup`; -a `po_link_to_current_language` option must allow switching -between them. +One can use the `po_link_to_` option in `ikiwiki.setup` to choose how +internal links should be generated, depending on web server features +and site-specific preferences. -If `po_link_to_current_language` is disabled, `[[page]]` links to the -negotiated preferred language, i.e.: +### Default linking behavior -- `usedirs` enabled: `bla/page/` -- `usedirs` disabled: `bla/page` +If `po_link_to` is unset, or set to `default`, ikiwiki's default +linking behavior is preserved: `[[page]]` links to the master +language's page. -This obviously does not work in case Content Negotiation is not -supported by the web server, hence one can enable -`po_link_to_current_language` to make `[[page]]` link to the current -page's language, i.e.: +### Link to negotiated language -- `usedirs` enabled: `bla/page/index.LL.html` -- `usedirs` disabled: `bla/page.LL.html` +If `po_link_to` is set to `negotiated`, `[[page]]` links to the +negotiated preferred language, *i.e.* `foo/page/`. -**FIXME**: should `po_link_to_current_language` be enabled by default? +(In)compatibility notes: + +- `po_link_to => negotiated` provides no useful behavior if `usedirs` + is disabled: +- `po_link_to => negotiated` provides no useful behavior if the web + server does not support Content Negotiation + +### Link to current language + +If `po_link_to` is set to `current` and the destination page is either +a translatable page or a translation, `[[page]]` links to the current +page's language, *i.e.*: + +- `foo/page/index.LL.html` if `usedirs` is enabled +- `foo/page.LL.html` if `usedirs` is disabled Display available translations ------------------------------ -- cgit v1.2.3 From fdc7974b2ac995b4ff12dfa208741189ff4bd274 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Fri, 10 Oct 2008 15:48:35 +0200 Subject: po plugin: implemented po_link_to=negotiated Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 19 +++++++++++-------- doc/plugins/po.mdwn | 3 ++- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 63be0e389..7b9945b0a 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -47,10 +47,10 @@ sub getsetup () { #{{{ safe => 1, rebuild => 1, }, - po_link_to_current_language => { - type => "boolean", - example => 1, - description => "internal links point to pages in the current language (useful if Content Negotiation is not supported)", + po_link_to => { + type => "string", + example => "current", + description => "internal linking behavior (default/current/negotiated)", safe => 1, rebuild => 1, }, @@ -62,9 +62,12 @@ sub checkconfig () { #{{{ error(sprintf(gettext("Must specify %s"), $field)); } } - if (! exists $config{po_link_to_current_language} || - ! defined $config{po_link_to_current_language}) { - $config{po_link_to_current_language}=0; + if (! exists $config{po_link_to} || + ! defined $config{po_link_to}) { + $config{po_link_to}="default"; + } + if ($config{po_link_to} eq "negotiated" && ! $config{usedirs}) { + error(gettext("po_link_to=negotiated requires usedirs to be set")); } } #}}} @@ -95,7 +98,7 @@ sub targetpage (@) { #{{{ sub tweakurlpath ($) { #{{{ my %params = @_; my $url=$params{url}; - if (! $config{po_link_to_current_language} && $config{usedirs}) { + if ($config{po_link_to} eq "negotiated") { $url =~ s!/index.$config{po_master_language}{code}.$config{htmlext}$!/!; } return $url; diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index d2f572706..0d93aadda 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -98,7 +98,8 @@ negotiated preferred language, *i.e.* `foo/page/`. (In)compatibility notes: - `po_link_to => negotiated` provides no useful behavior if `usedirs` - is disabled: + is disabled; this option combination is neither implemented nor + allowed - `po_link_to => negotiated` provides no useful behavior if the web server does not support Content Negotiation -- cgit v1.2.3 From 0791e5afe3d8405132adcfd1ebaa8b76d0def3fc Mon Sep 17 00:00:00 2001 From: intrigeri Date: Fri, 10 Oct 2008 17:10:40 +0200 Subject: po plugin: added istranslatable() pagespec function, and use it (do not name non-translatable pages index.LL.html) Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 43 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 7b9945b0a..e33133857 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -85,7 +85,7 @@ sub targetpage (@) { #{{{ return $masterpage . "/index." . $lang . "." . $ext; } } - else { + elsif (pagespec_match($page,"istranslatable()")) { if (! $config{usedirs} || $page eq 'index') { return $page . "." . $config{po_master_language}{code} . "." . $ext; } @@ -93,6 +93,7 @@ sub targetpage (@) { #{{{ return $page . "/index." . $config{po_master_language}{code} . "." . $ext; } } + return; } #}}} sub tweakurlpath ($) { #{{{ @@ -164,18 +165,21 @@ sub htmlize (@) { #{{{ } #}}} package IkiWiki::PageSpec; +use warnings; +use strict; +use IkiWiki 2.00; sub match_istranslation ($;@) { #{{{ my $page=shift; my $wanted=shift; my %params=@_; - my $file=exists $params{file} ? $params{file} : $IkiWiki::pagesources{$page}; + my $file=exists $params{file} ? $params{file} : $pagesources{$page}; if (! defined $file) { return IkiWiki::FailReason->new("no file specified"); } - if (! IkiWiki::pagetype($page) eq 'po') { + if (! defined pagetype($file) || ! pagetype($file) eq 'po') { return IkiWiki::FailReason->new("is not a PO file"); } @@ -185,16 +189,45 @@ sub match_istranslation ($;@) { #{{{ return IkiWiki::FailReason->new("is not named like a translation file"); } - if (! defined $IkiWiki::pagesources{$masterpage}) { + if (! defined $pagesources{$masterpage}) { return IkiWiki::FailReason->new("the master page does not exist"); } - if (! defined $IkiWiki::config{po_slave_languages}{$lang}) { + if (! defined $config{po_slave_languages}{$lang}) { return IkiWiki::FailReason->new("language $lang is not supported"); } return IkiWiki::SuccessReason->new("page $page is a translation"); +} #}}} + +sub match_istranslatable ($;@) { #{{{ + my $page=shift; + my $wanted=shift; + + my %params=@_; + my $file=exists $params{file} ? $params{file} : $pagesources{$page}; + if (! defined $file) { + return IkiWiki::FailReason->new("no file specified"); + } + + if (defined pagetype($file) && pagetype($file) eq 'po') { + return IkiWiki::FailReason->new("is a PO file"); + } + if ($file =~ /\.pot$/) { + return IkiWiki::FailReason->new("is a POT file"); + } + + foreach my $registering_page (keys %pagestate) { + if (exists $pagestate{$registering_page}{po_translatable}) { + foreach my $pagespec (sort keys %{$pagestate{$registering_page}{po_translatable}}) { + if (pagespec_match($page, $pagespec, location => $registering_page)) { + return IkiWiki::SuccessReason->new("is set as translatable on $registering_page"); + } + } + } + } + return IkiWiki::FailReason->new("is not set as translatable"); } #}}} 1 -- cgit v1.2.3 From 79d6f52d307aa587ef63ffc0aa04ab5070bf15cc Mon Sep 17 00:00:00 2001 From: intrigeri Date: Fri, 10 Oct 2008 17:37:14 +0200 Subject: po plugin: implemented po_link_to=current Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 14 ++++++++++++ doc/plugins/po.mdwn | 62 ++++++++++++++++++++++++++-------------------------- 2 files changed, 45 insertions(+), 31 deletions(-) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index e33133857..4b2990921 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -16,6 +16,7 @@ sub import { hook(type => "checkconfig", id => "po", call => \&checkconfig); hook(type => "targetpage", id => "po", call => \&targetpage); hook(type => "tweakurlpath", id => "po", call => \&tweakurlpath); + hook(type => "tweakbestlink", id => "po", call => \&tweakbestlink); hook(type => "filter", id => "po", call => \&filter); hook(type => "preprocess", id => "translatable", call => \&preprocess_translatable); hook(type => "htmlize", id => "po", call => \&htmlize); @@ -105,6 +106,19 @@ sub tweakurlpath ($) { #{{{ return $url; } #}}} +sub tweakbestlink ($$) { #{{{ + my %params = @_; + my $page=$params{page}; + my $link=$params{link}; + if ($config{po_link_to} eq "current" && pagespec_match($link, "istranslatable()")) { + if (pagespec_match($page, "istranslation()")) { + my ($masterpage, $curlang) = ($page =~ /(.*)[.]([a-z]{2})$/); + return $link . "." . $curlang; + } + } + return $link; +} #}}} + # We use filter to convert PO to the master page's type, # since other plugins should not work on PO files sub filter (@) { #{{{ diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index 0d93aadda..991f25c06 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -46,37 +46,6 @@ languages, such as: 'de' => { 'name' => 'Deutsch', } } - -Server support -============== - -Apache ------- - -Using `mod_negotiation` makes it really easy to have Apache serve the -page in the client's preferred language, if available. This is the -default Debian Apache configuration. - -When `usedirs` is enabled, one has to set `DirectoryIndex index` for -the wiki context. - -Setting `DefaultLanguage LL` (replace `LL` with your default MIME -language) for the wiki context can be needed, to ensure -`bla/page/index.en.html` is served as `Content-Language: LL`. -**FIXME**: is it still needed with the new `.en.html` naming convention? - -lighttpd --------- - -lighttpd unfortunately does not support content negotiation. - -**FIXME**: does `mod_magnet` provide the functionality needed to - emulate this? - - -TODO -==== - Internal links -------------- @@ -112,6 +81,37 @@ page's language, *i.e.*: - `foo/page/index.LL.html` if `usedirs` is enabled - `foo/page.LL.html` if `usedirs` is disabled + +Server support +============== + +Apache +------ + +Using `mod_negotiation` makes it really easy to have Apache serve the +page in the client's preferred language, if available. This is the +default Debian Apache configuration. + +When `usedirs` is enabled, one has to set `DirectoryIndex index` for +the wiki context. + +Setting `DefaultLanguage LL` (replace `LL` with your default MIME +language) for the wiki context can be needed, to ensure +`bla/page/index.en.html` is served as `Content-Language: LL`. +**FIXME**: is it still needed with the new `.en.html` naming convention? + +lighttpd +-------- + +lighttpd unfortunately does not support content negotiation. + +**FIXME**: does `mod_magnet` provide the functionality needed to + emulate this? + + +TODO +==== + Display available translations ------------------------------ -- cgit v1.2.3 From 23dccccdf22e09f1f9f0b8142a16983b93eaed5f Mon Sep 17 00:00:00 2001 From: intrigeri Date: Fri, 10 Oct 2008 17:39:28 +0200 Subject: po plugin: update doc (move finished item from todo) Signed-off-by: intrigeri --- doc/plugins/po.mdwn | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index 991f25c06..69fce52ef 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -46,6 +46,16 @@ languages, such as: 'de' => { 'name' => 'Deutsch', } } +Decide which pages are translatable +----------------------------------- + +The subset of "master" pages subject to translation is configurable: + +- a `[[!translatable ]]` directive, when put on a page, makes it + translatable +- to set at once a bunch of pages as being translatable, use this + [[ikiwiki/directive]] with the `match=PageSpec` argument. + Internal links -------------- @@ -131,17 +141,6 @@ implemented as a loop, a page using it should depend on any "master" and "slave" pages whose status is being displayed. -Decide which pages are translatable ------------------------------------ - -The subset of "master" pages subject to translation must be -configurable: - -- a `[[!translatable ]]` directive, when put on a page, makes it - translatable -- to set at once a bunch of pages as being translatable, use this - [[ikiwiki/directive]] with the `match=PageSpec` argument. - Automatic PO files update ------------------------- -- cgit v1.2.3 From b0b87d15843db10b6ff7a4e30ff8bf110e229075 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Fri, 10 Oct 2008 18:01:06 +0200 Subject: po plugin: respect documented convention to store pagestate Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 4b2990921..d7f245e96 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -160,7 +160,7 @@ sub preprocess_translatable (@) { #{{{ my %params = @_; my $match = exists $params{match} ? $params{match} : $params{page}; - $pagestate{$params{page}}{po_translatable}{$match}=1; + $pagestate{$params{page}}{po}{translatable}{$match}=1; return "" if ($params{silent} && IkiWiki::yesno($params{silent})); return sprintf(gettext("pages %s set as translatable"), $params{match}); @@ -232,8 +232,8 @@ sub match_istranslatable ($;@) { #{{{ } foreach my $registering_page (keys %pagestate) { - if (exists $pagestate{$registering_page}{po_translatable}) { - foreach my $pagespec (sort keys %{$pagestate{$registering_page}{po_translatable}}) { + if (exists $pagestate{$registering_page}{po}{translatable}) { + foreach my $pagespec (sort keys %{$pagestate{$registering_page}{po}{translatable}}) { if (pagespec_match($page, $pagespec, location => $registering_page)) { return IkiWiki::SuccessReason->new("is set as translatable on $registering_page"); } -- cgit v1.2.3 From ffd1fff775c97296c4d336cb35b9d59511c032bc Mon Sep 17 00:00:00 2001 From: intrigeri Date: Fri, 10 Oct 2008 18:08:00 +0200 Subject: po plugin: allow pagestate update (bugfix) Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index d7f245e96..5042d264e 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -14,6 +14,7 @@ use File::Temp; sub import { hook(type => "getsetup", id => "po", call => \&getsetup); hook(type => "checkconfig", id => "po", call => \&checkconfig); + hook(type => "needsbuild", id => "po", call => \&needsbuild); hook(type => "targetpage", id => "po", call => \&targetpage); hook(type => "tweakurlpath", id => "po", call => \&tweakurlpath); hook(type => "tweakbestlink", id => "po", call => \&tweakbestlink); @@ -72,6 +73,22 @@ sub checkconfig () { #{{{ } } #}}} +sub needsbuild (@) { #{{{ + my $needsbuild=shift; + + foreach my $page (keys %pagestate) { + if (exists $pagestate{$page}{po}{translatable}) { + if (exists $pagesources{$page} && + grep { $_ eq $pagesources{$page} } @$needsbuild) { + # remove state, it will be re-added + # if the preprocessor directive is still + # there during the rebuild + delete $pagestate{$page}{po}{translatable}; + } + } + } +} #}}} + sub targetpage (@) { #{{{ my %params = @_; my $page=$params{page}; -- cgit v1.2.3 From b852b0655c1cb40919fc2f45d6f8b899f2b298e5 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Fri, 10 Oct 2008 19:29:16 +0200 Subject: po plugin: added todo note about optimization Signed-off-by: intrigeri --- doc/plugins/po.mdwn | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index 69fce52ef..f71a36739 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -122,6 +122,15 @@ lighttpd unfortunately does not support content negotiation. TODO ==== +Optimization +------------ + +Move `match_istranslation` and `match_istranslatable` code into helper +functions, and pre-compute what can be early in the build process: + +- the list of translatable (master) pages +- for every translatable page, the list of slave pages + Display available translations ------------------------------ -- cgit v1.2.3 From 886f35153b0945ec39568c61d3e7451c18be6be8 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Fri, 10 Oct 2008 21:03:21 +0200 Subject: po plugin: added note about not publishing .pot files Signed-off-by: intrigeri --- doc/plugins/po.mdwn | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index f71a36739..2b0fba628 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -171,6 +171,8 @@ The latter can be implemented by making any "slave" page depend on the corresponding "master" page. The `add_depends` function can achieve this, if used in a **FIXME** hook. +The POT files should not be published on the wiki. + UI consistency: rename "Edit" button on slave pages --------------------------------------------------- -- cgit v1.2.3 From e163b037bf3c9fa68be0971752e6d6584f8d55fd Mon Sep 17 00:00:00 2001 From: intrigeri Date: Fri, 10 Oct 2008 21:47:20 +0200 Subject: po plugin: move translatable pages to setup file, refactor Replaced [[!translatable]] directive with po_translatable_pages setting. Moved istranslatable/istranslation code to helper functions leaving place for future caching and/or memoization. The PageSpec functions still work. Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 145 ++++++++++++++++++++++++--------------------------- doc/plugins/po.mdwn | 16 +++--- 2 files changed, 76 insertions(+), 85 deletions(-) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 5042d264e..ca59a8c9c 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -14,12 +14,11 @@ use File::Temp; sub import { hook(type => "getsetup", id => "po", call => \&getsetup); hook(type => "checkconfig", id => "po", call => \&checkconfig); - hook(type => "needsbuild", id => "po", call => \&needsbuild); + hook(type => "scan", id => "po", call => \&scan); hook(type => "targetpage", id => "po", call => \&targetpage); hook(type => "tweakurlpath", id => "po", call => \&tweakurlpath); hook(type => "tweakbestlink", id => "po", call => \&tweakbestlink); hook(type => "filter", id => "po", call => \&filter); - hook(type => "preprocess", id => "translatable", call => \&preprocess_translatable); hook(type => "htmlize", id => "po", call => \&htmlize); } @@ -49,6 +48,14 @@ sub getsetup () { #{{{ safe => 1, rebuild => 1, }, + po_translatable_pages => { + type => "pagespec", + example => "!*/Discussion", + description => "PageSpec controlling which pages are translatable", + link => "ikiwiki/PageSpec", + safe => 1, + rebuild => 1, + }, po_link_to => { type => "string", example => "current", @@ -68,25 +75,21 @@ sub checkconfig () { #{{{ ! defined $config{po_link_to}) { $config{po_link_to}="default"; } + if (! exists $config{po_translatable_pages} || + ! defined $config{po_translatable_pages}) { + $config{po_translatable_pages}=""; + } if ($config{po_link_to} eq "negotiated" && ! $config{usedirs}) { error(gettext("po_link_to=negotiated requires usedirs to be set")); } } #}}} -sub needsbuild (@) { #{{{ - my $needsbuild=shift; +sub scan (@) { #{{{ + my %params=@_; + my $page=$params{page}; - foreach my $page (keys %pagestate) { - if (exists $pagestate{$page}{po}{translatable}) { - if (exists $pagesources{$page} && - grep { $_ eq $pagesources{$page} } @$needsbuild) { - # remove state, it will be re-added - # if the preprocessor directive is still - # there during the rebuild - delete $pagestate{$page}{po}{translatable}; - } - } - } + # FIXME: cache (or memoize) the list of translatable/translation pages, + # and/or istranslation/istranslated results } #}}} sub targetpage (@) { #{{{ @@ -94,7 +97,7 @@ sub targetpage (@) { #{{{ my $page=$params{page}; my $ext=$params{ext}; - if (pagespec_match($page,"istranslation()")) { + if (istranslation($page)) { my ($masterpage, $lang) = ($page =~ /(.*)[.]([a-z]{2})$/); if (! $config{usedirs} || $page eq 'index') { return $masterpage . "." . $lang . "." . $ext; @@ -103,7 +106,7 @@ sub targetpage (@) { #{{{ return $masterpage . "/index." . $lang . "." . $ext; } } - elsif (pagespec_match($page,"istranslatable()")) { + elsif (istranslatable($page)) { if (! $config{usedirs} || $page eq 'index') { return $page . "." . $config{po_master_language}{code} . "." . $ext; } @@ -127,11 +130,11 @@ sub tweakbestlink ($$) { #{{{ my %params = @_; my $page=$params{page}; my $link=$params{link}; - if ($config{po_link_to} eq "current" && pagespec_match($link, "istranslatable()")) { - if (pagespec_match($page, "istranslation()")) { - my ($masterpage, $curlang) = ($page =~ /(.*)[.]([a-z]{2})$/); - return $link . "." . $curlang; - } + if ($config{po_link_to} eq "current" + && istranslatable($link) + && istranslation($page)) { + my ($masterpage, $curlang) = ($page =~ /(.*)[.]([a-z]{2})$/); + return $link . "." . $curlang; } return $link; } #}}} @@ -145,7 +148,7 @@ sub filter (@) { #{{{ # decide if this is a PO file that should be converted into a translated document, # and perform various sanity checks - if (! pagespec_match($page, "istranslation()")) { + if (! istranslation($page)) { return $content; } @@ -173,17 +176,6 @@ sub filter (@) { #{{{ return $content; } #}}} -sub preprocess_translatable (@) { #{{{ - my %params = @_; - my $match = exists $params{match} ? $params{match} : $params{page}; - - $pagestate{$params{page}}{po}{translatable}{$match}=1; - - return "" if ($params{silent} && IkiWiki::yesno($params{silent})); - return sprintf(gettext("pages %s set as translatable"), $params{match}); - -} #}}} - sub htmlize (@) { #{{{ my %params=@_; my $page = $params{page}; @@ -195,70 +187,67 @@ sub htmlize (@) { #{{{ return IkiWiki::htmlize($page, $page, pagetype($masterfile), $content); } #}}} -package IkiWiki::PageSpec; -use warnings; -use strict; -use IkiWiki 2.00; - -sub match_istranslation ($;@) { #{{{ +sub istranslatable ($) { #{{{ my $page=shift; - my $wanted=shift; + my $file=$pagesources{$page}; - my %params=@_; - my $file=exists $params{file} ? $params{file} : $pagesources{$page}; + if (! defined $file + || (defined pagetype($file) && pagetype($file) eq 'po') + || $file =~ /\.pot$/) { + return 0; + } + return pagespec_match($page, $config{po_translatable_pages}); +} #}}} + +sub istranslation ($) { #{{{ + my $page=shift; + my $file=$pagesources{$page}; if (! defined $file) { return IkiWiki::FailReason->new("no file specified"); } - if (! defined pagetype($file) || ! pagetype($file) eq 'po') { - return IkiWiki::FailReason->new("is not a PO file"); + if (! defined $file + || ! defined pagetype($file) + || ! pagetype($file) eq 'po' + || $file =~ /\.pot$/) { + return 0; } my ($masterpage, $lang) = ($page =~ /(.*)[.]([a-z]{2})$/); if (! defined $masterpage || ! defined $lang - || ! (length($masterpage) > 0) || ! (length($lang) > 0)) { - return IkiWiki::FailReason->new("is not named like a translation file"); - } - - if (! defined $pagesources{$masterpage}) { - return IkiWiki::FailReason->new("the master page does not exist"); - } - - if (! defined $config{po_slave_languages}{$lang}) { - return IkiWiki::FailReason->new("language $lang is not supported"); + || ! (length($masterpage) > 0) || ! (length($lang) > 0) + || ! defined $pagesources{$masterpage} + || ! defined $config{po_slave_languages}{$lang}) { + return 0; } - return IkiWiki::SuccessReason->new("page $page is a translation"); + return istranslatable($masterpage); } #}}} -sub match_istranslatable ($;@) { #{{{ - my $page=shift; - my $wanted=shift; - my %params=@_; - my $file=exists $params{file} ? $params{file} : $pagesources{$page}; - if (! defined $file) { - return IkiWiki::FailReason->new("no file specified"); - } +package IkiWiki::PageSpec; +use warnings; +use strict; +use IkiWiki 2.00; - if (defined pagetype($file) && pagetype($file) eq 'po') { - return IkiWiki::FailReason->new("is a PO file"); +sub match_istranslation ($;@) { #{{{ + my $page=shift; + if (IkiWiki::Plugins::po::istranslation($page)) { + return IkiWiki::SuccessReason->new("is a translation page"); } - if ($file =~ /\.pot$/) { - return IkiWiki::FailReason->new("is a POT file"); + else { + return IkiWiki::FailReason->new("is not a translation page"); } +} #}}} - foreach my $registering_page (keys %pagestate) { - if (exists $pagestate{$registering_page}{po}{translatable}) { - foreach my $pagespec (sort keys %{$pagestate{$registering_page}{po}{translatable}}) { - if (pagespec_match($page, $pagespec, location => $registering_page)) { - return IkiWiki::SuccessReason->new("is set as translatable on $registering_page"); - } - } - } +sub match_istranslatable ($;@) { #{{{ + my $page=shift; + if (IkiWiki::Plugins::po::istranslatable($page)) { + return IkiWiki::SuccessReason->new("is set as translatable in po_translatable_pages"); + } + else { + return IkiWiki::FailReason->new("is not set as translatable in po_translatable_pages"); } - - return IkiWiki::FailReason->new("is not set as translatable"); } #}}} 1 diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index 2b0fba628..20ca5c4a5 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -49,12 +49,13 @@ languages, such as: Decide which pages are translatable ----------------------------------- -The subset of "master" pages subject to translation is configurable: +The `po_translatable_pages` setting configures what pages are +translatable. It is a [[ikiwiki/PageSpec]], so you have lots of +control over what kind of pages are translatable. -- a `[[!translatable ]]` directive, when put on a page, makes it - translatable -- to set at once a bunch of pages as being translatable, use this - [[ikiwiki/directive]] with the `match=PageSpec` argument. +The `*.LL.po` translations files are anyway not considered as being +translatable, so you don't need to worry about excluding them manually +from this [[ikiwiki/PageSpec]]. Internal links -------------- @@ -125,12 +126,13 @@ TODO Optimization ------------ -Move `match_istranslation` and `match_istranslatable` code into helper -functions, and pre-compute what can be early in the build process: +Pre-compute what can be early in the build process: - the list of translatable (master) pages - for every translatable page, the list of slave pages +... and/or memoize `istranslation`/`istranslatable` function calls. + Display available translations ------------------------------ -- cgit v1.2.3 From 458ccebdd3f47dbae79d4129c043e049e954d7cc Mon Sep 17 00:00:00 2001 From: intrigeri Date: Fri, 10 Oct 2008 21:56:40 +0200 Subject: po plugin: added *.pot to wiki_file_prune_regexps Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 1 + doc/plugins/po.mdwn | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index ca59a8c9c..d60ade499 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -82,6 +82,7 @@ sub checkconfig () { #{{{ if ($config{po_link_to} eq "negotiated" && ! $config{usedirs}) { error(gettext("po_link_to=negotiated requires usedirs to be set")); } + push @{$config{wiki_file_prune_regexps}}, qr/\.pot$/; } #}}} sub scan (@) { #{{{ diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index 20ca5c4a5..b587c79c4 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -173,8 +173,6 @@ The latter can be implemented by making any "slave" page depend on the corresponding "master" page. The `add_depends` function can achieve this, if used in a **FIXME** hook. -The POT files should not be published on the wiki. - UI consistency: rename "Edit" button on slave pages --------------------------------------------------- -- cgit v1.2.3 From 52728bb6eaf71057a1b6bddc551ada1da1ea4ec4 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Sat, 11 Oct 2008 03:01:59 +0200 Subject: po plugin: bugfix (calling function in wrong module) Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index d60ade499..d3ccd37e1 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -233,7 +233,7 @@ use IkiWiki 2.00; sub match_istranslation ($;@) { #{{{ my $page=shift; - if (IkiWiki::Plugins::po::istranslation($page)) { + if (IkiWiki::Plugin::po::istranslation($page)) { return IkiWiki::SuccessReason->new("is a translation page"); } else { @@ -243,7 +243,7 @@ sub match_istranslation ($;@) { #{{{ sub match_istranslatable ($;@) { #{{{ my $page=shift; - if (IkiWiki::Plugins::po::istranslatable($page)) { + if (IkiWiki::Plugin::po::istranslatable($page)) { return IkiWiki::SuccessReason->new("is set as translatable in po_translatable_pages"); } else { -- cgit v1.2.3 From 1e874b3f0a396ba99ebf7ab8bad3d7eed1a846f2 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Sat, 11 Oct 2008 03:02:43 +0200 Subject: po plugin[filter]: avoid converting more than once per destfile Only the first filter function call on a given {page,destpage} must convert it from the PO file, subsequent calls must leave the passed $content unmodified. Else, preprocessing loops are the rule. Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index d3ccd37e1..0698b2488 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -140,16 +140,18 @@ sub tweakbestlink ($$) { #{{{ return $link; } #}}} +our %filtered; # We use filter to convert PO to the master page's type, # since other plugins should not work on PO files sub filter (@) { #{{{ my %params = @_; my $page = $params{page}; + my $destpage = $params{destpage}; my $content = decode_utf8(encode_utf8($params{content})); # decide if this is a PO file that should be converted into a translated document, # and perform various sanity checks - if (! istranslation($page)) { + if (! istranslation($page) || $filtered{$page}{$destpage}) { return $content; } @@ -174,6 +176,7 @@ sub filter (@) { #{{{ my $tmpout = $tmpfh->filename; $doc->write($tmpout) or error("[po/filter:$file] could not write $tmpout"); $content = readfile($tmpout) or error("[po/filter:$file] could not read $tmpout"); + $filtered{$page}{$destpage}=1; return $content; } #}}} -- cgit v1.2.3 From 08df9dcef78a38ceaa12d5b93442b77df4d63573 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Sat, 11 Oct 2008 03:41:12 +0200 Subject: po plugin: memoize istranslatable and _istranslation Both functions are called very often, and: - istranslatable has no side effect - _istranslation is the helper function, without any side effect, for the istranslation function Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 0698b2488..f29ad7a79 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -10,11 +10,15 @@ use IkiWiki 2.00; use Encode; use Locale::Po4a::Chooser; use File::Temp; +use Memoize; + +my %translations; +memoize("istranslatable"); +memoize("_istranslation"); sub import { hook(type => "getsetup", id => "po", call => \&getsetup); hook(type => "checkconfig", id => "po", call => \&checkconfig); - hook(type => "scan", id => "po", call => \&scan); hook(type => "targetpage", id => "po", call => \&targetpage); hook(type => "tweakurlpath", id => "po", call => \&tweakurlpath); hook(type => "tweakbestlink", id => "po", call => \&tweakbestlink); @@ -85,14 +89,6 @@ sub checkconfig () { #{{{ push @{$config{wiki_file_prune_regexps}}, qr/\.pot$/; } #}}} -sub scan (@) { #{{{ - my %params=@_; - my $page=$params{page}; - - # FIXME: cache (or memoize) the list of translatable/translation pages, - # and/or istranslation/istranslated results -} #}}} - sub targetpage (@) { #{{{ my %params = @_; my $page=$params{page}; @@ -203,7 +199,7 @@ sub istranslatable ($) { #{{{ return pagespec_match($page, $config{po_translatable_pages}); } #}}} -sub istranslation ($) { #{{{ +sub _istranslation ($) { #{{{ my $page=shift; my $file=$pagesources{$page}; if (! defined $file) { @@ -228,6 +224,16 @@ sub istranslation ($) { #{{{ return istranslatable($masterpage); } #}}} +sub istranslation ($) { #{{{ + my $page=shift; + if (_istranslation($page)) { + my ($masterpage, $lang) = ($page =~ /(.*)[.]([a-z]{2})$/); + $translations{$masterpage}{$lang}=$page unless exists $translations{$masterpage}{$lang}; + return 1; + } + return 0; +} #}}} + package IkiWiki::PageSpec; use warnings; -- cgit v1.2.3 From ae827a43f84bf18f971ff891d1d4f8d0c19b043c Mon Sep 17 00:00:00 2001 From: intrigeri Date: Mon, 13 Oct 2008 17:19:56 +0200 Subject: po plugin: build %translations at scan time ... so that we can consider it as complete at preprocess time Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 10 ++++++++++ doc/plugins/po.mdwn | 10 ---------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index f29ad7a79..e06fd5043 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -19,6 +19,7 @@ memoize("_istranslation"); sub import { hook(type => "getsetup", id => "po", call => \&getsetup); hook(type => "checkconfig", id => "po", call => \&checkconfig); + hook(type => "scan", id => "po", call => \&scan); hook(type => "targetpage", id => "po", call => \&targetpage); hook(type => "tweakurlpath", id => "po", call => \&tweakurlpath); hook(type => "tweakbestlink", id => "po", call => \&tweakbestlink); @@ -89,6 +90,15 @@ sub checkconfig () { #{{{ push @{$config{wiki_file_prune_regexps}}, qr/\.pot$/; } #}}} +sub scan (@) { #{{{ + my %params=@_; + my $page=$params{page}; + # let's build %translations, using istranslation's + # side-effect, so that we can consider it is complete at + # preprocess time + istranslation($page); +} #}}} + sub targetpage (@) { #{{{ my %params = @_; my $page=$params{page}; diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index b587c79c4..b702414c0 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -123,16 +123,6 @@ lighttpd unfortunately does not support content negotiation. TODO ==== -Optimization ------------- - -Pre-compute what can be early in the build process: - -- the list of translatable (master) pages -- for every translatable page, the list of slave pages - -... and/or memoize `istranslation`/`istranslatable` function calls. - Display available translations ------------------------------ -- cgit v1.2.3 From d39f69da7f392fb73a54b9fbeddfac497f5b824b Mon Sep 17 00:00:00 2001 From: intrigeri Date: Mon, 13 Oct 2008 17:22:49 +0200 Subject: po plugin: fix formatting in documentation Signed-off-by: intrigeri --- doc/plugins/po.mdwn | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index b702414c0..daee882ad 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -67,12 +67,12 @@ and site-specific preferences. ### Default linking behavior If `po_link_to` is unset, or set to `default`, ikiwiki's default -linking behavior is preserved: `[[page]]` links to the master +linking behavior is preserved: `\[[page]]` links to the master language's page. ### Link to negotiated language -If `po_link_to` is set to `negotiated`, `[[page]]` links to the +If `po_link_to` is set to `negotiated`, `\[[page]]` links to the negotiated preferred language, *i.e.* `foo/page/`. (In)compatibility notes: @@ -86,7 +86,7 @@ negotiated preferred language, *i.e.* `foo/page/`. ### Link to current language If `po_link_to` is set to `current` and the destination page is either -a translatable page or a translation, `[[page]]` links to the current +a translatable page or a translation, `\[[page]]` links to the current page's language, *i.e.*: - `foo/page/index.LL.html` if `usedirs` is enabled -- cgit v1.2.3 From 32cc0b336ae830831787b2024b855ed7db0a1589 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Mon, 13 Oct 2008 18:21:59 +0200 Subject: po plugin: po_slave_languages is a hash, rather than a hash of hashes The latter seems to be unsupported by ikiwiki config system. Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 8 ++++---- doc/plugins/po.mdwn | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index e06fd5043..0c95f6c14 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -45,9 +45,10 @@ sub getsetup () { #{{{ }, po_slave_languages => { type => "string", - example => {'fr' => { 'name' => 'Français' }, - 'es' => { 'name' => 'Castellano' }, - 'de' => { 'name' => 'Deutsch' }, + example => { + 'fr' => 'Français', + 'es' => 'Castellano', + 'de' => 'Deutsch' }, description => "slave languages (PO files)", safe => 1, @@ -244,7 +245,6 @@ sub istranslation ($) { #{{{ return 0; } #}}} - package IkiWiki::PageSpec; use warnings; use strict; diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index daee882ad..28b69e04b 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -41,9 +41,9 @@ Configuration `po_slave_languages` is used to set the list of supported "slave" languages, such as: - po_slave_languages => { 'fr' => { 'name' => 'Français', }, - 'es' => { 'name' => 'Castellano', }, - 'de' => { 'name' => 'Deutsch', } + po_slave_languages => { 'fr' => 'Français', + 'es' => 'Castellano', + 'de' => 'Deutsch', } Decide which pages are translatable -- cgit v1.2.3 From a28559798ad8c60e79fe80f109dd8e63204cd208 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Mon, 13 Oct 2008 22:07:21 +0200 Subject: po plugin: created OTHERLANGUAGES template loop It currently only provides basic translations/master pages links. Updated documentation accordingly. Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 44 ++++++++++++++++++++++++++++++++++++++++++++ doc/plugins/po.mdwn | 38 ++++++++++++++++++++++++++++++++------ 2 files changed, 76 insertions(+), 6 deletions(-) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 0c95f6c14..88985cd12 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -25,6 +25,7 @@ sub import { hook(type => "tweakbestlink", id => "po", call => \&tweakbestlink); hook(type => "filter", id => "po", call => \&filter); hook(type => "htmlize", id => "po", call => \&htmlize); + hook(type => "pagetemplate", id => "po", call => \&pagetemplate); } sub getsetup () { #{{{ @@ -198,6 +199,49 @@ sub htmlize (@) { #{{{ return IkiWiki::htmlize($page, $page, pagetype($masterfile), $content); } #}}} +sub otherlanguages ($) { #{{{ + my $page=shift; + my @ret; + if (istranslatable($page)) { + foreach my $lang (sort keys %{$translations{$page}}) { + push @ret, { + url => urlto($translations{$page}{$lang}, $page), + code => $lang, + language => $config{po_slave_languages}{$lang}, + master => 0, + }; + } + } + elsif (istranslation($page)) { + my ($masterpage, $curlang) = ($page =~ /(.*)[.]([a-z]{2})$/); + push @ret, { + url => urlto($masterpage, $page), + code => $config{po_master_language}{code}, + language => $config{po_master_language}{name}, + master => 1, + }; + foreach my $lang (sort keys %{$translations{$masterpage}}) { + push @ret, { + url => urlto($translations{$masterpage}{$lang}, $page), + code => $lang, + language => $config{po_slave_languages}{$lang}, + master => 0, + } unless ($lang eq $curlang); + } + } + return @ret; +} #}}} + +sub pagetemplate (@) { #{{{ + my %params=@_; + my $page=$params{page}; + my $template=$params{template}; + + if ($template->query(name => "otherlanguages")) { + $template->param(otherlanguages => [otherlanguages($page)]); + } +} # }}} + sub istranslatable ($) { #{{{ my $page=shift; my $file=$pagesources{$page}; diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index 28b69e04b..d8cde9cb8 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -93,6 +93,29 @@ page's language, *i.e.*: - `foo/page.LL.html` if `usedirs` is disabled +Templates +--------- + +The `OTHERLANGUAGES` loop provides ways to display the existing +translations and/or master page. One typically adds the following code +to `templates/page.tmpl`: + + + + + + Server support ============== @@ -123,12 +146,11 @@ lighttpd unfortunately does not support content negotiation. TODO ==== -Display available translations ------------------------------- +Link relationships +------------------ -The [[linguas|plugins/contrib/linguas]] plugin has some code that can -be used as a basis to display the existing translations, and allow to -navigate between them. +Should pages using the `OTHERLANGUAGES` template loop be declared as +linking to the same page in other versions? View translation status ----------------------- @@ -138,10 +160,14 @@ completeness, either for a given page or for the whole wiki. This should not be too hard using gettext tools. If this is implemented as a -[[HTML::Template|http://search.cpan.org/search?mode=dist&query=HTML%3A%3ATemplate]] +[HTML::Template](http://search.cpan.org/search?mode=dist&query=HTML%3A%3ATemplate) loop, a page using it should depend on any "master" and "slave" pages whose status is being displayed. +If it's not too heavy to compute, this status data may be made +available in the `OTHERLANGUAGES` template loop; else, a dedicated +loop would be needed. + Automatic PO files update ------------------------- -- cgit v1.2.3 From bd237d48cfd8b61639c2ccb41fb4ed27afde478e Mon Sep 17 00:00:00 2001 From: intrigeri Date: Tue, 14 Oct 2008 15:24:58 +0200 Subject: po plugin: build %translations in needsbuild hook rather than scan ... because we'll need this data to refresh POT/PO files in needsbuild hook Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 88985cd12..997f17fb3 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -19,7 +19,7 @@ memoize("_istranslation"); sub import { hook(type => "getsetup", id => "po", call => \&getsetup); hook(type => "checkconfig", id => "po", call => \&checkconfig); - hook(type => "scan", id => "po", call => \&scan); + hook(type => "needsbuild", id => "po", call => \&needsbuild); hook(type => "targetpage", id => "po", call => \&targetpage); hook(type => "tweakurlpath", id => "po", call => \&tweakurlpath); hook(type => "tweakbestlink", id => "po", call => \&tweakbestlink); @@ -92,13 +92,14 @@ sub checkconfig () { #{{{ push @{$config{wiki_file_prune_regexps}}, qr/\.pot$/; } #}}} -sub scan (@) { #{{{ - my %params=@_; - my $page=$params{page}; - # let's build %translations, using istranslation's - # side-effect, so that we can consider it is complete at - # preprocess time - istranslation($page); +sub needsbuild () { #{{{ + my $needsbuild=shift; + + # build %translations, using istranslation's side-effect + foreach my $page (keys %pagesources) { + istranslation($page); + } + } #}}} sub targetpage (@) { #{{{ -- cgit v1.2.3 From d5b5cfb8e42b7fed8a2a777c542461c0bcebf5ea Mon Sep 17 00:00:00 2001 From: intrigeri Date: Tue, 14 Oct 2008 16:36:01 +0200 Subject: po plugin: refresh POT files when a master page is updated Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 997f17fb3..1cab44dde 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -9,6 +9,8 @@ use strict; use IkiWiki 2.00; use Encode; use Locale::Po4a::Chooser; +use File::Basename; +use File::Spec; use File::Temp; use Memoize; @@ -92,6 +94,20 @@ sub checkconfig () { #{{{ push @{$config{wiki_file_prune_regexps}}, qr/\.pot$/; } #}}} +sub refreshpot ($) { #{{{ + my $masterfile=shift; + (my $name, my $dir, my $suffix) = fileparse($masterfile, qr/\.[^.]*/); + my $potfile=File::Spec->catfile($dir, $name . ".pot"); + my %options = ("markdown" => (pagetype($masterfile) eq 'mdwn') ? 1 : 0); + my $doc=Locale::Po4a::Chooser::new('text',%options); + $doc->read($masterfile); + $doc->{TT}{utf_mode} = 1; + $doc->{TT}{file_in_charset} = 'utf-8'; + $doc->{TT}{file_out_charset} = 'utf-8'; + $doc->parse or error("[po/refreshpot:$masterfile]: failed to parse"); + $doc->writepo($potfile); +} #}}} + sub needsbuild () { #{{{ my $needsbuild=shift; @@ -100,6 +116,9 @@ sub needsbuild () { #{{{ istranslation($page); } + foreach my $file (@$needsbuild) { + refreshpot(srcfile($file)) if (istranslatable(pagename($file))); + } } #}}} sub targetpage (@) { #{{{ -- cgit v1.2.3 From 6424d748a4da431c244d0775d4d4e839fdd3f671 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Tue, 14 Oct 2008 17:17:24 +0200 Subject: po plugin: refresh PO files when a master page is updated Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 1cab44dde..900ca90e4 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -10,6 +10,7 @@ use IkiWiki 2.00; use Encode; use Locale::Po4a::Chooser; use File::Basename; +use File::Copy; use File::Spec; use File::Temp; use Memoize; @@ -108,6 +109,27 @@ sub refreshpot ($) { #{{{ $doc->writepo($potfile); } #}}} +sub refreshpofiles ($@) { #{{{ + my $masterfile=shift; + my @pofiles=@_; + + (my $name, my $dir, my $suffix) = fileparse($masterfile, qr/\.[^.]*/); + my $potfile=File::Spec->catfile($dir, $name . ".pot"); + error("[po/refreshpofiles] POT file ($potfile) does not exist") unless (-e $potfile); + + foreach my $pofile (@pofiles) { + if (-e $pofile) { + my $cmd = "msgmerge -U $pofile $potfile"; + system ($cmd) == 0 + or error("[po/refreshpofiles:$pofile] failed to update"); + } + else { + File::Copy::syscopy($potfile,$pofile) + or error("[po/refreshpofiles:$pofile] failed to copy the POT file"); + } + } +} #}}} + sub needsbuild () { #{{{ my $needsbuild=shift; @@ -117,7 +139,13 @@ sub needsbuild () { #{{{ } foreach my $file (@$needsbuild) { - refreshpot(srcfile($file)) if (istranslatable(pagename($file))); + my $page=pagename($file); + refreshpot(srcfile($file)) if (istranslatable($page)); + my @pofiles; + foreach my $lang (keys %{$translations{$page}}) { + push @pofiles, $pagesources{$translations{$page}{$lang}}; + } + refreshpofiles(srcfile($file), map { srcfile($_) } @pofiles); } } #}}} -- cgit v1.2.3 From 37222492a534868c8cafc450f8d32bab4770f29a Mon Sep 17 00:00:00 2001 From: intrigeri Date: Tue, 14 Oct 2008 17:21:03 +0200 Subject: po plugin: updated doc to reflect current status of automatic PO files update Signed-off-by: intrigeri --- doc/plugins/po.mdwn | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index d8cde9cb8..e114e34fa 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -173,21 +173,14 @@ Automatic PO files update Committing changes to a "master" page must: -1. update the POT file and the PO files for the supported languages, - before putting them under version control -2. trigger a refresh of the corresponding HTML slave pages - -The former is to be done at a time when: - -- we know which "master" page was modified, and thus, which POT/PO - files have to be updated: the `needsbuild` hook is the first one to - run that provides us with the necessary information -- we can modify the list of pages needing a refresh; this is - `needsbuild` hook's job - -The latter can be implemented by making any "slave" page depend on the -corresponding "master" page. The `add_depends` function can achieve -this, if used in a **FIXME** hook. +1. update the POT file and the PO files for the supported languages; + this is done in the `needsbuild` hook; the updated PO files must + then be put under version control + +2. trigger a refresh of the corresponding HTML slave pages; this can + be implemented by making any "slave" page depend on the + corresponding "master" page. The `add_depends` function can achieve + this, if used in a **FIXME** hook. UI consistency: rename "Edit" button on slave pages --------------------------------------------------- -- cgit v1.2.3 From 9332457e6c9fb6699181c1b890d0045bd11ef88d Mon Sep 17 00:00:00 2001 From: intrigeri Date: Tue, 14 Oct 2008 23:54:26 +0200 Subject: po plugin: todo++: create POT/PO when the plugin is enabled Signed-off-by: intrigeri --- doc/plugins/po.mdwn | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index e114e34fa..6b04afd72 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -182,6 +182,9 @@ Committing changes to a "master" page must: corresponding "master" page. The `add_depends` function can achieve this, if used in a **FIXME** hook. +Also, when the plugin has just been enabled, all the needed POT and PO +files have to be created. + UI consistency: rename "Edit" button on slave pages --------------------------------------------------- -- cgit v1.2.3 From dc74c8e5770a1b1df02a001e5c8ffd5cf1325252 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Tue, 14 Oct 2008 23:55:46 +0200 Subject: po plugin: do not trust po4a functions return value Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 900ca90e4..42391089b 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -105,7 +105,7 @@ sub refreshpot ($) { #{{{ $doc->{TT}{utf_mode} = 1; $doc->{TT}{file_in_charset} = 'utf-8'; $doc->{TT}{file_out_charset} = 'utf-8'; - $doc->parse or error("[po/refreshpot:$masterfile]: failed to parse"); + $doc->parse; $doc->writepo($potfile); } #}}} -- cgit v1.2.3 From a8e8613fa11c1ac0b0f82e159df97d0837ae97e5 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Tue, 14 Oct 2008 23:58:21 +0200 Subject: po plugin: bugfix - only refresh POT/PO for translatable pages Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 42391089b..ca26101b7 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -138,14 +138,17 @@ sub needsbuild () { #{{{ istranslation($page); } + # refresh POT and PO files as needed foreach my $file (@$needsbuild) { my $page=pagename($file); - refreshpot(srcfile($file)) if (istranslatable($page)); - my @pofiles; - foreach my $lang (keys %{$translations{$page}}) { - push @pofiles, $pagesources{$translations{$page}{$lang}}; + if (istranslatable($page)) { + refreshpot(srcfile($file)); + my @pofiles; + foreach my $lang (keys %{$translations{$page}}) { + push @pofiles, $pagesources{$translations{$page}{$lang}}; + } + refreshpofiles(srcfile($file), map { srcfile($_) } @pofiles); } - refreshpofiles(srcfile($file), map { srcfile($_) } @pofiles); } } #}}} -- cgit v1.2.3 From d4f787ef528d9947473b4b99d1088b647d615200 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Wed, 15 Oct 2008 00:05:52 +0200 Subject: po plugin: make any slave page dependent on the corresponding master page Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 7 +++++++ doc/plugins/po.mdwn | 7 +++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index ca26101b7..5abe9d419 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -150,6 +150,13 @@ sub needsbuild () { #{{{ refreshpofiles(srcfile($file), map { srcfile($_) } @pofiles); } } + + # make existing translations depend on the corresponding master page + foreach my $master (keys %translations) { + foreach my $slave (values %{$translations{$master}}) { + add_depends($slave, $master); + } + } } #}}} sub targetpage (@) { #{{{ diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index 6b04afd72..06ecedc24 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -177,10 +177,9 @@ Committing changes to a "master" page must: this is done in the `needsbuild` hook; the updated PO files must then be put under version control -2. trigger a refresh of the corresponding HTML slave pages; this can - be implemented by making any "slave" page depend on the - corresponding "master" page. The `add_depends` function can achieve - this, if used in a **FIXME** hook. +2. trigger a refresh of the corresponding HTML slave pages: this is + achieved by making any "slave" page dependent on the corresponding + "master" page, in the `needsbuild` hook. Also, when the plugin has just been enabled, all the needed POT and PO files have to be created. -- cgit v1.2.3 From 27bfe18f51b717128b2d920bdfab2516dd8d6ac8 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Wed, 15 Oct 2008 00:10:32 +0200 Subject: po plugin: updated todo wrt. automatic POT/PO update/creation Signed-off-by: intrigeri --- doc/plugins/po.mdwn | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index 06ecedc24..9ae6d964a 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -171,18 +171,20 @@ loop would be needed. Automatic PO files update ------------------------- -Committing changes to a "master" page must: +Committing changes to a "master" page: -1. update the POT file and the PO files for the supported languages; - this is done in the `needsbuild` hook; the updated PO files must - then be put under version control +1. updates the POT file and the PO files for the supported languages; + this is done in the `needsbuild` hook; **FIXME**: the updated PO + files must then be put under version control -2. trigger a refresh of the corresponding HTML slave pages: this is +2. triggers a refresh of the corresponding HTML slave pages: this is achieved by making any "slave" page dependent on the corresponding "master" page, in the `needsbuild` hook. -Also, when the plugin has just been enabled, all the needed POT and PO -files have to be created. +**FIXME** Also, when the plugin has just been enabled: + +- all the needed POT and PO files have to be created +- the PO files must be checked into version control UI consistency: rename "Edit" button on slave pages --------------------------------------------------- -- cgit v1.2.3 From d07c6b707da7c22d6b744b8cf50e306766e11ba9 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Wed, 15 Oct 2008 00:34:25 +0200 Subject: po plugin: todo++ : security note about system() Signed-off-by: intrigeri --- doc/plugins/po.mdwn | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index 9ae6d964a..044a165b3 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -186,6 +186,10 @@ Committing changes to a "master" page: - all the needed POT and PO files have to be created - the PO files must be checked into version control +**FIXME** `refreshpofiles` uses `system()`, whose args have to be +checked more thoroughly to prevent any security issue (command +injection, etc.). + UI consistency: rename "Edit" button on slave pages --------------------------------------------------- -- cgit v1.2.3 From ce9db8989655a71bba32159e0a342acc67a6451b Mon Sep 17 00:00:00 2001 From: intrigeri Date: Wed, 15 Oct 2008 00:35:17 +0200 Subject: po plugin: added lang() custom PageSpec function Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 5abe9d419..05e57fab4 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -372,4 +372,26 @@ sub match_istranslatable ($;@) { #{{{ } } #}}} +sub match_lang ($$;@) { #{{{ + my $page=shift; + my $wanted=shift; + my $regexp=IkiWiki::glob2re($wanted); + my $lang; + my $masterpage; + + if (IkiWiki::Plugin::po::istranslation($page)) { + ($masterpage, $lang) = ($page =~ /(.*)[.]([a-z]{2})$/); + } + else { + $lang = $config{po_master_language}{code}; + } + + if ($lang!~/^$regexp$/i) { + return IkiWiki::FailReason->new("file language is $lang, not $wanted"); + } + else { + return IkiWiki::SuccessReason->new("file language is $wanted"); + } +} #}}} + 1 -- cgit v1.2.3 From 6f858cd59f6bb0734da499b88f385fb6a61ac48e Mon Sep 17 00:00:00 2001 From: intrigeri Date: Wed, 15 Oct 2008 01:05:22 +0200 Subject: po plugin: todo update wrt. newly translatable pages Signed-off-by: intrigeri --- doc/plugins/po.mdwn | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index 044a165b3..97981544d 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -181,7 +181,8 @@ Committing changes to a "master" page: achieved by making any "slave" page dependent on the corresponding "master" page, in the `needsbuild` hook. -**FIXME** Also, when the plugin has just been enabled: +**FIXME** Also, when the plugin has just been enabled, or when a page +has just been declared as being translatable: - all the needed POT and PO files have to be created - the PO files must be checked into version control -- cgit v1.2.3 From 886731612504bd4ac70244497b3313a20b7b6049 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Wed, 15 Oct 2008 01:23:19 +0200 Subject: po plugin: added currentlang() custom PageSpec function Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 05e57fab4..aa592989b 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -394,4 +394,34 @@ sub match_lang ($$;@) { #{{{ } } #}}} +sub match_currentlang ($$;@) { #{{{ + my $page=shift; + shift; + my %params=@_; + my ($currentmasterpage, $currentlang, $masterpage, $lang); + + return IkiWiki::FailReason->new("no location provided") unless exists $params{location}; + + if (IkiWiki::Plugin::po::istranslation($params{location})) { + ($currentmasterpage, $currentlang) = ($params{location} =~ /(.*)[.]([a-z]{2})$/); + } + else { + $currentlang = $config{po_master_language}{code}; + } + + if (IkiWiki::Plugin::po::istranslation($page)) { + ($masterpage, $lang) = ($page =~ /(.*)[.]([a-z]{2})$/); + } + else { + $lang = $config{po_master_language}{code}; + } + + if ($lang eq $currentlang) { + return IkiWiki::SuccessReason->new("file language is the same as current one, i.e. $currentlang"); + } + else { + return IkiWiki::FailReason->new("file language is $lang, whereas current language is $currentlang"); + } +} #}}} + 1 -- cgit v1.2.3 From d8c28006748ffe6037104bba4c040b2850cd8402 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Wed, 15 Oct 2008 01:25:01 +0200 Subject: po plugin: documented custom PageSpec tests, reorganized doc a bit Signed-off-by: intrigeri --- doc/ikiwiki/pagespec/po.mdwn | 16 +++++++++++ doc/plugins/po.mdwn | 65 ++++++++++++++++++++++---------------------- 2 files changed, 48 insertions(+), 33 deletions(-) create mode 100644 doc/ikiwiki/pagespec/po.mdwn diff --git a/doc/ikiwiki/pagespec/po.mdwn b/doc/ikiwiki/pagespec/po.mdwn new file mode 100644 index 000000000..2edfaa0c1 --- /dev/null +++ b/doc/ikiwiki/pagespec/po.mdwn @@ -0,0 +1,16 @@ +[[!if test="enabled(po)" + then="This wiki has po support **enabled**." + else="This wiki has po support **disabled**."]] + +If the [[po|plugins/po]] plugin is enabled, the regular +[[ikiwiki/PageSpec]] syntax is expanded with the following additional +tests that can be used to improve user navigation in a multi-lingual +wiki: + +* "`lang(LL)`" - Tests whether a page is written in the language + specified as a ISO639-1 (two-letter) language code. +* "`currentlang()`" - Tests whether a page is written in the same + language as the current page. + +Note: every non-PO page is considered to be written in +`po_master_language`, as specified in `ikiwiki.setup`. diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index 97981544d..64d22d34c 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -93,29 +93,6 @@ page's language, *i.e.*: - `foo/page.LL.html` if `usedirs` is disabled -Templates ---------- - -The `OTHERLANGUAGES` loop provides ways to display the existing -translations and/or master page. One typically adds the following code -to `templates/page.tmpl`: - - - - - - Server support ============== @@ -143,6 +120,38 @@ lighttpd unfortunately does not support content negotiation. emulate this? +Usage +===== + +Templates +--------- + +The `OTHERLANGUAGES` loop provides ways to display the existing +translations and/or master page. One typically adds the following code +to `templates/page.tmpl`: + + + + + +Additional PageSpec tests +------------------------- + +This plugin enhances the regular [[ikiwiki/PageSpec]] syntax with some +additional tests that are documented [[here|ikiwiki/pagespec/po]]. + + TODO ==== @@ -199,16 +208,6 @@ page, to end up editing a strange looking PO file. The *Edit* button displayed on "slave" pages must therefore be renamed *Improve translation* . -Pages selection depending on language -------------------------------------- - -To improve user navigation in a multi-lingual wiki, site developers -must be enabled to write: - - \[[!map pages="dev/* and lang(LL)" feeds="no"]] - - \[[!map pages="dev/* and currentlang()" feeds="no"]] - Translation quality assurance ----------------------------- -- cgit v1.2.3 From 1a670d3aca228fb9baed05890b175ef9aed9b102 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Wed, 15 Oct 2008 02:13:56 +0200 Subject: po plugin: make translation percentage available in OTHERLANGUAGES loop Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 31 +++++++++++++++++++++++++++---- doc/plugins/po.mdwn | 23 ++++++++++++++++------- 2 files changed, 43 insertions(+), 11 deletions(-) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index aa592989b..eee6d4058 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -237,7 +237,6 @@ sub filter (@) { #{{{ 'file_in_charset' => 'utf-8', 'file_out_charset' => 'utf-8', ) or error("[po/filter:$file]: failed to translate"); - my ($percent,$hit,$queries) = $doc->stats(); my $tmpfh = File::Temp->new(TEMPLATE => "/tmp/ikiwiki-po-filter-out.XXXXXXXXXX"); my $tmpout = $tmpfh->filename; $doc->write($tmpout) or error("[po/filter:$file] could not write $tmpout"); @@ -257,16 +256,40 @@ sub htmlize (@) { #{{{ return IkiWiki::htmlize($page, $page, pagetype($masterfile), $content); } #}}} +sub percenttranslated ($) { #{{{ + my $page=shift; + return "N/A" unless (istranslation($page)); + my ($masterpage, $lang) = ($page =~ /(.*)[.]([a-z]{2})$/); + my $file=srcfile($pagesources{$page}); + my $masterfile = srcfile($pagesources{$masterpage}); + my (@pos,@masters); + push @pos,$file; + push @masters,$masterfile; + my %options = ( + "markdown" => (pagetype($masterfile) eq 'mdwn') ? 1 : 0, + ); + my $doc=Locale::Po4a::Chooser::new('text',%options); + $doc->process( + 'po_in_name' => \@pos, + 'file_in_name' => \@masters, + 'file_in_charset' => 'utf-8', + 'file_out_charset' => 'utf-8', + ) or error("[po/percenttranslated:$file]: failed to translate"); + my ($percent,$hit,$queries) = $doc->stats(); + return $percent; +} #}}} + sub otherlanguages ($) { #{{{ my $page=shift; my @ret; if (istranslatable($page)) { foreach my $lang (sort keys %{$translations{$page}}) { + my $translation = $translations{$page}{$lang}; push @ret, { - url => urlto($translations{$page}{$lang}, $page), + url => urlto($translation, $page), code => $lang, language => $config{po_slave_languages}{$lang}, - master => 0, + percent => percenttranslated($translation), }; } } @@ -283,7 +306,7 @@ sub otherlanguages ($) { #{{{ url => urlto($translations{$masterpage}{$lang}, $page), code => $lang, language => $config{po_slave_languages}{$lang}, - master => 0, + percent => percenttranslated($page), } unless ($lang eq $curlang); } } diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index 64d22d34c..ab37ae419 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -126,25 +126,34 @@ Usage Templates --------- -The `OTHERLANGUAGES` loop provides ways to display the existing -translations and/or master page. One typically adds the following code -to `templates/page.tmpl`: +The `OTHERLANGUAGES` loop provides ways to display other languages' +versions of the same page, and the translations' status. + +One typically adds the following code to `templates/page.tmpl`: +The following variables are available inside the loop (for every page in): + +- `URL` - url to the page +- `CODE` - two-letters language code +- `LANGUAGE` - language name (as defined in `po_slave_languages`) +- `MASTER` - is true (1) if, and only if the page is a "master" page +- `PERCENT` - for "slave" pages, is set to the translation completeness, in percents + Additional PageSpec tests ------------------------- -- cgit v1.2.3 From 6add615928581ddacd03b01de126fb098d1a8eda Mon Sep 17 00:00:00 2001 From: intrigeri Date: Wed, 15 Oct 2008 02:25:34 +0200 Subject: po plugin: added and documented PERCENTTRANSLATED template variable Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 4 ++++ doc/plugins/po.mdwn | 34 +++++++++++++++------------------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index eee6d4058..98c070481 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -18,6 +18,7 @@ use Memoize; my %translations; memoize("istranslatable"); memoize("_istranslation"); +memoize("percenttranslated"); sub import { hook(type => "getsetup", id => "po", call => \&getsetup); @@ -318,6 +319,9 @@ sub pagetemplate (@) { #{{{ my $page=$params{page}; my $template=$params{template}; + if (istranslation($page) && $template->query(name => "percenttranslated")) { + $template->param(percenttranslated => percenttranslated($page)); + } if ($template->query(name => "otherlanguages")) { $template->param(otherlanguages => [otherlanguages($page)]); } diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index ab37ae419..02e6ca766 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -126,6 +126,8 @@ Usage Templates --------- +### Display page's versions in other languages + The `OTHERLANGUAGES` loop provides ways to display other languages' versions of the same page, and the translations' status. @@ -154,6 +156,11 @@ The following variables are available inside the loop (for every page in): - `MASTER` - is true (1) if, and only if the page is a "master" page - `PERCENT` - for "slave" pages, is set to the translation completeness, in percents +### Display the current translation status + +The `PERCENTTRANSLATED` variable is set to the translation +completeness, expressed in percent, on "slave" pages. + Additional PageSpec tests ------------------------- @@ -164,27 +171,16 @@ additional tests that are documented [[here|ikiwiki/pagespec/po]]. TODO ==== -Link relationships ------------------- +OTHERLANGUAGES dependencies +--------------------------- -Should pages using the `OTHERLANGUAGES` template loop be declared as -linking to the same page in other versions? +Pages using `OTHERLANGUAGES` must depend on any "master" and "slave" +pages whose status is being displayed. It will trigger dependency +loops; how to sort this out? -View translation status ------------------------ - -One should be able to view some information about the translation -completeness, either for a given page or for the whole wiki. - -This should not be too hard using gettext tools. If this is -implemented as a -[HTML::Template](http://search.cpan.org/search?mode=dist&query=HTML%3A%3ATemplate) -loop, a page using it should depend on any "master" and "slave" pages -whose status is being displayed. - -If it's not too heavy to compute, this status data may be made -available in the `OTHERLANGUAGES` template loop; else, a dedicated -loop would be needed. +Should pages using the `OTHERLANGUAGES` template loop be declared as +linking to the same page in other versions? To be rigorous, they +should, but this may clutter the backlinks. Automatic PO files update ------------------------- -- cgit v1.2.3 From f42cf38076ab8fe6dcf6d9695f0950ccb61fbc01 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Wed, 15 Oct 2008 02:42:08 +0200 Subject: po plugin: documentation work Signed-off-by: intrigeri --- doc/plugins/po.mdwn | 70 ++++++++++++++++++++++++----------------------------- 1 file changed, 32 insertions(+), 38 deletions(-) diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index 02e6ca766..4e7553a11 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -12,9 +12,9 @@ Introduction A language is chosen as the "master" one, and any other supported language is a "slave" one. -A page written in the "master" language is a "master" page, and is -written in any supported format but PO. It does not have to be named -a special way: migration from/to this plugin does not imply heavy +A page written in the "master" language is a "master" page. It can be +of any page type supported by ikiwiki, but PO. It does not have to be +named a special way: migration to this plugin does not imply any page renaming work. Example: `bla/page.mdwn` is a "master" Markdown page written in @@ -33,7 +33,10 @@ rendered as `bla/page/index.fr.html`, else as `bla/page.fr.html` Configuration ============= -`po_master_language` is used to set the master language in +Supported languages +------------------- + +`po_master_language` is used to set the "master" language in `ikiwiki.setup`, such as: po_master_language => { 'code' => 'en', 'name' => 'English' } @@ -53,23 +56,32 @@ The `po_translatable_pages` setting configures what pages are translatable. It is a [[ikiwiki/PageSpec]], so you have lots of control over what kind of pages are translatable. -The `*.LL.po` translations files are anyway not considered as being -translatable, so you don't need to worry about excluding them manually -from this [[ikiwiki/PageSpec]]. +The PO translations files are anyway not considered as being +translatable, so you don't need to worry about excluding them +explicitly from this [[ikiwiki/PageSpec]]. Internal links -------------- -One can use the `po_link_to_` option in `ikiwiki.setup` to choose how +The `po_link_to` option in `ikiwiki.setup` is used to decide how internal links should be generated, depending on web server features and site-specific preferences. ### Default linking behavior If `po_link_to` is unset, or set to `default`, ikiwiki's default -linking behavior is preserved: `\[[page]]` links to the master +linking behavior is preserved: `\[[destpage]]` links to the master language's page. +### Link to current language + +If `po_link_to` is set to `current`, `\[[destpage]]` links to the +`destpage`'s version written in the current page's language, if +available, *i.e.*: + +- `foo/destpage/index.LL.html` if `usedirs` is enabled +- `foo/destpage.LL.html` if `usedirs` is disabled + ### Link to negotiated language If `po_link_to` is set to `negotiated`, `\[[page]]` links to the @@ -77,20 +89,11 @@ negotiated preferred language, *i.e.* `foo/page/`. (In)compatibility notes: -- `po_link_to => negotiated` provides no useful behavior if `usedirs` - is disabled; this option combination is neither implemented nor - allowed -- `po_link_to => negotiated` provides no useful behavior if the web - server does not support Content Negotiation - -### Link to current language - -If `po_link_to` is set to `current` and the destination page is either -a translatable page or a translation, `\[[page]]` links to the current -page's language, *i.e.*: - -- `foo/page/index.LL.html` if `usedirs` is enabled -- `foo/page.LL.html` if `usedirs` is disabled +- if `usedirs` is disabled, it does not make sense to set `po_link_to` + to `negotiated`; this option combination is neither implemented + nor allowed. +- if the web server does not support Content Negotiation, setting + `po_link_to` to `negotiated` will produce a unusable website. Server support @@ -99,17 +102,16 @@ Server support Apache ------ -Using `mod_negotiation` makes it really easy to have Apache serve the -page in the client's preferred language, if available. This is the -default Debian Apache configuration. +Using Apache `mod_negotiation` makes it really easy to have Apache +serve any page in the client's preferred language, if available. +This is the default Debian Apache configuration. When `usedirs` is enabled, one has to set `DirectoryIndex index` for the wiki context. Setting `DefaultLanguage LL` (replace `LL` with your default MIME -language) for the wiki context can be needed, to ensure +language code) for the wiki context can help to ensure `bla/page/index.en.html` is served as `Content-Language: LL`. -**FIXME**: is it still needed with the new `.en.html` naming convention? lighttpd -------- @@ -205,19 +207,11 @@ has just been declared as being translatable: checked more thoroughly to prevent any security issue (command injection, etc.). -UI consistency: rename "Edit" button on slave pages ---------------------------------------------------- - -It may be surprising to some, after having pressed *Edit* on a wiki -page, to end up editing a strange looking PO file. The *Edit* button -displayed on "slave" pages must therefore be renamed *Improve -translation* . - Translation quality assurance ----------------------------- -Modifying a PO file via the CGI must only be allowed if the new -version is a valid PO file. As a bonus, check that it provides a more +Modifying a PO file via the CGI must be forbidden if the new version +is not a valid PO file. As a bonus, check that it provides a more complete translation than the existing one. A new `cansave` type of hook would be needed to implement this. -- cgit v1.2.3 From 58c77a01f79efaa5692fd30231695c6f8775a7d9 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Wed, 15 Oct 2008 05:22:41 +0200 Subject: po plugin: create missing POT/PO files in needsbuild hook Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 39 ++++++++++++++++++++++++++++----------- doc/plugins/po.mdwn | 6 +++--- 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 98c070481..43b36430f 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -96,10 +96,22 @@ sub checkconfig () { #{{{ push @{$config{wiki_file_prune_regexps}}, qr/\.pot$/; } #}}} -sub refreshpot ($) { #{{{ +sub potfile ($) { #{{{ + my $masterfile=shift; + (my $name, my $dir, my $suffix) = fileparse($masterfile, qr/\.[^.]*/); + return File::Spec->catfile($dir, $name . ".pot"); +} #}}} + +sub pofile ($$) { #{{{ my $masterfile=shift; + my $lang=shift; (my $name, my $dir, my $suffix) = fileparse($masterfile, qr/\.[^.]*/); - my $potfile=File::Spec->catfile($dir, $name . ".pot"); + return File::Spec->catfile($dir, $name . "." . $lang . ".po"); +} #}}} + +sub refreshpot ($) { #{{{ + my $masterfile=shift; + my $potfile=potfile($masterfile); my %options = ("markdown" => (pagetype($masterfile) eq 'mdwn') ? 1 : 0); my $doc=Locale::Po4a::Chooser::new('text',%options); $doc->read($masterfile); @@ -114,8 +126,7 @@ sub refreshpofiles ($@) { #{{{ my $masterfile=shift; my @pofiles=@_; - (my $name, my $dir, my $suffix) = fileparse($masterfile, qr/\.[^.]*/); - my $potfile=File::Spec->catfile($dir, $name . ".pot"); + my $potfile=potfile($masterfile); error("[po/refreshpofiles] POT file ($potfile) does not exist") unless (-e $potfile); foreach my $pofile (@pofiles) { @@ -139,16 +150,22 @@ sub needsbuild () { #{{{ istranslation($page); } - # refresh POT and PO files as needed - foreach my $file (@$needsbuild) { - my $page=pagename($file); + # refresh/create POT and PO files as needed + foreach my $page (keys %pagesources) { + my $pageneedsbuild = grep { $_ eq $pagesources{$page} } @$needsbuild; if (istranslatable($page)) { - refreshpot(srcfile($file)); + my $file=srcfile($pagesources{$page}); + if ($pageneedsbuild || ! -e potfile($file)) { + refreshpot($file); + } my @pofiles; - foreach my $lang (keys %{$translations{$page}}) { - push @pofiles, $pagesources{$translations{$page}{$lang}}; + foreach my $lang (keys %{$config{po_slave_languages}}) { + my $pofile=pofile($file, $lang); + if ($pageneedsbuild || ! -e $pofile) { + push @pofiles, $pofile; + } } - refreshpofiles(srcfile($file), map { srcfile($_) } @pofiles); + refreshpofiles($file, @pofiles) if (@pofiles); } } diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index 4e7553a11..ab7fcb725 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -197,11 +197,11 @@ Committing changes to a "master" page: achieved by making any "slave" page dependent on the corresponding "master" page, in the `needsbuild` hook. -**FIXME** Also, when the plugin has just been enabled, or when a page +Also, when the plugin has just been enabled, or when a page has just been declared as being translatable: -- all the needed POT and PO files have to be created -- the PO files must be checked into version control +- all the needed POT and PO files are be created +- **FIXME** the PO files must be checked into version control **FIXME** `refreshpofiles` uses `system()`, whose args have to be checked more thoroughly to prevent any security issue (command -- cgit v1.2.3 From 1e69eb482fdb30971c15a52b93ce6803175aca37 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Wed, 15 Oct 2008 05:27:28 +0200 Subject: po plugin: rebuild %translations after having created missing POT/PO files This is not needed yet, but when newly created POT/PO files are added to %pagesources and other data structures, we'll need this. Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 43b36430f..62a2aa3db 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -169,6 +169,14 @@ sub needsbuild () { #{{{ } } + # refresh %translations, using istranslation's side-effect + # (not needed yet, but when newly created POT/PO files are + # added to %pagesources and other data structures, we'll need + # this) + foreach my $page (keys %pagesources) { + istranslation($page); + } + # make existing translations depend on the corresponding master page foreach my $master (keys %translations) { foreach my $slave (values %{$translations{$master}}) { -- cgit v1.2.3 From c852203be808131ce5f9bbc376b04e76e3e82c8d Mon Sep 17 00:00:00 2001 From: intrigeri Date: Wed, 15 Oct 2008 05:36:24 +0200 Subject: po plugin: todo++ more security checks needed ... when creating new files. Signed-off-by: intrigeri --- doc/plugins/po.mdwn | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index ab7fcb725..717685df3 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -203,9 +203,12 @@ has just been declared as being translatable: - all the needed POT and PO files are be created - **FIXME** the PO files must be checked into version control -**FIXME** `refreshpofiles` uses `system()`, whose args have to be -checked more thoroughly to prevent any security issue (command -injection, etc.). +Security checks: + +- `refreshpofiles` uses `system()`, whose args have to be checked more + thoroughly to prevent any security issue (command injection, etc.). +- `refreshpofiles` and `refreshpot` create new files; this may need + some checks, e.g. using `IkiWiki::prep_writefile()` Translation quality assurance ----------------------------- -- cgit v1.2.3 From 1d767625178380c6b760b9ea4bb41a11a7c95d53 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Wed, 15 Oct 2008 06:47:06 +0200 Subject: po plugin: initial implementation of automatic POT/PO update The updated or created PO files are put under version control. Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 23 +++++++++++++++++++++-- doc/plugins/po.mdwn | 37 +++++++++++++++++-------------------- 2 files changed, 38 insertions(+), 22 deletions(-) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 62a2aa3db..1dcec7bec 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -16,6 +16,7 @@ use File::Temp; use Memoize; my %translations; +our %filtered; memoize("istranslatable"); memoize("_istranslation"); memoize("percenttranslated"); @@ -151,6 +152,7 @@ sub needsbuild () { #{{{ } # refresh/create POT and PO files as needed + my $updated_po_files=0; foreach my $page (keys %pagesources) { my $pageneedsbuild = grep { $_ eq $pagesources{$page} } @$needsbuild; if (istranslatable($page)) { @@ -165,8 +167,26 @@ sub needsbuild () { #{{{ push @pofiles, $pofile; } } - refreshpofiles($file, @pofiles) if (@pofiles); + if (@pofiles) { + refreshpofiles($file, @pofiles) ; + map { IkiWiki::rcs_add($_); } @pofiles if ($config{rcs}); + $updated_po_files = 1; + } + } + } + + # check staged changes in and trigger a wiki refresh. + if ($updated_po_files) { + if ($config{rcs}) { + IkiWiki::disable_commit_hook(); + IkiWiki::rcs_commit_staged(gettext("updated PO files"), + "refreshpofiles", "127.0.0.1"); + IkiWiki::enable_commit_hook(); + IkiWiki::rcs_update(); } + IkiWiki::refresh(); + IkiWiki::saveindex(); + %filtered=undef; } # refresh %translations, using istranslation's side-effect @@ -232,7 +252,6 @@ sub tweakbestlink ($$) { #{{{ return $link; } #}}} -our %filtered; # We use filter to convert PO to the master page's type, # since other plugins should not work on PO files sub filter (@) { #{{{ diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index 717685df3..2c46a80ed 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -169,6 +169,21 @@ Additional PageSpec tests This plugin enhances the regular [[ikiwiki/PageSpec]] syntax with some additional tests that are documented [[here|ikiwiki/pagespec/po]]. +Automatic PO files update +------------------------- + +Committing changes to a "master" page: + +1. updates the POT file and the PO files for the supported languages + (this is done in the `needsbuild` hook); the updated PO files are + then put under version control +2. triggers a refresh of the corresponding HTML slave pages (this is + achieved by making any "slave" page dependent on the corresponding + "master" page, in the `needsbuild` hook) + +Also, when the plugin has just been enabled, or when a page has just +been declared as being translatable, the needed POT and PO files are +created, and the PO files are checked into version control. TODO ==== @@ -184,26 +199,8 @@ Should pages using the `OTHERLANGUAGES` template loop be declared as linking to the same page in other versions? To be rigorous, they should, but this may clutter the backlinks. -Automatic PO files update -------------------------- - -Committing changes to a "master" page: - -1. updates the POT file and the PO files for the supported languages; - this is done in the `needsbuild` hook; **FIXME**: the updated PO - files must then be put under version control - -2. triggers a refresh of the corresponding HTML slave pages: this is - achieved by making any "slave" page dependent on the corresponding - "master" page, in the `needsbuild` hook. - -Also, when the plugin has just been enabled, or when a page -has just been declared as being translatable: - -- all the needed POT and PO files are be created -- **FIXME** the PO files must be checked into version control - -Security checks: +Security checks +--------------- - `refreshpofiles` uses `system()`, whose args have to be checked more thoroughly to prevent any security issue (command injection, etc.). -- cgit v1.2.3 From 1aad01f841be86bacaa0f055fc10abcad994bb3b Mon Sep 17 00:00:00 2001 From: intrigeri Date: Wed, 15 Oct 2008 07:06:35 +0200 Subject: po plugin: bugfix (OTHERLANGUAGES) Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 1dcec7bec..716aa9151 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -351,7 +351,7 @@ sub otherlanguages ($) { #{{{ url => urlto($translations{$masterpage}{$lang}, $page), code => $lang, language => $config{po_slave_languages}{$lang}, - percent => percenttranslated($page), + percent => percenttranslated($translations{$masterpage}{$lang}), } unless ($lang eq $curlang); } } -- cgit v1.2.3 From 93b316f7c1ec87170882ebf6ebae657f41e5f7e3 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Wed, 15 Oct 2008 07:11:13 +0200 Subject: po plugin: todo++ Signed-off-by: intrigeri --- doc/plugins/po.mdwn | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index 2c46a80ed..e8c6975b0 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -207,6 +207,13 @@ Security checks - `refreshpofiles` and `refreshpot` create new files; this may need some checks, e.g. using `IkiWiki::prep_writefile()` +gettext/po4a rough corners +-------------------------- + +- fix the "duplicate message definition" error when updating a PO + file; do PO files need normalizing? +- should `*.po~` backup files really be saved? + Translation quality assurance ----------------------------- -- cgit v1.2.3 From 7b7865150f1670e92d6d81ece36902df7028ec97 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Wed, 15 Oct 2008 07:12:28 +0200 Subject: po plugin: add correct dependencies on pages using OTHERLANGUAGES Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 12 ++++++++++++ doc/plugins/po.mdwn | 6 +++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 716aa9151..9a25ff602 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -368,6 +368,18 @@ sub pagetemplate (@) { #{{{ } if ($template->query(name => "otherlanguages")) { $template->param(otherlanguages => [otherlanguages($page)]); + if (istranslatable($page)) { + foreach my $translation (values %{$translations{$page}}) { + add_depends($page, $translation); + } + } + elsif (istranslation($page)) { + my ($masterpage, $curlang) = ($page =~ /(.*)[.]([a-z]{2})$/); + add_depends($page, $masterpage); + foreach my $translation (values %{$translations{$masterpage}}) { + add_depends($page, $translation); + } + } } } # }}} diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index e8c6975b0..b3c50a925 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -191,9 +191,9 @@ TODO OTHERLANGUAGES dependencies --------------------------- -Pages using `OTHERLANGUAGES` must depend on any "master" and "slave" -pages whose status is being displayed. It will trigger dependency -loops; how to sort this out? +Pages using `OTHERLANGUAGES` depend on any "master" and "slave" pages +whose status is being displayed. It is supposed to trigger dependency +loops, but no practical bugs were noticed yet. Should pages using the `OTHERLANGUAGES` template loop be declared as linking to the same page in other versions? To be rigorous, they -- cgit v1.2.3 From 892809bb53dd173cfdd353799c58df82851348d9 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Wed, 15 Oct 2008 07:23:06 +0200 Subject: po plugin: only refresh private module variables when needed Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 9a25ff602..e4cd6165f 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -186,16 +186,14 @@ sub needsbuild () { #{{{ } IkiWiki::refresh(); IkiWiki::saveindex(); + # refresh module's private variables %filtered=undef; + %translations=undef; + foreach my $page (keys %pagesources) { + istranslation($page); + } } - # refresh %translations, using istranslation's side-effect - # (not needed yet, but when newly created POT/PO files are - # added to %pagesources and other data structures, we'll need - # this) - foreach my $page (keys %pagesources) { - istranslation($page); - } # make existing translations depend on the corresponding master page foreach my $master (keys %translations) { -- cgit v1.2.3 From d0c4d5061d6b85cbd0e4bdef5087c467f7c2bfff Mon Sep 17 00:00:00 2001 From: intrigeri Date: Sat, 18 Oct 2008 02:49:32 +0200 Subject: po plugin: todo++ Signed-off-by: intrigeri --- doc/plugins/po.mdwn | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index b3c50a925..1dc72fe47 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -210,8 +210,10 @@ Security checks gettext/po4a rough corners -------------------------- +- fix the duplicated PO header mysterious bug - fix the "duplicate message definition" error when updating a PO - file; do PO files need normalizing? + file; do PO files need normalizing? (may be a side effect of + previous bug) - should `*.po~` backup files really be saved? Translation quality assurance -- cgit v1.2.3 From a021d97d30a646611457f1a22ed698e5bf90d4fc Mon Sep 17 00:00:00 2001 From: intrigeri Date: Sat, 18 Oct 2008 16:22:37 +0200 Subject: syntax.t: skip po since it uses a perl module not in build deps Signed-off-by: intrigeri --- t/syntax.t | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/t/syntax.t b/t/syntax.t index d09d17f7f..8c96d1d84 100755 --- a/t/syntax.t +++ b/t/syntax.t @@ -6,7 +6,7 @@ use Test::More; my @progs="ikiwiki.in"; my @libs="IkiWiki.pm"; # monotone, external, amazon_s3 skipped since they need perl modules -push @libs, map { chomp; $_ } `find IkiWiki -type f -name \\*.pm | grep -v monotone.pm | grep -v external.pm | grep -v amazon_s3.pm`; +push @libs, map { chomp; $_ } `find IkiWiki -type f -name \\*.pm | grep -v monotone.pm | grep -v external.pm | grep -v amazon_s3.pm | grep -v po.pm`; push @libs, 'IkiWiki/Plugin/skeleton.pm.example'; plan(tests => (@progs + @libs)); -- cgit v1.2.3 From a0deb3038c45c066e2c0c3acb8c6c4a93ca3301d Mon Sep 17 00:00:00 2001 From: intrigeri Date: Sat, 18 Oct 2008 19:18:22 +0200 Subject: po plugin: do not allow msgmerge to create backup files Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 2 +- doc/plugins/po.mdwn | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index e4cd6165f..07896d95a 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -132,7 +132,7 @@ sub refreshpofiles ($@) { #{{{ foreach my $pofile (@pofiles) { if (-e $pofile) { - my $cmd = "msgmerge -U $pofile $potfile"; + my $cmd = "msgmerge -U --backup=none $pofile $potfile"; system ($cmd) == 0 or error("[po/refreshpofiles:$pofile] failed to update"); } diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index 1dc72fe47..c83d5a612 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -214,7 +214,6 @@ gettext/po4a rough corners - fix the "duplicate message definition" error when updating a PO file; do PO files need normalizing? (may be a side effect of previous bug) -- should `*.po~` backup files really be saved? Translation quality assurance ----------------------------- -- cgit v1.2.3 From 629968fc89bced6727981c0a1138072631751fee Mon Sep 17 00:00:00 2001 From: intrigeri Date: Sat, 18 Oct 2008 21:47:49 +0200 Subject: po plugin(refreshpot): prevent PO references to be written ... else we can fall into some kind of nasty infinite loop, when two ikiwiki instances don't store their working copy of the repository at the same place: every POT file update in one repository would trigger an update of the same POT file in the others repository, and so on. Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 07896d95a..26bd893a9 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -9,6 +9,7 @@ use strict; use IkiWiki 2.00; use Encode; use Locale::Po4a::Chooser; +use Locale::Po4a::Po; use File::Basename; use File::Copy; use File::Spec; @@ -119,6 +120,12 @@ sub refreshpot ($) { #{{{ $doc->{TT}{utf_mode} = 1; $doc->{TT}{file_in_charset} = 'utf-8'; $doc->{TT}{file_out_charset} = 'utf-8'; + # let's cheat a bit to force porefs option to be passed to Locale::Po4a::Po; + # this is undocument use of internal Locale::Po4a::TransTractor's data, + # compulsory since this module prevents us from using the porefs option. + my %po_options = ('porefs' => 'none'); + $doc->{TT}{po_out}=Locale::Po4a::Po->new(\%po_options); + # do the actual work $doc->parse; $doc->writepo($potfile); } #}}} -- cgit v1.2.3 From da494462a8bd18913247ff09a8bcfe5fe6c0f809 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Sat, 18 Oct 2008 23:06:56 +0200 Subject: po plugin: todo++ Signed-off-by: intrigeri --- doc/plugins/po.mdwn | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index c83d5a612..a0c75699d 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -214,6 +214,12 @@ gettext/po4a rough corners - fix the "duplicate message definition" error when updating a PO file; do PO files need normalizing? (may be a side effect of previous bug) +- fix infinite loop when synchronizing two ikiwiki (when checkouts + live in different directories): say bla.fr.po has been updated in + repo2; pulling repo2 from repo1 seems to trigger a PO update, that + changes bla.fr.po in repo1; then pushing repo1 to repo2 triggers + a PO update, that changes bla.fr.po in repo2; etc.; fixed in + `629968fc89bced6727981c0a1138072631751fee` ? Translation quality assurance ----------------------------- -- cgit v1.2.3 From 72dc1a5f021595d9878fb6380280307400a46c4e Mon Sep 17 00:00:00 2001 From: intrigeri Date: Sat, 18 Oct 2008 23:06:56 +0200 Subject: po plugin: todo++ Signed-off-by: intrigeri --- doc/plugins/po.mdwn | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index c83d5a612..be3f4821e 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -214,6 +214,25 @@ gettext/po4a rough corners - fix the "duplicate message definition" error when updating a PO file; do PO files need normalizing? (may be a side effect of previous bug) +- fix infinite loop when synchronizing two ikiwiki (when checkouts + live in different directories): say bla.fr.po has been updated in + repo2; pulling repo2 from repo1 seems to trigger a PO update, that + changes bla.fr.po in repo1; then pushing repo1 to repo2 triggers + a PO update, that changes bla.fr.po in repo2; etc.; fixed in + `629968fc89bced6727981c0a1138072631751fee` ? + +Misc. bugs +---------- + + + +Misc. improvements +------------------ + +### page titles + +Use nice page titles from meta plugin in links, as inline already does. + Translation quality assurance ----------------------------- @@ -233,6 +252,8 @@ Translating online As PO is a wiki page type, we already have an online PO editor, that is ikiwiki's CGI. +**FIXME** preview does not work for PO files. + A message-by-message interface could also be implemented at some point; a nice way to do offline translation work (without VCS access) still has to be offered, though. -- cgit v1.2.3 From f096a9d7986025badd2f2773bbf71fb33cb96b7b Mon Sep 17 00:00:00 2001 From: intrigeri Date: Sun, 19 Oct 2008 00:05:13 +0200 Subject: po plugin: added ISTRANSLATION and ISTRANSLATABLE template variables Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 6 ++++++ doc/plugins/po.mdwn | 11 +++++++++++ 2 files changed, 17 insertions(+) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 26bd893a9..56f4162da 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -371,6 +371,12 @@ sub pagetemplate (@) { #{{{ if (istranslation($page) && $template->query(name => "percenttranslated")) { $template->param(percenttranslated => percenttranslated($page)); } + if ($template->query(name => "istranslation")) { + $template->param(istranslation => istranslation($page)); + } + if ($template->query(name => "istranslatable")) { + $template->param(istranslatable => istranslatable($page)); + } if ($template->query(name => "otherlanguages")) { $template->param(otherlanguages => [otherlanguages($page)]); if (istranslatable($page)) { diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index be3f4821e..bc455021a 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -128,6 +128,9 @@ Usage Templates --------- +The `ISTRANSLATION` and `ISTRANSLATABLE` variables can be used to +display things only on translatable or translation pages. + ### Display page's versions in other languages The `OTHERLANGUAGES` loop provides ways to display other languages' @@ -163,6 +166,14 @@ The following variables are available inside the loop (for every page in): The `PERCENTTRANSLATED` variable is set to the translation completeness, expressed in percent, on "slave" pages. +One can use it this way: + + +
+ +
+
+ Additional PageSpec tests ------------------------- -- cgit v1.2.3 From b4316fd941579cb93eba450272a6ec72caffa982 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Sun, 19 Oct 2008 00:15:44 +0200 Subject: po plugin: doc fix Signed-off-by: intrigeri --- doc/plugins/po.mdwn | 6 ------ 1 file changed, 6 deletions(-) diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index bc455021a..97c2e2d4e 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -232,11 +232,6 @@ gettext/po4a rough corners a PO update, that changes bla.fr.po in repo2; etc.; fixed in `629968fc89bced6727981c0a1138072631751fee` ? -Misc. bugs ----------- - - - Misc. improvements ------------------ @@ -244,7 +239,6 @@ Misc. improvements Use nice page titles from meta plugin in links, as inline already does. - Translation quality assurance ----------------------------- -- cgit v1.2.3 From 8211910566922dc66a09fa73286bb311de456afa Mon Sep 17 00:00:00 2001 From: intrigeri Date: Sun, 19 Oct 2008 17:18:17 +0200 Subject: po plugin: set every configuration item to unsafe We will check later which ones are actually safe enough for websetup. Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 8 ++++---- doc/plugins/po.mdwn | 4 ++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 56f4162da..f535ebd39 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -47,7 +47,7 @@ sub getsetup () { #{{{ 'name' => 'English' }, description => "master language (non-PO files)", - safe => 1, + safe => 0, rebuild => 1, }, po_slave_languages => { @@ -58,7 +58,7 @@ sub getsetup () { #{{{ 'de' => 'Deutsch' }, description => "slave languages (PO files)", - safe => 1, + safe => 0, rebuild => 1, }, po_translatable_pages => { @@ -66,14 +66,14 @@ sub getsetup () { #{{{ example => "!*/Discussion", description => "PageSpec controlling which pages are translatable", link => "ikiwiki/PageSpec", - safe => 1, + safe => 0, rebuild => 1, }, po_link_to => { type => "string", example => "current", description => "internal linking behavior (default/current/negotiated)", - safe => 1, + safe => 0, rebuild => 1, }, } #}}} diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index 97c2e2d4e..14d3ac65b 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -239,6 +239,10 @@ Misc. improvements Use nice page titles from meta plugin in links, as inline already does. +### websetup + +Which configuration settings are safe enough for websetup? + Translation quality assurance ----------------------------- -- cgit v1.2.3 From 654adc105e008b57aa5b9700d7aece2a0f7b0682 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Mon, 20 Oct 2008 14:30:22 +0200 Subject: po plugin: todo++ Signed-off-by: intrigeri --- doc/plugins/po.mdwn | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index 14d3ac65b..1412cfea2 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -235,6 +235,10 @@ gettext/po4a rough corners Misc. improvements ------------------ +### automatic POT/PO update + +Use the `change` hook instead of `needsbuild`? + ### page titles Use nice page titles from meta plugin in links, as inline already does. -- cgit v1.2.3 From fafa98ea96c0e28818ffcf47b7202c4130615c68 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Sun, 2 Nov 2008 16:44:42 +0100 Subject: disable istranslatable memoization It makes some test cases cry once every two tries; this may be related to the artificial way the testsuite is run, or not. In the meantime, stop memoizing this function. Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index f535ebd39..a1f7476a3 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -18,7 +18,9 @@ use Memoize; my %translations; our %filtered; -memoize("istranslatable"); +## FIXME: makes some test cases cry once every two tries; this may be +## related to the artificial way the testsuite is run, or not. +# memoize("istranslatable"); memoize("_istranslation"); memoize("percenttranslated"); -- cgit v1.2.3 From 06e3558318d332f91b23f60c3580a0ff9042a352 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Sun, 2 Nov 2008 16:46:09 +0100 Subject: po plugin: added testsuite I want to have an easy way to know if I break something when I'll convert custom added hooks to the new "inject" feature. It will also be useful after this conversion, to trigger an alert when IkiWiki's internals change enough to break my wrapper functions. Signed-off-by: intrigeri --- t/po.t | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100755 t/po.t diff --git a/t/po.t b/t/po.t new file mode 100755 index 000000000..9afe8d88f --- /dev/null +++ b/t/po.t @@ -0,0 +1,99 @@ +#!/usr/bin/perl +# -*- cperl-indent-level: 8; -*- +use warnings; +use strict; +use File::Temp; + +BEGIN { + unless (eval { require Locale::Po4a::Chooser }) { + eval q{ + use Test::More skip_all => "Locale::Po4a::Chooser::new is not available" + } + } + unless (eval { require Locale::Po4a::Po }) { + eval q{ + use Test::More skip_all => "Locale::Po4a::Po::new is not available" + } + } +} + +use Test::More tests => 24; + +BEGIN { use_ok("IkiWiki"); } + +my $msgprefix; + +### Init +%config=IkiWiki::defaultconfig(); +$config{srcdir}=$config{destdir}="/dev/null"; +## will need this when more thorough tests are written +# $config{srcdir} = "t/po/src"; +# $config{destdir} = File::Temp->newdir("ikiwiki-test-po.XXXXXXXXXX", TMPDIR => 1)->dirname; +$config{po_master_language} = { code => 'en', + name => 'English' + }; +$config{po_slave_languages} = { + es => 'Castellano', + fr => "Français" + }; +$config{po_translatable_pages}='test1 or test2'; +$config{po_link_to}='negotiated'; +IkiWiki::loadplugins(); +IkiWiki::checkconfig(); +ok(IkiWiki::loadplugin('po'), "po plugin loaded"); + +### seed %pagesources and %pagecase +$pagesources{'test1'}='test1.mdwn'; +$pagesources{'test1.fr'}='test1.fr.po'; +$pagesources{'test2'}='test2.mdwn'; +$pagesources{'test2.es'}='test2.es.po'; +$pagesources{'test2.fr'}='test2.fr.po'; +$pagesources{'test3'}='test3.mdwn'; +$pagesources{'test3.es'}='test3.es.mdwn'; +foreach my $page (keys %pagesources) { + $IkiWiki::pagecase{lc $page}=$page; +} + +### istranslatable/istranslation +# we run these tests twice because memoization attempts made them +# succeed once every two tries... +ok(IkiWiki::Plugin::po::istranslatable('test2'), "test2 is translatable"); +ok(IkiWiki::Plugin::po::istranslatable('test2'), "test2 is translatable"); +ok(! IkiWiki::Plugin::po::istranslation('test2'), "test2 is not a translation"); +ok(! IkiWiki::Plugin::po::istranslation('test2'), "test2 is not a translation"); +ok(! IkiWiki::Plugin::po::istranslatable('test3'), "test3 is not translatable"); +ok(! IkiWiki::Plugin::po::istranslatable('test3'), "test3 is not translatable"); +ok(! IkiWiki::Plugin::po::istranslation('test3'), "test3 is not a translation"); +ok(! IkiWiki::Plugin::po::istranslation('test3'), "test3 is not a translation"); + +### targetpage +$config{usedirs}=0; +$msgprefix="targetpage (usedirs=0)"; +is(targetpage('test1', 'html'), 'test1.en.html', "$msgprefix test1"); +is(targetpage('test1.fr', 'html'), 'test1.fr.html', "$msgprefix test1.fr"); +$config{usedirs}=1; +$msgprefix="targetpage (usedirs=1)"; +is(targetpage('test1', 'html'), 'test1/index.en.html', "$msgprefix test1"); +is(targetpage('test1.fr', 'html'), 'test1/index.fr.html', "$msgprefix test1.fr"); +is(targetpage('test3', 'html'), 'test3/index.html', "$msgprefix test3 (non-translatable page)"); +is(targetpage('test3.es', 'html'), 'test3.es/index.html', "$msgprefix test3.es (non-translatable page)"); + +### bestlink +$config{po_link_to}='current'; +$msgprefix="bestlink (po_link_to=current)"; +is(bestlink('test1.fr', 'test2'), 'test2.fr', "$msgprefix test1.fr -> test2"); +is(bestlink('test1.fr', 'test2.es'), 'test2.es', "$msgprefix test1.fr -> test2.es"); +$config{po_link_to}='negotiated'; +$msgprefix="bestlink (po_link_to=negotiated)"; +is(bestlink('test1.fr', 'test2'), 'test2', "$msgprefix test1.fr -> test2"); +is(bestlink('test1.fr', 'test2.es'), 'test2.es', "$msgprefix test1.fr -> test2.es"); + +### beautify_urlpath +$config{po_link_to}='default'; +$msgprefix="beautify_urlpath (po_link_to=default)"; +is(IkiWiki::beautify_urlpath('test1/index.en.html'), './test1/index.en.html', "$msgprefix test1/index.en.html"); +is(IkiWiki::beautify_urlpath('test1/index.fr.html'), './test1/index.fr.html', "$msgprefix test1/index.fr.html"); +$config{po_link_to}='negotiated'; +$msgprefix="beautify_urlpath (po_link_to=negotiated)"; +is(IkiWiki::beautify_urlpath('test1/index.en.html'), './test1/', "$msgprefix test1/index.en.html"); +is(IkiWiki::beautify_urlpath('test1/index.fr.html'), './test1/index.fr.html', "$msgprefix test1/index.fr.html"); -- cgit v1.2.3 From 9643ce20d8988da38f192689468075fe44709703 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Sun, 2 Nov 2008 17:33:32 +0100 Subject: Revert "added the tweakbestlink hook" This reverts commit e51089e11fc1093a253fc13ebfbd5d55912eba59. The new "inject()" feature should replace this ad-hoc hook. Signed-off-by: intrigeri --- IkiWiki.pm | 27 ++++++++------------------- doc/plugins/write.mdwn | 11 ----------- 2 files changed, 8 insertions(+), 30 deletions(-) diff --git a/IkiWiki.pm b/IkiWiki.pm index 90fedca4f..ba1847093 100644 --- a/IkiWiki.pm +++ b/IkiWiki.pm @@ -815,7 +815,6 @@ sub will_render ($$;$) { #{{{ sub bestlink ($$) { #{{{ my $page=shift; my $link=shift; - my $res=undef; my $cwd=$page; if ($link=~s/^\/+//) { @@ -830,35 +829,25 @@ sub bestlink ($$) { #{{{ $l.=$link; if (exists $links{$l}) { - $res=$l; + return $l; } elsif (exists $pagecase{lc $l}) { - $res=$pagecase{lc $l}; + return $pagecase{lc $l}; } - } while ($cwd=~s{/?[^/]+$}{} && ! defined $res); + } while $cwd=~s{/?[^/]+$}{}; - if (! defined $res && length $config{userdir}) { + if (length $config{userdir}) { my $l = "$config{userdir}/".lc($link); if (exists $links{$l}) { - $res=$l; + return $l; } elsif (exists $pagecase{lc $l}) { - $res=$pagecase{lc $l}; + return $pagecase{lc $l}; } } - if (defined $res) { - run_hooks(tweakbestlink => sub { - $res=shift->( - page => $page, - link => $res); - }); - return $res; - } - else { - #print STDERR "warning: page $page, broken link: $link\n"; - return ""; - } + #print STDERR "warning: page $page, broken link: $link\n"; + return ""; } #}}} sub isinlinableimage ($) { #{{{ diff --git a/doc/plugins/write.mdwn b/doc/plugins/write.mdwn index f147b0766..82b377820 100644 --- a/doc/plugins/write.mdwn +++ b/doc/plugins/write.mdwn @@ -446,17 +446,6 @@ ikiwiki; it is run just after ikiwiki has removed the trailing It should return the modified url. -### tweakbestlink - - hook(type => "tweakbestlink", id => "foo", call => \&tweakbestlink); - -This hook can be used to modify the page returned by `bestlink`. It is -passed named parameters `page` and `link`. These are, respectively, -the page where the link will appear and the link ikiwiki would choose -as the best one, if no `tweakbestlink` hook was in effect. - -It should return the modified link. - ## Plugin interface To import the ikiwiki plugin interface: -- cgit v1.2.3 From 502a3433c410369eca4eb36b8fb8be5bc4a34a2d Mon Sep 17 00:00:00 2001 From: intrigeri Date: Sun, 2 Nov 2008 17:56:15 +0100 Subject: po plugin: replace tweakbestlink hook with a wrapper function ... thanks to the new inject() feature. Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index a1f7476a3..fa250f3a4 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -18,6 +18,7 @@ use Memoize; my %translations; our %filtered; +my $origbestlink=\&bestlink; ## FIXME: makes some test cases cry once every two tries; this may be ## related to the artificial way the testsuite is run, or not. # memoize("istranslatable"); @@ -30,10 +31,10 @@ sub import { hook(type => "needsbuild", id => "po", call => \&needsbuild); hook(type => "targetpage", id => "po", call => \&targetpage); hook(type => "tweakurlpath", id => "po", call => \&tweakurlpath); - hook(type => "tweakbestlink", id => "po", call => \&tweakbestlink); hook(type => "filter", id => "po", call => \&filter); hook(type => "htmlize", id => "po", call => \&htmlize); hook(type => "pagetemplate", id => "po", call => \&pagetemplate); + inject(name => "IkiWiki::bestlink", call => \&mybestlink); } sub getsetup () { #{{{ @@ -246,17 +247,22 @@ sub tweakurlpath ($) { #{{{ return $url; } #}}} -sub tweakbestlink ($$) { #{{{ - my %params = @_; - my $page=$params{page}; - my $link=$params{link}; - if ($config{po_link_to} eq "current" - && istranslatable($link) - && istranslation($page)) { - my ($masterpage, $curlang) = ($page =~ /(.*)[.]([a-z]{2})$/); - return $link . "." . $curlang; +sub mybestlink ($$) { #{{{ + my $page=shift; + my $link=shift; + my $res=$origbestlink->($page, $link); + if (length $res) { + if ($config{po_link_to} eq "current" + && istranslatable($res) + && istranslation($page)) { + my ($masterpage, $curlang) = ($page =~ /(.*)[.]([a-z]{2})$/); + return $res . "." . $curlang; + } + else { + return $res; + } } - return $link; + return ""; } #}}} # We use filter to convert PO to the master page's type, -- cgit v1.2.3 From c696239b6b1ce6b3a3ee20cc88eb5fcb48c0bb7d Mon Sep 17 00:00:00 2001 From: intrigeri Date: Sun, 2 Nov 2008 18:07:01 +0100 Subject: po plugin: added TODO about charset/encoding in new translations Signed-off-by: intrigeri --- doc/plugins/po.mdwn | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index 1412cfea2..9baa60964 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -221,6 +221,10 @@ Security checks gettext/po4a rough corners -------------------------- +- new translations created in the web interface must get proper charset/encoding + gettext metadata, else the next automatic PO update removes any non-ascii + chars; possible solution: put such metadata into the Pot file, and let it + propagate - fix the duplicated PO header mysterious bug - fix the "duplicate message definition" error when updating a PO file; do PO files need normalizing? (may be a side effect of -- cgit v1.2.3 From 7c173aca3e87d13fdd044cb79dac80ad83d64a38 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Sun, 2 Nov 2008 18:08:50 +0100 Subject: Revert "added hook urlpath" and "rename urlpath hook into tweakurlpath..." This reverts commits d9b9022c13af3aa6c469df05beaa293fcf33cafc and 39d44d443d2271ec8787e6192b8b5811bee41ebf. This functionality should now be achieved using the new inject() function. Signed-off-by: intrigeri --- IkiWiki.pm | 4 ---- IkiWiki/Plugin/skeleton.pm.example | 5 ----- doc/plugins/write.mdwn | 10 ---------- 3 files changed, 19 deletions(-) diff --git a/IkiWiki.pm b/IkiWiki.pm index ba1847093..8b3a91114 100644 --- a/IkiWiki.pm +++ b/IkiWiki.pm @@ -942,10 +942,6 @@ sub beautify_urlpath ($) { #{{{ $url =~ s!/index.$config{htmlext}$!/!; } - run_hooks(tweakurlpath => sub { - $url=shift->(url => $url); - }); - # Ensure url is not an empty link, and # if it's relative, make that explicit to avoid colon confusion. if ($url !~ /^\//) { diff --git a/IkiWiki/Plugin/skeleton.pm.example b/IkiWiki/Plugin/skeleton.pm.example index ecf2a2407..af22b3406 100644 --- a/IkiWiki/Plugin/skeleton.pm.example +++ b/IkiWiki/Plugin/skeleton.pm.example @@ -35,7 +35,6 @@ sub import { #{{{ hook(type => "formbuilder", id => "skeleton", call => \&formbuilder); hook(type => "savestate", id => "skeleton", call => \&savestate); hook(type => "targetpage", id => "skeleton", call => \&targetpage); - hook(type => "urlpath", id => "skeleton", call => \&urlpath); } # }}} sub getopt () { #{{{ @@ -210,8 +209,4 @@ sub targetpage () { #{{{ debug("skeleton plugin running in targetpage"); } #}}} -sub urlpath () { #{{{ - debug("skeleton plugin running in urlpath"); -} #}}} - 1 diff --git a/doc/plugins/write.mdwn b/doc/plugins/write.mdwn index 82b377820..e8ac9614b 100644 --- a/doc/plugins/write.mdwn +++ b/doc/plugins/write.mdwn @@ -436,16 +436,6 @@ be compiled into. It should return the target filename. -### tweakurlpath - - hook(type => "tweakurlpath", id => "foo", call => \&tweakurlpath); - -This hook can be used to modify the internal urls generated by -ikiwiki; it is run just after ikiwiki has removed the trailing -`index.html`, in case `usedirs` is enabled. - -It should return the modified url. - ## Plugin interface To import the ikiwiki plugin interface: -- cgit v1.2.3 From 307d11541a80a4fed897ef51087c35546506aa70 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Sun, 2 Nov 2008 18:29:23 +0100 Subject: po plugin: replace tweakurlpath hook with a wrapper function Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index fa250f3a4..9b5652561 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -18,13 +18,18 @@ use Memoize; my %translations; our %filtered; -my $origbestlink=\&bestlink; + ## FIXME: makes some test cases cry once every two tries; this may be ## related to the artificial way the testsuite is run, or not. # memoize("istranslatable"); memoize("_istranslation"); memoize("percenttranslated"); +# backup references to subs that will be overriden +my %origsubs; +$origsubs{'bestlink'}=\&IkiWiki::bestlink; +$origsubs{'beautify_urlpath'}=\&IkiWiki::beautify_urlpath; + sub import { hook(type => "getsetup", id => "po", call => \&getsetup); hook(type => "checkconfig", id => "po", call => \&checkconfig); @@ -35,6 +40,7 @@ sub import { hook(type => "htmlize", id => "po", call => \&htmlize); hook(type => "pagetemplate", id => "po", call => \&pagetemplate); inject(name => "IkiWiki::bestlink", call => \&mybestlink); + inject(name => "IkiWiki::beautify_urlpath", call => \&mybeautify_urlpath); } sub getsetup () { #{{{ @@ -238,19 +244,19 @@ sub targetpage (@) { #{{{ return; } #}}} -sub tweakurlpath ($) { #{{{ - my %params = @_; - my $url=$params{url}; +sub mybeautify_urlpath ($) { #{{{ + my $url=shift; + my $res=$origsubs{'beautify_urlpath'}->($url); if ($config{po_link_to} eq "negotiated") { - $url =~ s!/index.$config{po_master_language}{code}.$config{htmlext}$!/!; + $res =~ s!/index.$config{po_master_language}{code}.$config{htmlext}$!/!; } - return $url; + return $res; } #}}} sub mybestlink ($$) { #{{{ my $page=shift; my $link=shift; - my $res=$origbestlink->($page, $link); + my $res=$origsubs{'bestlink'}->($page, $link); if (length $res) { if ($config{po_link_to} eq "current" && istranslatable($res) -- cgit v1.2.3 From 439a2d3c443a032b26ce2455c6f15352a7e606be Mon Sep 17 00:00:00 2001 From: intrigeri Date: Sun, 2 Nov 2008 18:34:10 +0100 Subject: Revert "added the targetpage hook" This reverts commit fc299df955879bf958aa78338ba64d56a7df17a9. Such functionality can now be achieved using the inject() function. Signed-off-by: intrigeri --- IkiWiki.pm | 15 ++------------- IkiWiki/Plugin/skeleton.pm.example | 5 ----- doc/plugins/write.mdwn | 9 --------- 3 files changed, 2 insertions(+), 27 deletions(-) diff --git a/IkiWiki.pm b/IkiWiki.pm index 8b3a91114..bab7b707a 100644 --- a/IkiWiki.pm +++ b/IkiWiki.pm @@ -655,19 +655,8 @@ sub newpagefile ($$) { #{{{ sub targetpage ($$) { #{{{ my $page=shift; my $ext=shift; - - my $targetpage=''; - run_hooks(targetpage => sub { - $targetpage=shift->( - page => $page, - ext => $ext, - ); - }); - - if (defined $targetpage && (length($targetpage) > 0)) { - return $targetpage; - } - elsif (! $config{usedirs} || $page eq 'index') { + + if (! $config{usedirs} || $page eq 'index') { return $page.".".$ext; } else { diff --git a/IkiWiki/Plugin/skeleton.pm.example b/IkiWiki/Plugin/skeleton.pm.example index af22b3406..f844ddb91 100644 --- a/IkiWiki/Plugin/skeleton.pm.example +++ b/IkiWiki/Plugin/skeleton.pm.example @@ -34,7 +34,6 @@ sub import { #{{{ hook(type => "formbuilder_setup", id => "skeleton", call => \&formbuilder_setup); hook(type => "formbuilder", id => "skeleton", call => \&formbuilder); hook(type => "savestate", id => "skeleton", call => \&savestate); - hook(type => "targetpage", id => "skeleton", call => \&targetpage); } # }}} sub getopt () { #{{{ @@ -205,8 +204,4 @@ sub savestate () { #{{{ debug("skeleton plugin running in savestate"); } #}}} -sub targetpage () { #{{{ - debug("skeleton plugin running in targetpage"); -} #}}} - 1 diff --git a/doc/plugins/write.mdwn b/doc/plugins/write.mdwn index e8ac9614b..abcabbdc3 100644 --- a/doc/plugins/write.mdwn +++ b/doc/plugins/write.mdwn @@ -427,15 +427,6 @@ describes the plugin as a whole. For example: and undef if a rebuild could be needed in some circumstances, but is not strictly required. -### targetpage - - hook(type => "targetpage", id => "foo", call => \&targetpage); - -This hook can be used to override the name of the file a page should -be compiled into. - -It should return the target filename. - ## Plugin interface To import the ikiwiki plugin interface: -- cgit v1.2.3 From 950c29679df8f8f2f20e150896dc7ec686f123e8 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Sun, 2 Nov 2008 18:48:56 +0100 Subject: po plugin: replace targetpage hook with wrapper function Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 9b5652561..127d6d47f 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -29,18 +29,19 @@ memoize("percenttranslated"); my %origsubs; $origsubs{'bestlink'}=\&IkiWiki::bestlink; $origsubs{'beautify_urlpath'}=\&IkiWiki::beautify_urlpath; +$origsubs{'targetpage'}=\&IkiWiki::targetpage; sub import { hook(type => "getsetup", id => "po", call => \&getsetup); hook(type => "checkconfig", id => "po", call => \&checkconfig); hook(type => "needsbuild", id => "po", call => \&needsbuild); - hook(type => "targetpage", id => "po", call => \&targetpage); hook(type => "tweakurlpath", id => "po", call => \&tweakurlpath); hook(type => "filter", id => "po", call => \&filter); hook(type => "htmlize", id => "po", call => \&htmlize); hook(type => "pagetemplate", id => "po", call => \&pagetemplate); inject(name => "IkiWiki::bestlink", call => \&mybestlink); inject(name => "IkiWiki::beautify_urlpath", call => \&mybeautify_urlpath); + inject(name => "IkiWiki::targetpage", call => \&mytargetpage); } sub getsetup () { #{{{ @@ -219,10 +220,9 @@ sub needsbuild () { #{{{ } } #}}} -sub targetpage (@) { #{{{ - my %params = @_; - my $page=$params{page}; - my $ext=$params{ext}; +sub mytargetpage ($$) { #{{{ + my $page=shift; + my $ext=shift; if (istranslation($page)) { my ($masterpage, $lang) = ($page =~ /(.*)[.]([a-z]{2})$/); @@ -241,7 +241,7 @@ sub targetpage (@) { #{{{ return $page . "/index." . $config{po_master_language}{code} . "." . $ext; } } - return; + return $origsubs{'targetpage'}->($page, $ext); } #}}} sub mybeautify_urlpath ($) { #{{{ -- cgit v1.2.3 From 439ba4490acbeafe6206d8723901e16ddcfc611a Mon Sep 17 00:00:00 2001 From: intrigeri Date: Sun, 2 Nov 2008 18:51:00 +0100 Subject: po plugin: removed last (?) bit of deprecated custom hook Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 1 - 1 file changed, 1 deletion(-) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 127d6d47f..4608f59c7 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -35,7 +35,6 @@ sub import { hook(type => "getsetup", id => "po", call => \&getsetup); hook(type => "checkconfig", id => "po", call => \&checkconfig); hook(type => "needsbuild", id => "po", call => \&needsbuild); - hook(type => "tweakurlpath", id => "po", call => \&tweakurlpath); hook(type => "filter", id => "po", call => \&filter); hook(type => "htmlize", id => "po", call => \&htmlize); hook(type => "pagetemplate", id => "po", call => \&pagetemplate); -- cgit v1.2.3 From 7d88fb3ff873e1423ed198895ac5647cea58c8ba Mon Sep 17 00:00:00 2001 From: intrigeri Date: Sun, 2 Nov 2008 18:54:04 +0100 Subject: po plugin: added test cases for index.* (Translatable index is currently buggy, let's fix this.) Signed-off-by: intrigeri --- t/po.t | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/t/po.t b/t/po.t index 9afe8d88f..232c98c81 100755 --- a/t/po.t +++ b/t/po.t @@ -17,7 +17,7 @@ BEGIN { } } -use Test::More tests => 24; +use Test::More tests => 34; BEGIN { use_ok("IkiWiki"); } @@ -36,13 +36,15 @@ $config{po_slave_languages} = { es => 'Castellano', fr => "Français" }; -$config{po_translatable_pages}='test1 or test2'; +$config{po_translatable_pages}='index or test1 or test2'; $config{po_link_to}='negotiated'; IkiWiki::loadplugins(); IkiWiki::checkconfig(); ok(IkiWiki::loadplugin('po'), "po plugin loaded"); ### seed %pagesources and %pagecase +$pagesources{'index'}='index.mdwn'; +$pagesources{'index.fr'}='index.fr.po'; $pagesources{'test1'}='test1.mdwn'; $pagesources{'test1.fr'}='test1.fr.po'; $pagesources{'test2'}='test2.mdwn'; @@ -57,6 +59,14 @@ foreach my $page (keys %pagesources) { ### istranslatable/istranslation # we run these tests twice because memoization attempts made them # succeed once every two tries... +ok(IkiWiki::Plugin::po::istranslatable('index'), "index is translatable"); +ok(IkiWiki::Plugin::po::istranslatable('index'), "index is translatable"); +ok(! IkiWiki::Plugin::po::istranslatable('index.fr'), "index is not translatable"); +ok(! IkiWiki::Plugin::po::istranslatable('index.fr'), "index is not translatable"); +ok(! IkiWiki::Plugin::po::istranslation('index'), "index is not a translation"); +ok(! IkiWiki::Plugin::po::istranslation('index'), "index is not a translation"); +ok(IkiWiki::Plugin::po::istranslation('index.fr'), "index.fr is a translation"); +ok(IkiWiki::Plugin::po::istranslation('index.fr'), "index.fr is a translation"); ok(IkiWiki::Plugin::po::istranslatable('test2'), "test2 is translatable"); ok(IkiWiki::Plugin::po::istranslatable('test2'), "test2 is translatable"); ok(! IkiWiki::Plugin::po::istranslation('test2'), "test2 is not a translation"); @@ -73,6 +83,8 @@ is(targetpage('test1', 'html'), 'test1.en.html', "$msgprefix test1"); is(targetpage('test1.fr', 'html'), 'test1.fr.html', "$msgprefix test1.fr"); $config{usedirs}=1; $msgprefix="targetpage (usedirs=1)"; +is(targetpage('index', 'html'), 'index.en.html', "$msgprefix index"); +is(targetpage('index.fr', 'html'), 'index.fr.html', "$msgprefix index.fr"); is(targetpage('test1', 'html'), 'test1/index.en.html', "$msgprefix test1"); is(targetpage('test1.fr', 'html'), 'test1/index.fr.html', "$msgprefix test1.fr"); is(targetpage('test3', 'html'), 'test3/index.html', "$msgprefix test3 (non-translatable page)"); -- cgit v1.2.3 From 37a9e642910628b021f0dd3cf9203f7f76f3a7cd Mon Sep 17 00:00:00 2001 From: intrigeri Date: Sun, 2 Nov 2008 18:54:53 +0100 Subject: po plugin: fix targetpage for home page's translations Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 4608f59c7..88f8194fb 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -225,7 +225,7 @@ sub mytargetpage ($$) { #{{{ if (istranslation($page)) { my ($masterpage, $lang) = ($page =~ /(.*)[.]([a-z]{2})$/); - if (! $config{usedirs} || $page eq 'index') { + if (! $config{usedirs} || $masterpage eq 'index') { return $masterpage . "." . $lang . "." . $ext; } else { -- cgit v1.2.3 From 2ebc0bb82dd907b6c0eaa39441378cb3bd8152d5 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Sun, 2 Nov 2008 20:08:38 +0100 Subject: po plugin: fix linking from a translation to its master page Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 88f8194fb..0902322e3 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -252,6 +252,17 @@ sub mybeautify_urlpath ($) { #{{{ return $res; } #}}} +sub urlto_with_orig_beautiful_urlpath($$) { #{{{ + my $to=shift; + my $from=shift; + + inject(name => "IkiWiki::beautify_urlpath", call => $origsubs{'beautify_urlpath'}); + my $res=urlto($to, $from); + inject(name => "IkiWiki::beautify_urlpath", call => \&mybeautify_urlpath); + + return $res; +} #}}} + sub mybestlink ($$) { #{{{ my $page=shift; my $link=shift; @@ -359,7 +370,7 @@ sub otherlanguages ($) { #{{{ elsif (istranslation($page)) { my ($masterpage, $curlang) = ($page =~ /(.*)[.]([a-z]{2})$/); push @ret, { - url => urlto($masterpage, $page), + url => urlto_with_orig_beautiful_urlpath($masterpage, $page), code => $config{po_master_language}{code}, language => $config{po_master_language}{name}, master => 1, -- cgit v1.2.3 From 773de05a7a1ee68d2bed173367cf5e716884945a Mon Sep 17 00:00:00 2001 From: intrigeri Date: Sun, 2 Nov 2008 21:35:52 +0100 Subject: po plugin: force utf-8 encoding in POT files Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 0902322e3..59d938d82 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -134,6 +134,7 @@ sub refreshpot ($) { #{{{ # compulsory since this module prevents us from using the porefs option. my %po_options = ('porefs' => 'none'); $doc->{TT}{po_out}=Locale::Po4a::Po->new(\%po_options); + $doc->{TT}{po_out}->set_charset('utf-8'); # do the actual work $doc->parse; $doc->writepo($potfile); -- cgit v1.2.3 From c0d1f2caceae468598861f435c1d7318a94c1302 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Sun, 2 Nov 2008 23:10:59 +0100 Subject: po plugin: updated todo / doc Signed-off-by: intrigeri --- doc/plugins/po.mdwn | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index 9baa60964..1a9144aee 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -221,20 +221,17 @@ Security checks gettext/po4a rough corners -------------------------- -- new translations created in the web interface must get proper charset/encoding - gettext metadata, else the next automatic PO update removes any non-ascii - chars; possible solution: put such metadata into the Pot file, and let it - propagate -- fix the duplicated PO header mysterious bug -- fix the "duplicate message definition" error when updating a PO - file; do PO files need normalizing? (may be a side effect of - previous bug) - fix infinite loop when synchronizing two ikiwiki (when checkouts live in different directories): say bla.fr.po has been updated in repo2; pulling repo2 from repo1 seems to trigger a PO update, that changes bla.fr.po in repo1; then pushing repo1 to repo2 triggers a PO update, that changes bla.fr.po in repo2; etc.; fixed in - `629968fc89bced6727981c0a1138072631751fee` ? + `629968fc89bced6727981c0a1138072631751fee`? +- new translations created in the web interface must get proper charset/encoding + gettext metadata, else the next automatic PO update removes any non-ascii + chars; possible solution: put such metadata into the Pot file, and let it + propagate; should be fixed in `773de05a7a1ee68d2bed173367cf5e716884945a`, time + will tell. Misc. improvements ------------------ @@ -251,6 +248,25 @@ Use nice page titles from meta plugin in links, as inline already does. Which configuration settings are safe enough for websetup? +### Discussion pages + +Decide something, probably that "slave" pages, being only translations, don't +deserve a discussion page: the discussion should happen in the language in which +the pages are written for real, which is the "master" one. + +### parentlinks + +When the wiki home page is translatable, the parentlinks plugin sets +`./index.html` as its translations' single parent link. Ideally, the home page's +translations should get no parent link at all, just like the version written in +the master language. + +### backlinks + +If a given translatable `sourcepage.mdwn` links to \[[destpage]], +`sourcepage.LL.po` also link to \[[destpage]], and the latter has the master +page *and* all its translations listed in the backlinks. + Translation quality assurance ----------------------------- -- cgit v1.2.3 From 9bd3262f50eb3096482a24b0c15db47bce752c3d Mon Sep 17 00:00:00 2001 From: intrigeri Date: Sun, 2 Nov 2008 23:12:43 +0100 Subject: po plugin: replace %hash=undef with undef %hash Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 59d938d82..155af706f 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -204,8 +204,8 @@ sub needsbuild () { #{{{ IkiWiki::refresh(); IkiWiki::saveindex(); # refresh module's private variables - %filtered=undef; - %translations=undef; + undef %filtered; + undef %translations; foreach my $page (keys %pagesources) { istranslation($page); } -- cgit v1.2.3 From c7fbcf6c5eab205d69ebdd18e5b5f142aea21e97 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Mon, 3 Nov 2008 00:52:27 +0100 Subject: po plugin: slave pages link to the master's discussion page Signed-off-by: intrigeri --- IkiWiki/Plugin/po.pm | 19 +++++++++++++++++++ doc/plugins/po.mdwn | 13 +++++++------ 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/IkiWiki/Plugin/po.pm b/IkiWiki/Plugin/po.pm index 155af706f..9dda8c0db 100644 --- a/IkiWiki/Plugin/po.pm +++ b/IkiWiki/Plugin/po.pm @@ -391,6 +391,7 @@ sub otherlanguages ($) { #{{{ sub pagetemplate (@) { #{{{ my %params=@_; my $page=$params{page}; + my $destpage=$params{destpage}; my $template=$params{template}; if (istranslation($page) && $template->query(name => "percenttranslated")) { @@ -417,6 +418,24 @@ sub pagetemplate (@) { #{{{ } } } + # Rely on IkiWiki::Render's genpage() to decide wether + # a discussion link should appear on $page; this is not + # totally accurate, though: some broken links may be generated + # when cgiurl is disabled. + # This compromise avoids some code duplication, and will probably + # prevent future breakage when ikiwiki internals change. + # Known limitations are preferred to future random bugs. + if ($template->param('discussionlink') && istranslation($page)) { + my ($masterpage, $lang) = ($page =~ /(.*)[.]([a-z]{2})$/); + $template->param('discussionlink' => htmllink( + $page, + $destpage, + $masterpage . '/' . gettext("Discussion"), + noimageinline => 1, + forcesubpage => 0, + linktext => gettext("Discussion"), + )); + } } # }}} sub istranslatable ($) { #{{{ diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index 1a9144aee..1b240de1a 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -196,6 +196,13 @@ Also, when the plugin has just been enabled, or when a page has just been declared as being translatable, the needed POT and PO files are created, and the PO files are checked into version control. +Discussion pages +---------------- + +Discussion should happen in the language in which the pages are written for +real, *i.e.* the "master" one. If discussion pages are enabled, "slave" pages +therefore link to the "master" page's discussion page. + TODO ==== @@ -248,12 +255,6 @@ Use nice page titles from meta plugin in links, as inline already does. Which configuration settings are safe enough for websetup? -### Discussion pages - -Decide something, probably that "slave" pages, being only translations, don't -deserve a discussion page: the discussion should happen in the language in which -the pages are written for real, which is the "master" one. - ### parentlinks When the wiki home page is translatable, the parentlinks plugin sets -- cgit v1.2.3 From 78155454a4d46c085e50937bda58bc4e2d40a648 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Mon, 3 Nov 2008 01:21:06 +0100 Subject: po plugin: updated doc+todo Signed-off-by: intrigeri --- doc/plugins/po.mdwn | 58 ++++++++++++++++------------------------------------- 1 file changed, 17 insertions(+), 41 deletions(-) diff --git a/doc/plugins/po.mdwn b/doc/plugins/po.mdwn index 1b240de1a..fe6b6b562 100644 --- a/doc/plugins/po.mdwn +++ b/doc/plugins/po.mdwn @@ -203,6 +203,15 @@ Discussion should happen in the language in which the pages are written for real, *i.e.* the "master" one. If discussion pages are enabled, "slave" pages therefore link to the "master" page's discussion page. +Translating +----------- + +One can edit the PO files using ikiwiki's CGI (a message-by-message interface +could also be implemented at some point). + +If [[tips/untrusted_git_push]] is setup, one can edit the PO files in her +preferred `$EDITOR`, without needing to be online. + TODO ==== @@ -243,13 +252,20 @@ gettext/po4a rough corners Misc. improvements ------------------ +### preview + +preview does not work for PO files. + ### automatic POT/PO update Use the `change` hook instead of `needsbuild`? ### page titles -Use nice page titles from meta plugin in links, as inline already does. +Use nice page titles from meta plugin in links, as inline already does. This is +actually a duplicate for +[[bugs/pagetitle_function_does_not_respect_meta_titles]], which might be fixed +by something like [[todo/using_meta_titles_for_parentlinks]]. ### websetup @@ -279,43 +295,3 @@ A new `cansave` type of hook would be needed to implement this. Note: committing to the underlying repository is a way to bypass this check. - -Translating online ------------------- - -As PO is a wiki page type, we already have an online PO editor, that -is ikiwiki's CGI. - -**FIXME** preview does not work for PO files. - -A message-by-message interface could also be implemented at some -point; a nice way to do offline translation work (without VCS access) -still has to be offered, though. - -Translating offline without VCS access --------------------------------------- - -The following workflow should be made possible for translators without -VCS access who need to edit the PO files in another editor than a web -browser: - -- download the page's PO file -- use any PO editor to update the translation -- upload the updated PO file - -Implementation note: a generic mechanism to upload a page's source is -needed: it's only an alternative way to allow saving a the modified -page's source with the CGI. - -### Short-term workflow - -A possible workaround is: - -- pretend to edit the PO file online -- copy the PO file content from the textarea -- cancel the edit -- paste the content into a local file. -- edit the local file in any PO editor -- pretend to edit the PO file online -- paste the modified local file's content into the edit textarea -- save -- cgit v1.2.3