2 ewiki internals and extension howto
3 ===================================
5 This part of the [README] series describes a bit of the internals of
6 the ewiki script and its plugin system. It lists variables, coding
7 guidelines and a few recommendations.
8 These informations are useful if you'd like to change some of the
9 hardcoded behaviour, fix annoying bugs you've found or to write your
10 own extensions. You do not need to read this, if you just want to
17 2 $GLOBALS pollution ($ewiki_ variables)
18 3 internal coding explained
19 3.1 how ewiki operates
25 4.2.2 authentication/permission plugins
26 4.3 writing your own plugin
27 4.4 format_* / rendering plugins
28 4.4.1 ewiki_format() internals
29 4.4.2 the format_ plugin hooks
30 4.4.3 $iii[] and $ooo[] block flags
31 4.4.4 your own block markup plugin
33 5 mysql database structure
34 6 Just using the wiki source transformation
39 -------------------------------------------------------------------- 1 --
47 Some of the core functions of ewiki.php can be used separate from the
48 others and some of them were designed to be replaced by different
50 Btw, all the functions, constants and variables start with "ewiki_"
51 to make it easier to mix it into other projects (reduces function name
52 conflicts and similar problems, that usually arise if you join two
53 or more scripts into one program).
58 This is the main function which fetches the selected WikiPage
59 (or the one given with $id) via ewiki_database to transform
61 If the requested page does not exist it returns the edit
63 It also includes some virtual pages (InfoAboutThisPage,
64 NewestPages, SearchPage, ReferencesToThisPage, ...).
69 These functions were separated out from the main ewiki_page()
70 to make it more readable.
71 Most of them contain code to generate the few special/internal
72 WikiPages (Search, Newest, Info, and the Edit <FORM>, ...)
75 ewiki_control_links($id, $data)
76 -------------------------------
77 Prints the line with the EditThisPage and PageInfo, ... links.
80 ewiki_format($wiki_source, $params)
81 ----------------------------------------------------------
82 This returns the formatted (HTML) output for the given WikiSource
83 (with all the WikiMarkup in it).
85 The second param is an array with various config overrides. An entry
86 of "scan_links"=>1 for example tells ewiki_format to lookup the
87 referenced WikiPages in the database (see ewiki_scan_wikiwords) for
88 filling up $ewiki_links. Another $params entry is "html"=>0, which
89 controls interpetation of the <html>...</html> page content blocks.
92 ewiki_render_wiki_links(&$o)
93 ----------------------------
94 Transforms WikiLinks and square brackets in a page into html links.
97 ewiki_scan_wikiwords(&$wiki_source, &$ewiki_links)
98 --------------------------------------------------
99 work with regex on the wiki source text, to find valid WikiWords,
100 the $ewiki_links will be filled with informations if the found page
101 names exist in the DB.
104 ewiki_link_regex_callback()
105 ---------------------------
106 Called from ewiki_format(). To separate the ewiki_format() from
107 the database this function will utilize the global $ewiki_links
108 (generated on demand by ewiki_format) to output either a normal
109 link or a question-mark after the WikiPageName to signal a
115 Builds the complete URL needed to access the given resource. This
116 function replaces/enhances the static EWIKI_SCRIPT constant and
117 unifies the generated URLs (less bugs). It also helps around
118 various design flaws (like nice looking URL strings), that made
119 some parts of ewiki a bit weird and unreliable in the past. Btw,
120 now the base URL is stored in $ewiki_config["script"].
123 ewiki_script_binary()
124 ---------------------
125 Is just a ewiki_script() wrapper, but can additionally distinguish
126 between binary download and upload URLs, which could be utilized by
127 (database external) plain file storages (see plugins/binary_store).
132 Gets called automatically for requests with the ?binary= trailer
133 which is used to reference cached and uploaded images (or not
139 returns a string with REMOTE_ADDR and the $ewiki_author or a default
145 Is a simple interface to a probably large collection of plugins,
146 which should to actual user and permission management. Support for
147 this in the core is however still sporadic.
152 Queries all registered user databases, and is usually itself called
153 from within an auth_method/auth_query plugin.
158 Fetches a text string from the $ewiki_t[] array and additionally adds
159 some text pieces into it (given as second param). It can retrieve
160 translations for registered abbreviations, or searches for complete
161 text fragment replacements. It also understands _{...} to recursively
162 translate a text snippet inside of larger text blocks.
163 This is probably a bit slower and less readable than the previous usage
164 of EWIKI_T_ constants, but it saves some memory and allows to extend
165 translations or additional text constants (of plugins) a lot more
166 easier (previously one had to edit inside a function, which is almost
167 impossible to do from outside / per configuration).
172 Returns a string enclosing (the generated) page title (as link) into
173 the html title markup "<h2>". The $class parameter actually tells from
174 which plugin sort it was called, and this decides if a link will be
175 generated or the title will be unclickable plain text (the setting in
176 $ewiki_config["print_title"] is used to determine that). $go_action tells
177 which action to link the title to.
180 ewiki_chunked_page(...)
181 -----------------------
182 Is a helper function to split large results into multiple click-through
183 pages, and is used by info/ and some search functions/plugins. It only
184 produces the click-through links for inclusion on other dynamic pages,
185 allows overlapping of page chunk ranges.
188 ewiki_in_array($value, &$array, $dn=0)
189 --------------------------------------
190 Case-insensitive variant of PHPs` in_array(), returns the $value if
191 found. The $array will be all-lowercased afterwards (except when $dn
195 ewiki_array($array, $index=false, $am=1)
196 ----------------------------------------
197 Returns input-array lowercased (indices), or just the entry for the
198 $index if searched for. The $am decides if multiple entries should be
199 merged together (uppercase+lowercase merging produces overlaps).
204 This static class provides the interface to the database backends.
205 It abstracts the database as a simple flat store for named entries
206 (file or page names). Therefore it is that easy to switch from a
207 SQL backend to a flat file based data store.
208 Actually, this rude form of "database abstraction" has the drawback,
209 that it knows only little about the data it maintains. But this also
210 allows to internally extend the used structures if necessary.
212 You call the individual functions like " ewiki_db::GET() ",
213 the atomic features are:
216 Fetches the latest version of the "$id" page from the database.
219 Retrieves a given version instead. Counting starts at 1.
222 Saves the contents of the given data array in the database,
223 does _never_ overwrite an existing entry (you must keep track
224 of the {version} yourself) unless a second paremeter (1) was
227 ::GETALL($fieldnames, $mask, $filter)
228 Fetches an array of all existing pages in the database, but
229 returns it as ewiki_dbquery_result object, which will throw
230 the requested columns on ->get(), where the entries 'id',
231 'version' and 'flags' are always present.
233 ::FIND($list_of_pagenames)
234 Searches the database for the queried page names, returns an
235 array which associates the boolean value (if pages found) with
238 ::SEARCH($field, $content, $caseinsensitive, $regex, $mask, $filter)
239 Returns only those pages, where the database COLUMN has a content
240 that matches the requested value; the list of pages is returned
241 as ewiki_dbquery_result object, where you can access the
242 individual entries using the ->get() call, which will return the
243 columns 'id', 'version', 'flags' and the scanned COLUMN of course
244 unless you ->get("_ALL=1").
246 The following three actions are not required for correct operation,
247 but provide additional functionality for some plugins or tools.
250 Increases the hit counter of the given wiki page by 1,
251 what is not implemented in db_flat_file.
253 ::DELETE($id, $version)
254 Removes the specified page (only the given version) from the
255 database; implemented in all database plugins but should be used
256 from within the tools/ only.
259 For SQL database backends this creates the required tables.
261 There are also a few virtual functions, that only provide utility
262 code or make use of the atomic funtions itself:
265 Adds the given $text at the bottom of the named page.
268 Refreshes all the meta data fields in the given page hash, but of
269 the {version} field. This is usefully be called before any ::WRITE
272 ::CREATE($id, $flags, $author)
273 Returns a fresh page $data hash.
275 Other functions are usually used internally only, as for example the
276 ->ALLFILES() command in dbff or dba/dbm plugins.
279 $ewiki_dbquery_result
280 ---------------------
281 Has the member variables $keys and $entries, where the latter
282 contains an array of page names that where triggered by your GETALL
283 or SEARCH request, and the $keys array contains the column names that
284 each subsequent "$result->get()" will return.
287 Returns the database entry array (see GET above), but only the
288 fields the database query should return (at minimum these are
289 'id', 'version' and 'flags' and the searched column for SEARCH).
292 Instead returns the complete entry.
295 The second parameter is for filtering out content:
296 0x0001 strips out _HIDDEN pages from the result set
297 0x0002 removes any _DISABLED pages
298 0x0020 performs the _PROTECTED_MODE_HIDING checks
300 ->get(0, $mask, $type)
301 if the $type parameter is supplied, then the results are filtered
302 by the given page type (_DB_F_TYPE mask)
305 Returns the number of found database entries.
308 [internal] This is used by the ewiki_database() core functions
309 to initialize the $result object with the found entries.
312 -------------------------------------------------------------------- 2 --
316 $GLOBALS pollution ($ewiki_ variables)
317 ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
318 At least the ewiki_page() function produces variables in the
319 global namespace. Of course they also were named to not interfere
320 with anything from yoursite.php:
322 $ewiki_id - Contains the current page name, after ewiki_page()
325 $ewiki_action - Contains the $action/ForTheCurrentPage.
327 $ewiki_title - Will be set after the first call to ewiki_page(),
328 it is most useful to be printed inside the <TITLE>
329 tags inside <HEAD>. So if you want to use it you
330 should call ewiki_page() very early, but save its
331 output into a variable for later use. This way
332 you can make the current wiki pages` title available
333 (the _title may be different from the pages _id).
335 $ewiki_data - Contains the page data hash as retrieved from the
336 database, but that {content} has been removed.
338 $ewiki_errmsg - Sometimes used to pass error notices back (ewiki_auth
339 does so for example).
341 $ewiki_links - Is an array produced by ewiki_format() that associates
342 all found WikiPageNames with a value of 0 or 1,
343 depending on if the referred page exists in the
346 $ewiki_author - The content of this variable is saved in the author
347 field of newly created wiki pages (it will be filled
348 with IP:PORT if not set from outside). This is only an
349 informational setting, and does not directly correspond
350 to the _PROTECTED_MODE.
351 You should set it, whenever yoursite.php notes a logged in
352 user (so his login gets saved in the wiki pages 'author'
353 column). But you should REALLY NOT SPAM IT with your own
356 $ewiki_auth_user - Is set by ewiki_auth_user() whenever it successfully
357 authenticates a user in _PROTECTED_MODE. This variable
358 is then used as reliable state setting, which affects
361 $ewiki_ring - Holds the permission level ('ring') of the currently
362 authenticated user (or else will be unset). This value
363 tells only about the user, many plugin functions have
364 built-in requirements which will be compared against
365 this value (no value or zero means full permissions).
366 While this is the built-in way to grant permissions
367 and often also suits the needs to do it, the _auth()
368 plugin interface allows to work at a much finer degree
370 values: 0=administrator, 1=moderator, 2=editor, 3=guest
371 See also plugins/auth/README.auth for more informations.
373 $ewiki_plugins - Is an array which connects task names (say "database"
374 or "image_resize" for example) to function names.
375 You can utilize this if you decide to extend ewiki.
376 There is an own chapter on this.
378 $ewiki_config - Imports some configuration settings from older constants,
379 and introduces newer ones, which can then be overridden at
380 runtime. Also holds some work and markup transform data.
382 $ewiki_t - Text definitions and translations for all possible
388 -------------------------------------------------------------------- 3 --
393 internal coding explained
394 ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
395 This section is to explain some of the coding style of ewiki, and how some
396 things work. While many parts of ewiki carry good source code comments, it
397 is always difficult to quickly understand larger scripts like ewiki.php by
398 just reading through it.
405 - decodes the $id and $action from the GET or POST parameters
406 - tries to load the page from ewiki_database()
407 - if this failed then it calls the database init function
408 - calls some init plugins, calls the _auth() interface
409 - chains to ["page"] plugins which activate for registered $id's
410 - alternatively calls a plugin that was registered for $action
411 - the default however is to render the current page via _page_view()
413 - sends the generated output (view page or plugin output) back to
414 caller (for output into yoursite.php)
417 - feeds the current page $data's ["content"] into ewiki_format()
418 - also decodes a few formatting parameters (e.g. if html allowed)
419 - returns the gererated html back
422 - beatifies the source code (unifies to plain UNIX newlines)
423 - calls init plugins (wiki source mangling)
424 - splits source into blocks, calls block plugins
425 - then goes through each line of the wiki source to generate html
426 - there is line-start, in-line and complete-markup
427 - afterwards everything went from source into the $ooo-output var
428 - first calls the link_pre_scan_regex (which searches for
429 wikiwords and stores that information into $ewiki_links)
430 - then calls the wiki-link transformation regex function
431 - then calls post plugins and returns generated <html>
433 ewiki_render_wiki_links()
434 - searches for all (pre-fetched) $ewiki_links via ewiki_db::FIND()
435 - transforms the wikiwords into html-links
436 - with the regex and callback func: returns output back to
439 ewiki_link_regex_callback()
440 - transform the wiki source snippet returned from the
441 preg_replace() call into a html link string
444 ewiki_$page_plugin_*()
445 - page plugins return html output, which usually is hardcoded as
447 - provide some interactivity
449 ewiki_$action_plugins_*()
450 - activate on pages with special registered $action's
451 - provide some interactivity (for page editing for example)
457 Variables in ewiki often have similar names, and are also
458 regularily passed by reference from one function to another (so it
459 is in fact the same variable).
461 $id - Is often the name of the current page (which is to be
462 returned as output. The content of this variable is
463 also available via the global $ewiki_id [[for plugins
464 that do not have the common ($id,$data,$action)
465 interface parameters]].
467 $data - Contains the entry fetched with the initial
468 ewiki_database() call. This is an array of the form:
470 "id" => "CurrentPageName",
471 "version" => 1, # 1 is the lowest possible
473 "created" => 1002056301,
474 "lastmodified" => 1002171711,
476 "author" => "localhost (127.0.0.1:4981),
477 "meta" => array("Http-Header"=>"X", "setting"=>"val"),
478 "content" => "wiki source...",
481 $action - The $action with wich the current page was requested
482 (most often "view", but everybody also knows "edit").
484 $uu - Short for "unused". Is used as temporary variable, especially
485 with preg_match() and string functions.
487 $result - Used for database queries SEARCH and GETALL.
489 $row - Holds temporarily fetched entries from the databases
490 (like $data), if page lists are to be generated.
494 -------------------------------------------------------------------- 4 --
501 Best way to extend ewiki is to read the man page on vi or emacs ;->
502 However the tool that made this all possible was: joe.
508 The $ewiki_plugins array holds an array of "task names" connected to
509 function names (that of course should do something senseful). As an
512 $ewiki_plugins["image_resize"][0] = "ewiki_binary_image_resize_gd";
514 connects the task name "image_resize" to function already inside ewiki.php,
515 and the task "image_resize" will be called for every uploaded or to be
516 cached image. The function name here does not say anything about the
517 parameters the function will be called with later. You have to look up
518 the original function implementation in ewiki.php to see which parameters
519 will be passed; so you could write your own task plugin.
521 The [0] in the example above shows that this is the very first registered
522 function for the task "image_resize", there could be others as well. So
523 if you write a plugin you should take care to add your function name using
524 $ewiki_plugins["task"][] = "my_func" so you won't overwrite a previous
525 function name ''registration''.
526 There are of course tasks like ["database"] where only one of the plugin
527 functions will be called, in this case you should of course overwrite [0].
529 Two special case "tasks" are ["page"] and ["action"], because they aren't
530 counted with numerical indices, but instead carry WikiPageNames or
531 other idf strings as array/hash index.
537 Here's a short summary of current PlugInterface "tasks" and (recommended)
538 function interface definitions (the "= function (..." lines). A plugin hook
539 with [] means there can be multiple, and each one would be tried.
544 ["page"][$PageName] - called for requests to page "$PageName"
545 (like "SearchPage", "NewestPages")
546 = function ( $id, $data, $action )
548 ["action"][$ACTION] - called for requests with url "?id=$ACTION/pagename"
549 (core actions are "edit", "links", "info", "view")
550 = function ( $id, &$data, $action )
552 ["handler"][] - called from ewiki_page() on start-up, if it returns
553 a string the page was handled and no further
554 processing takes place, the plugins output is used
555 = function ( $id, &$data, $action )
560 ["render"][0] - alias for ewiki_format() - our "WikiKernel"
562 ["format_source"][] - called inside the format function for the wiki
563 source, implement this or the following ones to
564 use complex wiki markup
565 = function ( &$wiki_source )
567 ["format_line"][] - generic call from inside wiki format engine
568 for every line, you may need to use static
569 vars inside your plugin function
570 = function ( &$o, &$line, &$post )
572 ["format_tbl"][0] - called to handle "wiki|table|markup"
573 (the first and last | are already stripped)
574 = function ( &$o, &$line, &$post, $tbl_open=0 )
576 ["format_final"][] - call after wiki source was transformed into html
577 (WikiPageLinks were already interpolated too)
578 = function ( &$html )
580 ["format_block"][] - called, with the page fragment extracted using
581 the string patterns of the according
582 $ewiki_config["format_block"] entry
583 = function (&$currbuf, &$in, &$iii, &$s, $btype);
585 ["format_para"][] - called, if the $para (text enclosed in <p></p>)
586 is to be written into the output stream $ooo[$in][0]
587 = function (&$para, &$ooo, &$s);
589 ["link_url"][] - called to transform wiki source references
590 = function ( $href, $title )
592 ["link_final"][] - called from ewiki_link_regex_callback to transform
594 = function ( &$str,, $type, $href, $title )
599 ["database"][0] - only [0] will be called in favour of the ewiki.php
600 internal ewiki_database_mysql()
601 = function ( $action, $args=array() )
603 ["image_resize"][] - all [] registered functions will be invoked
604 = function ( &$content, &$mime, $return=0 )
606 ["mime_magic"][0] - hooks before save_binary/image to fetch the
607 correct mime type for non-image files; nowadays
608 just an always-available get_content_type()
609 = function ( &$content )
611 ["binary_get"][0] - the binary_repository handles large/binary content
612 (to separate it out of the standard sql-database),
613 usually just sending it to stdout
614 = function ( $id, $meta )
619 ["list_pages"][0] - <li>st generating callback function
620 = function ( $lines )
622 ["list_dict"][0] - special variant of the above one (called just for /
623 from within PageIndex and WordIndex listings)
626 ["list_transform"][] - works on the given list of links (text transformations)
627 = function ( &$lines )
629 ["make_title"][0] - allows to chain a replacement function for
631 = function ($title, $class, $action, $go_action, $may_split)
633 ["title_transform"] - changing the currently linked title (called from
635 = function ($id, &$title, &$go_action)
637 page transform / additions
638 --------------------------
640 ["view_append"][] - output will be printed below a rendered page
641 = function ( $id, $data, $action )
643 ["view_final"][] - can rework the full html of the rendered page
644 = function ( &$html, $id, $data, $action )
646 ["view_append"][] - add <html> code at the end of the currently
648 = function ($id, $data, $action)
650 ["view_final"][] - filter hook for final processing of "view/"ed pages
651 = function ($o, $id, $data, $action)
653 ["page_final"][] - filter hook for final processing of any
654 shown page (any action: edit/, view/, info/, ...)
655 = function ($o, $id, $data, $action)
660 ["edit_preview"][] - called if edit pages [preview] button pressed
663 ["edit_form_final"][] - add <html>/<form>s to the edit/ page
664 = function (&$o, $id, &$data, $action)
666 ["edit_form_append"][] - insert other <input> fields between <textarea>
667 and <submit> button on the edit/ page
668 = function ($id, &$data, $action)
670 ["edit_hook"][] - chains into before the edit box is printed
671 (to allow security checks, pre-edit-tweaking, ...)
672 any output terminates the current edit/ attemp
673 = function (&$id, &$data, &$hidden_postdata)
675 ["edit_save"][] - immediately called before saving the currently
676 "edit/"ed page into the database, allows last
677 transformations or rejection (unsetting $data)
678 = function (&$data, &$old_data)
680 ["edit_patch"][0] - special hook for the patchsaving plugin
681 = function ($id, &$data)
686 ["auth_*"][] - plugin tasks used with ewiki_auth()
687 = see the plugins/auth/README.auth
689 ["mpi"][...] - markup plugins, see next paragraph
691 ["init"][] - run once, when the main script is included()
693 ["page_init"][...] - init functions, called when ewiki_page()
694 is called the very first time
699 ["action_always"][$ACTION] - are called with precedence over ["page"]
700 plugins (for example "links" which also
701 works for registered page plugins)
703 ["action_binary"][$ACTION] - action/admin plugins which do not care, if
704 the current page actually is binary data
707 Some other entries have been re-extracted into $ewiki_config, because they
708 were falsely in $ewiki_plugins. See the paragraph at the start of the README
709 on the $ewiki_config array.
711 This list will probably not stay up-to-date, so please grep the ewiki.php
712 script for all occurrences of 'ewiki_plugins["', and you can of course
713 invent some new and tell the author how it helped you to implement something
720 Plugins of the class "mpi" extend the wiki markup with html like
721 calls to dynamic content generating functions. They were taken from
722 the ewiki adaption of Hans B Pufal and are very similar to the
723 plugins found in PhpWiki.
725 In order to use them you must first load their generic PlugInterface
726 file using include("plugins/mpi.php");
727 As an exception to all other ewiki plugins, the mpi plugins are then
728 loaded only as needed (the mpi interface takes care). You could
729 however still load all the "mpi_*.php" scripts yourself beforehand.
731 You can then call those plugins from the wiki markup with:
735 There are many different plugins available (not all included with
736 this ewiki distribution), and the allowed arguments differ widely
737 (must all be noted inside the < > and are written in arg=value style
738 separated by semicolon):
740 <?plugin Insert WikiPageName ?>
741 # this includes the referenced WikiPage in a box
742 # into the current one, Note the ! to prevent that
743 # WikiWord from getting rendered (before mpi sees
746 <?plugin BackLinks page="ForGivenPageName" ?>
748 <?plugin SparseTable columns="c1,c2,c3"
764 See the distributed page "MpiPlugins" for a complete list.
766 The API is very simple, so one could easily write a custom
767 code block extension. (The mpi_backlinks plugin makes a nicely
772 authentication/permission plugins
773 ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
774 The paragraph and descriptions about the _auth interfaces have gone
775 into plugins/auth/README.auth
779 writing your own plugin
780 ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
781 Using the list of current plugin tasks, you could (hopefully) write your own
782 extension with ease. It is probably most simple to write a dynamic ["page"]
783 plugin, so we start with this as example. All you need is a function
786 function my_page_plugin($id, $data, $action) {
787 return("This is the returned page <b>content</b>.");
790 And then just register it as ["page"] plugin, using your defined function
791 name (yes, this does NOT need to start with the usual "ewiki_" prefix!). You
792 also need to tell ewiki about the WikiPageName under which your plugin
793 should be made available:
795 $ewiki_plugins["page"]["MyPagePlugin"] = "my_page_plugin";
797 That's it. But of course your function should do something more useful, than
798 just returning a hardcoded html string - even if this all, what's necessary
799 here. The parameters to your ["page"] plugin function you'll often just want
800 to ignore, and implement your plugin functionality (hard disk formation e.g.)
801 independently from such things.
803 It is likewise easy to write an ["action"] plugin; but this type of plugin
804 should then process some parts of the $data entry and work for nearly any
805 page (extracting contents or presenting the current page differently). So
806 this kind of plugin could be used to initialize a download for the current
807 page or to allow to email it to someone else (beware of the spammers!).
811 format_* / rendering plugins
812 ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
813 It is rather simple to add WikiMarkup using the $ewiki_config["wm_..."]
814 settings, but for some tasks you need stronger weapons like rendering
817 The ewiki_format() function (often blatantly referred to as "rendering
818 kernel") recently got rather complicated to add support for the 'block'
819 plugins. Therefore we'll first need to discuss the variables structures
820 and names used inside of it:
824 ewiki_format() internals
825 ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
826 When the function receives the input string (WikiSource), it first
827 escapes all html tags using & < > to replace the & < >
828 chars (because HTML is not allowed within Wiki, initially).
830 Then it runs optional ["format_source"] plugins on the whole wiki
831 page (still one source string).
832 Afterwards ewiki_format() starts to split that wikisource into
833 fragments meant to get handled by ["format_block"] plugins AND/OR
834 the Wiki -> HTML transformation code inside of it. It creates an
835 array called $iii[] from it - each fragment being an array on its
838 0 => "WikiSource ...",
842 Initially we here just have one fragment [0] - and often this
843 remains the only one (if no block plugin activates for the current
844 WikiPage). The 0=> entry contains the body (wiki source) of a
845 fragment, while at the 1=> index you'll find the block flags and 2=>
846 is just the name of the block plugin to handle that fragment.
848 If there is some block code, like <htm>...</htm> or <pre>...</pre>
849 in the WikiPage, you'll end up with a larger $iii[] input array:
850 $iii[0] = array("WikiSource...",0xFFFF,"core"),
851 $iii[1] = array("<b>....",0x0002,"html"),
852 $iii[2] = array("text",0x0FFF,""),
854 Besides the $iii[] input array, we'll also have an array containing
855 rendering status variables called $s[]. The most important entry
856 there is $s["in"], which is the index into the currently accessed
857 $iii[] wiki page source or block fragment.
858 And ewiki_format() then uses various alias variable names for
859 entries of the status var $s[] array - for example $in and $s["in"]
860 are the same index number.
862 After ewiki_format() separated the input source into the block
863 fragments of $iii[], it will then run the actual ["fragment_block"]
864 plugins on it. These can then apply regexs on them, or strip the
865 fragments completely out of $iii[] or transform then into regular
868 Then the large wiki transform loop comes into action, but only
869 for $iii[] fragments, whose flags (in the $iii[...][1] number)
870 have the bit 0x0001 set. Other blocks/fragments of $iii[] remain
872 While transforming the $iii[] arrays WikiSource a new fragments
873 array will be created, called $ooo[] - the output array, which has
874 exactly the same layout. And every $iii[$in] directly maps to the
875 $ooo[$in] - same index number! But the later then already contains
876 <html> instead of wiki source.
878 Inside of the transformation loop, two other plugin types are
879 activated (besides applying the $ewiki_config["wm_..."] ruleset):
880 the ["format_line"] and ["format_para"] plugin groups.
882 After all $iii[] blocks have been transformed into $ooo[], a second
883 loop will check the flags (this time $ooo[...][1]) for the bit 0x0002
884 which tells, if WikiWords should be transformed into html <a href=>
887 After link conversion (on the selected fragments), all blocks (the
888 content entries $ooo[...][0] of course) of $ooo[] are merged together
889 into one <html> string. After the ["format_final"] plugins run over
890 this, ewiki_format() returns the resulting <html> page.
894 the format_ plugin hooks
895 ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
896 As denoted above, the ["format_source"] and ["format_final"] plugin
897 hooks are the simplest to work with, as both only get one parameter
898 (passed by reference) containing either the full WikiPage source
899 text or the already fully rendered <html> output.
901 The ["format_line"] and ["format_tbl"] hooks are also rather simple,
902 lookup their interface to know which variables you could modify.
904 The ["format_para"] and ["format_block"] plugins both recieve
905 either the $iii[] or $ooo[] and status $s[] array variables (plus
906 a few aliases and shortcomings). This makes these hooks look a
907 bit more complicated, but allows great flexibility - a "_block"
908 plugin could for example merge its $iii[] fragment with another
909 one, or replace itself with nothing.
911 To write a markup plugin, you should lookup the actual interface in
912 the 'ewiki.php' script or in this README. And don't forget that most
913 parameters are meant to be passed by reference to be useful!
917 $iii[] and $ooo[] block flags
918 ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
919 The $iii[...][1] and $ooo[...][1] hold the flags (as defined by
920 $ewiki_config["format_block"][...][2]) for each fragment of the
921 WikiPage. The "core" blocks (plain WikiSource) always have the
922 default 0x137F assigned.
924 currently used bit values are:
925 0x0001 - render WikiMarkup (inline / text style)
926 0x0002 - render WikiLinks
927 0x0004 - international character &#htmlentities; allowed
928 0x0008 - enable BlockMarkup (lists, tables, headlines, ...)
929 *NEW* 0x0400 - decode < > htmlentities again before calling block plugin
930 0x1000 - fragment further (other block plugins can split it)
932 pseudo-values (OR checks / behaviour):
933 0x0010 - consider to be inline block between WikiSourceBlocks
934 (prevents paragraph breaks between plugin and wiki block)
935 0x0022 - scan for WikiWords in this paragraph
939 your own block markup plugin
940 ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
941 Of course a _block plugin is a bit more complicated than a action
942 or page plugin, but generally you only need this small stub:
944 $ewiki_plugins["format_block"]["your"] = "your_block_func";
945 $ewiki_config["format_block"]["your"] = array(
948 false, // no special filter rule/flag
949 0x0014 // see above, often also just 0x0000
951 function your_block_func(&$str, &$in, &$iii, &$s, $btype) {
955 Where you would just rework the conents of "$str", which will be
956 the text part in between the <your> and </your> tags as defined
957 by the $ewiki_config[] block plugin settings. The other variables
958 in that API aren't normally important.
960 You only must take care, that "<", ">" and "&" are still encoded
961 in htmlentities() at this stage.
967 A newer extension of ewiki (namely plugins/feature/xpi) allows to store
968 addon functions in the database (the code is saved as _BINARY db entry
969 where usually page text was stored). The "PlugInstall" page allows to load
970 the extension code from (even remotely located) .xpi files into the
971 database, from where it can be used later.
972 In order to use once installed xpi code, only the "feature/xpi0.php"
975 Through the design of the xpi feature extension nearly all plugins could
976 be converted and installed in the .xpi format. Though this doesn't make
977 sense for database backends, and converting all to-date plugins is silly.
978 So this feature is further merely used for fun and mini-extensions.
980 You could easily write your own .xpi plugins using the description in the
981 "tools/mkxpi" script. First you need to create a .src file with the plugin
982 code as usual (write it like an ordinary plugin script, except for page
983 plugins), and a few meta: informations on top of that file. Then the mkxpi
984 tool converts this in the binary .xpi format for distribution and
986 Typically this would look like:
988 id: UniqueExtensionName
989 type: actionlink_and_textdata
991 author: PutYourNameHere
992 description: adds the search/ action to the control-links line
993 icon: data:image/png;base64,iVBORw0KGgoAAAANS...
995 // just look'n'feel settings, no real plugin code here...
996 $ewiki_config["action_links"]["view"]["search"] = "SEARCH_ACTION";
997 $ewiki_t["en"]["SEARCH_ACTION"] = "search in other pages";
998 $ewiki_t["de"]["SEARCH_ACTION"] = "woanders suchen";
1001 Most of the fields are optional (author, license, description and of course
1002 icon) but senseful. The type: is required, but only a value of "page" has
1003 a special meaning here (otherwise is merely descriptive). The id: gives that
1004 plugin an internal identifier which will later be used for storing the
1005 extension with a database-wide unique name; for "page" type plugins it of
1006 course would be the name under which it was installed.
1008 The code: contains the usual plugin registration and function definition
1009 code. But for "page" xpi plugins it may not have a function body, but lots
1010 of 'echo' calls to output the dynamic pages contents when called (no return
1011 allowed in this incarnation of page plugins). After this no other fields
1014 Future .xpi versions may allow to embed other files for instant installation
1015 (maybe image files for storage in database). But until now onle the code:
1016 entry carries data which will be installed as database page. All the other
1017 meta entries (id, type, author, ...) will however be stored in the xpi
1018 registry database entry, which is also used to control the enable/disable
1019 flag for each of it (only page plugins cannot be disabled).
1021 To share your own extensions simply send them to one of the core project
1022 developers (Andy or Mario) or just leave a link on the "XpiPlugins" page:
1023 http://erfurtwiki.sourceforge.net/?XpiPlugins
1025 because that way users will immediately see it when remotely installing
1026 .xpi plugins from that default xpi plugin repository. It may be an
1027 security risk for users if they install code from unchecked sources, but
1028 the complete URL is always displayed right before storing the external
1029 code into the database.
1031 The most interesting part of the .xpi system (PlugInstall page) is the
1032 possibility to later disable or remove extensions easily. You only need
1033 to setup the administrator password to install and control click-and-run
1034 extensions without hacking the 'config.php'.
1038 ------------------------------------------------------------------ 5 ---
1042 mysql database structure
1043 ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
1044 The MySQL database table structure is (to a certain degree) compatible
1045 with that of the well known »PHPWiki« v1.2.x (you only need to change
1046 EWIKI_DB_TABLE_NAME to "wiki" to use it). This is the MySQL statement
1047 which creates our database table (you can find it at the bottom of the
1048 "ewiki.php" script):
1049 CREATE TABLE ewiki (
1050 pagename VARCHAR(160) NOT NULL,
1051 version INTEGER UNSIGNED NOT NULL DEFAULT 0,
1052 flags INTEGER UNSIGNED DEFAULT 0,
1054 author VARCHAR(100) DEFAULT 'ewiki',
1055 created INTEGER UNSIGNED DEFAULT 0,
1056 lastmodified INTEGER UNSIGNED DEFAULT 0,
1059 hits INTEGER UNSIGNED DEFAULT 0,
1060 PRIMARY KEY id (pagename, version)
1063 I didn't like the column name {pagename} but as I've seen this was
1064 the only difference I renamed it, therefore now the ewiki_database()
1065 function translates it from "pagename" to "id" and vice versa most of
1066 the time - else this would be really slim and nice code :)
1068 The columns {version} holds the different saved page versions. Other
1069 Wikis require a secondary "backup" or "history" table for old versions,
1070 but as I couldn't imagine what this is for, there is just one table
1071 in ewiki; and it seems this is really enough. The first {version} of
1072 a wiki page is always numbered 1. An existing page {version} will
1073 never get overwritten => very secure MySQL usage.
1075 For what's in the {flags}, see the README section about constants. The
1076 {content} of course holds the wiki pages source. The {created} and
1077 {lastmodified} should be clear too.
1079 {refs} contain a "\n" separated list of referenced WikiPages. The
1080 code to generate that list is rather unclean, so it often contains
1081 GhostPages. However this does not hurt ewiki and the few functions
1082 that utilize {refs}, so there is currently no need to slow it down
1085 {meta} can hold additional informations, which allows to extend ewiki
1086 without requiring to ALTER and convert the ewiki database table. It
1087 currently holds some mime headers for binary content and some other
1088 useful informations for images and uploaded files.
1090 {hits} should have gone into {meta} really. But having it separate
1091 allows us to use the very fast mysql UPDATE function.
1093 Note, that the ewiki database table can hold other things than wiki
1094 pages - binary content (images) for example, depending on the setting
1095 of the {flags} field.
1097 And last comment about this, the one-table-concept also made it really easy
1098 to implement the flat file based "database backend".
1102 ------------------------------------------------------------------ 6 ---
1106 Just using the wiki source transformation
1107 ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
1108 The ewiki_format function was designed to be used independently from the
1111 ewiki_format($wiki_source, 0);
1113 It just needs the "wiki_source" as argument and generates a nicely
1114 formatted page from it. All you need to take care about is the
1115 $ewiki_links variable.
1116 Set the $ewiki_links=true ("true" and not "1" or anything else) to
1117 enforce ewiki_format() to treat all references as existing.
1119 To separate the ewiki_format() function out of recent ewiki versions,
1120 you'll also need ewiki_script(), ewiki_link_regex_callback(), ... and
1121 a lot of constants to take with. It is often much easier to just
1122 include("ewiki.php") for using ewiki_format(). You then should however
1123 take care, that the _binary part doesn't get activated by accident. To
1124 prevent this, just put following before the include() statement:
1126 unset($_REQUEST["binary"]);
1127 include("ewiki.php");
1129 If you need it more quickly, or don't want to load the whole ewiki.php
1130 file, then just try the fragments/wiki_format.inc, which is a stripped
1131 down version of an older rendering core function (no WikiLinks, no binary
1132 stuff). Contributed by Frank Luithle.