fe0fd46b0ec4b5504f1bef4e315a98414762bacb
[ikiwiki.git] / doc / tips / convert_mediawiki_to_ikiwiki.mdwn
1 [[!toc levels=2]]
2
3 Mediawiki is a dynamically-generated wiki which stores it's data in a
4 relational database. Pages are marked up using a proprietary markup. It is
5 possible to import the contents of a Mediawiki site into an ikiwiki,
6 converting some of the Mediawiki conventions into Ikiwiki ones.
7
8 The following instructions describe ways of obtaining the current version of
9 the wiki. We do not yet cover importing the history of edits.
10
11 Another set of instructions and conversion tools (which imports the full history)
12 can be found at <http://github.com/mithro/media2iki>
13
14 ## Step 1: Getting a list of pages
15
16 The first bit of information you require is a list of pages in the Mediawiki.
17 There are several different ways of obtaining these.
18
19 ### Parsing the output of `Special:Allpages`
20
21 Mediawikis have a special page called `Special:Allpages` which list all the
22 pages for a given namespace on the wiki.
23
24 If you fetch the output of this page to a local file with something like
25
26     wget -q -O tmpfile 'http://your-mediawiki/wiki/Special:Allpages'
27
28 You can extract the list of page names using the following python script. Note
29 that this script is sensitive to the specific markup used on the page, so if
30 you have tweaked your mediawiki theme a lot from the original, you will need
31 to adjust this script too:
32
33     import sys
34     from xml.dom.minidom import parse, parseString
35     
36     dom = parse(sys.argv[1])
37     tables = dom.getElementsByTagName("table")
38     pagetable = tables[-1]
39     anchors = pagetable.getElementsByTagName("a")
40     for a in anchors:
41         print a.firstChild.toxml().\
42             replace('&amp;','&').\
43             replace('&lt;','<').\
44             replace('&gt;','>')
45
46 Also, if you have pages with titles that need to be encoded to be represented
47 in HTML, you may need to add further processing to the last line.
48
49 Note that by default, `Special:Allpages` will only list pages in the main
50 namespace. You need to add a `&namespace=XX` argument to get pages in a
51 different namespace. (See below for the default list of namespaces)
52
53 Note that the page names obtained this way will not include any namespace
54 specific prefix: e.g. `Category:` will be stripped off.
55
56 ### Querying the database
57
58 If you have access to the relational database in which your mediawiki data is
59 stored, it is possible to derive a list of page names from this. With mediawiki's
60 MySQL backend, the page table is, appropriately enough, called `table`:
61
62  SELECT page_namespace, page_title FROM page;
63
64 As with the previous method, you will need to do some filtering based on the
65 namespace.
66
67 ### namespaces
68
69 The list of default namespaces in mediawiki is available from <http://www.mediawiki.org/wiki/Manual:Namespace#Built-in_namespaces>, reproduced here for convenience:
70
71 [[mediawiki_namespaces]]
72
73 ## Step 2: fetching the page data
74
75 Once you have a list of page names, you can fetch the data for each page.
76
77 ### Method 1: via HTTP and `action=raw`
78
79 You need to create two derived strings from the page titles: the
80 destination path for the page and the source URL. Assuming `$pagename` 
81 contains a pagename obtained above, and `$wiki` contains the URL to your
82 mediawiki's `index.php` file:
83
84     src=`echo "$pagename" | tr ' ' _ | sed 's,&,&amp;,g'`
85     dest=`"$pagename" | tr ' ' _ | sed 's,&,__38__,g'`
86     
87     mkdir -p `dirname "$dest"`
88     wget -q "$wiki?title=$src&action=raw" -O "$dest"
89
90 You may need to add more conversions here depending on the precise page titles
91 used in your wiki.
92
93 If you are trying to fetch pages from a different namespace to the default,
94 you will need to prefix the page title with the relevant prefix, e.g.
95 `Category:` for category pages. You probably don't want to prefix it to the
96 output page, but you may want to vary the destination path (i.e. insert an
97 extra directory component corresponding to your ikiwiki's `tagbase`).
98
99 ### Method 2: via HTTP and `Special:Export`
100
101 Mediawiki also has a special page `Special:Export` which can be used to obtain
102 the source of the page and other metadata such as the last contributor, or the
103 full history, etc.
104
105 You need to send a `POST` request to the `Special:Export` page. See the source
106 of the page fetched via `GET` to determine the correct arguments.
107
108 You will then need to write an XML parser to extract the data you need from
109 the result.
110
111 ### Method 3: via the database
112
113 It is possible to extract the page data from the database with some
114 well-crafted queries.
115
116 ## Step 3: format conversion
117
118 The next step is to convert Mediawiki conventions into Ikiwiki ones.
119
120 ### categories
121
122 Mediawiki uses a special page name prefix to define "Categories", which
123 otherwise behave like ikiwiki tags. You can convert every Mediawiki category
124 into an ikiwiki tag name using a script such as
125
126     import sys, re
127     pattern =  r'\[\[Category:([^\]]+)\]\]'
128     
129     def manglecat(mo):
130             return '\[[!tag %s]]' % mo.group(1).strip().replace(' ','_')
131             
132     for line in sys.stdin.readlines():
133             res = re.match(pattern, line)
134             if res:
135                     sys.stdout.write(re.sub(pattern, manglecat, line))
136             else: sys.stdout.write(line)
137
138 ## Step 4: Mediawiki plugin
139
140 The [[plugins/contrib/mediawiki]] plugin can be used by ikiwiki to interpret
141 most of the Mediawiki syntax.
142
143 ## External links
144
145 [[sabr]] used to explain how to [import MediaWiki content into
146 git](http://u32.net/Mediawiki_Conversion/index.html?updated), including full
147 edit history, but as of 2009/10/16 that site is not available. A copy of the 
148 information found on this website is stored at <http://github.com/mithro/media2iki>
149
150