| 1 | # -*- coding: utf-8 -*- |
|---|
| 2 | # |
|---|
| 3 | # Copyright (C) 2007 Optaros, Inc. |
|---|
| 4 | # All rights reserved. |
|---|
| 5 | # |
|---|
| 6 | import re |
|---|
| 7 | from trac.core import Component, implements |
|---|
| 8 | from trac.config import ListOption |
|---|
| 9 | from trac.web.main import IRequestHandler, IRequestFilter |
|---|
| 10 | from trac.web.chrome import ITemplateProvider, add_ctxtnav |
|---|
| 11 | from trac.wiki import WikiSystem |
|---|
| 12 | from trac.wiki.web_ui import WikiModule |
|---|
| 13 | from trac.util.compat import set |
|---|
| 14 | |
|---|
| 15 | class WikiNewPageModule(Component): |
|---|
| 16 | """Overrides the new and missing page mechanism for the wiki. |
|---|
| 17 | Provides a sub-nav link for New Page. Allows for "template" pages. |
|---|
| 18 | """ |
|---|
| 19 | implements(ITemplateProvider, IRequestFilter, IRequestHandler) |
|---|
| 20 | |
|---|
| 21 | template_pages = ListOption('wiki', 'template_pages', '', |
|---|
| 22 | doc="Wiki page(s) that can be cloned. Defaults to none.") |
|---|
| 23 | |
|---|
| 24 | template_prefix = ListOption('wiki', 'template_prefixes', |
|---|
| 25 | [WikiModule.PAGE_TEMPLATES_PREFIX], |
|---|
| 26 | doc="""Wiki page name prefixes of pages that can be cloned. |
|---|
| 27 | Defaults to %s."""%(WikiModule.PAGE_TEMPLATES_PREFIX)) |
|---|
| 28 | |
|---|
| 29 | template_tags = ListOption('wiki', 'template_tags', '', |
|---|
| 30 | doc="""Tag(s) that are used to designate pages that can be cloned. |
|---|
| 31 | Defaults to none.""") |
|---|
| 32 | |
|---|
| 33 | # ITemplateProvider methods |
|---|
| 34 | def get_templates_dirs(self): |
|---|
| 35 | from pkg_resources import resource_filename |
|---|
| 36 | return [resource_filename(__name__, 'templates')] |
|---|
| 37 | def get_htdocs_dirs(self): |
|---|
| 38 | return [] |
|---|
| 39 | |
|---|
| 40 | # IRequestFilter methods |
|---|
| 41 | def pre_process_request(self, req, handler): |
|---|
| 42 | return handler |
|---|
| 43 | |
|---|
| 44 | def post_process_request(self, req, template, data, content_type): |
|---|
| 45 | if ((len(req.path_info) <= 1 or req.path_info == '/' |
|---|
| 46 | or req.path_info.startswith('/wiki')) |
|---|
| 47 | and req.perm.has_permission('WIKI_CREATE')): |
|---|
| 48 | add_ctxtnav(req, 'New Page', req.href.newwikipage()) |
|---|
| 49 | # hijack wiki requests |
|---|
| 50 | if template in [ 'wiki_view.html' , 'wiki_edit.html', |
|---|
| 51 | 'tagswiki_view.html', 'tagswiki_edit.html']: |
|---|
| 52 | if ''==data.get('action') and 0 == data['latest_version']: |
|---|
| 53 | # show custom newpage for missing pages |
|---|
| 54 | req.redirect(req.href.newwikipage(req.args['page'])) |
|---|
| 55 | elif 'edit'==data.get('action') and None == data.get('latest_version'): |
|---|
| 56 | # copy the clone page source for new pages with 'clone' parameter |
|---|
| 57 | wiki_template_page = req.args.get('wikitemplate', '') |
|---|
| 58 | if wiki_template_page: |
|---|
| 59 | from trac.wiki.model import WikiPage |
|---|
| 60 | templatePage = WikiPage(self.env, wiki_template_page) |
|---|
| 61 | data.get('page').text = templatePage.text |
|---|
| 62 | data['comment'] = 'based on template %s' % wiki_template_page |
|---|
| 63 | |
|---|
| 64 | return (template, data, content_type) |
|---|
| 65 | |
|---|
| 66 | # IRequestHandler methods |
|---|
| 67 | def match_request(self, req): |
|---|
| 68 | match = re.match(r'^/newwikipage(?:/(.*))?', req.path_info) |
|---|
| 69 | if match: |
|---|
| 70 | if match.group(1): |
|---|
| 71 | req.args['page'] = match.group(1) |
|---|
| 72 | return 1 |
|---|
| 73 | |
|---|
| 74 | def process_request(self, req): |
|---|
| 75 | req.perm.assert_permission('WIKI_CREATE') |
|---|
| 76 | data = self._get_templates_data(req) |
|---|
| 77 | |
|---|
| 78 | return 'wiki_newpage.html', data, None |
|---|
| 79 | |
|---|
| 80 | def _get_templates_data(self, req): |
|---|
| 81 | data = {'wikitemplate' : req.args.get('wikitemplate', ''), |
|---|
| 82 | 'tags' : req.args.get('tags', ''), |
|---|
| 83 | 'page_name' : req.args.get('page', ''), |
|---|
| 84 | } |
|---|
| 85 | |
|---|
| 86 | template_page_list = set(self.template_pages) |
|---|
| 87 | if self.template_tags: |
|---|
| 88 | # only invoke TagEngine if template_tags is set |
|---|
| 89 | from tractags.api import TagEngine |
|---|
| 90 | template_page_list |= TagEngine(self.env).get_tagged_names( |
|---|
| 91 | self.template_tags, ['wiki'], 'union')['wiki'] |
|---|
| 92 | if self.template_prefix: |
|---|
| 93 | for wiki_prefix in self.template_prefix: |
|---|
| 94 | for wiki_page in WikiSystem(self.env).get_pages(wiki_prefix): |
|---|
| 95 | template_page_list.add(wiki_page) |
|---|
| 96 | template_page_list.add(req.args.get('wikitemplate', '')) |
|---|
| 97 | template_page_list.discard('') |
|---|
| 98 | data['template_page_list'] = sorted(template_page_list) |
|---|
| 99 | return data |
|---|
| 100 | |
|---|