X-Git-Url: https://sipb.mit.edu/gitweb.cgi/ikiwiki.git/blobdiff_plain/dc342e20703804d2ff2f36458e54e298226d5db0..29bf14fcc3209e798259f61f5c43deaf470620b9:/doc/todo/support_for_plugins_written_in_other_languages.mdwn diff --git a/doc/todo/support_for_plugins_written_in_other_languages.mdwn b/doc/todo/support_for_plugins_written_in_other_languages.mdwn index 65fd84f90..8476d1b44 100644 --- a/doc/todo/support_for_plugins_written_in_other_languages.mdwn +++ b/doc/todo/support_for_plugins_written_in_other_languages.mdwn @@ -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 @@ -8,40 +10,47 @@ that, never again.) Instead, I'm considering using XML RPC to let ikiwiki communicate with a child process that it can spawn. The child could then be any program, -written in any language. It could talk XML RPC via stdio. +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..) For ease of implementation, each rpc request sent via stio should +end with a newline, and begin with "". Here's how it would basically look, not showing the actual XML RPC used to pass values. - -> init - <- 1 - <- hook type => preprocess, id => foo - -> 1 - <- done 1 - -> 1 - - -> callback type => preprocess id => foo, page => bar - <- 1 - <- getconfig url - -> "http://example.com", ... - <- debug "foo" - -> 1 - <- done "my return value" - -> 1 + -> call import + <- call hook type => preprocess, id => foo, call => plugin_preprocess + -> result 1 + <- result 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. -* Call the appropriate callback. -* The callback can use XML::RPC to communicate with ikiwiki to get things +* 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 +probably be easiest for ikiwiki to dispatch a command by just evaling +IkiWiki::$command. + +Plugin programs could be dropped into /usr/share/ikiwiki/plugins/, and +load_plugin() would just open2 the plugin program and call import.