def directory(ctx): """List the contents of the current directory, with links to each page and subdirectory. Supports VirtualDirectory restrictions, but always shows subdirectories.""" res = [] if ctx.page.type != "dir" or not ctx.page.displayable(): return '' # Just in case: ctx.newtime(ctx.page.timestamp) dl = ctx.page.children() if not dl: return '' # Restrict the results if we've been asked to. This is complicated # by our need to preserve directories *always*, because we don't # know if they have any files within the restriction inside them. if pageranges.is_restriction(ctx): dirl = [z for z in dl if z.type == 'dir'] tl = pageranges.filter_files(ctx, [(z.timestamp, z.path) for z in dl if z.type != 'dir']) if not tl and not dirl: return '' dl = [ctx.model.get_page(z[1]) for z in tl] dl.extend(dirl) dl.sort(key=lambda x: x.name) res.append("<ul>") for de in dl: res.append("\n<li> ") res.append(htmlrends.makelink(de.name, ctx.url(de))) res.append("\n</ul>\n") return ''.join(res)
def descendants(self, context): # It is evil to call into the context so that we can load # descendant information from the caches, but it vastly # speeds up handling virtual directories. We'll live with # it for now. # (This just shows that the interface is wrong.) return pageranges.filter_files(context, context.cache_page_children(self.root))
def blogdir(context): """Generate a BlogDir rendering of the current directory: display all real pages in the current directory from most recent to oldest, rendering each with the template _blog/blogdirpage.tmpl_. Supports VirtualDirectory restrictions.""" if context.page.type != "dir": return '' if not context.page.displayable(): raise derrors.IntErr("undisplayable directory page") dl = context.page.children("file") if not dl: return '' # Boil it down to just files, in modtime order. # (Technically this is real files: displayable, non-redirect.) dl = [z for z in dl if z.realpage() and not z.is_util()] # This directory might have nothing. if not dl: return '' # Apply restrictions, backwardly. # Because restrictions are designed to be hugely scalable, they # want the output we'd get from page.descendants(). if pageranges.is_restriction(context): tl = pageranges.filter_files(context, [(z.timestamp, z.path) for z in dl]) if not tl: return '' dl = [context.model.get_page(z[1]) for z in tl] else: dl.sort(key=lambda x: x.timestamp, reverse=True) # For each file, clone the context, set the current page to # it (!), and render it with the blogentry template. to = context.model.get_template("blog/blogdirpage.tmpl") context.setvar(rollvar, {}) res = [] for page in dl: # Note: we do not reset the view type, because we do # not render through the interface that cares; we go # straight to template. nc = context.clone_to_page(page) res.append(template.Template(to).render(nc)) context.newtime(nc.modtime) return ''.join(res)