= Description = If you generate Table-of-contents for Headings generated by Include, then the links in the TOC and the anchors of Headings mismatch. And it seems, if you have Includes in your included pages, then the headings of the included pages of the included pages doesn't appear in the TOC. == Example == ----- TOC: <> ----- /IncludedPageWhichIncludesAnotherPage : <> ----- == Details == This Wiki. == Workaround == Use full paths to included pages, e.g., on page '''!ParentPage''', you'd write `[[Include(ParentPage/SubPage)]]`, not `[[Include(/SubPage)]]` = Discussion = That Include/TOC code is a mess. If somebody wants it fixed, debug it yourself. :) -- ThomasWaldmann <> Here is a possible fix: 1. Create the toc while formatting the page, by hooking to formatter.heading and text. Each time heading is opened, an item will be added to the toc. Then all the text will go to both heading and toc item. 1. The toc will be collected and saved for all pages, in request.toc 1. `TableOfContents` macro will put a place holder into the page: `<<>>` 1. Page will be rendered into a buffer, always 1. After the page is rendered, the table of contents placeholder will be replaced by the content of the toc, and the text sent to the client. 1. Only the first toc macro will place a toc, next calls will add nothing. Multiple toc on one page does not make sense. Just for the record, this problem (or a very similar one) has returned with a vengeance in 1.9.0. Even fully specified included pages fail to be linked correctly from the TOC. You can see it for example in the second TOC on MoinMoinQuestions. See [[#Fix_for_Moin_1.9|Fix for Moin 1.9]] below. == text_python output == The fix will create the text_python output bellow. headings can be static items, rendered on compile time, while tocItem will be dynamic call, made when the cache is executed, adding items to a toc object. === Alt 1: adding toc hook in the formatter === Add call to tocItem to formatter.base.heading I'm not sure it will work, as text or _text is static. {{{ formatter.tocItem(1, 1, "id") request.write('

) formatter.text('heading') request.write('heading') formatter.tocItem(0) request.write('

') }}} === Alt 2: adding toc hook in the parser === Call formatter.tocItem from the parser, just before or after the heading This seems to be the easiest solution. {{{ formatter.tocItem(1, "id", "heading") request.write('

) request.write('heading') request.write('

') }}} == Partial Fix == This code fixes the problem with the mis-pointed anchor. Isolating the problem, I noticed that if the included page was a complete Pagename - in this example {{{ [[Include(/IncludedPageWhichIncludesAnotherPage)]] }}} produces the error and doing {{{ [[Include(MoinMoinBugs/TableOfContentsBrokenForIncludedPages/IncludedPageWhichIncludesAnotherPage)]] }}} worked. It appears that the anchor in the TableOfContents is built based on the included page name and that mismatches when you have leading slash subpages or regular expressions in the Include. Change !TableOfContents.py seems to work in my 1.5.3 Wiki. {{{#!python @@ -114,9 +114,35 @@ else: inc_page_lines = [] - inc_page_lines = inc_page_lines + self.IncludeMacro(self.macro, match.group(1), called_by_toc=1) - self.process_lines(inc_page_lines, inc_pagename) + + # get list of pages to include + inc_name = wikiutil.AbsPageName(self.macro.request, self.macro.formatter.page.page_name, match.group(1) ) + pagelist = [inc_name] + if inc_name.startswith("^"): + try: + inc_match = re.compile(inc_name) + except re.error: + pass # treat as plain page name + else: + # Get user filtered readable page list + pagelist = self.macro.request.rootpage.getPageList(filter=inc_match.match) + + # sort and limit page list + pagelist.sort() + sort_dir = tmp.group('sort') + if sort_dir == 'descending': + pagelist.reverse() + max_items = tmp.group('items') + if max_items: + pagelist = pagelist[:int(max_items)] + + for inc_name in pagelist: + if not self.macro.request.user.may.read(inc_name): + continue + self.process_lines( self.IncludeMacro(self.macro, inc_name, called_by_toc=1), + inc_name) + else: self.parse_line(line, pagename) }}} == Another partial fix (works for regexes) == -- MaximYanchenko <> The following fix changes the Include macro behavior when it's called `called_by_toc` parameter. In the current version, it returns raw text (so it can be only wiki text, you can't get headings from other markups). I changed the protocol to return just the information about the headers in this case, i.e. a list of tuples like (level, id, text). So the TableOfContents macro get the heading information directly from the Include macro. I failed to get correct heading ids inside the Include macro, so now I just get it directly from the rendered page. I believe MoinMoin gurus can easily fix this. === Good === * No dependency on the Include macro args * No dependency on markup of the included page * Works for any type of inclusion (by name, by regex) * Cleaner `TableOfContents.py` code :) === Bad === All bad things come from my fault to get correct heading ids inside the Include macro without rendering the page (I'm not a MoinMoin guru, I believe there are ways to do this without rendering the page). Namely: * The included pages are rendered twice (i.e. all macros will be called twice, this may cause problems if macros have side-effects like running programs etc) * Include macro is called several times (as in the old version), so you need to tweak `request._page_headings`, otherwise all headings will get -2, -3 etc in their ids * TableOfContents should be in the beginning of the page (before included pages) * Doesn't work for multiple inclusion of the same page (will jump to the first inclusion only). {{attachment:toc_for_included_pages.patch}} == Fix for Moin 1.9 == RenatoSilva - This bug is not reproducible in Moin 1.8.5 but came back in 1.9.0, as reported by [[http://mywiki.wooledge.org/GreyCat|GreyCat]]. I propose the following patch for 1.9 (looks like someone forgot to update this part in uid refactoring): {{{#!highlight diff --- MoinMoin/macro/TableOfContents.py 2009-12-19 19:49:35 +0000 +++ MoinMoin/macro/TableOfContents.py 2009-12-19 19:49:31 +0000 @@ -197,7 +197,7 @@ continue # will be reset by pop_unique_ids below - macro.request.include_id = incl_id + macro.request.uid_generator.include_id = incl_id need_li = lastlvl >= lvl while lastlvl > lvl: }}} . Worked for me. Thanks. -- GregWooledge a.k.a. greycat = Plan = ## This part is for Moin``Moin developers: * Priority: * Assigned to: * Status: 1.9: fixed by http://hg.moinmo.in/moin/1.9/rev/3d098b21edb5 /* Patched by RenatoSilva */ ---- ## When the bug is fixed, replace the category to Category MoinMoinBugFixed ## If this is not a bug, replace with Category MoinMoinNoBug CategoryMoinMoinBugFixed