-
Notifications
You must be signed in to change notification settings - Fork 1
/
wiki5.py
143 lines (99 loc) · 3.86 KB
/
wiki5.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# --
# Copyright (c) 2008-2017 Net-ng.
# All rights reserved.
#
# This software is licensed under the BSD License, as described in
# the file LICENSE.txt, which you should have received as part of
# this distribution.
# --
"""Adding a second view to the Page and PageEditor component, displaying
meta data about the current page and action.
"""
import re
import docutils.core
from nagare import component, presentation, var
from wikidata import PageData
# ---------------------------------------------------------------------------
wikiwords = re.compile(r'\b([A-Z]\w+[A-Z]+\w+)')
class Page(object):
def __init__(self, title):
self.title = title
def edit(self, comp):
content = comp.call(PageEditor(self))
if content is not None:
page = PageData.get_by(pagename=self.title)
page.data = content
@presentation.render_for(Page)
def render(self, h, comp, *args):
page = PageData.get_by(pagename=self.title)
content = docutils.core.publish_parts(page.data, writer_name='html')['html_body']
content = wikiwords.sub(r'<wiki>\1</wiki>', content)
html = h.parse_htmlstring(content, fragment=True)[0]
for node in html.getiterator():
if node.tag == 'wiki':
a = h.a(node.text).action(comp.answer, unicode(node.text))
node.replace(a)
return (html, h.a('Edit this page').action(self.edit, comp))
@presentation.render_for(Page, model='meta')
def render(self, h, comp, *args):
"""Second view, called ``meta``, for the Page component
Display:
- the current action : 'Viewing'
- the current page title
- a link to return to the 'FrontPage' page
"""
return ('Viewing ', h.b(self.title), h.br, h.br,
'You can return to the ', h.a('FrontPage').action(comp.becomes, Page(u'FrontPage')))
# ---------------------------------------------------------------------------
class PageEditor(object):
def __init__(self, page):
self.page = page
def answer(self, comp, text):
comp.answer(text())
@presentation.render_for(PageEditor)
def render(self, h, comp, *args):
content = var.Var()
page = PageData.get_by(pagename=self.page.title)
with h.form:
with h.textarea(rows='10', cols='40').action(content):
h << page.data
h << h.br
h << h.input(type='submit', value='Save').action(self.answer, comp, content)
h << ' '
h << h.input(type='submit', value='Cancel').action(comp.answer)
return h.root
@presentation.render_for(PageEditor, model='meta')
def render(self, h, *args):
"""Second view, called ``meta``, for the PageEditor component
Display:
- the current action : 'Editing'
- the title of the current edited page
"""
return ('Editing ', h.b(self.page.title))
# ---------------------------------------------------------------------------
class Wiki(object):
def __init__(self):
self.content = component.Component(None)
self.content.on_answer(self.goto)
self.goto(u'FrontPage')
def goto(self, title):
page = PageData.get_by(pagename=title)
if page is None:
PageData(pagename=title, data=u'')
self.content.becomes(Page(title))
@presentation.render_for(Wiki)
def render(self, h, *args):
h.head.css('main_css', '''
.document:first-letter { font-size:2em }
.meta { float:right; width: 10em; border: 1px dashed gray;padding: 1em; margin: 1em; }
''')
return (
# The following div display the 'meta' view of the current
# ``self.content`` component. It can be a Page component or
# a PageEditor component. We don't care because both has a
# ``meta`` view.
h.div(self.content.render(h, model='meta'), class_='meta'),
self.content,
)
# ---------------------------------------------------------------------------
app = Wiki