+++ /dev/null
-
-ewiki internals and extension howto
-===================================
-
-This part of the [README] series describes a bit of the internals of
-the ewiki script and its plugin system. It lists variables, coding
-guidelines and a few recommendations.
-These informations are useful if you'd like to change some of the
-hardcoded behaviour, fix annoying bugs you've found or to write your
-own extensions. You do not need to read this, if you just want to
-setup and use a Wiki.
-
-
-README.programming
-¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
- 1 ewiki_ functions()
- 2 $GLOBALS pollution ($ewiki_ variables)
- 3 internal coding explained
- 3.1 how ewiki operates
- 3.2 used variables
- 4 Extension HowTo
- 4.1 the PlugInterface
- 4.2 plugin tasks
- 4.2.1 mpi plugins
- 4.2.2 authentication/permission plugins
- 4.3 writing your own plugin
- 4.4 format_* / rendering plugins
- 4.4.1 ewiki_format() internals
- 4.4.2 the format_ plugin hooks
- 4.4.3 $iii[] and $ooo[] block flags
- 4.4.4 your own block markup plugin
- 4.5 xpi plugin system
- 5 mysql database structure
- 6 Just using the wiki source transformation
-
-
-
-
- -------------------------------------------------------------------- 1 --
-
-
-
-
-
-ewiki_ functions()
-¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
-Some of the core functions of ewiki.php can be used separate from the
-others and some of them were designed to be replaced by different
-implementations.
-Btw, all the functions, constants and variables start with "ewiki_"
-to make it easier to mix it into other projects (reduces function name
-conflicts and similar problems, that usually arise if you join two
-or more scripts into one program).
-
-
- ewiki_page($id)
- ---------------
- This is the main function which fetches the selected WikiPage
- (or the one given with $id) via ewiki_database to transform
- with ewiki_format().
- If the requested page does not exist it returns the edit
- screen.
- It also includes some virtual pages (InfoAboutThisPage,
- NewestPages, SearchPage, ReferencesToThisPage, ...).
-
-
- ewiki_page_...()
- ----------------
- These functions were separated out from the main ewiki_page()
- to make it more readable.
- Most of them contain code to generate the few special/internal
- WikiPages (Search, Newest, Info, and the Edit <FORM>, ...)
-
-
- ewiki_control_links($id, $data)
- -------------------------------
- Prints the line with the EditThisPage and PageInfo, ... links.
-
-
- ewiki_format($wiki_source, $params)
- ----------------------------------------------------------
- This returns the formatted (HTML) output for the given WikiSource
- (with all the WikiMarkup in it).
-
- The second param is an array with various config overrides. An entry
- of "scan_links"=>1 for example tells ewiki_format to lookup the
- referenced WikiPages in the database (see ewiki_scan_wikiwords) for
- filling up $ewiki_links. Another $params entry is "html"=>0, which
- controls interpetation of the <html>...</html> page content blocks.
-
-
- ewiki_render_wiki_links(&$o)
- ----------------------------
- Transforms WikiLinks and square brackets in a page into html links.
-
-
- ewiki_scan_wikiwords(&$wiki_source, &$ewiki_links)
- --------------------------------------------------
- work with regex on the wiki source text, to find valid WikiWords,
- the $ewiki_links will be filled with informations if the found page
- names exist in the DB.
-
-
- ewiki_link_regex_callback()
- ---------------------------
- Called from ewiki_format(). To separate the ewiki_format() from
- the database this function will utilize the global $ewiki_links
- (generated on demand by ewiki_format) to output either a normal
- link or a question-mark after the WikiPageName to signal a
- non-existent page.
-
-
- ewiki_script()
- --------------
- Builds the complete URL needed to access the given resource. This
- function replaces/enhances the static EWIKI_SCRIPT constant and
- unifies the generated URLs (less bugs). It also helps around
- various design flaws (like nice looking URL strings), that made
- some parts of ewiki a bit weird and unreliable in the past. Btw,
- now the base URL is stored in $ewiki_config["script"].
-
-
- ewiki_script_binary()
- ---------------------
- Is just a ewiki_script() wrapper, but can additionally distinguish
- between binary download and upload URLs, which could be utilized by
- (database external) plain file storages (see plugins/binary_store).
-
-
- ewiki_binary()
- --------------
- Gets called automatically for requests with the ?binary= trailer
- which is used to reference cached and uploaded images (or not
- yet cached ones).
-
-
- ewiki_author()
- --------------
- returns a string with REMOTE_ADDR and the $ewiki_author or a default
- string incorporated
-
-
- ewiki_auth()
- ------------
- Is a simple interface to a probably large collection of plugins,
- which should to actual user and permission management. Support for
- this in the core is however still sporadic.
-
-
- ewiki_auth_user()
- -----------------
- Queries all registered user databases, and is usually itself called
- from within an auth_method/auth_query plugin.
-
-
- ewiki_t()
- ---------
- Fetches a text string from the $ewiki_t[] array and additionally adds
- some text pieces into it (given as second param). It can retrieve
- translations for registered abbreviations, or searches for complete
- text fragment replacements. It also understands _{...} to recursively
- translate a text snippet inside of larger text blocks.
- This is probably a bit slower and less readable than the previous usage
- of EWIKI_T_ constants, but it saves some memory and allows to extend
- translations or additional text constants (of plugins) a lot more
- easier (previously one had to edit inside a function, which is almost
- impossible to do from outside / per configuration).
-
-
- ewiki_make_title()
- ------------------
- Returns a string enclosing (the generated) page title (as link) into
- the html title markup "<h2>". The $class parameter actually tells from
- which plugin sort it was called, and this decides if a link will be
- generated or the title will be unclickable plain text (the setting in
- $ewiki_config["print_title"] is used to determine that). $go_action tells
- which action to link the title to.
-
-
- ewiki_chunked_page(...)
- -----------------------
- Is a helper function to split large results into multiple click-through
- pages, and is used by info/ and some search functions/plugins. It only
- produces the click-through links for inclusion on other dynamic pages,
- allows overlapping of page chunk ranges.
-
-
- ewiki_in_array($value, &$array, $dn=0)
- --------------------------------------
- Case-insensitive variant of PHPs` in_array(), returns the $value if
- found. The $array will be all-lowercased afterwards (except when $dn
- was set).
-
-
- ewiki_array($array, $index=false, $am=1)
- ----------------------------------------
- Returns input-array lowercased (indices), or just the entry for the
- $index if searched for. The $am decides if multiple entries should be
- merged together (uppercase+lowercase merging produces overlaps).
-
-
- ewiki_db::
- ----------
- This static class provides the interface to the database backends.
- It abstracts the database as a simple flat store for named entries
- (file or page names). Therefore it is that easy to switch from a
- SQL backend to a flat file based data store.
- Actually, this rude form of "database abstraction" has the drawback,
- that it knows only little about the data it maintains. But this also
- allows to internally extend the used structures if necessary.
-
- You call the individual functions like " ewiki_db::GET() ",
- the atomic features are:
-
- ::GET($id)
- Fetches the latest version of the "$id" page from the database.
-
- ::GET($id, $version)
- Retrieves a given version instead. Counting starts at 1.
-
- ::WRITE($data)
- Saves the contents of the given data array in the database,
- does _never_ overwrite an existing entry (you must keep track
- of the {version} yourself) unless a second paremeter (1) was
- given.
-
- ::GETALL($fieldnames, $mask, $filter)
- Fetches an array of all existing pages in the database, but
- returns it as ewiki_dbquery_result object, which will throw
- the requested columns on ->get(), where the entries 'id',
- 'version' and 'flags' are always present.
-
- ::FIND($list_of_pagenames)
- Searches the database for the queried page names, returns an
- array which associates the boolean value (if pages found) with
- their names
-
- ::SEARCH($field, $content, $caseinsensitive, $regex, $mask, $filter)
- Returns only those pages, where the database COLUMN has a content
- that matches the requested value; the list of pages is returned
- as ewiki_dbquery_result object, where you can access the
- individual entries using the ->get() call, which will return the
- columns 'id', 'version', 'flags' and the scanned COLUMN of course
- unless you ->get("_ALL=1").
-
- The following three actions are not required for correct operation,
- but provide additional functionality for some plugins or tools.
-
- ::HIT($id)
- Increases the hit counter of the given wiki page by 1,
- what is not implemented in db_flat_file.
-
- ::DELETE($id, $version)
- Removes the specified page (only the given version) from the
- database; implemented in all database plugins but should be used
- from within the tools/ only.
-
- ::INIT()
- For SQL database backends this creates the required tables.
-
- There are also a few virtual functions, that only provide utility
- code or make use of the atomic funtions itself:
-
- ::APPEND($id, $text)
- Adds the given $text at the bottom of the named page.
-
- ::UPDATE(&$data)
- Refreshes all the meta data fields in the given page hash, but of
- the {version} field. This is usefully be called before any ::WRITE
- call.
-
- ::CREATE($id, $flags, $author)
- Returns a fresh page $data hash.
-
- Other functions are usually used internally only, as for example the
- ->ALLFILES() command in dbff or dba/dbm plugins.
-
-
- $ewiki_dbquery_result
- ---------------------
- Has the member variables $keys and $entries, where the latter
- contains an array of page names that where triggered by your GETALL
- or SEARCH request, and the $keys array contains the column names that
- each subsequent "$result->get()" will return.
-
- ->get()
- Returns the database entry array (see GET above), but only the
- fields the database query should return (at minimum these are
- 'id', 'version' and 'flags' and the searched column for SEARCH).
-
- ->get("_ALL=1")
- Instead returns the complete entry.
-
- ->get(0, $mask)
- The second parameter is for filtering out content:
- 0x0001 strips out _HIDDEN pages from the result set
- 0x0002 removes any _DISABLED pages
- 0x0020 performs the _PROTECTED_MODE_HIDING checks
-
- ->get(0, $mask, $type)
- if the $type parameter is supplied, then the results are filtered
- by the given page type (_DB_F_TYPE mask)
-
- ->count()
- Returns the number of found database entries.
-
- ->add($row)
- [internal] This is used by the ewiki_database() core functions
- to initialize the $result object with the found entries.
-
-
- -------------------------------------------------------------------- 2 --
-
-
-
-$GLOBALS pollution ($ewiki_ variables)
-¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
-At least the ewiki_page() function produces variables in the
-global namespace. Of course they also were named to not interfere
-with anything from yoursite.php:
-
- $ewiki_id - Contains the current page name, after ewiki_page()
- was called.
-
- $ewiki_action - Contains the $action/ForTheCurrentPage.
-
- $ewiki_title - Will be set after the first call to ewiki_page(),
- it is most useful to be printed inside the <TITLE>
- tags inside <HEAD>. So if you want to use it you
- should call ewiki_page() very early, but save its
- output into a variable for later use. This way
- you can make the current wiki pages` title available
- (the _title may be different from the pages _id).
-
- $ewiki_data - Contains the page data hash as retrieved from the
- database, but that {content} has been removed.
-
- $ewiki_errmsg - Sometimes used to pass error notices back (ewiki_auth
- does so for example).
-
- $ewiki_links - Is an array produced by ewiki_format() that associates
- all found WikiPageNames with a value of 0 or 1,
- depending on if the referred page exists in the
- database.
-
- $ewiki_author - The content of this variable is saved in the author
- field of newly created wiki pages (it will be filled
- with IP:PORT if not set from outside). This is only an
- informational setting, and does not directly correspond
- to the _PROTECTED_MODE.
- You should set it, whenever yoursite.php notes a logged in
- user (so his login gets saved in the wiki pages 'author'
- column). But you should REALLY NOT SPAM IT with your own
- name or ad words.
-
- $ewiki_auth_user - Is set by ewiki_auth_user() whenever it successfully
- authenticates a user in _PROTECTED_MODE. This variable
- is then used as reliable state setting, which affects
- permission granting.
-
- $ewiki_ring - Holds the permission level ('ring') of the currently
- authenticated user (or else will be unset). This value
- tells only about the user, many plugin functions have
- built-in requirements which will be compared against
- this value (no value or zero means full permissions).
- While this is the built-in way to grant permissions
- and often also suits the needs to do it, the _auth()
- plugin interface allows to work at a much finer degree
- of access granting.
- values: 0=administrator, 1=moderator, 2=editor, 3=guest
- See also plugins/auth/README.auth for more informations.
-
- $ewiki_plugins - Is an array which connects task names (say "database"
- or "image_resize" for example) to function names.
- You can utilize this if you decide to extend ewiki.
- There is an own chapter on this.
-
- $ewiki_config - Imports some configuration settings from older constants,
- and introduces newer ones, which can then be overridden at
- runtime. Also holds some work and markup transform data.
-
- $ewiki_t - Text definitions and translations for all possible
- messages.
-
-
-
-
- -------------------------------------------------------------------- 3 --
-
-
-
-
-internal coding explained
-¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
-This section is to explain some of the coding style of ewiki, and how some
-things work. While many parts of ewiki carry good source code comments, it
-is always difficult to quickly understand larger scripts like ewiki.php by
-just reading through it.
-
-
-
- how ewiki operates
- ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
- ewiki_page()
- - decodes the $id and $action from the GET or POST parameters
- - tries to load the page from ewiki_database()
- - if this failed then it calls the database init function
- - calls some init plugins, calls the _auth() interface
- - chains to ["page"] plugins which activate for registered $id's
- - alternatively calls a plugin that was registered for $action
- - the default however is to render the current page via _page_view()
- - adds a page title
- - sends the generated output (view page or plugin output) back to
- caller (for output into yoursite.php)
-
- ewiki_page_view()
- - feeds the current page $data's ["content"] into ewiki_format()
- - also decodes a few formatting parameters (e.g. if html allowed)
- - returns the gererated html back
-
- ewiki_format()
- - beatifies the source code (unifies to plain UNIX newlines)
- - calls init plugins (wiki source mangling)
- - splits source into blocks, calls block plugins
- - then goes through each line of the wiki source to generate html
- - there is line-start, in-line and complete-markup
- - afterwards everything went from source into the $ooo-output var
- - first calls the link_pre_scan_regex (which searches for
- wikiwords and stores that information into $ewiki_links)
- - then calls the wiki-link transformation regex function
- - then calls post plugins and returns generated <html>
-
- ewiki_render_wiki_links()
- - searches for all (pre-fetched) $ewiki_links via ewiki_db::FIND()
- - transforms the wikiwords into html-links
- - with the regex and callback func: returns output back to
- - ewiki_format()
-
- ewiki_link_regex_callback()
- - transform the wiki source snippet returned from the
- preg_replace() call into a html link string
- - (complicated)
-
- ewiki_$page_plugin_*()
- - page plugins return html output, which usually is hardcoded as
- strings into them
- - provide some interactivity
-
- ewiki_$action_plugins_*()
- - activate on pages with special registered $action's
- - provide some interactivity (for page editing for example)
-
-
-
- used variables
- ¯¯¯¯¯¯¯¯¯¯¯¯¯¯
- Variables in ewiki often have similar names, and are also
- regularily passed by reference from one function to another (so it
- is in fact the same variable).
-
- $id - Is often the name of the current page (which is to be
- returned as output. The content of this variable is
- also available via the global $ewiki_id [[for plugins
- that do not have the common ($id,$data,$action)
- interface parameters]].
-
- $data - Contains the entry fetched with the initial
- ewiki_database() call. This is an array of the form:
- array(
- "id" => "CurrentPageName",
- "version" => 1, # 1 is the lowest possible
- "flags" => 1,
- "created" => 1002056301,
- "lastmodified" => 1002171711,
- "hits" => 235,
- "author" => "localhost (127.0.0.1:4981),
- "meta" => array("Http-Header"=>"X", "setting"=>"val"),
- "content" => "wiki source...",
- )
-
- $action - The $action with wich the current page was requested
- (most often "view", but everybody also knows "edit").
-
- $uu - Short for "unused". Is used as temporary variable, especially
- with preg_match() and string functions.
-
- $result - Used for database queries SEARCH and GETALL.
-
- $row - Holds temporarily fetched entries from the databases
- (like $data), if page lists are to be generated.
-
-
-
- -------------------------------------------------------------------- 4 --
-
-
-
-
-Extension HowTo
-¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
-Best way to extend ewiki is to read the man page on vi or emacs ;->
-However the tool that made this all possible was: joe.
-
-
-
-the PlugInterface
-¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
-The $ewiki_plugins array holds an array of "task names" connected to
-function names (that of course should do something senseful). As an
-example:
-
- $ewiki_plugins["image_resize"][0] = "ewiki_binary_image_resize_gd";
-
-connects the task name "image_resize" to function already inside ewiki.php,
-and the task "image_resize" will be called for every uploaded or to be
-cached image. The function name here does not say anything about the
-parameters the function will be called with later. You have to look up
-the original function implementation in ewiki.php to see which parameters
-will be passed; so you could write your own task plugin.
-
-The [0] in the example above shows that this is the very first registered
-function for the task "image_resize", there could be others as well. So
-if you write a plugin you should take care to add your function name using
-$ewiki_plugins["task"][] = "my_func" so you won't overwrite a previous
-function name ''registration''.
-There are of course tasks like ["database"] where only one of the plugin
-functions will be called, in this case you should of course overwrite [0].
-
-Two special case "tasks" are ["page"] and ["action"], because they aren't
-counted with numerical indices, but instead carry WikiPageNames or
-other idf strings as array/hash index.
-
-
-
-plugin tasks
-¯¯¯¯¯¯¯¯¯¯¯¯
-Here's a short summary of current PlugInterface "tasks" and (recommended)
-function interface definitions (the "= function (..." lines). A plugin hook
-with [] means there can be multiple, and each one would be tried.
-
-basic
------
-
- ["page"][$PageName] - called for requests to page "$PageName"
- (like "SearchPage", "NewestPages")
- = function ( $id, $data, $action )
-
- ["action"][$ACTION] - called for requests with url "?id=$ACTION/pagename"
- (core actions are "edit", "links", "info", "view")
- = function ( $id, &$data, $action )
-
- ["handler"][] - called from ewiki_page() on start-up, if it returns
- a string the page was handled and no further
- processing takes place, the plugins output is used
- = function ( $id, &$data, $action )
-
-rendering
----------
-
- ["render"][0] - alias for ewiki_format() - our "WikiKernel"
-
- ["format_source"][] - called inside the format function for the wiki
- source, implement this or the following ones to
- use complex wiki markup
- = function ( &$wiki_source )
-
- ["format_line"][] - generic call from inside wiki format engine
- for every line, you may need to use static
- vars inside your plugin function
- = function ( &$o, &$line, &$post )
-
- ["format_tbl"][0] - called to handle "wiki|table|markup"
- (the first and last | are already stripped)
- = function ( &$o, &$line, &$post, $tbl_open=0 )
-
- ["format_final"][] - call after wiki source was transformed into html
- (WikiPageLinks were already interpolated too)
- = function ( &$html )
-
- ["format_block"][] - called, with the page fragment extracted using
- the string patterns of the according
- $ewiki_config["format_block"] entry
- = function (&$currbuf, &$in, &$iii, &$s, $btype);
-
- ["format_para"][] - called, if the $para (text enclosed in <p></p>)
- is to be written into the output stream $ooo[$in][0]
- = function (&$para, &$ooo, &$s);
-
- ["link_url"][] - called to transform wiki source references
- = function ( $href, $title )
-
- ["link_final"][] - called from ewiki_link_regex_callback to transform
- the final <a href>
- = function ( &$str,, $type, $href, $title )
-
-special tasks
--------------
-
- ["database"][0] - only [0] will be called in favour of the ewiki.php
- internal ewiki_database_mysql()
- = function ( $action, $args=array() )
-
- ["image_resize"][] - all [] registered functions will be invoked
- = function ( &$content, &$mime, $return=0 )
-
- ["mime_magic"][0] - hooks before save_binary/image to fetch the
- correct mime type for non-image files; nowadays
- just an always-available get_content_type()
- = function ( &$content )
-
- ["binary_get"][0] - the binary_repository handles large/binary content
- (to separate it out of the standard sql-database),
- usually just sending it to stdout
- = function ( $id, $meta )
-
-page lists
-----------
-
- ["list_pages"][0] - <li>st generating callback function
- = function ( $lines )
-
- ["list_dict"][0] - special variant of the above one (called just for /
- from within PageIndex and WordIndex listings)
- = ???
-
- ["list_transform"][] - works on the given list of links (text transformations)
- = function ( &$lines )
-
- ["make_title"][0] - allows to chain a replacement function for
- ewiki_make_title()
- = function ($title, $class, $action, $go_action, $may_split)
-
- ["title_transform"] - changing the currently linked title (called from
- within _make_title)
- = function ($id, &$title, &$go_action)
-
-page transform / additions
---------------------------
-
- ["view_append"][] - output will be printed below a rendered page
- = function ( $id, $data, $action )
-
- ["view_final"][] - can rework the full html of the rendered page
- = function ( &$html, $id, $data, $action )
-
- ["view_append"][] - add <html> code at the end of the currently
- viewed page
- = function ($id, $data, $action)
-
- ["view_final"][] - filter hook for final processing of "view/"ed pages
- = function ($o, $id, $data, $action)
-
- ["page_final"][] - filter hook for final processing of any
- shown page (any action: edit/, view/, info/, ...)
- = function ($o, $id, $data, $action)
-
-edit/ hooks
------------
-
- ["edit_preview"][] - called if edit pages [preview] button pressed
- = function ( $data )
-
- ["edit_form_final"][] - add <html>/<form>s to the edit/ page
- = function (&$o, $id, &$data, $action)
-
- ["edit_form_append"][] - insert other <input> fields between <textarea>
- and <submit> button on the edit/ page
- = function ($id, &$data, $action)
-
- ["edit_hook"][] - chains into before the edit box is printed
- (to allow security checks, pre-edit-tweaking, ...)
- any output terminates the current edit/ attemp
- = function (&$id, &$data, &$hidden_postdata)
-
- ["edit_save"][] - immediately called before saving the currently
- "edit/"ed page into the database, allows last
- transformations or rejection (unsetting $data)
- = function (&$data, &$old_data)
-
- ["edit_patch"][0] - special hook for the patchsaving plugin
- = function ($id, &$data)
-
-bloat extensions
-----------------
-
- ["auth_*"][] - plugin tasks used with ewiki_auth()
- = see the plugins/auth/README.auth
-
- ["mpi"][...] - markup plugins, see next paragraph
-
- ["init"][] - run once, when the main script is included()
-
- ["page_init"][...] - init functions, called when ewiki_page()
- is called the very first time
-
-aliases and variants
---------------------
-
- ["action_always"][$ACTION] - are called with precedence over ["page"]
- plugins (for example "links" which also
- works for registered page plugins)
-
- ["action_binary"][$ACTION] - action/admin plugins which do not care, if
- the current page actually is binary data
-
-
-Some other entries have been re-extracted into $ewiki_config, because they
-were falsely in $ewiki_plugins. See the paragraph at the start of the README
-on the $ewiki_config array.
-
-This list will probably not stay up-to-date, so please grep the ewiki.php
-script for all occurrences of 'ewiki_plugins["', and you can of course
-invent some new and tell the author how it helped you to implement something
-very different.
-
-
-
- mpi plugins
- ¯¯¯¯¯¯¯¯¯¯¯
- Plugins of the class "mpi" extend the wiki markup with html like
- calls to dynamic content generating functions. They were taken from
- the ewiki adaption of Hans B Pufal and are very similar to the
- plugins found in PhpWiki.
-
- In order to use them you must first load their generic PlugInterface
- file using include("plugins/mpi.php");
- As an exception to all other ewiki plugins, the mpi plugins are then
- loaded only as needed (the mpi interface takes care). You could
- however still load all the "mpi_*.php" scripts yourself beforehand.
-
- You can then call those plugins from the wiki markup with:
-
- <?plugin Calendar ?>
-
- There are many different plugins available (not all included with
- this ewiki distribution), and the allowed arguments differ widely
- (must all be noted inside the < > and are written in arg=value style
- separated by semicolon):
-
- <?plugin Insert WikiPageName ?>
- # this includes the referenced WikiPage in a box
- # into the current one, Note the ! to prevent that
- # WikiWord from getting rendered (before mpi sees
- # it)
-
- <?plugin BackLinks page="ForGivenPageName" ?>
-
- <?plugin SparseTable columns="c1,c2,c3"
-
- c1="column 1"
- c2="column 2"
- c3="column 3"
-
- c1="#1"
- c2="2.0"
-
- c1="#2"
- c3="3.0"
-
- c2="2.5"
- c3="--"
- ?>
-
- See the distributed page "MpiPlugins" for a complete list.
-
- The API is very simple, so one could easily write a custom
- code block extension. (The mpi_backlinks plugin makes a nicely
- short example.)
-
-
-
- authentication/permission plugins
- ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
- The paragraph and descriptions about the _auth interfaces have gone
- into plugins/auth/README.auth
-
-
-
-writing your own plugin
-¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
-Using the list of current plugin tasks, you could (hopefully) write your own
-extension with ease. It is probably most simple to write a dynamic ["page"]
-plugin, so we start with this as example. All you need is a function
-definition like:
-
- function my_page_plugin($id, $data, $action) {
- return("This is the returned page <b>content</b>.");
- }
-
-And then just register it as ["page"] plugin, using your defined function
-name (yes, this does NOT need to start with the usual "ewiki_" prefix!). You
-also need to tell ewiki about the WikiPageName under which your plugin
-should be made available:
-
- $ewiki_plugins["page"]["MyPagePlugin"] = "my_page_plugin";
-
-That's it. But of course your function should do something more useful, than
-just returning a hardcoded html string - even if this all, what's necessary
-here. The parameters to your ["page"] plugin function you'll often just want
-to ignore, and implement your plugin functionality (hard disk formation e.g.)
-independently from such things.
-
-It is likewise easy to write an ["action"] plugin; but this type of plugin
-should then process some parts of the $data entry and work for nearly any
-page (extracting contents or presenting the current page differently). So
-this kind of plugin could be used to initialize a download for the current
-page or to allow to email it to someone else (beware of the spammers!).
-
-
-
-format_* / rendering plugins
-¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
-It is rather simple to add WikiMarkup using the $ewiki_config["wm_..."]
-settings, but for some tasks you need stronger weapons like rendering
-and markup plugins.
-
-The ewiki_format() function (often blatantly referred to as "rendering
-kernel") recently got rather complicated to add support for the 'block'
-plugins. Therefore we'll first need to discuss the variables structures
-and names used inside of it:
-
-
-
- ewiki_format() internals
- ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
- When the function receives the input string (WikiSource), it first
- escapes all html tags using & < > to replace the & < >
- chars (because HTML is not allowed within Wiki, initially).
-
- Then it runs optional ["format_source"] plugins on the whole wiki
- page (still one source string).
- Afterwards ewiki_format() starts to split that wikisource into
- fragments meant to get handled by ["format_block"] plugins AND/OR
- the Wiki -> HTML transformation code inside of it. It creates an
- array called $iii[] from it - each fragment being an array on its
- own:
- $iii[0] = array(
- 0 => "WikiSource ...",
- 1 => 0x0FFF,
- 2 => "core",
- );
- Initially we here just have one fragment [0] - and often this
- remains the only one (if no block plugin activates for the current
- WikiPage). The 0=> entry contains the body (wiki source) of a
- fragment, while at the 1=> index you'll find the block flags and 2=>
- is just the name of the block plugin to handle that fragment.
-
- If there is some block code, like <htm>...</htm> or <pre>...</pre>
- in the WikiPage, you'll end up with a larger $iii[] input array:
- $iii[0] = array("WikiSource...",0xFFFF,"core"),
- $iii[1] = array("<b>....",0x0002,"html"),
- $iii[2] = array("text",0x0FFF,""),
-
- Besides the $iii[] input array, we'll also have an array containing
- rendering status variables called $s[]. The most important entry
- there is $s["in"], which is the index into the currently accessed
- $iii[] wiki page source or block fragment.
- And ewiki_format() then uses various alias variable names for
- entries of the status var $s[] array - for example $in and $s["in"]
- are the same index number.
-
- After ewiki_format() separated the input source into the block
- fragments of $iii[], it will then run the actual ["fragment_block"]
- plugins on it. These can then apply regexs on them, or strip the
- fragments completely out of $iii[] or transform then into regular
- wiki source.
-
- Then the large wiki transform loop comes into action, but only
- for $iii[] fragments, whose flags (in the $iii[...][1] number)
- have the bit 0x0001 set. Other blocks/fragments of $iii[] remain
- untouched.
- While transforming the $iii[] arrays WikiSource a new fragments
- array will be created, called $ooo[] - the output array, which has
- exactly the same layout. And every $iii[$in] directly maps to the
- $ooo[$in] - same index number! But the later then already contains
- <html> instead of wiki source.
-
- Inside of the transformation loop, two other plugin types are
- activated (besides applying the $ewiki_config["wm_..."] ruleset):
- the ["format_line"] and ["format_para"] plugin groups.
-
- After all $iii[] blocks have been transformed into $ooo[], a second
- loop will check the flags (this time $ooo[...][1]) for the bit 0x0002
- which tells, if WikiWords should be transformed into html <a href=>
- links.
-
- After link conversion (on the selected fragments), all blocks (the
- content entries $ooo[...][0] of course) of $ooo[] are merged together
- into one <html> string. After the ["format_final"] plugins run over
- this, ewiki_format() returns the resulting <html> page.
-
-
-
- the format_ plugin hooks
- ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
- As denoted above, the ["format_source"] and ["format_final"] plugin
- hooks are the simplest to work with, as both only get one parameter
- (passed by reference) containing either the full WikiPage source
- text or the already fully rendered <html> output.
-
- The ["format_line"] and ["format_tbl"] hooks are also rather simple,
- lookup their interface to know which variables you could modify.
-
- The ["format_para"] and ["format_block"] plugins both recieve
- either the $iii[] or $ooo[] and status $s[] array variables (plus
- a few aliases and shortcomings). This makes these hooks look a
- bit more complicated, but allows great flexibility - a "_block"
- plugin could for example merge its $iii[] fragment with another
- one, or replace itself with nothing.
-
- To write a markup plugin, you should lookup the actual interface in
- the 'ewiki.php' script or in this README. And don't forget that most
- parameters are meant to be passed by reference to be useful!
-
-
-
- $iii[] and $ooo[] block flags
- ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
- The $iii[...][1] and $ooo[...][1] hold the flags (as defined by
- $ewiki_config["format_block"][...][2]) for each fragment of the
- WikiPage. The "core" blocks (plain WikiSource) always have the
- default 0x137F assigned.
-
- currently used bit values are:
- 0x0001 - render WikiMarkup (inline / text style)
- 0x0002 - render WikiLinks
- 0x0004 - international character &#htmlentities; allowed
- 0x0008 - enable BlockMarkup (lists, tables, headlines, ...)
- *NEW* 0x0400 - decode < > htmlentities again before calling block plugin
- 0x1000 - fragment further (other block plugins can split it)
-
- pseudo-values (OR checks / behaviour):
- 0x0010 - consider to be inline block between WikiSourceBlocks
- (prevents paragraph breaks between plugin and wiki block)
- 0x0022 - scan for WikiWords in this paragraph
-
-
-
- your own block markup plugin
- ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
- Of course a _block plugin is a bit more complicated than a action
- or page plugin, but generally you only need this small stub:
-
- $ewiki_plugins["format_block"]["your"] = "your_block_func";
- $ewiki_config["format_block"]["your"] = array(
- "<your>",
- "</your>",
- false, // no special filter rule/flag
- 0x0014 // see above, often also just 0x0000
- );
- function your_block_func(&$str, &$in, &$iii, &$s, $btype) {
- ...
- }
-
- Where you would just rework the conents of "$str", which will be
- the text part in between the <your> and </your> tags as defined
- by the $ewiki_config[] block plugin settings. The other variables
- in that API aren't normally important.
-
- You only must take care, that "<", ">" and "&" are still encoded
- in htmlentities() at this stage.
-
-
-
-xpi plugin system
-¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
-A newer extension of ewiki (namely plugins/feature/xpi) allows to store
-addon functions in the database (the code is saved as _BINARY db entry
-where usually page text was stored). The "PlugInstall" page allows to load
-the extension code from (even remotely located) .xpi files into the
-database, from where it can be used later.
-In order to use once installed xpi code, only the "feature/xpi0.php"
-plugin was needed.
-
-Through the design of the xpi feature extension nearly all plugins could
-be converted and installed in the .xpi format. Though this doesn't make
-sense for database backends, and converting all to-date plugins is silly.
-So this feature is further merely used for fun and mini-extensions.
-
-You could easily write your own .xpi plugins using the description in the
-"tools/mkxpi" script. First you need to create a .src file with the plugin
-code as usual (write it like an ordinary plugin script, except for page
-plugins), and a few meta: informations on top of that file. Then the mkxpi
-tool converts this in the binary .xpi format for distribution and
-installation.
-Typically this would look like:
-
- id: UniqueExtensionName
- type: actionlink_and_textdata
- license: Free to use
- author: PutYourNameHere
- description: adds the search/ action to the control-links line
- icon: data:image/png;base64,iVBORw0KGgoAAAANS...
- code: <?php
- // just look'n'feel settings, no real plugin code here...
- $ewiki_config["action_links"]["view"]["search"] = "SEARCH_ACTION";
- $ewiki_t["en"]["SEARCH_ACTION"] = "search in other pages";
- $ewiki_t["de"]["SEARCH_ACTION"] = "woanders suchen";
- ?>
-
-Most of the fields are optional (author, license, description and of course
-icon) but senseful. The type: is required, but only a value of "page" has
-a special meaning here (otherwise is merely descriptive). The id: gives that
-plugin an internal identifier which will later be used for storing the
-extension with a database-wide unique name; for "page" type plugins it of
-course would be the name under which it was installed.
-
-The code: contains the usual plugin registration and function definition
-code. But for "page" xpi plugins it may not have a function body, but lots
-of 'echo' calls to output the dynamic pages contents when called (no return
-allowed in this incarnation of page plugins). After this no other fields
-should appear.
-
-Future .xpi versions may allow to embed other files for instant installation
-(maybe image files for storage in database). But until now onle the code:
-entry carries data which will be installed as database page. All the other
-meta entries (id, type, author, ...) will however be stored in the xpi
-registry database entry, which is also used to control the enable/disable
-flag for each of it (only page plugins cannot be disabled).
-
-To share your own extensions simply send them to one of the core project
-developers (Andy or Mario) or just leave a link on the "XpiPlugins" page:
-http://erfurtwiki.sourceforge.net/?XpiPlugins
-
-because that way users will immediately see it when remotely installing
-.xpi plugins from that default xpi plugin repository. It may be an
-security risk for users if they install code from unchecked sources, but
-the complete URL is always displayed right before storing the external
-code into the database.
-
-The most interesting part of the .xpi system (PlugInstall page) is the
-possibility to later disable or remove extensions easily. You only need
-to setup the administrator password to install and control click-and-run
-extensions without hacking the 'config.php'.
-
-
-
- ------------------------------------------------------------------ 5 ---
-
-
-
-mysql database structure
-¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
-The MySQL database table structure is (to a certain degree) compatible
-with that of the well known »PHPWiki« v1.2.x (you only need to change
-EWIKI_DB_TABLE_NAME to "wiki" to use it). This is the MySQL statement
-which creates our database table (you can find it at the bottom of the
-"ewiki.php" script):
- CREATE TABLE ewiki (
- pagename VARCHAR(160) NOT NULL,
- version INTEGER UNSIGNED NOT NULL DEFAULT 0,
- flags INTEGER UNSIGNED DEFAULT 0,
- content MEDIUMTEXT,
- author VARCHAR(100) DEFAULT 'ewiki',
- created INTEGER UNSIGNED DEFAULT 0,
- lastmodified INTEGER UNSIGNED DEFAULT 0,
- refs MEDIUMTEXT,
- meta MEDIUMTEXT,
- hits INTEGER UNSIGNED DEFAULT 0,
- PRIMARY KEY id (pagename, version)
- )
-
-I didn't like the column name {pagename} but as I've seen this was
-the only difference I renamed it, therefore now the ewiki_database()
-function translates it from "pagename" to "id" and vice versa most of
-the time - else this would be really slim and nice code :)
-
-The columns {version} holds the different saved page versions. Other
-Wikis require a secondary "backup" or "history" table for old versions,
-but as I couldn't imagine what this is for, there is just one table
-in ewiki; and it seems this is really enough. The first {version} of
-a wiki page is always numbered 1. An existing page {version} will
-never get overwritten => very secure MySQL usage.
-
-For what's in the {flags}, see the README section about constants. The
-{content} of course holds the wiki pages source. The {created} and
-{lastmodified} should be clear too.
-
-{refs} contain a "\n" separated list of referenced WikiPages. The
-code to generate that list is rather unclean, so it often contains
-GhostPages. However this does not hurt ewiki and the few functions
-that utilize {refs}, so there is currently no need to slow it down
-by fixing this.
-
-{meta} can hold additional informations, which allows to extend ewiki
-without requiring to ALTER and convert the ewiki database table. It
-currently holds some mime headers for binary content and some other
-useful informations for images and uploaded files.
-
-{hits} should have gone into {meta} really. But having it separate
-allows us to use the very fast mysql UPDATE function.
-
-Note, that the ewiki database table can hold other things than wiki
-pages - binary content (images) for example, depending on the setting
-of the {flags} field.
-
-And last comment about this, the one-table-concept also made it really easy
-to implement the flat file based "database backend".
-
-
-
- ------------------------------------------------------------------ 6 ---
-
-
-
-Just using the wiki source transformation
-¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
-The ewiki_format function was designed to be used independently from the
-ewiki database.
-
- ewiki_format($wiki_source, 0);
-
-It just needs the "wiki_source" as argument and generates a nicely
-formatted page from it. All you need to take care about is the
-$ewiki_links variable.
-Set the $ewiki_links=true ("true" and not "1" or anything else) to
-enforce ewiki_format() to treat all references as existing.
-
-To separate the ewiki_format() function out of recent ewiki versions,
-you'll also need ewiki_script(), ewiki_link_regex_callback(), ... and
-a lot of constants to take with. It is often much easier to just
-include("ewiki.php") for using ewiki_format(). You then should however
-take care, that the _binary part doesn't get activated by accident. To
-prevent this, just put following before the include() statement:
-
- unset($_REQUEST["binary"]);
- include("ewiki.php");
-
-If you need it more quickly, or don't want to load the whole ewiki.php
-file, then just try the fragments/wiki_format.inc, which is a stripped
-down version of an older rendering core function (no WikiLinks, no binary
-stuff). Contributed by Frank Luithle.
-
-
-