* Fix --libdir to work at the command line.
* Plugins can now be written as standalone external programs, which can be written in any language that can do XML::RPC.master
parent
b2101850e2
commit
506bcbac04
|
@ -160,11 +160,20 @@ sub loadplugin ($) { #{{{
|
|||
|
||||
return if grep { $_ eq $plugin} @{$config{disable_plugins}};
|
||||
|
||||
foreach my $dir ($config{libdir}, "$installdir/lib/ikiwiki") {
|
||||
if (defined $dir && -x "$dir/plugins/$plugin") {
|
||||
require IkiWiki::Plugin::external;
|
||||
import IkiWiki::Plugin::external "$dir/plugins/$plugin";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
my $mod="IkiWiki::Plugin::".possibly_foolish_untaint($plugin);
|
||||
eval qq{use $mod};
|
||||
if ($@) {
|
||||
error("Failed to load plugin $mod: $@");
|
||||
}
|
||||
return 1;
|
||||
} #}}}
|
||||
|
||||
sub error ($;$) { #{{{
|
||||
|
|
|
@ -0,0 +1,169 @@
|
|||
#!/usr/bin/perl
|
||||
# Support for external plugins written in other languages.
|
||||
# Communication via XML RPC a pipe.
|
||||
# See externaldemo for an example of a plugin that uses this.
|
||||
package IkiWiki::Plugin::external;
|
||||
|
||||
use warnings;
|
||||
use strict;
|
||||
use IkiWiki 2.00;
|
||||
use RPC::XML;
|
||||
use RPC::XML::Parser;
|
||||
use IPC::Open2;
|
||||
use IO::Handle;
|
||||
|
||||
my %plugins;
|
||||
|
||||
sub import { #{{{
|
||||
my $self=shift;
|
||||
my $plugin=shift;
|
||||
return unless defined $plugin;
|
||||
|
||||
my ($plugin_read, $plugin_write);
|
||||
my $pid = open2($plugin_read, $plugin_write, $plugin);
|
||||
|
||||
# open2 doesn't respect "use open ':utf8'"
|
||||
binmode($plugin_read, ':utf8');
|
||||
binmode($plugin_write, ':utf8');
|
||||
|
||||
$plugins{$plugin}={in => $plugin_read, out => $plugin_write, pid => $pid,
|
||||
accum => ""};
|
||||
|
||||
rpc_call($plugins{$plugin}, "import");
|
||||
} #}}}
|
||||
|
||||
sub rpc_write ($$) { #{{{
|
||||
my $fh=shift;
|
||||
my $string=shift;
|
||||
|
||||
$fh->print($string."\n");
|
||||
$fh->flush;
|
||||
} #}}}
|
||||
|
||||
sub rpc_call ($$;@) { #{{{
|
||||
my $plugin=shift;
|
||||
my $command=shift;
|
||||
|
||||
# send the command
|
||||
my $req=RPC::XML::request->new($command, @_);
|
||||
rpc_write($plugin->{out}, $req->as_string);
|
||||
|
||||
# process incoming rpc until a result is available
|
||||
while ($_ = $plugin->{in}->getline) {
|
||||
$plugin->{accum}.=$_;
|
||||
while ($plugin->{accum} =~ /^\s*(<\?xml\s.*?<\/(?:methodCall|methodResponse)>)\n(.*)/s) {
|
||||
$plugin->{accum}=$2;
|
||||
my $r = RPC::XML::Parser->new->parse($1);
|
||||
error("XML RPC parser failure: $r") unless ref $r;
|
||||
if ($r->isa('RPC::XML::response')) {
|
||||
my $value=$r->value;
|
||||
if ($value->isa('RPC::XML::array')) {
|
||||
return @{$value->value};
|
||||
}
|
||||
elsif ($value->isa('RPC::XML::struct')) {
|
||||
return %{$value->value};
|
||||
}
|
||||
elsif ($value->isa('RPC::XML::fault')) {
|
||||
die $value->string;
|
||||
}
|
||||
else {
|
||||
return $value->value;
|
||||
}
|
||||
}
|
||||
|
||||
my $name=$r->name;
|
||||
my @args=map { $_->value } @{$r->args};
|
||||
|
||||
# When dispatching a function, first look in
|
||||
# IkiWiki::RPC::XML. This allows overriding
|
||||
# IkiWiki functions with RPC friendly versions.
|
||||
my $ret;
|
||||
if (exists $IkiWiki::RPC::XML::{$name}) {
|
||||
$ret=$IkiWiki::RPC::XML::{$name}($plugin, @args);
|
||||
}
|
||||
elsif (exists $IkiWiki::{$name}) {
|
||||
$ret=$IkiWiki::{$name}(@args);
|
||||
}
|
||||
else {
|
||||
error("XML RPC call error, unknown function: $name");
|
||||
}
|
||||
|
||||
my $string=eval { RPC::XML::response->new($ret)->as_string };
|
||||
if ($@ && ref $ret) {
|
||||
# One common reason for serialisation to
|
||||
# fail is a complex return type that cannot
|
||||
# be represented as an XML RPC response.
|
||||
# Handle this case by just returning 1.
|
||||
$string=eval { RPC::XML::response->new(1)->as_string };
|
||||
}
|
||||
if ($@) {
|
||||
error("XML response serialisation failed: $@");
|
||||
}
|
||||
rpc_write($plugin->{out}, $string);
|
||||
}
|
||||
}
|
||||
|
||||
return undef;
|
||||
} #}}}
|
||||
|
||||
package IkiWiki::RPC::XML;
|
||||
|
||||
sub getvar ($$$) { #{{{
|
||||
my $plugin=shift;
|
||||
my $varname="IkiWiki::".shift;
|
||||
my $key=shift;
|
||||
|
||||
no strict 'refs';
|
||||
my $ret=$varname->{$key};
|
||||
use strict 'refs';
|
||||
return $ret;
|
||||
} #}}}
|
||||
|
||||
sub setvar ($$$;@) { #{{{
|
||||
my $plugin=shift;
|
||||
my $varname="IkiWiki::".shift;
|
||||
my $key=shift;
|
||||
|
||||
no strict 'refs';
|
||||
my $ret=$varname->{$key}=@_;
|
||||
use strict 'refs';
|
||||
return $ret;
|
||||
} #}}}
|
||||
|
||||
sub inject ($@) { #{{{
|
||||
# Bind a given perl function name to a particular RPC request.
|
||||
my $plugin=shift;
|
||||
my %params=@_;
|
||||
|
||||
if (! exists $params{name} || ! exists $params{call}) {
|
||||
die "inject needs name and call parameters";
|
||||
}
|
||||
my $sub = sub {
|
||||
IkiWiki::Plugin::external::rpc_call($plugin, $params{call}, @_)
|
||||
};
|
||||
eval qq{*$params{name}=\$sub};
|
||||
return 1;
|
||||
} #}}}
|
||||
|
||||
sub hook ($@) { #{{{
|
||||
# the call parameter is a function name to call, since XML RPC
|
||||
# cannot pass a function reference
|
||||
my $plugin=shift;
|
||||
my %params=@_;
|
||||
|
||||
my $callback=$params{call};
|
||||
delete $params{call};
|
||||
|
||||
IkiWiki::hook(%params, call => sub {
|
||||
IkiWiki::Plugin::external::rpc_call($plugin, $callback, @_)
|
||||
});
|
||||
} #}}}
|
||||
|
||||
sub pagespec_match ($@) { #{{{
|
||||
# convert pagespec_match's return object into a XML RPC boolean
|
||||
my $plugin=shift;
|
||||
|
||||
return RPC::XML::boolean->new(0 + IkiWiki::pagespec_march(@_));
|
||||
} #}}}
|
||||
|
||||
1
|
|
@ -55,6 +55,11 @@ extra_install:
|
|||
install -m 644 $$file $(DESTDIR)$(PREFIX)/share/ikiwiki/$$dir; \
|
||||
done; \
|
||||
done
|
||||
|
||||
install -d $(DESTDIR)$(PREFIX)/lib/ikiwiki/plugins
|
||||
for file in `find plugins -maxdepth 1 -type f`; do \
|
||||
install -m 755 $$file $(DESTDIR)$(PREFIX)/lib/ikiwiki/plugins; \
|
||||
done; \
|
||||
|
||||
install -d $(DESTDIR)$(PREFIX)/share/man/man1
|
||||
install -m 644 ikiwiki.man $(DESTDIR)$(PREFIX)/share/man/man1/ikiwiki.1
|
||||
|
|
|
@ -22,8 +22,11 @@ ikiwiki (2.6) UNRELEASED; urgency=low
|
|||
* Support pagespec "functions" with no parameters, like included() in the
|
||||
conditional plugin.
|
||||
* Add time=mtime option to postsparkline.
|
||||
* Fix --libdir to work at the command line.
|
||||
* Plugins can now be written as standalone external programs, which can
|
||||
be written in any language that can do XML::RPC.
|
||||
|
||||
-- Joey Hess <joeyh@debian.org> Sun, 12 Aug 2007 05:17:23 -0400
|
||||
-- Joey Hess <joeyh@debian.org> Sun, 12 Aug 2007 20:49:23 -0400
|
||||
|
||||
ikiwiki (2.5) unstable; urgency=low
|
||||
|
||||
|
|
|
@ -6,10 +6,10 @@ rootpage="plugins/contrib" postformtext="Add a new plugin named:" show=0]]
|
|||
|
||||
# Installing third party plugins
|
||||
|
||||
Plugins are perl modules and should be installed somewhere in the perl
|
||||
module search path. See the @INC list at the end of the output of `perl -V`
|
||||
for a list of the directories in that path. All plugins are in the
|
||||
IkiWiki::Plugin namespace, so they go in a IkiWiki/Plugin subdirectory
|
||||
Most ikiwiki plugins are perl modules and should be installed somewhere in
|
||||
the perl module search path. See the @INC list at the end of the output of
|
||||
`perl -V` for a list of the directories in that path. All plugins are in
|
||||
the IkiWiki::Plugin namespace, so they go in a IkiWiki/Plugin subdirectory
|
||||
inside the perl search path. For example, if your perl looks in
|
||||
`/usr/local/lib/site_perl` for modules, you can locally install ikiwiki
|
||||
plugins to `/usr/local/lib/site_perl/IkiWiki/Plugin`
|
||||
|
@ -17,3 +17,8 @@ plugins to `/usr/local/lib/site_perl/IkiWiki/Plugin`
|
|||
You can use the `libdir` configuration option to add a directory to the
|
||||
search path. For example, if you set `libdir` to `/home/you/.ikiwiki/`,
|
||||
then ikiwiki will look for plugins in `/home/you/.ikiwiki/IkiWiki/Plugins`.
|
||||
|
||||
Ikiwiki also supports plugins that are external programs. These are
|
||||
typically written in some other language than perl. Ikiwiki searches for
|
||||
these in /usr/lib/ikiwiki/plugins by default. If `libdir` is set, it will
|
||||
also look in that directory, for example in `/home/you/.ikiwiki/plugins`.
|
||||
|
|
|
@ -1,8 +1,26 @@
|
|||
ikiwiki [[plugins]] are written in perl. Each plugin is a perl module, in
|
||||
the `IkiWiki::Plugin` namespace. The name of the plugin is typically in
|
||||
lowercase, such as `IkiWiki::Plugin::inline`. Ikiwiki includes a
|
||||
`IkiWiki::Plugin::skeleton` that can be fleshed out to make a useful
|
||||
plugin. `IkiWiki::Plugin::pagecount` is another simple example.
|
||||
Most ikiwiki [[plugins]] are written in perl, like ikiwiki. This gives the
|
||||
plugin full access to ikiwiki's internals, and is the most efficient.
|
||||
However, plugins can actually be written in any language that supports XML
|
||||
RPC. These are called [[external]] plugins.
|
||||
|
||||
A plugin written in perl is a perl module, in the `IkiWiki::Plugin`
|
||||
namespace. The name of the plugin is typically in lowercase, such as
|
||||
`IkiWiki::Plugin::inline`. Ikiwiki includes a `IkiWiki::Plugin::skeleton`
|
||||
that can be fleshed out to make a useful plugin.
|
||||
`IkiWiki::Plugin::pagecount` is another simple example. All perl plugins
|
||||
should `use IkiWiki` to import the ikiwiki plugin interface. It's a good
|
||||
idea to include the version number of the plugin interface that your plugin
|
||||
expects: `use IkiWiki 2.00`.
|
||||
|
||||
An external plugin is an executable program. It can be written in any
|
||||
language. Its interface to ikiwiki is via XML RPC, which it reads from
|
||||
ikiwiki on its standard input, and writes to ikiwiki on its standard
|
||||
output. For more details on writing external plugins, see [[external]].
|
||||
|
||||
Despite these two types of plugins having such different interfaces,
|
||||
they're the same as far as how they hook into ikiwiki. This document will
|
||||
explain how to write both sorts of plugins, albeit with an emphasis on perl
|
||||
plugins.
|
||||
|
||||
[[toc levels=2]]
|
||||
|
||||
|
@ -19,18 +37,13 @@ being edited.
|
|||
|
||||
## Registering plugins
|
||||
|
||||
All plugins should `use IkiWiki` to import the ikiwiki plugin interface.
|
||||
It's a good idea to include the version number of the plugin interface that
|
||||
your plugin expects: `use IkiWiki 2.00`
|
||||
|
||||
Plugins should, when imported, call `hook()` to hook into ikiwiki's
|
||||
processing. The function uses named parameters, and use varies depending on
|
||||
the type of hook being registered -- see below. Note that a plugin can call
|
||||
the function more than once to register multiple hooks. All calls to
|
||||
`hook()` should be passed a "type" parameter, which gives the type of
|
||||
hook, a "id" paramter, which should be a unique string for this plugin, and
|
||||
a "call" parameter, which is a reference to a function to call for the
|
||||
hook.
|
||||
a "call" parameter, which tells what function to call for the hook.
|
||||
|
||||
An optional "last" parameter, if set to a true value, makes the hook run
|
||||
after all other hooks of its type. Useful if the hook depends on some other
|
||||
|
@ -272,7 +285,7 @@ namespace. These variables and functions are the ones most plugins need,
|
|||
and a special effort will be made to avoid changing them in incompatible
|
||||
ways, and to document any changes that have to be made in the future.
|
||||
|
||||
Note that IkiWiki also provides other variables functions that are not
|
||||
Note that IkiWiki also provides other variables and functions that are not
|
||||
exported by default. No guarantee is made about these in the future, so if
|
||||
it's not exported, the wise choice is to not use it.
|
||||
|
||||
|
@ -287,7 +300,7 @@ hash. The best way to understand the contents of the hash is to look at
|
|||
If your plugin needs to access data about other pages in the wiki. It can
|
||||
use the following hashes, using a page name as the key:
|
||||
|
||||
* `links` lists the names of each page that a page links to, in an array
|
||||
* `%links` lists the names of each page that a page links to, in an array
|
||||
reference.
|
||||
* `%destsources` contains the name of the source file used to create each
|
||||
destination file.
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
External plugins are standalone, executable programs, that can be written
|
||||
in any language. When ikiwiki starts up, it runs the program, and
|
||||
communicates with it using XML RPC. If you want to [[write]] an external
|
||||
plugin, read on..
|
||||
|
||||
ikiwiki contains one sample external plugin, named `externaldemo`. This is
|
||||
written in perl, but is intended to be an example of how to write an
|
||||
external plugin in your favorite programming language. Wow us at how much
|
||||
easier you can do the same thing in your favorite language. ;-)
|
||||
|
||||
## How external plugins use XML RPC
|
||||
|
||||
While XML RPC is typically used over http, ikiwiki doesn't do that.
|
||||
Instead, the external plugin reads XML RPC data from stdin, and writes it
|
||||
to stdout. To ease parsing, each separate XML RPC request or response must
|
||||
start at the beginning of a line, and end with a newline. When outputting
|
||||
XML RPC to stdout, be _sure_ to flush stdout. Failure to do so will result
|
||||
in deadlock!
|
||||
|
||||
An external plugin should operate in a loop. First, read a command from
|
||||
stdin, using XML RPC. Dispatch the command, and return its result to
|
||||
stdout, also using XML RPC. After reading a command, and before returning
|
||||
the result, the plugin can output XML RPC requests of its own, calling
|
||||
functions in ikiwiki. Note: *Never* make an XML RPC request at any other
|
||||
time. Ikiwiki won't be listening for it, and you will deadlock.
|
||||
|
||||
When ikiwiki starts up an external plugin, the first RPC it will make
|
||||
is to call the plugin's `import()` function. That function typically makes
|
||||
an RPC to ikiwiki's `hook()` function, registering a callback.
|
||||
|
||||
An external plugin can use XML RPC to call any of the exported functions
|
||||
documented in the [[plugin_interface_documentation|write]]. It can also
|
||||
actually call any non-exported IkiWiki function, but doing so is a good way
|
||||
to break your plugin when ikiwiki changes. There is currently no versioned
|
||||
interface like there is for perl plugins, but external plugins were first
|
||||
supported in ikiwiki version 2.6.
|
||||
|
||||
## Accessing data structures
|
||||
|
||||
Ikiwiki has a few global data structures such as `%config`, which holds
|
||||
its configuration. External plugins can use the `getvar` and `setvar` RPCs
|
||||
to access any such global hash. To get the "url" configuration value,
|
||||
call `getvar("config", "url")`. To set it, call
|
||||
`setvar("config", "url", "http://example.com/)`.
|
||||
|
||||
## Notes on function parameters
|
||||
|
||||
The [[plugin_interface_documentation|write]] talks about functions that take
|
||||
"named parameters". When such a function is called over XML RPC, such named
|
||||
parameters look like a list of keys and values:
|
||||
|
||||
page, foo, destpage, bar, magnify, 1
|
||||
|
||||
If a name is repeated in the list, the later value overrides the earlier
|
||||
one:
|
||||
|
||||
name, Bob, age, 20, name, Sally, gender, female
|
||||
|
||||
In perl, boiling this down to an associative array of named parameters is
|
||||
very easy:
|
||||
|
||||
sub foo {
|
||||
my %params=@list;
|
||||
|
||||
Other languages might not find it so easy. If not, it might be a good idea
|
||||
to convert these named parameters into something more natural for the
|
||||
language as part of their XML RPC interface.
|
||||
|
||||
## Function injection
|
||||
|
||||
Some parts of ikiwiki are extensible by adding functions. For example, the
|
||||
RCS interface relies on plugins providing several IkiWiki::rcs_* functions.
|
||||
It's actually possible to do this from an external plugin too.
|
||||
|
||||
To make your external plugin provide an `IkiWiki::rcs_update` function, for
|
||||
example, make an RPC call to `inject`. Pass it named parameters "name" and
|
||||
"call", where "name" is the name of the function to inject into perl (here
|
||||
"Ikiwiki::rcs_update" and "call" is the RPC call ikiwiki will make whenever
|
||||
that function is run.
|
||||
|
||||
## Limitations of XML RPC
|
||||
|
||||
Since XML RPC can't pass around references to objects, it can't be used
|
||||
with functions that take or return such references. That means you can't
|
||||
use XML RPC for `cgi` or `formbuilder` hooks (which are passed CGI and
|
||||
FormBuilder perl objects), or use it to call `template()` (which returns a
|
||||
perl HTML::Template object).
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
ikiwiki should support writing plugins in other languages
|
||||
|
||||
> [[done]] !!
|
||||
|
||||
While it should be possible to call ikiwiki from C, doing the callbacks in C is
|
||||
probably hard. And accessing perl at all from C is ugly. It also doesn't
|
||||
make it very easy to write plugins in an interpreted language, since that
|
||||
|
@ -11,46 +13,39 @@ child process that it can spawn. The child could then be any program,
|
|||
written in any language. It could talk XML RPC via stdio. (This assumes
|
||||
that most languages allow easily serialising XML::RPC calls and responses
|
||||
to a file descriptor. Some XML RPC implementations may be hardcoded to use
|
||||
http..)
|
||||
http..) For ease of implementation, each rpc request sent via stio should
|
||||
end with a newline, and begin with "<?xml ..>".
|
||||
|
||||
Here's how it would basically look, not showing the actual XML RPC used to
|
||||
pass values.
|
||||
|
||||
-> import
|
||||
<- 1
|
||||
<- hook type => preprocess, id => foo
|
||||
-> 1
|
||||
<- done 1
|
||||
-> 1
|
||||
-> call import
|
||||
<- call hook type => preprocess, id => foo, call => plugin_preprocess
|
||||
-> result 1
|
||||
<- result 1
|
||||
|
||||
-> callback type => preprocess, id => foo, page => bar
|
||||
<- 1
|
||||
<- getconfig url
|
||||
-> "http://example.com", ...
|
||||
<- debug "foo"
|
||||
-> 1
|
||||
<- done "my return value"
|
||||
-> 1
|
||||
-> call plugin_preprocess page => bar
|
||||
<- call getconfig url
|
||||
-> result "http://example.com", ...
|
||||
<- call debug "foo"
|
||||
-> result 1
|
||||
<- result done "my return value"
|
||||
|
||||
From ikiwiki's POV:
|
||||
|
||||
* ikiwiki always initiates each conversation with a command
|
||||
* After sending a command, ikiwiki reads commands, dispatches them, and
|
||||
returns the results, in a loop.
|
||||
* The loop continues until the plugin calls the "done" command, with a value
|
||||
that is the return value for the command that initiated the conversation.
|
||||
returns the results, in a loop, until it gets a result for the command it
|
||||
called.
|
||||
|
||||
From the plugin's POV:
|
||||
|
||||
* It's probably sitting in an XML::RPC loop.
|
||||
* Get a command from ikiwiki.
|
||||
* Disaptch the command to the appropriate function. The main commands seem
|
||||
to be "import" and "callback"; callback can call any function that the
|
||||
plugin has registered a hook for. Others commands might include
|
||||
"rcs_*" for RCS plugins..
|
||||
* Dispatch the command to the appropriate function.
|
||||
* The function can use XML::RPC to communicate with ikiwiki to get things
|
||||
like config values; and to call ikiwiki functions.
|
||||
* When the callback returns, use XML::RPC to send a "done" command to ikiwiki.
|
||||
* Send the function's return value back to ikiwiki.
|
||||
|
||||
Simple enough, really. ikiwiki would need to add accessor functions for
|
||||
all important variables, such as "getconfig" and "setconfig". It would
|
||||
|
|
|
@ -231,9 +231,10 @@ configuration options of their own.
|
|||
|
||||
* --libdir directory
|
||||
|
||||
Makes ikiwiki look in the specified directory first, before the regular perl
|
||||
library directories. For example, if you set libdir to "/home/you/.ikiwiki/",
|
||||
you can install plugins in "/home/you/.ikiwiki/IkiWiki/Plugin/".
|
||||
Makes ikiwiki look in the specified directory first, before the regular
|
||||
locations when loading library files and plugins. For example, if you set
|
||||
libdir to "/home/you/.ikiwiki/", you can install a Foo.pm plugin as
|
||||
"/home/you/.ikiwiki/IkiWiki/Plugin/Foo.pm".
|
||||
|
||||
* --discussion, --no-discussion
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ sub getconfig () { #{{{
|
|||
"httpauth!" => \$config{httpauth},
|
||||
"userdir=s" => \$config{userdir},
|
||||
"htmlext=s" => \$config{htmlext},
|
||||
"libdir" => \$config{libdir},
|
||||
"libdir=s" => \$config{libdir},
|
||||
"exclude=s@" => sub {
|
||||
push @{$config{wiki_file_prune_regexps}}, $_[1];
|
||||
},
|
||||
|
|
|
@ -0,0 +1,132 @@
|
|||
#!/usr/bin/perl
|
||||
# Demo external plugin. Kinda pointless, since it's a perl script, but
|
||||
# useful for testing or as an hint of how to write an external plugin in
|
||||
# other languages.
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
print STDERR "externaldemo plugin running as pid $$\n";
|
||||
|
||||
use RPC::XML;
|
||||
use RPC::XML::Parser;
|
||||
use IO::Handle;
|
||||
|
||||
# autoflush stdout
|
||||
$|=1;
|
||||
|
||||
# Used to build up RPC calls as they're read from stdin.
|
||||
my $accum="";
|
||||
|
||||
sub rpc_read {
|
||||
# Read stdin, a line at a time, until a whole RPC call is accumulated.
|
||||
# Parse to XML::RPC object and return.
|
||||
while (<>) {
|
||||
$accum.=$_;
|
||||
|
||||
# Kinda hackish approch to parse a single XML RPC out of the
|
||||
# accumulated input. Relies on calls always ending with a
|
||||
# newline, which ikiwiki's protocol requires be true.
|
||||
if ($accum =~ /^\s*(<\?xml\s.*?<\/(?:methodCall|methodResponse)>)\n(.*)/s) {
|
||||
$accum=$2; # the rest
|
||||
|
||||
# Now parse the XML RPC.
|
||||
my $r = RPC::XML::Parser->new->parse($1);
|
||||
if (! ref $r) {
|
||||
die "error: XML RPC parse failure $r";
|
||||
}
|
||||
return $r;
|
||||
}
|
||||
}
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub rpc_handle {
|
||||
# Handle an incoming XML RPC command.
|
||||
my $r=rpc_read();
|
||||
if (! defined $r) {
|
||||
return 0;
|
||||
}
|
||||
if ($r->isa("RPC::XML::request")) {
|
||||
my $name=$r->name;
|
||||
my @args=map { $_->value } @{$r->args};
|
||||
# Dispatch the requested function. This could be
|
||||
# done with a switch statement on the name, or
|
||||
# whatever. I'll use eval to call the function with
|
||||
# the name.
|
||||
my $ret = eval $name.'(@args)';
|
||||
die $@ if $@;
|
||||
|
||||
# Now send the repsonse from the function back,
|
||||
# followed by a newline.
|
||||
my $resp=RPC::XML::response->new($ret);
|
||||
$resp->serialize(\*STDOUT);
|
||||
print "\n";
|
||||
# stdout needs to be flushed here. If it isn't,
|
||||
# things will deadlock. Perl flushes it
|
||||
# automatically when $| is set.
|
||||
return 1;
|
||||
}
|
||||
elsif ($r->isa("RPC::XML::response")) {
|
||||
die "protocol error; got a response when expecting a request";
|
||||
}
|
||||
}
|
||||
|
||||
sub rpc_call {
|
||||
# Make an XML RPC call and return the result.
|
||||
my $command=shift;
|
||||
my @params=@_;
|
||||
|
||||
my $req=RPC::XML::request->new($command, @params);
|
||||
$req->serialize(\*STDOUT);
|
||||
print "\n";
|
||||
# stdout needs to be flushed here to prevent deadlock. Perl does it
|
||||
# automatically when $| is set.
|
||||
|
||||
my $r=rpc_read();
|
||||
if ($r->isa("RPC::XML::response")) {
|
||||
return $r->value->value;
|
||||
}
|
||||
else {
|
||||
die "protocol error; got a request when expecting a response";
|
||||
}
|
||||
}
|
||||
|
||||
# Now on with the actual plugin. Let's do a simple preprocessor plugin.
|
||||
|
||||
sub import {
|
||||
# The import function will be called by ikiwiki when the plugin is
|
||||
# loaded. When it's imported, it needs to hook into the preprocessor
|
||||
# stage of ikiwiki.
|
||||
rpc_call("hook", type => "preprocess", id => "externaldemo", call => "preprocess");
|
||||
|
||||
# Here's an example of how to inject an arbitrary function into
|
||||
# ikiwiki. Ikiwiki will be able to call bob() just like any other
|
||||
# function.
|
||||
rpc_call("inject", name => "IkiWiki::bob", call => "bob");
|
||||
|
||||
# Here's an exmaple of how to access values in %IkiWiki::config.
|
||||
print STDERR "url is set to: ".
|
||||
rpc_call("getvar", "config", "url")."\n";
|
||||
|
||||
print STDERR "externaldemo plugin successfully imported\n";
|
||||
}
|
||||
|
||||
sub preprocess {
|
||||
# This function will be called when ikiwiki wants to preprocess
|
||||
# something.
|
||||
my %params=@_;
|
||||
|
||||
# Let's use IkiWiki's pagetitle function to turn the page name into
|
||||
# a title.
|
||||
my $title=rpc_call("pagetitle", $params{page});
|
||||
|
||||
return "externaldemo plugin preprocessing on $title!";
|
||||
}
|
||||
|
||||
sub bob {
|
||||
print STDERR "externaldemo plugin's bob called via RPC";
|
||||
}
|
||||
|
||||
# Now all that's left to do is loop and handle each incoming RPC request.
|
||||
while (rpc_handle()) { print STDERR "externaldemo plugin handled RPC request\n" }
|
29
po/es.po
29
po/es.po
|
@ -7,7 +7,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: es\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2007-08-05 13:46-0700\n"
|
||||
"POT-Creation-Date: 2007-08-12 22:57-0400\n"
|
||||
"PO-Revision-Date: 2007-04-28 22:01+0200\n"
|
||||
"Last-Translator: Víctor Moral <victor@taquiones.net>\n"
|
||||
"Language-Team: Spanish <es@li.org>\n"
|
||||
|
@ -41,7 +41,7 @@ msgid "%s is not an editable page"
|
|||
msgstr "la página %s no es modificable"
|
||||
|
||||
#: ../IkiWiki/CGI.pm:429 ../IkiWiki/Plugin/brokenlinks.pm:24
|
||||
#: ../IkiWiki/Plugin/inline.pm:184 ../IkiWiki/Plugin/opendiscussion.pm:17
|
||||
#: ../IkiWiki/Plugin/inline.pm:208 ../IkiWiki/Plugin/opendiscussion.pm:17
|
||||
#: ../IkiWiki/Plugin/orphans.pm:28 ../IkiWiki/Render.pm:99
|
||||
#: ../IkiWiki/Render.pm:179
|
||||
msgid "discussion"
|
||||
|
@ -58,11 +58,11 @@ msgstr "creando página %s"
|
|||
msgid "editing %s"
|
||||
msgstr "modificando página %s"
|
||||
|
||||
#: ../IkiWiki/CGI.pm:691
|
||||
#: ../IkiWiki/CGI.pm:688
|
||||
msgid "You are banned."
|
||||
msgstr "Ha sido expulsado."
|
||||
|
||||
#: ../IkiWiki/CGI.pm:723
|
||||
#: ../IkiWiki/CGI.pm:708
|
||||
msgid "login failed, perhaps you need to turn on cookies?"
|
||||
msgstr ""
|
||||
"registro fallido, ¿ tal vez necesita activar las cookies en el navegador ?"
|
||||
|
@ -170,34 +170,35 @@ msgid "failed to resize: %s"
|
|||
msgstr "redimensionado fallido: %s"
|
||||
|
||||
#: ../IkiWiki/Plugin/img.pm:96
|
||||
#, perl-format
|
||||
msgid "failed to determine size of image %s"
|
||||
msgstr "no he podido determinar el tamaño de la imagen %s"
|
||||
|
||||
#: ../IkiWiki/Plugin/inline.pm:36
|
||||
#: ../IkiWiki/Plugin/inline.pm:39
|
||||
msgid "Must specify url to wiki with --url when using --rss or --atom"
|
||||
msgstr ""
|
||||
"Es obligatorio indicar un url al wiki cuando se usan los parámetros --rss ó "
|
||||
"--atom"
|
||||
|
||||
#: ../IkiWiki/Plugin/inline.pm:106
|
||||
#: ../IkiWiki/Plugin/inline.pm:130
|
||||
#, perl-format
|
||||
msgid "unknown sort type %s"
|
||||
msgstr "no conozco este tipo de ordenación %s"
|
||||
|
||||
#: ../IkiWiki/Plugin/inline.pm:146
|
||||
#: ../IkiWiki/Plugin/inline.pm:170
|
||||
msgid "Add a new post titled:"
|
||||
msgstr "Añadir una entrada nueva titulada:"
|
||||
|
||||
#: ../IkiWiki/Plugin/inline.pm:161
|
||||
#: ../IkiWiki/Plugin/inline.pm:185
|
||||
#, perl-format
|
||||
msgid "nonexistant template %s"
|
||||
msgstr "la plantilla %s no existe "
|
||||
|
||||
#: ../IkiWiki/Plugin/inline.pm:192 ../IkiWiki/Render.pm:103
|
||||
#: ../IkiWiki/Plugin/inline.pm:216 ../IkiWiki/Render.pm:103
|
||||
msgid "Discussion"
|
||||
msgstr "Comentarios"
|
||||
|
||||
#: ../IkiWiki/Plugin/inline.pm:403
|
||||
#: ../IkiWiki/Plugin/inline.pm:429
|
||||
msgid "RPC::XML::Client not found, not pinging"
|
||||
msgstr "No he encontrado el componente RPC::XML::Client, no envío señal alguna"
|
||||
|
||||
|
@ -281,11 +282,11 @@ msgstr "El complemento polygen no ha sido instalado"
|
|||
msgid "polygen failed"
|
||||
msgstr "El programa polygen ha fallado"
|
||||
|
||||
#: ../IkiWiki/Plugin/postsparkline.pm:25
|
||||
#: ../IkiWiki/Plugin/postsparkline.pm:32
|
||||
msgid "missing formula"
|
||||
msgstr "falta la fórmula"
|
||||
|
||||
#: ../IkiWiki/Plugin/postsparkline.pm:32
|
||||
#: ../IkiWiki/Plugin/postsparkline.pm:39
|
||||
msgid "unknown formula"
|
||||
msgstr "fórmula desconocida "
|
||||
|
||||
|
@ -586,7 +587,7 @@ msgstr ""
|
|||
"Es obligatorio especificar un url al wiki con el parámetro --url si se "
|
||||
"utiliza el parámetro --cgi"
|
||||
|
||||
#: ../IkiWiki.pm:175 ../IkiWiki.pm:176
|
||||
#: ../IkiWiki.pm:184 ../IkiWiki.pm:185
|
||||
msgid "Error"
|
||||
msgstr "Error"
|
||||
|
||||
|
@ -594,7 +595,7 @@ msgstr "Error"
|
|||
#. translators: preprocessor directive name,
|
||||
#. translators: the second a page name, the
|
||||
#. translators: third a number.
|
||||
#: ../IkiWiki.pm:667
|
||||
#: ../IkiWiki.pm:676
|
||||
#, perl-format
|
||||
msgid "%s preprocessing loop detected on %s at depth %i"
|
||||
msgstr ""
|
||||
|
|
78
po/fr.po
78
po/fr.po
|
@ -7,7 +7,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: ikiwiki\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2007-06-29 20:49-0400\n"
|
||||
"POT-Creation-Date: 2007-08-12 22:57-0400\n"
|
||||
"PO-Revision-Date: 2007-08-05 23:38+0200\n"
|
||||
"Last-Translator: Cyril Brulebois <cyril.brulebois@enst-bretagne.fr>\n"
|
||||
"Language-Team: French <debian-l10n-french@lists.debian.org>\n"
|
||||
|
@ -37,34 +37,34 @@ msgstr "Administrateur"
|
|||
msgid "Preferences saved."
|
||||
msgstr "Les préférences ont été enregistrées."
|
||||
|
||||
#: ../IkiWiki/CGI.pm:349
|
||||
#: ../IkiWiki/CGI.pm:350
|
||||
#, perl-format
|
||||
msgid "%s is not an editable page"
|
||||
msgstr "%s n'est pas une page éditable"
|
||||
|
||||
#: ../IkiWiki/CGI.pm:428 ../IkiWiki/Plugin/brokenlinks.pm:24
|
||||
#: ../IkiWiki/Plugin/inline.pm:184 ../IkiWiki/Plugin/opendiscussion.pm:17
|
||||
#: ../IkiWiki/Plugin/orphans.pm:28 ../IkiWiki/Render.pm:91
|
||||
#: ../IkiWiki/Render.pm:171
|
||||
#: ../IkiWiki/CGI.pm:429 ../IkiWiki/Plugin/brokenlinks.pm:24
|
||||
#: ../IkiWiki/Plugin/inline.pm:208 ../IkiWiki/Plugin/opendiscussion.pm:17
|
||||
#: ../IkiWiki/Plugin/orphans.pm:28 ../IkiWiki/Render.pm:99
|
||||
#: ../IkiWiki/Render.pm:179
|
||||
msgid "discussion"
|
||||
msgstr "Discussion"
|
||||
|
||||
#: ../IkiWiki/CGI.pm:474
|
||||
#: ../IkiWiki/CGI.pm:475
|
||||
#, perl-format
|
||||
msgid "creating %s"
|
||||
msgstr "Création de %s"
|
||||
|
||||
#: ../IkiWiki/CGI.pm:491 ../IkiWiki/CGI.pm:506 ../IkiWiki/CGI.pm:517
|
||||
#: ../IkiWiki/CGI.pm:543 ../IkiWiki/CGI.pm:587
|
||||
#: ../IkiWiki/CGI.pm:493 ../IkiWiki/CGI.pm:509 ../IkiWiki/CGI.pm:521
|
||||
#: ../IkiWiki/CGI.pm:548 ../IkiWiki/CGI.pm:593
|
||||
#, perl-format
|
||||
msgid "editing %s"
|
||||
msgstr "Édition de %s"
|
||||
|
||||
#: ../IkiWiki/CGI.pm:684
|
||||
#: ../IkiWiki/CGI.pm:688
|
||||
msgid "You are banned."
|
||||
msgstr "Vous avez été banni."
|
||||
|
||||
#: ../IkiWiki/CGI.pm:716
|
||||
#: ../IkiWiki/CGI.pm:708
|
||||
msgid "login failed, perhaps you need to turn on cookies?"
|
||||
msgstr ""
|
||||
"Échec de l'identification, vous devriez peut-être autoriser les cookies."
|
||||
|
@ -146,11 +146,11 @@ msgstr "Échec du lancement de « fortune »"
|
|||
msgid "failed to find url in html"
|
||||
msgstr "Échec dans la recherche de l'URL dans le code HTML"
|
||||
|
||||
#: ../IkiWiki/Plugin/graphviz.pm:59
|
||||
#: ../IkiWiki/Plugin/graphviz.pm:58
|
||||
msgid "failed to run graphviz"
|
||||
msgstr "Échec du lancement de graphviz"
|
||||
|
||||
#: ../IkiWiki/Plugin/graphviz.pm:81
|
||||
#: ../IkiWiki/Plugin/graphviz.pm:85
|
||||
msgid "prog not a valid graphviz program"
|
||||
msgstr "Le programme n'est pas un programme graphviz valable"
|
||||
|
||||
|
@ -175,31 +175,31 @@ msgstr "Échec du redimensionnement : %s"
|
|||
msgid "failed to determine size of image %s"
|
||||
msgstr "Échec du redimensionnement : %s"
|
||||
|
||||
#: ../IkiWiki/Plugin/inline.pm:36
|
||||
#: ../IkiWiki/Plugin/inline.pm:39
|
||||
msgid "Must specify url to wiki with --url when using --rss or --atom"
|
||||
msgstr ""
|
||||
"Vous devez indiquer l'URL du wiki par --url lors de l'utilisation de --rss "
|
||||
"ou --atom"
|
||||
|
||||
#: ../IkiWiki/Plugin/inline.pm:106
|
||||
#: ../IkiWiki/Plugin/inline.pm:130
|
||||
#, perl-format
|
||||
msgid "unknown sort type %s"
|
||||
msgstr "Type de tri %s inconnu"
|
||||
|
||||
#: ../IkiWiki/Plugin/inline.pm:146
|
||||
#: ../IkiWiki/Plugin/inline.pm:170
|
||||
msgid "Add a new post titled:"
|
||||
msgstr "Ajouter un nouveau article dont le titre est :"
|
||||
|
||||
#: ../IkiWiki/Plugin/inline.pm:161
|
||||
#: ../IkiWiki/Plugin/inline.pm:185
|
||||
#, perl-format
|
||||
msgid "nonexistant template %s"
|
||||
msgstr "Le modèle (« template ») %s n'existe pas"
|
||||
|
||||
#: ../IkiWiki/Plugin/inline.pm:192 ../IkiWiki/Render.pm:95
|
||||
#: ../IkiWiki/Plugin/inline.pm:216 ../IkiWiki/Render.pm:103
|
||||
msgid "Discussion"
|
||||
msgstr "Discussion"
|
||||
|
||||
#: ../IkiWiki/Plugin/inline.pm:403
|
||||
#: ../IkiWiki/Plugin/inline.pm:429
|
||||
msgid "RPC::XML::Client not found, not pinging"
|
||||
msgstr "RPC::XML::Client introuvable, pas de réponse au ping"
|
||||
|
||||
|
@ -247,6 +247,10 @@ msgstr "Obtenir un compte OpenID"
|
|||
msgid "All pages are linked to by other pages."
|
||||
msgstr "Toutes les pages sont liées à d'autres pages."
|
||||
|
||||
#: ../IkiWiki/Plugin/pagetemplate.pm:21
|
||||
msgid "bad or missing template"
|
||||
msgstr ""
|
||||
|
||||
#: ../IkiWiki/Plugin/passwordauth.pm:162
|
||||
msgid "Account creation successful. Now you can Login."
|
||||
msgstr "Le compte a été créé. Vous pouvez maintenant vous identifier."
|
||||
|
@ -279,11 +283,11 @@ msgstr "polygen n'est pas installé"
|
|||
msgid "polygen failed"
|
||||
msgstr "Échec du lancement de polygen"
|
||||
|
||||
#: ../IkiWiki/Plugin/postsparkline.pm:25
|
||||
#: ../IkiWiki/Plugin/postsparkline.pm:32
|
||||
msgid "missing formula"
|
||||
msgstr "formule manquante"
|
||||
|
||||
#: ../IkiWiki/Plugin/postsparkline.pm:32
|
||||
#: ../IkiWiki/Plugin/postsparkline.pm:39
|
||||
msgid "unknown formula"
|
||||
msgstr "formule inconnue"
|
||||
|
||||
|
@ -459,47 +463,47 @@ msgstr ""
|
|||
"après un commit sur le SVN (« hook post-commit »), impossible d'envoyer des "
|
||||
"notifications"
|
||||
|
||||
#: ../IkiWiki/Render.pm:255 ../IkiWiki/Render.pm:275
|
||||
#: ../IkiWiki/Render.pm:263 ../IkiWiki/Render.pm:283
|
||||
#, perl-format
|
||||
msgid "skipping bad filename %s"
|
||||
msgstr "Saut du fichier incorrect %s"
|
||||
|
||||
#: ../IkiWiki/Render.pm:315
|
||||
#: ../IkiWiki/Render.pm:323
|
||||
#, perl-format
|
||||
msgid "removing old page %s"
|
||||
msgstr "Suppression de l'ancienne page %s"
|
||||
|
||||
#: ../IkiWiki/Render.pm:343
|
||||
#: ../IkiWiki/Render.pm:356
|
||||
#, perl-format
|
||||
msgid "scanning %s"
|
||||
msgstr "Parcours de %s"
|
||||
|
||||
#: ../IkiWiki/Render.pm:348
|
||||
#: ../IkiWiki/Render.pm:361
|
||||
#, perl-format
|
||||
msgid "rendering %s"
|
||||
msgstr "Rendu de %s"
|
||||
|
||||
#: ../IkiWiki/Render.pm:360
|
||||
#: ../IkiWiki/Render.pm:373
|
||||
#, perl-format
|
||||
msgid "rendering %s, which links to %s"
|
||||
msgstr "Rendu de %s, qui est lié à %s"
|
||||
|
||||
#: ../IkiWiki/Render.pm:377
|
||||
#: ../IkiWiki/Render.pm:390
|
||||
#, perl-format
|
||||
msgid "rendering %s, which depends on %s"
|
||||
msgstr "Rendu de %s, qui dépend de %s"
|
||||
|
||||
#: ../IkiWiki/Render.pm:415
|
||||
#: ../IkiWiki/Render.pm:428
|
||||
#, perl-format
|
||||
msgid "rendering %s, to update its backlinks"
|
||||
msgstr "Rendu de %s, afin de mettre à jour ses rétroliens"
|
||||
|
||||
#: ../IkiWiki/Render.pm:427
|
||||
#: ../IkiWiki/Render.pm:440
|
||||
#, perl-format
|
||||
msgid "removing %s, no longer rendered by %s"
|
||||
msgstr "Suppression de %s, qui n'est plus rendu par %s"
|
||||
|
||||
#: ../IkiWiki/Render.pm:453
|
||||
#: ../IkiWiki/Render.pm:466
|
||||
#, perl-format
|
||||
msgid "ikiwiki: cannot render %s"
|
||||
msgstr "ikiwiki : impossible d'effectuer le rendu de %s"
|
||||
|
@ -558,13 +562,13 @@ msgid "failed to write %s: %s"
|
|||
msgstr "Échec de l'écriture de %s : %s"
|
||||
|
||||
#. translators: The parameter is a C filename.
|
||||
#: ../IkiWiki/Wrapper.pm:100
|
||||
#: ../IkiWiki/Wrapper.pm:107
|
||||
#, perl-format
|
||||
msgid "failed to compile %s"
|
||||
msgstr "Échec de la compilation de %s"
|
||||
|
||||
#. translators: The parameter is a filename.
|
||||
#: ../IkiWiki/Wrapper.pm:108
|
||||
#: ../IkiWiki/Wrapper.pm:115
|
||||
#, perl-format
|
||||
msgid "successfully generated %s"
|
||||
msgstr "%s a été créé avec succès"
|
||||
|
@ -573,13 +577,17 @@ msgstr "%s a été créé avec succès"
|
|||
msgid "usage: ikiwiki [options] source dest"
|
||||
msgstr "Syntaxe : ikiwiki [options] source destination"
|
||||
|
||||
#: ../IkiWiki.pm:122
|
||||
#: ../ikiwiki.in:81
|
||||
msgid "usage: --set var=value"
|
||||
msgstr ""
|
||||
|
||||
#: ../IkiWiki.pm:124
|
||||
msgid "Must specify url to wiki with --url when using --cgi"
|
||||
msgstr ""
|
||||
"Vous devez indiquer une URL vers le wiki par --url lors de l'utilisation de "
|
||||
"--cgi"
|
||||
|
||||
#: ../IkiWiki.pm:169 ../IkiWiki.pm:170
|
||||
#: ../IkiWiki.pm:184 ../IkiWiki.pm:185
|
||||
msgid "Error"
|
||||
msgstr "Erreur"
|
||||
|
||||
|
@ -587,7 +595,7 @@ msgstr "Erreur"
|
|||
#. translators: preprocessor directive name,
|
||||
#. translators: the second a page name, the
|
||||
#. translators: third a number.
|
||||
#: ../IkiWiki.pm:656
|
||||
#: ../IkiWiki.pm:676
|
||||
#, perl-format
|
||||
msgid "%s preprocessing loop detected on %s at depth %i"
|
||||
msgstr ""
|
||||
|
|
|
@ -8,7 +8,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2007-08-05 14:56-0700\n"
|
||||
"POT-Creation-Date: 2007-08-12 22:57-0400\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
|
@ -42,7 +42,7 @@ msgid "%s is not an editable page"
|
|||
msgstr ""
|
||||
|
||||
#: ../IkiWiki/CGI.pm:429 ../IkiWiki/Plugin/brokenlinks.pm:24
|
||||
#: ../IkiWiki/Plugin/inline.pm:206 ../IkiWiki/Plugin/opendiscussion.pm:17
|
||||
#: ../IkiWiki/Plugin/inline.pm:208 ../IkiWiki/Plugin/opendiscussion.pm:17
|
||||
#: ../IkiWiki/Plugin/orphans.pm:28 ../IkiWiki/Render.pm:99
|
||||
#: ../IkiWiki/Render.pm:179
|
||||
msgid "discussion"
|
||||
|
@ -173,29 +173,29 @@ msgstr ""
|
|||
msgid "failed to determine size of image %s"
|
||||
msgstr ""
|
||||
|
||||
#: ../IkiWiki/Plugin/inline.pm:37
|
||||
#: ../IkiWiki/Plugin/inline.pm:39
|
||||
msgid "Must specify url to wiki with --url when using --rss or --atom"
|
||||
msgstr ""
|
||||
|
||||
#: ../IkiWiki/Plugin/inline.pm:128
|
||||
#: ../IkiWiki/Plugin/inline.pm:130
|
||||
#, perl-format
|
||||
msgid "unknown sort type %s"
|
||||
msgstr ""
|
||||
|
||||
#: ../IkiWiki/Plugin/inline.pm:168
|
||||
#: ../IkiWiki/Plugin/inline.pm:170
|
||||
msgid "Add a new post titled:"
|
||||
msgstr ""
|
||||
|
||||
#: ../IkiWiki/Plugin/inline.pm:183
|
||||
#: ../IkiWiki/Plugin/inline.pm:185
|
||||
#, perl-format
|
||||
msgid "nonexistant template %s"
|
||||
msgstr ""
|
||||
|
||||
#: ../IkiWiki/Plugin/inline.pm:214 ../IkiWiki/Render.pm:103
|
||||
#: ../IkiWiki/Plugin/inline.pm:216 ../IkiWiki/Render.pm:103
|
||||
msgid "Discussion"
|
||||
msgstr ""
|
||||
|
||||
#: ../IkiWiki/Plugin/inline.pm:425
|
||||
#: ../IkiWiki/Plugin/inline.pm:429
|
||||
msgid "RPC::XML::Client not found, not pinging"
|
||||
msgstr ""
|
||||
|
||||
|
@ -277,11 +277,11 @@ msgstr ""
|
|||
msgid "polygen failed"
|
||||
msgstr ""
|
||||
|
||||
#: ../IkiWiki/Plugin/postsparkline.pm:25
|
||||
#: ../IkiWiki/Plugin/postsparkline.pm:32
|
||||
msgid "missing formula"
|
||||
msgstr ""
|
||||
|
||||
#: ../IkiWiki/Plugin/postsparkline.pm:32
|
||||
#: ../IkiWiki/Plugin/postsparkline.pm:39
|
||||
msgid "unknown formula"
|
||||
msgstr ""
|
||||
|
||||
|
@ -575,7 +575,7 @@ msgstr ""
|
|||
msgid "Must specify url to wiki with --url when using --cgi"
|
||||
msgstr ""
|
||||
|
||||
#: ../IkiWiki.pm:175 ../IkiWiki.pm:176
|
||||
#: ../IkiWiki.pm:184 ../IkiWiki.pm:185
|
||||
msgid "Error"
|
||||
msgstr ""
|
||||
|
||||
|
@ -583,7 +583,7 @@ msgstr ""
|
|||
#. translators: preprocessor directive name,
|
||||
#. translators: the second a page name, the
|
||||
#. translators: third a number.
|
||||
#: ../IkiWiki.pm:667
|
||||
#: ../IkiWiki.pm:676
|
||||
#, perl-format
|
||||
msgid "%s preprocessing loop detected on %s at depth %i"
|
||||
msgstr ""
|
||||
|
|
Loading…
Reference in New Issue