-
Notifications
You must be signed in to change notification settings - Fork 2
/
tree.py
139 lines (117 loc) · 4.63 KB
/
tree.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
##############################################################################
#
# Copyright (c) 2002, 2003 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""`OnlineHelp` tree view
"""
__docformat__ = 'restructuredtext'
from zope.component import getUtility
from zope.i18n import translate
from zope.publisher.browser import BrowserView
from zope.traversing.api import getPath, joinPath
from zope.app.onlinehelp.interfaces import IOnlineHelp
class OnlineHelpTopicTreeView(BrowserView):
"""Online help topic tree view."""
def __init__(self, context, request):
super(OnlineHelpTopicTreeView, self).__init__(context, request)
self.onlinehelp = getUtility(IOnlineHelp, "OnlineHelp")
def getTopicTree(self):
"""Return the tree of help topics.
We build a flat list of tpoics info dict.
Iterate this dict oan build from the level info
a navigation tree in the page tmeplate.
Each time you get a level 0 means this is a subitem of the
Onlinehelp itself::
>>> info = [('id',{infoDict}),(),()] # noqa: F821 undefined name
<ul class="tree" id="tree">
<li><a href="#">items</a>
<ul>
<li><a href="#">item</a></li>
</ul>
</li>
<li><a href="#">items</a>
<ul>
<li><a href="#">items</a>
<ul>
<li><a href="#">item</a></li>
<li><a href="#">item</a></li>
<li><a href="#">item</a></li>
</ul>
</li>
<li><a href="#">items</a>
<ul>
<li><a href="#">item</a></li>
<li id="activeTreeNode"><a href="#">active item</a></li>
<li><a href="#">item</a></li>
</ul>
</li>
</ul>
</li>
<ul>
"""
return self.renderTree(self.onlinehelp)
def renderTree(self, root):
"""Reder a unordered list 'ul' tree with a class name 'tree'."""
res = []
intend = " "
res.append('<ul class="tree" id="tree">')
for topic in root.getSubTopics():
item = self.renderLink(topic)
# expand if context is in tree
if self.isExpanded(topic):
res.append(' <li class="expand">%s' % item)
else:
res.append(' <li>%s' % item)
if len(topic.getSubTopics()) > 0:
res.append(self.renderItemList(topic, intend))
res.append(' </li>')
res.append('<ul>')
return '\n'.join(res)
def renderItemList(self, topic, intend):
"""Render a 'ul' elements as childs of the 'ul' tree."""
res = []
intend = intend + " "
res.append('%s<ul>' % intend)
for item in topic.getSubTopics():
# expand if context is in tree
if self.isExpanded(topic):
res.append(' %s<li class="expand">' % intend)
else:
res.append(' %s<li>' % intend)
res.append(self.renderLink(item))
if len(item.getSubTopics()) > 0:
res.append(' %s%s' % (
self.renderItemList(item, intend), intend))
res.append(' %s</li>' % intend)
res.append('%s</ul>' % intend)
return '\n'.join(res)
def renderLink(self, topic):
"""Render a href element."""
title = translate(topic.title, context=self.request,
default=topic.title)
if topic.parentPath:
url = joinPath(topic.parentPath, topic.id)
else:
url = topic.id
return '<a href="/++help++/%s">%s</a>\n' % (url, title)
def isExpanded(self, topic):
if topic.parentPath:
path = joinPath(topic.parentPath, topic.id)
else:
path = topic.id
try:
if getPath(self.context).startswith('/' + path):
return True
except: # noqa: E722 do not use bare 'except'
# TODO: fix it, functional test doesn't like getPath? ri
pass
return False