Skip to content

Commit

Permalink
Merge pull request #1602 from UlrichB22/titleindex
Browse files Browse the repository at this point in the history
Add macro TitleIndex
  • Loading branch information
RogerHaase authored Feb 12, 2024
2 parents 9d65bd6 + 47176b8 commit af76c68
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 43 deletions.
5 changes: 3 additions & 2 deletions src/moin/macros/ItemList.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Copyright: 2019 MoinMoin:KentWatsen
# Copyright: 2024 MoinMoin:UlrichB
# License: GNU GPL v2 (or any later version), see LICENSE.txt for details.

"""
Expand Down Expand Up @@ -67,7 +68,7 @@
from moin.i18n import _
from moin.utils.tree import moin_page
from moin.utils.interwiki import split_fqname
from moin.macros._base import MacroPageLinkListBase
from moin.macros._base import MacroPageLinkListBase, get_item_names


class Macro(MacroPageLinkListBase):
Expand Down Expand Up @@ -131,7 +132,7 @@ def macro(self, content, arguments, page_url, alternative):
return admonition

# process subitems
children = self.get_item_names(item, startswith=startswith, skiptag=skiptag)
children = get_item_names(item, startswith=startswith, skiptag=skiptag)
if regex:
try:
regex_re = re.compile(regex, re.IGNORECASE)
Expand Down
5 changes: 3 additions & 2 deletions src/moin/macros/RandomItem.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Copyright: 2000 Juergen Hermann <[email protected]>
# Copyright: 2008-2011 MoinMoin:ThomasWaldmann
# Copyright: 2024 MoinMoin:UlrichB
# License: GNU GPL v2 (or any later version), see LICENSE.txt for details.

"""
Expand All @@ -13,7 +14,7 @@
from moin.utils.iri import Iri
from moin.utils.tree import moin_page, xlink
from moin.items import Item
from moin.macros._base import MacroPageLinkListBase
from moin.macros._base import MacroPageLinkListBase, get_item_names
from moin.storage.middleware.protecting import AccessDenied

random.seed()
Expand All @@ -26,7 +27,7 @@ def macro(self, content, arguments, page_url, alternative):
else:
item_count = 1

all_item_names = self.get_item_names()
all_item_names = get_item_names()

# Now select random item from the full list, and if it exists and
# we can read it, save.
Expand Down
35 changes: 35 additions & 0 deletions src/moin/macros/TitleIndex.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Copyright: 2024 MoinMoin:UlrichB
# License: GNU GPL v2 (or any later version), see LICENSE.txt for details.

"""
TitleIndex - generates a list of links for the namespace of the current item, grouped by initials
Parameters:
None
Usage:
<<TitleIndex>>
"""

from moin.macros._base import MacroMultiLinkListBase, get_item_names
from moin.i18n import _
from moin.utils.tree import moin_page
from moin.utils.interwiki import split_fqname


class Macro(MacroMultiLinkListBase):
def macro(self, content, arguments, page_url, alternative):
# get namespace of current item
namespace = split_fqname(str(page_url.path)).namespace

if arguments:
raise ValueError(_("TitleList macro does not have any arguments."))

children = get_item_names(namespace)
if not children:
empty_list = moin_page.list(attrib={moin_page.item_label_generate: 'unordered'})
item_body = moin_page.list_item_body(children=[_("<TitleList macro: No matching items were found.>")])
empty_list.append(moin_page.list_item(children=[item_body]))
return empty_list

return self.create_multi_pagelink_list(children, namespace)
150 changes: 111 additions & 39 deletions src/moin/macros/_base.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Copyright: 2008 MoinMoin:BastianBlank
# Copyright: 2024 MoinMoin:UlrichB
# License: GNU GPL v2 (or any later version), see LICENSE.txt for details.

"""
Expand All @@ -15,6 +16,51 @@
from moin.constants.keys import TAGS


def get_item_names(name='', startswith='', kind='files', skiptag=''):
"""
For the specified item, return the fullname of matching descendents.
Input:
name: the name of the item to get. If '' is passed, then the
top-level item is used.
startwith: a substring the matching pages must begin with. If no
value is specified, then all pages are returned.
kind: the kind of page to return. Valid values include:
files: decendents that do not contain decendents. (default)
dirs: decendents that contain decendents.
both: both 'files' and 'dirs', with duplicates removed.
skiptag: skip items having this tag
Output:
A List of descendent items using their "fullname" value
"""
try:
item = Item.create(name)
except AccessDenied:
abort(403)
dirs, files = item.get_index(startswith)
item_names = []
if not kind or kind == "files" or kind == "both":
for item in files:
if skiptag and TAGS in item.meta and skiptag in item.meta[TAGS]:
continue
item_names.append(item.fullname)
if kind == "dirs" or kind == "both":
for item in dirs:
if skiptag and skiptag in item.meta[TAGS]:
continue
item_names.append(item.fullname)
if kind == "both":
item_names = list(set(item_names)) # remove duplicates
return item_names


class MacroBase:
"""
Macro base class.
Expand Down Expand Up @@ -96,10 +142,12 @@ def create_pagelink_list(self, pagenames, ordered=False, display="FullPath"):
uppercase character.
skiptag : skip items with this tag
ItemTitle : Use the title from the first header in the linked page *not implemented
"""
"""

page_list = moin_page.list(attrib={moin_page.item_label_generate: ordered and 'ordered' or 'unordered'})

for pagename in pagenames:

fqname = pagename.fullname
# This link can never reach pagelinks
url = str(iri.Iri(scheme='wiki', authority='', path='/' + fqname))
Expand Down Expand Up @@ -128,51 +176,75 @@ def create_pagelink_list(self, pagenames, ordered=False, display="FullPath"):
item_body = moin_page.list_item_body(children=[pagelink])
item = moin_page.list_item(children=[item_body])
page_list.append(item)
return page_list

def get_item_names(self, name='', startswith='', kind='files', skiptag=''):
"""
For the specified item, return the fullname of matching descendents.

Input:
name: the name of the item to get. If '' is passed, then the
top-level item is used.
startwith: a substring the matching pages must begin with. If no
value is specified, then all pages are returned.
return page_list

kind: the kind of page to return. Valid values include:

files: decendents that do not contain decendents. (default)
dirs: decendents that contain decendents.
both: both 'files' and 'dirs', with duplicates removed.
class MacroMultiLinkListBase(MacroBlockBase):
def create_multi_pagelink_list(self, itemnames, namespace):
""" Creates an ET with a list of itemlinks from a list of itemnames
grouped by initials.
skiptag: skip items having this tag
Parameters:
Output:
itemnames: a list of items, each being like a flask request.path[1:]
A List of descendent items using their "fullname" value
namespace: Namespace of items
"""
try:
item = Item.create(name)
except AccessDenied:
abort(403)
dirs, files = item.get_index(startswith)
item_names = []
if not kind or kind == "files" or kind == "both":
for item in files:
if skiptag and TAGS in item.meta and skiptag in item.meta[TAGS]:
continue
item_names.append(item.fullname)
if kind == "dirs" or kind == "both":
for item in dirs:
if skiptag and skiptag in item.meta[TAGS]:
continue
item_names.append(item.fullname)
if kind == "both":
item_names = list(set(item_names)) # remove duplicates
return item_names

result_body = []
initials_linklist = []
initial_letter = ' '

if namespace == '':
namespace_name = _("Namespace '%(name)s' ", name='default')
pos_namespace_cut = 0
else:
namespace_name = _("Namespace '%(name)s' ", name=namespace)
pos_namespace_cut = len(namespace) + 1

item_list = moin_page.list(attrib={moin_page.item_label_generate: 'unordered'})
initials_link = moin_page.a(attrib={xlink.href: '#idx-top'}, children=['top', ])
initials_linklist.extend([initials_link, moin_page.strong(children=[' | ', ])])

for itemname in itemnames:
if not itemname.value.startswith(initial_letter):
# generate header line with initial
initial_letter = itemname.value[0]
result_body.append(item_list) # finish item_list for last initial and initialize new item_list
item_list = moin_page.list(attrib={moin_page.item_label_generate: 'unordered'})

header_with_anchor = moin_page.span(
attrib={moin_page.class_: "moin-big", moin_page.id: 'idx-' + initial_letter},
children=[initial_letter,
moin_page.a(attrib={moin_page.class_: "moin-align-right", xlink.href: '#idx-top'},
children=['^', ])])
result_body.append(header_with_anchor)
initials_link = moin_page.a(attrib={xlink.href: '#idx-' + initial_letter}, children=[initial_letter])
initials_linklist.extend([initials_link, moin_page.strong(children=[' | ',])])

# build and add itemname link
fqname = itemname.fullname
url = str(iri.Iri(scheme='wiki', authority='', path='/' + fqname))
linkname = fqname[pos_namespace_cut:]
pagelink = moin_page.a(attrib={xlink.href: url}, children=[linkname])
item_body = moin_page.list_item_body(children=[pagelink])
item = moin_page.list_item(children=[item_body])
item_list.append(item)

result_body.append(item_list) # finish item_list for last initial

# Add a list of links for each used initial at top and bottom of the index
initials_begin = moin_page.span(attrib={moin_page.id: "idx-top", moin_page.class_: "moin-align-left"},
children=[_("Index of %(what)s", what=namespace_name), ])
initials_link_end = moin_page.a(attrib={xlink.href: '#idx-bottom'}, children=['bottom', ])
initials_linklist.append(initials_link_end)
initials_links_span = moin_page.span(attrib={moin_page.class_: "moin-align-right"}, children=initials_linklist)
result_body.insert(0, moin_page.p(children=[initials_begin, initials_links_span]))
initials_end = moin_page.span(
attrib={moin_page.id: "idx-bottom", moin_page.class_: "moin-align-left"}, children=".")
result_body.append(moin_page.p(children=[initials_end, initials_links_span]))
return moin_page.body(children=result_body)


class MacroNumberPageLinkListBase(MacroBlockBase):
Expand Down

0 comments on commit af76c68

Please sign in to comment.