Bläddra i källkod

Tree view added

master
Dirk Alders 2 månader sedan
förälder
incheckning
18dd102fe2
8 ändrade filer med 95 tillägg och 23 borttagningar
  1. 5
    0
      data/system-pages/tree/meta.json
  2. 2
    0
      data/system-pages/tree/page
  3. 3
    3
      pages/__init__.py
  4. 17
    8
      pages/context.py
  5. 1
    1
      pages/help.py
  6. 62
    6
      pages/page.py
  7. 4
    4
      pages/views.py
  8. 1
    1
      themes

+ 5
- 0
data/system-pages/tree/meta.json Visa fil

1
+{
2
+    "modified_time": 1729022206,
3
+    "modified_user": "system-page",
4
+    "creation_time": 1729022206
5
+}

+ 2
- 0
data/system-pages/tree/page Visa fil

1
+= Tree
2
+<<allpagestree>>

+ 3
- 3
pages/__init__.py Visa fil

10
     return params
10
     return params
11
 
11
 
12
 
12
 
13
-def url_page(request, rel_path, **kwargs):
13
+def url_page(rel_path, **kwargs):
14
     return reverse('page-page', kwargs={'rel_path': rel_path}) + params(**kwargs)
14
     return reverse('page-page', kwargs={'rel_path': rel_path}) + params(**kwargs)
15
 
15
 
16
 
16
 
17
-def url_helpview(request, page):
17
+def url_helpview(page):
18
     return reverse('page-helpview', kwargs={'page': page})
18
     return reverse('page-helpview', kwargs={'page': page})
19
 
19
 
20
 
20
 
21
-def url_edit(request, rel_path, **kwargs):
21
+def url_edit(rel_path, **kwargs):
22
     return reverse('page-edit', kwargs={'rel_path': rel_path}) + params(**kwargs)
22
     return reverse('page-edit', kwargs={'rel_path': rel_path}) + params(**kwargs)
23
 
23
 
24
 
24
 

+ 17
- 8
pages/context.py Visa fil

20
 EDIT_UID = 'edit'
20
 EDIT_UID = 'edit'
21
 HELP_UID = 'help'
21
 HELP_UID = 'help'
22
 INDEX_UID = 'index'
22
 INDEX_UID = 'index'
23
+TREE_UID = 'tree'
23
 NAVIGATION_ENTRY_UID = 'navigation-%s'
24
 NAVIGATION_ENTRY_UID = 'navigation-%s'
24
 
25
 
25
 
26
 
65
     if not cms_mode_active(request):
66
     if not cms_mode_active(request):
66
         menubar_users(bar, request)
67
         menubar_users(bar, request)
67
         add_help_menu(request, bar, "current_help_page" in kwargs)
68
         add_help_menu(request, bar, "current_help_page" in kwargs)
68
-    add_index_menu(request, bar, kwargs.get("rel_path", ''))
69
+    add_nav_links(request, bar, kwargs.get("rel_path", ''))
69
     finalise_bar(request, bar)
70
     finalise_bar(request, bar)
70
 
71
 
71
 
72
 
100
         NAVIGATION_ENTRY_UID % os.path.basename(path),          # uid
101
         NAVIGATION_ENTRY_UID % os.path.basename(path),          # uid
101
         '/' + os.path.basename(path),                           # name
102
         '/' + os.path.basename(path),                           # name
102
         None,                                                   # icon
103
         None,                                                   # icon
103
-        pages.url_page(request, path),                          # url
104
+        pages.url_page(path),                                   # url
104
         False,                                                  # left
105
         False,                                                  # left
105
         False                                                   # active
106
         False                                                   # active
106
     )
107
     )
111
         HELP_UID,                                   # uid
112
         HELP_UID,                                   # uid
112
         _('Help'),                                  # name
113
         _('Help'),                                  # name
113
         color_icon_url(request, 'help.png'),        # icon
114
         color_icon_url(request, 'help.png'),        # icon
114
-        pages.url_helpview(request, 'main'),        # url
115
+        pages.url_helpview('main'),                 # url
115
         True,                                       # left
116
         True,                                       # left
116
         active                                      # active
117
         active                                      # active
117
     )
118
     )
118
 
119
 
119
 
120
 
120
-def add_index_menu(request, bar, rel_path):
121
+def add_nav_links(request, bar, rel_path):
121
     bar.append_entry(
122
     bar.append_entry(
122
         INDEX_UID,                                  # uid
123
         INDEX_UID,                                  # uid
123
         _('Index'),                                 # name
124
         _('Index'),                                 # name
124
         color_icon_url(request, 'edit.png'),        # icon
125
         color_icon_url(request, 'edit.png'),        # icon
125
-        pages.url_page(request, 'index'),           # url
126
+        pages.url_page('index'),                    # url
126
         True,                                       # left
127
         True,                                       # left
127
         request.path == "/page/index"               # active
128
         request.path == "/page/index"               # active
128
     )
129
     )
130
+    bar.append_entry(
131
+        TREE_UID,                                   # uid
132
+        _('Tree'),                                  # name
133
+        color_icon_url(request, 'tree.png'),        # icon
134
+        pages.url_page('tree'),                     # url
135
+        True,                                       # left
136
+        request.path == "/page/tree"                # active
137
+    )
129
 
138
 
130
 
139
 
131
 def add_edit_menu(request, bar, rel_path):
140
 def add_edit_menu(request, bar, rel_path):
133
         EDIT_UID,                                   # uid
142
         EDIT_UID,                                   # uid
134
         _('Edit'),                                  # name
143
         _('Edit'),                                  # name
135
         color_icon_url(request, 'edit2.png'),       # icon
144
         color_icon_url(request, 'edit2.png'),       # icon
136
-        pages.url_edit(request, rel_path),          # url
145
+        pages.url_edit(rel_path),                   # url
137
         True,                                       # left
146
         True,                                       # left
138
         False                                       # active
147
         False                                       # active
139
     )
148
     )
156
             EDIT_UID,                                       # uid
165
             EDIT_UID,                                       # uid
157
             _('Page'),                                      # name
166
             _('Page'),                                      # name
158
             color_icon_url(request, 'display.png'),         # icon
167
             color_icon_url(request, 'display.png'),         # icon
159
-            pages.url_page(request, rel_path),              # url
168
+            pages.url_page(rel_path),                       # url
160
             True,                                           # left
169
             True,                                           # left
161
             False                                           # active
170
             False                                           # active
162
         )
171
         )
165
             EDIT_UID,                                       # uid
174
             EDIT_UID,                                       # uid
166
             _('Meta'),                                      # name
175
             _('Meta'),                                      # name
167
             color_icon_url(request, 'info.png'),            # icon
176
             color_icon_url(request, 'info.png'),            # icon
168
-            pages.url_page(request, rel_path, meta=None),   # url
177
+            pages.url_page(rel_path, meta=None),            # url
169
             True,                                           # left
178
             True,                                           # left
170
             False                                           # active
179
             False                                           # active
171
         )
180
         )

+ 1
- 1
pages/help.py Visa fil

131
             HELP_UID + '-%s' % name.lower(),                        # uid
131
             HELP_UID + '-%s' % name.lower(),                        # uid
132
             _(name),                                                # name
132
             _(name),                                                # name
133
             color_icon_url(request, num + '.png'),                  # icon
133
             color_icon_url(request, num + '.png'),                  # icon
134
-            pages.url_helpview(request, name.lower()),              # url
134
+            pages.url_helpview(name.lower()),                       # url
135
             True,                                                   # left
135
             True,                                                   # left
136
             name.lower() == current_help_page,                      # active
136
             name.lower() == current_help_page,                      # active
137
         )
137
         )

+ 62
- 6
pages/page.py Visa fil

22
     system_pages = fstools.dirlist(settings.SYSTEM_PAGES_ROOT, expression=expression, rekursive=False)
22
     system_pages = fstools.dirlist(settings.SYSTEM_PAGES_ROOT, expression=expression, rekursive=False)
23
     system_pages = [os.path.join(settings.PAGES_ROOT, os.path.basename(path)) for path in system_pages]
23
     system_pages = [os.path.join(settings.PAGES_ROOT, os.path.basename(path)) for path in system_pages]
24
     pages = fstools.dirlist(settings.PAGES_ROOT, expression=expression, rekursive=False)
24
     pages = fstools.dirlist(settings.PAGES_ROOT, expression=expression, rekursive=False)
25
+    # TODO: strip path, if page or meta.json is missing
25
     return list(set(system_pages + pages))
26
     return list(set(system_pages + pages))
26
 
27
 
27
 
28
 
197
             name = _("Current")
198
             name = _("Current")
198
             meta += f"| {name} \
199
             meta += f"| {name} \
199
                       | {timestamp_to_datetime(self._request, mtime)} \
200
                       | {timestamp_to_datetime(self._request, mtime)} \
200
-                      | [[{url_page(self._request, self.rel_path)} | Page]] \
201
-                      | [[{url_page(self._request, self.rel_path, meta=None)} | Meta]]\n"
201
+                      | [[{url_page(self.rel_path)} | Page]] \
202
+                      | [[{url_page(self.rel_path, meta=None)} | Meta]]\n"
202
             # History
203
             # History
203
             for num in reversed(hnl):
204
             for num in reversed(hnl):
204
                 p = page_wrapped(self._request, self._path, history_version=num)
205
                 p = page_wrapped(self._request, self._path, history_version=num)
205
                 meta += f"| {num} \
206
                 meta += f"| {num} \
206
                           | {timestamp_to_datetime(self._request, p.modified_time)} \
207
                           | {timestamp_to_datetime(self._request, p.modified_time)} \
207
-                          | [[{url_page(self._request, p.rel_path, history=num)} | Page]] \
208
-                          | [[{url_page(self._request, p.rel_path, meta=None, history=num)} | Meta]] (with page changes)\n"
208
+                          | [[{url_page(p.rel_path, history=num)} | Page]] \
209
+                          | [[{url_page(p.rel_path, meta=None, history=num)} | Meta]] (with page changes)\n"
209
         # Diff
210
         # Diff
210
         html_diff = ""
211
         html_diff = ""
211
         if self._history_version:
212
         if self._history_version:
222
         macros = {
223
         macros = {
223
             "subpages": self.macro_subpages,
224
             "subpages": self.macro_subpages,
224
             "allpages": self.macro_allpages,
225
             "allpages": self.macro_allpages,
226
+            "subpagetree": self.macro_subpagetree,
227
+            "allpagestree": self.macro_allpagestree,
225
         }
228
         }
226
         return mycreole.render(request, txt, self.attachment_path, macros=macros)
229
         return mycreole.render(request, txt, self.attachment_path, macros=macros)
227
 
230
 
231
 
234
 
232
     def macro_subpages(self, *args, **kwargs):
235
     def macro_subpages(self, *args, **kwargs):
233
         allpages = kwargs.pop("allpages", False)
236
         allpages = kwargs.pop("allpages", False)
237
+        tree = kwargs.pop("tree", False)
234
         #
238
         #
235
 
239
 
236
         def parse_depth(s: str):
240
         def parse_depth(s: str):
263
             self._request,
267
             self._request,
264
             [page_django(self._request, path) for path in full_path_all_pages(expression)]
268
             [page_django(self._request, path) for path in full_path_all_pages(expression)]
265
         )
269
         )
266
-        return pl.html_list(depth=depth, filter_str=filter_str, parent_rel_path=parent_rel_path)
270
+        if tree:
271
+            return page_tree(pl).html()
272
+        else:
273
+            return pl.html_list(depth=depth, filter_str=filter_str, parent_rel_path=parent_rel_path)
274
+
275
+    def macro_allpagestree(self, *args, **kwargs):
276
+        kwargs["allpages"] = True
277
+        kwargs["tree"] = True
278
+        return self.macro_subpages(*args, **kwargs)
279
+
280
+    def macro_subpagetree(self, * args, **kwargs):
281
+        kwargs["tree"] = True
282
+        return self.macro_subpages(*args, **kwargs)
267
 
283
 
268
 
284
 
269
 class page_list(list):
285
 class page_list(list):
290
                     if last_char != first_char:
306
                     if last_char != first_char:
291
                         last_char = first_char
307
                         last_char = first_char
292
                         rv += f"=== {first_char}\n"
308
                         rv += f"=== {first_char}\n"
293
-                    rv += f"* [[{url_page(self._request, page.rel_path)} | {name} ]]\n"
309
+                    rv += f"* [[{url_page(page.rel_path)} | {name} ]]\n"
294
         return rv
310
         return rv
295
 
311
 
296
     def html_list(self, depth=9999, filter_str='', parent_rel_path=''):
312
     def html_list(self, depth=9999, filter_str='', parent_rel_path=''):
297
         return mycreole.render_simple(self.creole_list(depth, filter_str, parent_rel_path))
313
         return mycreole.render_simple(self.creole_list(depth, filter_str, parent_rel_path))
298
 
314
 
299
 
315
 
316
+class page_tree(dict):
317
+    T_PATTERN = "├── "
318
+    L_PATTERN = "└── "
319
+    I_PATTERN = "│   "
320
+    D_PATTERN = "   &nbsp;&nbsp;&nbsp;"
321
+
322
+    def __init__(self, pl: page_list):
323
+        super().__init__()
324
+        for page in pl:
325
+            store_item = self
326
+            for entry in page.rel_path.split("/"):
327
+                if not entry in store_item:
328
+                    store_item[entry] = {}
329
+                store_item = store_item[entry]
330
+
331
+    def html(self, rel_path=None, fill=""):
332
+        base = self
333
+        try:
334
+            for key in rel_path.split("/"):
335
+                base = base[key]
336
+        except AttributeError:
337
+            rel_path = ''
338
+        #
339
+        rv = ""
340
+        #
341
+        l = len(base)
342
+        for entry in sorted(list(base.keys())):
343
+            l -= 1
344
+            page_path = os.path.join(rel_path, entry)
345
+            page = page_wrapped(None, page_path)
346
+            if page.is_available():
347
+                entry = f'<a href="{url_page(page_path)}">{entry}</a>'
348
+            rv += fill + (self.L_PATTERN if l == 0 else self.T_PATTERN) + entry + "<br>\n"
349
+            rv += self.html(page_path, fill=fill+(self.D_PATTERN if l == 0 else self.I_PATTERN))
350
+        return rv
351
+
352
+
300
 class page_wrapped(object):
353
 class page_wrapped(object):
301
     """
354
     """
302
     This class holds different page and meta instances and decides which will be used in which case.
355
     This class holds different page and meta instances and decides which will be used in which case.
395
         rv = page.attachment_path
448
         rv = page.attachment_path
396
         return rv
449
         return rv
397
 
450
 
451
+    def is_available(self):
452
+        return self._page.is_available() or self._system_page.is_available()
453
+
398
     @property
454
     @property
399
     def raw_page_src(self):
455
     def raw_page_src(self):
400
         page = self.__page_choose__()
456
         page = self.__page_choose__()

+ 4
- 4
pages/views.py Visa fil

23
 
23
 
24
 
24
 
25
 def root(request):
25
 def root(request):
26
-    return HttpResponseRedirect(url_page(request, config.STARTPAGE))
26
+    return HttpResponseRedirect(url_page(config.STARTPAGE))
27
 
27
 
28
 
28
 
29
 def page(request, rel_path):
29
 def page(request, rel_path):
92
                     messages.edit_success(request)
92
                     messages.edit_success(request)
93
                 else:
93
                 else:
94
                     messages.edit_no_change(request)
94
                     messages.edit_no_change(request)
95
-                return HttpResponseRedirect(url_page(request, rel_path))
95
+                return HttpResponseRedirect(url_page(rel_path))
96
             elif preview is not None:
96
             elif preview is not None:
97
                 form = EditForm(page_data=page_txt, page_tags=tags)
97
                 form = EditForm(page_data=page_txt, page_tags=tags)
98
                 #
98
                 #
107
                 )
107
                 )
108
                 return render(request, 'pages/page_form.html', context=context)
108
                 return render(request, 'pages/page_form.html', context=context)
109
             else:
109
             else:
110
-                return HttpResponseRedirect(url_page(request, rel_path))
110
+                return HttpResponseRedirect(url_page(rel_path))
111
     else:
111
     else:
112
         messages.permission_denied_msg_page(request, rel_path)
112
         messages.permission_denied_msg_page(request, rel_path)
113
-        return HttpResponseRedirect(url_page(request, rel_path))
113
+        return HttpResponseRedirect(url_page(rel_path))
114
 
114
 
115
 
115
 
116
 def search(request):
116
 def search(request):

+ 1
- 1
themes

1
-Subproject commit c63d8731fe85374ef74abf24b0d205bce24f66b1
1
+Subproject commit c13b45a7f736c0e8658fbd24ff826ad9b5d336e6

Laddar…
Avbryt
Spara