def extranav(self, d): """ Assemble the helpful extra navigation Of course in a normal theme these come from wikiconfig.py @param d: parameter dictionary @rtype: unicode @return: extranav html """ request = self.request _ = request.getText changesPage = wikiutil.getLocalizedPage(request, 'RecentChanges') findPage = wikiutil.getLocalizedPage(request, 'FindPage') helpPage = wikiutil.getLocalizedPage(request, 'HelpContents') extralinks = [] # Set page to localized RC page title = changesPage.split_title(request) extralinks.append(changesPage.link_to(request, text=title)) # Set page to localized find page title = findPage.split_title(request) extralinks.append(findPage.link_to(request, text=title)) # Set page to localized help page title = helpPage.split_title(request) extralinks.append(helpPage.link_to(request, text=title)) extralinks = [u'<li>%s</li>\n' % link for link in extralinks] html = u'<ul class="extranav">\n%s</ul>' % ''.join(extralinks) return html
def get_macro_help(request): """ Read help texts from SystemPage('HelpOnMacros')""" helppage = wikiutil.getLocalizedPage(request, "HelpOnMacros") content = helppage.get_raw_body() macro_re = re.compile( r"\|\|(<.*?>)?\{\{\{" + r"<<(?P<prototype>(?P<macro>\w*).*)>>" + r"\}\}\}\s*\|\|" + r"[^|]*\|\|[^|]*\|\|<[^>]*>" + r"\s*(?P<help>.*?)\s*\|\|\s*(?P<example>.*?)\s*(<<[^>]*>>)*\s*\|\|$", re.U | re.M) help = {} for match in macro_re.finditer(content): help[match.group('macro')] = match return help
def get_macro_help(request): """ Read help texts from SystemPage('HelpOnMacros')""" helppage = wikiutil.getLocalizedPage(request, "HelpOnMacros") content = helppage.get_raw_body() macro_re = re.compile( r"\|\|(<.*?>)?\{\{\{" + r"<<(?P<prototype>(?P<macro>\w*).*)>>" + r"\}\}\}\s*\|\|" + r"[^|]*\|\|[^|]*\|\|<[^>]*>" + r"\s*(?P<help>.*?)\s*\|\|\s*(?P<example>.*?)\s*(<<[^>]*>>)*\s*\|\|$", re.U|re.M) help = {} for match in macro_re.finditer(content): help[match.group('macro')] = match return help
def sendEditor(self, **kw): """ Send the editor form page. @keyword preview: if given, show this text in preview mode @keyword staytop: don't go to #preview @keyword comment: comment field (when preview is true) """ from MoinMoin import i18n from MoinMoin.action import SpellCheck request = self.request form = request.form _ = self._ raw_body = '' msg = None conflict_msg = None edit_lock_message = None preview = kw.get('preview', None) staytop = kw.get('staytop', 0) # check edit permissions if not request.user.may.write(self.page_name): msg = _('You are not allowed to edit this page.') elif not self.isWritable(): msg = _('Page is immutable!') elif self.rev: # Trying to edit an old version, this is not possible via # the web interface, but catch it just in case... msg = _('Cannot edit old revisions!') else: # try to acquire edit lock ok, edit_lock_message = self.lock.acquire() if not ok: # failed to get the lock if preview is not None: edit_lock_message = _('The lock you held timed out. Be prepared for editing conflicts!' ) + "<br>" + edit_lock_message else: msg = edit_lock_message # Did one of the prechecks fail? if msg: request.theme.add_msg(msg, "error") self.send_page() return # Emit http_headers after checks (send_page) request.disableHttpCaching(level=2) # check if we want to load a draft use_draft = None if 'button_load_draft' in form: wanted_draft_timestamp = int(form.get('draft_ts', '0')) if wanted_draft_timestamp: draft = self._load_draft() if draft is not None: draft_timestamp, draft_rev, draft_text = draft if draft_timestamp == wanted_draft_timestamp: use_draft = draft_text # Check for draft / normal / preview submit if use_draft is not None: title = _('Draft of "%(pagename)s"') # Propagate original revision rev = int(form['draft_rev']) self.set_raw_body(use_draft, modified=1) preview = use_draft elif preview is None: title = _('Edit "%(pagename)s"') else: title = _('Preview of "%(pagename)s"') # Propagate original revision rev = request.rev self.set_raw_body(preview, modified=1) # send header stuff lock_timeout = self.lock.timeout / 60 lock_page = wikiutil.escape(self.page_name, quote=1) lock_expire = _("Your edit lock on %(lock_page)s has expired!") % {'lock_page': lock_page} lock_mins = _("Your edit lock on %(lock_page)s will expire in # minutes.") % {'lock_page': lock_page} lock_secs = _("Your edit lock on %(lock_page)s will expire in # seconds.") % {'lock_page': lock_page} # get request parameters try: text_rows = int(form['rows']) except StandardError: text_rows = self.cfg.edit_rows if request.user.valid: text_rows = int(request.user.edit_rows) if preview is not None: # Check for editing conflicts if not self.exists(): # page does not exist, are we creating it? if rev: conflict_msg = _('Someone else deleted this page while you were editing!') elif rev != self.current_rev(): conflict_msg = _('Someone else changed this page while you were editing!') if self.mergeEditConflict(rev): conflict_msg = _("""Someone else saved this page while you were editing! Please review the page and save then. Do not save this page as it is!""") rev = self.current_rev() if conflict_msg: # We don't show preview when in conflict preview = None elif self.exists(): # revision of existing page rev = self.current_rev() else: # page creation rev = 0 self.setConflict(bool(conflict_msg)) # Page editing is done using user language request.setContentLanguage(request.lang) # Get the text body for the editor field. # TODO: what about deleted pages? show the text of the last revision or use the template? if preview is not None: raw_body = self.get_raw_body() if use_draft: request.write(_("[Content loaded from draft]"), '<br>') elif self.exists(): # If the page exists, we get the text from the page. # TODO: maybe warn if template argument was ignored because the page exists? raw_body = self.get_raw_body() elif 'template' in request.values: # If the page does not exist, we try to get the content from the template parameter. template_page = wikiutil.unquoteWikiname(request.values['template']) template_page_escaped = wikiutil.escape(template_page) if request.user.may.read(template_page): raw_body = Page(request, template_page).get_raw_body() if raw_body: request.write(_("[Content of new page loaded from %s]") % (template_page_escaped, ), '<br>') else: request.write(_("[Template %s not found]") % (template_page_escaped, ), '<br>') else: request.write(_("[You may not read %s]") % (template_page_escaped, ), '<br>') # Make backup on previews - but not for new empty pages if not use_draft and preview and raw_body: self._save_draft(raw_body, rev) draft_message = None loadable_draft = False if preview is None: draft = self._load_draft() if draft is not None: draft_timestamp, draft_rev, draft_text = draft if draft_text != raw_body: loadable_draft = True page_rev = rev draft_timestamp_str = request.user.getFormattedDateTime(draft_timestamp) draft_message = _(u"'''<<BR>>Your draft based on revision %(draft_rev)d (saved %(draft_timestamp_str)s) can be loaded instead of the current revision %(page_rev)d by using the load draft button - in case you lost your last edit somehow without saving it.''' A draft gets saved for you when you do a preview, cancel an edit or unsuccessfully save.", wiki=True, percent=True) % locals() # Setup status message status = [kw.get('msg', ''), conflict_msg, edit_lock_message, draft_message] status = [msg for msg in status if msg] status = ' '.join(status) status = Status(request, content=status) request.theme.add_msg(status, "error") request.theme.send_title( title % {'pagename': self.split_title(), }, page=self, html_head=self.lock.locktype and ( PageEditor._countdown_js % { 'countdown_script': request.theme.externalScript('countdown'), 'lock_timeout': lock_timeout, 'lock_expire': lock_expire, 'lock_mins': lock_mins, 'lock_secs': lock_secs, }) or '', editor_mode=1, allow_doubleclick=1, ) request.write(request.formatter.startContent("content")) # Generate default content for new pages if not raw_body: raw_body = _('Describe %s here.') % (self.page_name, ) # send form request.write('<form id="editor" method="post" action="%s#preview">' % ( request.href(self.page_name) )) # yet another weird workaround for broken IE6 (it expands the text # editor area to the right after you begin to type...). IE sucks... # http://fplanque.net/2003/Articles/iecsstextarea/ request.write('<fieldset style="border:none;padding:0;">') request.write(unicode(html.INPUT(type="hidden", name="action", value="edit"))) # Send revision of the page our edit is based on request.write('<input type="hidden" name="rev" value="%d">' % (rev, )) # Add src format (e.g. 'wiki') into a hidden form field, so that # we can load the correct converter after POSTing. request.write('<input type="hidden" name="format" value="%s">' % self.pi['format']) # Create and send a ticket, so we can check the POST request.write('<input type="hidden" name="ticket" value="%s">' % wikiutil.createTicket(request)) # Save backto in a hidden input backto = request.values.get('backto') if backto: request.write(unicode(html.INPUT(type="hidden", name="backto", value=backto))) # button bar button_spellcheck = '<input class="button" type="submit" name="button_spellcheck" value="%s">' % _('Check Spelling') save_button_text = _('Save Changes') cancel_button_text = _('Cancel') if self.cfg.page_license_enabled: request.write('<p><em>', _( """By hitting '''%(save_button_text)s''' you put your changes under the %(license_link)s. If you don't want that, hit '''%(cancel_button_text)s''' to cancel your changes.""", wiki=True) % { 'save_button_text': save_button_text, 'cancel_button_text': cancel_button_text, 'license_link': wikiutil.getLocalizedPage(request, self.cfg.page_license_page).link_to(request), }, '</em></p>') request.write(''' <input class="button" type="submit" name="button_save" value="%s"> <input class="button" type="submit" name="button_preview" value="%s"> <input class="button" type="submit" name="button_switch" value="%s"> ''' % (save_button_text, _('Preview'), _('Text mode'), )) if loadable_draft: request.write(''' <input class="button" type="submit" name="button_load_draft" value="%s" onClick="flgChange = false;"> <input type="hidden" name="draft_ts" value="%d"> <input type="hidden" name="draft_rev" value="%d"> ''' % (_('Load Draft'), draft_timestamp, draft_rev)) request.write(''' %s <input class="button" type="submit" name="button_cancel" value="%s"> <input type="hidden" name="editor" value="gui"> ''' % (button_spellcheck, cancel_button_text, )) if self.cfg.mail_enabled: request.write(''' <script type="text/javascript"> function toggle_trivial(CheckedBox) { TrivialBoxes = document.getElementsByName("trivial"); for (var i = 0; i < TrivialBoxes.length; i++) TrivialBoxes[i].checked = CheckedBox.checked; } </script> <input type="checkbox" name="trivial" id="chktrivialtop" value="1" %(checked)s onclick="toggle_trivial(this)"> <label for="chktrivialtop">%(label)s</label> ''' % { 'checked': ('', 'checked')[form.get('trivial', '0') == '1'], 'label': _("Trivial change"), }) from MoinMoin.security.textcha import TextCha request.write(TextCha(request).render()) self.sendconfirmleaving() # TODO update state of flgChange to make this work, see PageEditor # Add textarea with page text lang = self.pi.get('language', request.cfg.language_default) contentlangdirection = i18n.getDirection(lang) # 'ltr' or 'rtl' uilanguage = request.lang url_prefix_static = request.cfg.url_prefix_static url_prefix_local = request.cfg.url_prefix_local wikipage = wikiutil.quoteWikinameURL(self.page_name) fckbasepath = request.cfg.url_prefix_fckeditor wikiurl = request.script_root + '/' themepath = '%s/%s' % (url_prefix_static, request.theme.name) smileypath = themepath + '/img' # auto-generating a list for SmileyImages does NOT work from here! text_rows = int(request.user.edit_rows) if not text_rows: # if no specific value is given for editor height, but 0, we # compute the rows from the raw_body line count plus some # extra rows for adding new text in the editor. Maybe this helps # with the "double slider" usability issue, esp. for devices like # the iphone where you can't operate both sliders. current_rows = len(raw_body.split('\n')) text_rows = max(10, int(current_rows * 1.5)) editor_size = text_rows * 22 # 22 height_pixels/line word_rule = self.word_rule() request.write(""" <script type="text/javascript" src="%(fckbasepath)s/fckeditor.js"></script> <script type="text/javascript"> <!-- var oFCKeditor = new FCKeditor( 'savetext', '100%%', %(editor_size)s, 'MoinDefault' ) ; oFCKeditor.BasePath= '%(fckbasepath)s/' ; oFCKeditor.Config['WikiBasePath'] = '%(wikiurl)s' ; oFCKeditor.Config['WikiPage'] = '%(wikipage)s' ; oFCKeditor.Config['PluginsPath'] = '%(url_prefix_local)s/applets/moinFCKplugins/' ; oFCKeditor.Config['CustomConfigurationsPath'] = '%(url_prefix_local)s/applets/moinfckconfig.js' ; oFCKeditor.Config['WordRule'] = %(word_rule)s ; oFCKeditor.Config['SmileyPath'] = '%(smileypath)s/' ; oFCKeditor.Config['EditorAreaCSS'] = '%(themepath)s/css/common.css' ; oFCKeditor.Config['SkinPath'] = '%(fckbasepath)s/editor/skins/silver/' ; oFCKeditor.Config['AutoDetectLanguage'] = false ; oFCKeditor.Config['DefaultLanguage'] = '%(uilanguage)s' ; oFCKeditor.Config['ContentLangDirection'] = '%(contentlangdirection)s' ; oFCKeditor.Value= """ % locals()) from MoinMoin.formatter.text_gedit import Formatter self.formatter = Formatter(request) self.formatter.page = self output = request.redirectedOutput(self.send_page_content, request, raw_body, format=self.pi['format'], do_cache=False) output = repr(output) if output[0] == 'u': output = output[1:] request.write(output) request.write(""" ; oFCKeditor.Create() ; //--> </script> """) request.write("<p>") request.write(_("Comment:"), ' <input id="editor-comment" type="text" name="comment" value="%s" size="80" maxlength="200">' % ( wikiutil.escape(kw.get('comment', ''), 1), )) request.write("</p>") # Category selection filterfn = self.cfg.cache.page_category_regexact.search cat_pages = request.rootpage.getPageList(filter=filterfn) cat_pages.sort() cat_pages = [wikiutil.pagelinkmarkup(p) for p in cat_pages] cat_pages.insert(0, ('', _('<No addition>'))) request.write("<p>") request.write(_('Add to: %(category)s') % { 'category': unicode(web.makeSelection('category', cat_pages)), }) if self.cfg.mail_enabled: request.write(''' <input type="checkbox" name="trivial" id="chktrivial" value="1" %(checked)s onclick="toggle_trivial(this)"> <label for="chktrivial">%(label)s</label> ''' % { 'checked': ('', 'checked')[form.get('trivial', '0') == '1'], 'label': _("Trivial change"), }) request.write(''' <input type="checkbox" name="rstrip" id="chkrstrip" value="1" %(checked)s> <label for="chkrstrip">%(label)s</label> </p> ''' % { 'checked': ('', 'checked')[form.get('rstrip', '0') == '1'], 'label': _('Remove trailing whitespace from each line') }) request.write("</p>") badwords_re = None if preview is not None: if 'button_spellcheck' in form or 'button_newwords' in form: badwords, badwords_re, msg = SpellCheck.checkSpelling(self, request, own_form=0) request.write("<p>%s</p>" % msg) request.write('</fieldset>') request.write("</form>") if preview is not None: if staytop: content_id = 'previewbelow' else: content_id = 'preview' self.send_page(content_id=content_id, content_only=1, hilite_re=badwords_re) request.write(request.formatter.endContent()) # end content div request.theme.send_footer(self.page_name) request.theme.send_closing_html()
def mainloop(self): """ moin-dump's main code. """ outputdir = '/' date_str = '' with open(self._input_file, 'r') as fd: for line in fd: if line.startswith("pubdate ="): date_str = line[10:].strip() break # Insert config dir or the current directory to the start of the path. config_dir = self.options.config_dir if config_dir and os.path.isfile(config_dir): config_dir = os.path.dirname(config_dir) if config_dir and not os.path.isdir(config_dir): script.fatal("bad path given to --config-dir option") sys.path.insert(0, os.path.abspath(config_dir or os.curdir)) self.init_request() request = self.request # fix script_root so we get relative paths in output html request.script_root = url_prefix_static # use this user for permissions checks request.user = user.User(request, name=self.options.dump_user) pages = request.rootpage.getPageList(user='') # get list of all pages in wiki pages.sort() if self._input_file: # did user request a particular page or group of pages? try: namematch = re.compile(self._input_file) pages = [page for page in pages if namematch.match(page)] if not pages: pages = [self._input_file] except: pages = [self._input_file] wikiutil.quoteWikinameURL = lambda pagename, qfn=wikiutil.quoteWikinameFS: (qfn(pagename) + HTML_SUFFIX) AttachFile.getAttachUrl = lambda pagename, filename, request, **kw: _attachment(request, pagename, filename, outputdir, **kw) errlog = sys.stderr errcnt = 0 page_front_page = wikiutil.getLocalizedPage(request, request.cfg.page_front_page).page_name page_title_index = wikiutil.getLocalizedPage(request, 'TitleIndex').page_name page_word_index = wikiutil.getLocalizedPage(request, 'WordIndex').page_name navibar_html = '' urlbase = request.url # save wiki base url for pagename in pages: # we have the same name in URL and FS script.log('Writing "%s"...' % self._output_file) try: pagehtml = '' request.url = urlbase + pagename # add current pagename to url base page = FSPage(request, pagename, formatter = CustomHtmlFormatter(request, store_pagelinks=1)) request.page = page try: request.reset() pagehtml = request.redirectedOutput(page.send_page, count_hit=0, content_only=1, do_cache=0) except: errcnt = errcnt + 1 print >> sys.stderr, "*** Caught exception while writing page!" print >> errlog, "~" * 78 print >> errlog, file # page filename import traceback traceback.print_exc(None, errlog) finally: timestamp = time.strftime("%Y-%m-%d %H:%M") filepath = self._output_file fileout = codecs.open(filepath, 'w', config.charset) fileout.write(page_template % { 'charset': config.charset, 'pagename': pagename, 'pagehtml': pagehtml, 'logo_html': logo_html, 'navibar_html': navibar_html, 'timestamp': timestamp, 'theme': request.cfg.theme_default, 'date_str': date_str, }) fileout.close()
def menu(self, d): """ Build dropdown menu html. Incompatible with original actionsMenu() method. Menu can be customized by adding a config variable 'memodump_menuoverride'. The variable will override the default menu set. Additional menu definitions are given via config method 'memodump_menu_def(request)'. See the code below or project wiki for details. @param d: parameter dictionary @rtype: string @return: menu html """ request = self.request _ = request.getText rev = request.rev page = d['page'] page_recent_changes = wikiutil.getLocalizedPage(request, u'RecentChanges') page_find_page = wikiutil.getLocalizedPage(request, u'FindPage') page_help_contents = wikiutil.getLocalizedPage(request, u'HelpContents') page_help_formatting = wikiutil.getLocalizedPage(request, u'HelpOnFormatting') page_help_wikisyntax = wikiutil.getLocalizedPage(request, u'HelpOnMoinWikiSyntax') page_title_index = wikiutil.getLocalizedPage(request, u'TitleIndex') page_word_index = wikiutil.getLocalizedPage(request, u'WordIndex') page_front_page = wikiutil.getFrontPage(request) page_sidebar = Page(request, request.getPragma('sidebar', u'SideBar')) quicklink = self.menuQuickLink(page) subscribe = self.menuSubscribe(page) try: menu = request.cfg.memodump_menuoverride except AttributeError: # default list of items in dropdown menu. # menu items are assembled in this order. # see wiki for detailed info on customization. menu = [ '===== Navigation =====', 'RecentChanges', 'FindPage', 'LocalSiteMap', '__separator__', '===== Help =====', 'HelpContents', 'HelpOnMoinWikiSyntax', '__separator__', '===== Display =====', 'AttachFile', 'info', 'raw', 'print', '__separator__', '===== Edit =====', 'RenamePage', 'DeletePage', 'revert', 'CopyPage', 'Load', 'Save', 'Despam', 'editSideBar', '__separator__', '===== User =====', 'quicklink', 'subscribe', ] # menu element definitions menu_def = { 'raw': { # Title for this menu entry 'title': _('Raw Text'), # href and args are for normal entries ('special': False), otherwise ignored. # 'href': Nonexistent or empty for current page 'href': '', # 'args': {'query1': 'value1', 'query2': 'value2', } # Optionally specify this for <a href="href?query1=value1&query2=value2"> # If href and args are both nonexistent or empty, key is automatically interpreted to be an action name # and href and args are automatically set. 'args': '', # 'special' can be: # 'disabled', 'removed', 'separator' or 'header' for whatever they say, # False, None or nonexistent for normal menu display. # 'separator' and 'header' are automatically removed when there are no entries to show among them. 'special': False, }, 'print': {'title': _('Print View'), }, 'refresh': { 'title': _('Delete Cache'), 'special': not (self.memodumpIsAvailableAction(page, 'refresh') and page.canUseCache()) and 'removed', }, 'SpellCheck': {'title': _('Check Spelling'), }, 'RenamePage': {'title': _('Rename Page'), }, 'CopyPage': {'title': _('Copy Page'), }, 'DeletePage': {'title': _('Delete Page'), }, 'LikePages': {'title': _('Like Pages'), }, 'LocalSiteMap': {'title': _('Local Site Map'), }, 'MyPages': {'title': _('My Pages'), }, 'SubscribeUser': { 'title': _('Subscribe User'), 'special': not (self.memodumpIsAvailableAction(page, 'SubscribeUser') and request.user.may.admin(page.page_name)) and 'removed', }, 'Despam': { 'title': _('Remove Spam'), 'special': not (self.memodumpIsAvailableAction(page, 'Despam') and request.user.isSuperUser()) and 'removed', }, 'revert': { 'title': _('Revert to this revision'), 'special': not (self.memodumpIsAvailableAction(page, 'revert') and rev and request.user.may.revert(page.page_name)) and 'removed', }, 'PackagePages': {'title': _('Package Pages'), }, 'RenderAsDocbook': {'title': _('Render as Docbook'), }, 'SyncPages': {'title': _('Sync Pages'), }, 'AttachFile': {'title': _('Attachments'), }, 'quicklink': { 'title': quicklink[1], 'args': dict(action=quicklink[0], rev=rev), 'special': not quicklink[0] and 'removed', }, 'subscribe': { 'title': subscribe[1], 'args': dict(action=subscribe[0], rev=rev), 'special': not subscribe[0] and 'removed', }, 'info': {'title': _('Info'), }, # menu items not in menu_def will be assumed to be action names, # and receive appropriate title, href, and args automatically. # 'Load': {'title': _('Load'), }, # 'Save': {'title': _('Save'), }, # menu decorations '__separator__': {'title': _('------------------------'), 'special': 'separator', }, '----': {'title': _('------------------------'), 'special': 'separator', }, '-----': {'title': _('------------------------'), 'special': 'separator', }, '------': {'title': _('------------------------'), 'special': 'separator', }, '-------': {'title': _('------------------------'), 'special': 'separator', }, '--------': {'title': _('------------------------'), 'special': 'separator', }, '---------': {'title': _('------------------------'), 'special': 'separator', }, '----------': {'title': _('------------------------'), 'special': 'separator', }, # header example '__title_navigation__': {'title': _('Navigation'), 'special': 'header', }, # useful pages 'RecentChanges': {'title': page_recent_changes.page_name, 'href': page_recent_changes.url(request)}, 'FindPage': {'title': page_find_page.page_name, 'href': page_find_page.url(request)}, 'HelpContents': {'title': page_help_contents.page_name, 'href': page_help_contents.url(request)}, 'HelpOnFormatting': {'title': page_help_formatting.page_name, 'href': page_help_formatting.url(request)}, 'HelpOnMoinWikiSyntax': {'title': page_help_wikisyntax.page_name, 'href': page_help_wikisyntax.url(request)}, 'TitleIndex': {'title': page_title_index.page_name, 'href': page_title_index.url(request)}, 'WordIndex': {'title': page_word_index.page_name, 'href': page_word_index.url(request)}, 'FrontPage': {'title': page_front_page.page_name, 'href': page_front_page.url(request)}, 'SideBar': {'title': page_sidebar.page_name, 'href': page_sidebar.url(request)}, 'editSideBar': { 'title': _('Edit SideBar'), 'href': page_sidebar.url(request), 'args': dict(action='edit'), 'special': not self.memodumpIsEditablePage(page_sidebar) and 'removed' }, } # register state determining functions on request for use in config request.memodumpIsAvailableAction = self.memodumpIsAvailableAction request.memodumpIsEditablePage = self.memodumpIsEditablePage try: menu_def.update(request.cfg.memodump_menu_def(request)) except AttributeError: pass compiled = self.menuCompile(d, menu, menu_def) menubody = self.menuRender(compiled) if menubody: html = u''' <li class="dropdown"> <!-- Menu button --> <a href="#" class="menu-nav-menu dropdown-toggle" data-toggle="dropdown"> %s<span class="padding"></span><span class="caret"></span> </a> <!-- Dropdown contents --> <ul class="dropdown-menu"> %s </ul> </li> <!-- /dropdown --> ''' % (_('Menu'), menubody) else: html = u'' return html
def splitNavilink(self, text, localize=1): """ Split navibar links into pagename, link to page Changed: name attrib added for accesskeys """ request = self.request # Handle [pagename title] or [url title] formats if text.startswith('[') and text.endswith(']'): try: pagename, title = text[1:-1].strip().split(' ', 1) title = title.strip() localize = 0 except (ValueError, TypeError): # Just use the text as is. pagename = title = text # Handle regular pagename like "FrontPage" else: # Use localized pages for the current user if localize: # Try..except for backwards compatibility of Moin versions only try: page = wikiutil.getSysPage(request, text) except: page = wikiutil.getLocalizedPage(request, text) else: page = Page(request, text) pagename = page.page_name # Try..except for backwards compatibility of Moin versions only try: title = page.split_title() except: title = page.split_title(request) title = self.shortenPagename(title) link = page.link_to(request, title, name=title) from MoinMoin import config for scheme in config.url_schemas: if pagename.startswith(scheme): title = wikiutil.escape(title) link = self.request.formatter.url(1, pagename, name=title) + \ self.request.formatter.text(title) +\ self.request.formatter.url(0) return pagename, link # remove wiki: url prefix if pagename.startswith("wiki:"): pagename = pagename[5:] # try handling interwiki links try: interwiki, page = pagename.split(':', 1) thiswiki = request.cfg.interwikiname if interwiki == thiswiki: pagename = page title = page else: return (pagename, self.request.formatter.interwikilink(True, interwiki, page, name=page) + page + self.request.formatter.interwikilink(False, interwiki, page) ) except ValueError: pass pagename = request.normalizePagename(pagename) link = Page(request, pagename).link_to(request, title, name=title) return pagename, link
def execute(pagename, request): """ edit a page """ _ = request.getText if 'button_preview' in request.form and 'button_spellcheck' in request.form: # multiple buttons pressed at once? must be some spammer/bot check_surge_protect(request, kick=True) # get rid of him return if not request.user.may.write(pagename): page = wikiutil.getLocalizedPage(request, 'PermissionDeniedPage') page.body = _('You are not allowed to edit this page.') page.page_name = pagename page.send_page(send_special=True) return valideditors = ['text', 'gui', ] editor = '' if request.user.valid: editor = request.user.editor_default if editor not in valideditors: editor = request.cfg.editor_default editorparam = request.values.get('editor', editor) if editorparam == "guipossible": lasteditor = editor elif editorparam == "textonly": editor = lasteditor = 'text' else: editor = lasteditor = editorparam if request.cfg.editor_force: editor = request.cfg.editor_default # if it is still nothing valid, we just use the text editor if editor not in valideditors: editor = 'text' rev = request.rev or 0 savetext = request.form.get('savetext') comment = request.form.get('comment', u'') category = request.form.get('category') rstrip = int(request.form.get('rstrip', '0')) trivial = int(request.form.get('trivial', '0')) if 'button_switch' in request.form: if editor == 'text': editor = 'gui' else: # 'gui' editor = 'text' # load right editor class if editor == 'gui': from MoinMoin.PageGraphicalEditor import PageGraphicalEditor pg = PageGraphicalEditor(request, pagename) else: # 'text' from MoinMoin.PageEditor import PageEditor pg = PageEditor(request, pagename) # is invoked without savetext start editing if savetext is None or 'button_load_draft' in request.form: pg.sendEditor() return # did user hit cancel button? cancelled = 'button_cancel' in request.form from MoinMoin.error import ConvertError try: if lasteditor == 'gui': # convert input from Graphical editor format = request.form.get('format', 'wiki') if format == 'wiki': converter_name = 'text_html_text_moin_wiki' else: converter_name = 'undefined' # XXX we don't have other converters yet convert = wikiutil.importPlugin(request.cfg, "converter", converter_name, 'convert') savetext = convert(request, pagename, savetext) # IMPORTANT: normalize text from the form. This should be done in # one place before we manipulate the text. savetext = pg.normalizeText(savetext, stripspaces=rstrip) except ConvertError: # we don't want to throw an exception if user cancelled anyway if not cancelled: raise if cancelled: pg.sendCancel(savetext or "", rev) pagedir = pg.getPagePath(check_create=0) import os if not os.listdir(pagedir): os.removedirs(pagedir) return comment = wikiutil.clean_input(comment) # Add category # TODO: this code does not work with extended links, and is doing # things behind your back, and in general not needed. Either we have # a full interface for categories (add, delete) or just add them by # markup. if category and category != _('<No addition>'): # opera 8.5 needs this # strip trailing whitespace savetext = savetext.rstrip() # Add category separator if last non-empty line contains # non-categories. lines = [line for line in savetext.splitlines() if line] if lines: #TODO: this code is broken, will not work for extended links #categories, e.g ["category hebrew"] categories = lines[-1].split() if categories: confirmed = wikiutil.filterCategoryPages(request, categories) if len(confirmed) < len(categories): # This was not a categories line, add separator savetext += u'\n----\n' # Add new category if savetext and savetext[-1] != u'\n': savetext += ' ' savetext += category + u'\n' # Should end with newline! if (request.cfg.edit_ticketing and not wikiutil.checkTicket(request, request.form.get('ticket', ''))): request.theme.add_msg(_('Please use the interactive user interface to use action %(actionname)s!') % {'actionname': 'edit' }, "error") pg.sendEditor(preview=savetext, comment=comment, staytop=1) # Preview, spellcheck or spellcheck add new words elif ('button_preview' in request.form or 'button_spellcheck' in request.form or 'button_newwords' in request.form): pg.sendEditor(preview=savetext, comment=comment) # Preview with mode switch elif 'button_switch' in request.form: pg.sendEditor(preview=savetext, comment=comment, staytop=1) # Save new text else: try: from MoinMoin.security.textcha import TextCha if not TextCha(request).check_answer_from_form(): raise pg.SaveError(_('TextCha: Wrong answer! Try again below...')) if request.cfg.comment_required and not comment: raise pg.SaveError(_('Supplying a comment is mandatory. Write a comment below and try again...')) savemsg = pg.saveText(savetext, rev, trivial=trivial, comment=comment) except pg.EditConflict, e: msg = e.message # Handle conflict and send editor pg.set_raw_body(savetext, modified=1) pg.mergeEditConflict(rev) # We don't send preview when we do merge conflict pg.sendEditor(msg=msg, comment=comment) return except pg.SaveError, msg: # Show the error message request.theme.add_msg(unicode(msg), "error") # And show the editor again pg.sendEditor(preview=savetext, comment=comment, staytop=1) return
def execute(pagename, request): """ edit a page """ _ = request.getText if 'button_preview' in request.form and 'button_spellcheck' in request.form: # multiple buttons pressed at once? must be some spammer/bot check_surge_protect(request, kick=True) # get rid of him return if not request.user.may.write(pagename): page = wikiutil.getLocalizedPage(request, 'PermissionDeniedPage') page.body = _('You are not allowed to edit this page.') page.page_name = pagename page.send_page(send_special=True) return valideditors = [ 'text', 'gui', ] editor = '' if request.user.valid: editor = request.user.editor_default if editor not in valideditors: editor = request.cfg.editor_default editorparam = request.values.get('editor', editor) if editorparam == "guipossible": lasteditor = editor elif editorparam == "textonly": editor = lasteditor = 'text' else: editor = lasteditor = editorparam if request.cfg.editor_force: editor = request.cfg.editor_default # if it is still nothing valid, we just use the text editor if editor not in valideditors: editor = 'text' rev = request.rev or 0 savetext = request.form.get('savetext') comment = request.form.get('comment', u'') category = request.form.get('category') rstrip = int(request.form.get('rstrip', '0')) trivial = int(request.form.get('trivial', '0')) ideastatus = int(request.form.get('ideastatus', '0')) if 'button_switch' in request.form: if editor == 'text': editor = 'gui' else: # 'gui' editor = 'text' # load right editor class if editor == 'gui': from MoinMoin.PageGraphicalEditor import PageGraphicalEditor pg = PageGraphicalEditor(request, pagename) else: # 'text' from MoinMoin.PageEditor import PageEditor pg = PageEditor(request, pagename) # is invoked without savetext start editing if savetext is None or 'button_load_draft' in request.form: pg.sendEditor() return # did user hit cancel button? cancelled = 'button_cancel' in request.form from MoinMoin.error import ConvertError try: if lasteditor == 'gui': # convert input from Graphical editor format = request.form.get('format', 'wiki') if format == 'wiki': converter_name = 'text_html_text_moin_wiki' else: converter_name = 'undefined' # XXX we don't have other converters yet convert = wikiutil.importPlugin(request.cfg, "converter", converter_name, 'convert') savetext = convert(request, pagename, savetext) # IMPORTANT: normalize text from the form. This should be done in # one place before we manipulate the text. savetext = pg.normalizeText(savetext, stripspaces=rstrip) except ConvertError: # we don't want to throw an exception if user cancelled anyway if not cancelled: raise if cancelled: pg.sendCancel(savetext or "", rev) pagedir = pg.getPagePath(check_create=0) import os if not os.listdir(pagedir): os.removedirs(pagedir) return comment = wikiutil.clean_input(comment) # Add category # TODO: this code does not work with extended links, and is doing # things behind your back, and in general not needed. Either we have # a full interface for categories (add, delete) or just add them by # markup. if category and category != _('<No addition>'): # opera 8.5 needs this # strip trailing whitespace savetext = savetext.rstrip() # Add category separator if last non-empty line contains # non-categories. lines = [line for line in savetext.splitlines() if line] if lines: #TODO: this code is broken, will not work for extended links #categories, e.g ["category hebrew"] categories = lines[-1].split() if categories: confirmed = wikiutil.filterCategoryPages(request, categories) if len(confirmed) < len(categories): # This was not a categories line, add separator savetext += u'\n----\n' # Add new category if savetext and savetext[-1] != u'\n': savetext += ' ' savetext += category + u'\n' # Should end with newline! if (request.cfg.edit_ticketing and not wikiutil.checkTicket(request, request.form.get('ticket', ''))): request.theme.add_msg( _('Please use the interactive user interface to use action %(actionname)s!' ) % {'actionname': 'edit'}, "error") pg.sendEditor(preview=savetext, comment=comment, staytop=1) # Preview, spellcheck or spellcheck add new words elif ('button_preview' in request.form or 'button_spellcheck' in request.form or 'button_newwords' in request.form): pg.sendEditor(preview=savetext, comment=comment) # Preview with mode switch elif 'button_switch' in request.form: pg.sendEditor(preview=savetext, comment=comment, staytop=1) # Save new text else: try: from MoinMoin.security.textcha import TextCha if not TextCha(request).check_answer_from_form(): raise pg.SaveError( _('TextCha: Wrong answer! Try again below...')) if request.cfg.comment_required and not comment: raise pg.SaveError( _('Supplying a comment is mandatory. Write a comment below and try again...' )) savemsg = pg.saveText(savetext, rev, trivial=trivial, comment=comment) except pg.EditConflict, e: msg = e.message # Handle conflict and send editor pg.set_raw_body(savetext, modified=1) pg.mergeEditConflict(rev) # We don't send preview when we do merge conflict pg.sendEditor(msg=msg, comment=comment) return except pg.SaveError, msg: # Show the error message request.theme.add_msg(unicode(msg), "error") # And show the editor again pg.sendEditor(preview=savetext, comment=comment, staytop=1) return
class PluginScript(script.MoinScript): """\ Purpose: ======== This tool allows you to dump MoinMoin wiki pages to static HTML files. Detailed Instructions: ====================== General syntax: moin [options] export dump [dump-options] [options] usually should be: --config-dir=/path/to/my/cfg/ --wiki-url=http://wiki.example.org/ [dump-options] see below: 0. You must run this script as owner of the wiki files, usually this is the web server user. 1. To dump all the pages on the wiki to the directory '/mywiki' moin ... export dump --target-dir=/mywiki 2. To dump all the pages readable by 'JohnSmith' on the wiki to the directory '/mywiki' moin ... export dump --target-dir=/mywiki --username JohnSmith """ def __init__(self, argv=None, def_values=None): script.MoinScript.__init__(self, argv, def_values) self.parser.add_option("-t", "--target-dir", dest="target_dir", help="Write html dump to DIRECTORY") self.parser.add_option( "-u", "--username", dest="dump_user", help="User the dump will be performed as (for ACL checks, etc)") def mainloop(self): """ moin-dump's main code. """ # Prepare output directory if not self.options.target_dir: script.fatal( "you must use --target-dir=/your/output/path to specify the directory we write the html files to" ) outputdir = os.path.abspath(self.options.target_dir) try: os.mkdir(outputdir) script.log("Created output directory '%s'!" % outputdir) except OSError, err: if err.errno != errno.EEXIST: script.fatal("Cannot create output directory '%s'!" % outputdir) # Insert config dir or the current directory to the start of the path. config_dir = self.options.config_dir if config_dir and os.path.isfile(config_dir): config_dir = os.path.dirname(config_dir) if config_dir and not os.path.isdir(config_dir): script.fatal("bad path given to --config-dir option") sys.path.insert(0, os.path.abspath(config_dir or os.curdir)) self.init_request() request = self.request # fix script_root so we get relative paths in output html request.script_root = url_prefix_static # use this user for permissions checks request.user = user.User(request, name=self.options.dump_user) pages = request.rootpage.getPageList( user='') # get list of all pages in wiki pages.sort() if self.options.page: # did user request a particular page or group of pages? try: namematch = re.compile(self.options.page) pages = [page for page in pages if namematch.match(page)] if not pages: pages = [self.options.page] except: pages = [self.options.page] wikiutil.quoteWikinameURL = lambda pagename, qfn=wikiutil.quoteWikinameFS: ( qfn(pagename) + HTML_SUFFIX) AttachFile.getAttachUrl = lambda pagename, filename, request, **kw: _attachment( request, pagename, filename, outputdir, **kw) errfile = os.path.join(outputdir, 'error.log') errlog = open(errfile, 'w') errcnt = 0 page_front_page = wikiutil.getLocalizedPage( request, request.cfg.page_front_page).page_name page_title_index = wikiutil.getLocalizedPage(request, 'TitleIndex').page_name page_word_index = wikiutil.getLocalizedPage(request, 'WordIndex').page_name navibar_html = '' for p in [page_front_page, page_title_index, page_word_index]: navibar_html += '[<a href="%s">%s</a>] ' % ( wikiutil.quoteWikinameURL(p), wikiutil.escape(p)) urlbase = request.url # save wiki base url for pagename in pages: # we have the same name in URL and FS file = wikiutil.quoteWikinameURL(pagename) script.log('Writing "%s"...' % file) try: pagehtml = '' request.url = urlbase + pagename # add current pagename to url base page = Page.Page(request, pagename) request.page = page try: request.reset() pagehtml = request.redirectedOutput(page.send_page, count_hit=0, content_only=1) except: errcnt = errcnt + 1 print >> sys.stderr, "*** Caught exception while writing page!" print >> errlog, "~" * 78 print >> errlog, file # page filename import traceback traceback.print_exc(None, errlog) finally: timestamp = time.strftime("%Y-%m-%d %H:%M") filepath = os.path.join(outputdir, file) fileout = codecs.open(filepath, 'w', config.charset) fileout.write( page_template % { 'charset': config.charset, 'pagename': pagename, 'pagehtml': pagehtml, 'logo_html': logo_html, 'navibar_html': navibar_html, 'timestamp': timestamp, 'theme': request.cfg.theme_default, }) fileout.close() # copy FrontPage to "index.html" indexpage = page_front_page if self.options.page: indexpage = pages[ 0] # index page has limited use when dumping specific pages, but create one anyway shutil.copyfile( os.path.join(outputdir, wikiutil.quoteWikinameFS(indexpage) + HTML_SUFFIX), os.path.join(outputdir, 'index' + HTML_SUFFIX)) errlog.close() if errcnt: print >> sys.stderr, "*** %d error(s) occurred, see '%s'!" % ( errcnt, errfile)
def send_title(self, text, **keywords): """ Output the page header (and title). @param text: the title text @keyword page: the page instance that called us - using this is more efficient than using pagename.. @keyword pagename: 'PageName' @keyword print_mode: 1 (or 0) @keyword editor_mode: 1 (or 0) @keyword media: css media type, defaults to 'screen' @keyword allow_doubleclick: 1 (or 0) @keyword html_head: additional <head> code @keyword body_attr: additional <body> attributes @keyword body_onload: additional "onload" JavaScript code """ request = self.request _ = request.getText rev = request.rev if keywords.has_key('page'): page = keywords['page'] pagename = page.page_name else: pagename = keywords.get('pagename', '') page = Page(request, pagename) if keywords.get('msg', ''): raise DeprecationWarning("Using send_page(msg=) is deprecated! Use theme.add_msg() instead!") scriptname = request.script_root # get name of system pages page_front_page = wikiutil.getFrontPage(request).page_name page_help_contents = wikiutil.getLocalizedPage(request, 'HelpContents').page_name page_title_index = wikiutil.getLocalizedPage(request, 'TitleIndex').page_name page_site_navigation = wikiutil.getLocalizedPage(request, 'SiteNavigation').page_name page_word_index = wikiutil.getLocalizedPage(request, 'WordIndex').page_name page_help_formatting = wikiutil.getLocalizedPage(request, 'HelpOnFormatting').page_name page_find_page = wikiutil.getLocalizedPage(request, 'FindPage').page_name home_page = wikiutil.getInterwikiHomePage(request) # sorry theme API change!!! Either None or tuple (wikiname,pagename) now. page_parent_page = getattr(page.getParentPage(), 'page_name', None) # Prepare the HTML <head> element user_head = [request.cfg.html_head] # include charset information - needed for moin_dump or any other case # when reading the html without a web server user_head.append('''<meta http-equiv="Content-Type" content="%s;charset=%s">\n''' % (page.output_mimetype, page.output_charset)) meta_keywords = request.getPragma('keywords') meta_desc = request.getPragma('description') if meta_keywords: user_head.append('<meta name="keywords" content="%s">\n' % wikiutil.escape(meta_keywords, 1)) if meta_desc: user_head.append('<meta name="description" content="%s">\n' % wikiutil.escape(meta_desc, 1)) # search engine precautions / optimization: # if it is an action or edit/search, send query headers (noindex,nofollow): if request.query_string: user_head.append(request.cfg.html_head_queries) elif request.method == 'POST': user_head.append(request.cfg.html_head_posts) # we don't want to have BadContent stuff indexed: elif pagename in ['BadContent', 'LocalBadContent', ]: user_head.append(request.cfg.html_head_posts) # if it is a special page, index it and follow the links - we do it # for the original, English pages as well as for (the possibly # modified) frontpage: elif pagename in [page_front_page, request.cfg.page_front_page, page_title_index, 'TitleIndex', page_find_page, 'FindPage', page_site_navigation, 'SiteNavigation', 'RecentChanges', ]: user_head.append(request.cfg.html_head_index) # if it is a normal page, index it, but do not follow the links, because # there are a lot of illegal links (like actions) or duplicates: else: user_head.append(request.cfg.html_head_normal) if 'pi_refresh' in keywords and keywords['pi_refresh']: user_head.append('<meta http-equiv="refresh" content="%d;URL=%s">' % keywords['pi_refresh']) # output buffering increases latency but increases throughput as well output = [] # later: <html xmlns=\"http://www.w3.org/1999/xhtml\"> output.append("""\ <!doctype html> <!--[if lt IE 7]> <html class="no-js ie6 oldie" lang="en"> <![endif]--> <!--[if IE 7]> <html class="no-js ie7 oldie" lang="en"> <![endif]--> <!--[if IE 8]> <html class="no-js ie8 oldie" lang="en"> <![endif]--> <!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]--> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <title>%(title)s</title> <meta name="description" content=""> <meta name="author" content=""> <meta name="viewport" content="width=device-width,initial-scale=1"> <link rel="stylesheet" href="%(static_url)scss/style.css"> <script src="%(static_url)sjs/libs/moin.common.js"></script> <script type="text/javascript"> <!-- var search_hint = "Search"; //--> </script> <script src="%(static_url)sjs/libs/modernizr-2.0.6.min.js"></script> """ %{'title':text, 'static_url':django_settings.STATIC_URL}) # Links output.append('<link rel="Start" href="%s">\n' % request.href(page_front_page)) if pagename: output.append('<link rel="Alternate" title="%s" href="%s">\n' % ( _('Wiki Markup'), request.href(pagename, action='raw'))) output.append('<link rel="Alternate" media="print" title="%s" href="%s">\n' % ( _('Print View'), request.href(pagename, action='print'))) # !!! currently disabled due to Mozilla link prefetching, see # http://www.mozilla.org/projects/netlib/Link_Prefetching_FAQ.html #~ all_pages = request.getPageList() #~ if all_pages: #~ try: #~ pos = all_pages.index(pagename) #~ except ValueError: #~ # this shopuld never happend in theory, but let's be sure #~ pass #~ else: #~ request.write('<link rel="First" href="%s/%s">\n' % (request.script_root, quoteWikinameURL(all_pages[0])) #~ if pos > 0: #~ request.write('<link rel="Previous" href="%s/%s">\n' % (request.script_root, quoteWikinameURL(all_pages[pos-1]))) #~ if pos+1 < len(all_pages): #~ request.write('<link rel="Next" href="%s/%s">\n' % (request.script_root, quoteWikinameURL(all_pages[pos+1]))) #~ request.write('<link rel="Last" href="%s/%s">\n' % (request.script_root, quoteWikinameURL(all_pages[-1]))) if page_parent_page: output.append('<link rel="Up" href="%s">\n' % request.href(page_parent_page)) # write buffer because we call AttachFile request.write(''.join(output)) output = [] # XXX maybe this should be removed completely. moin emits all attachments as <link rel="Appendix" ...> # and it is at least questionable if this fits into the original intent of rel="Appendix". if pagename and request.user.may.read(pagename): from MoinMoin.action import AttachFile AttachFile.send_link_rel(request, pagename) output.extend([ '<link rel="Search" href="%s">\n' % request.href(page_find_page), '<link rel="Index" href="%s">\n' % request.href(page_title_index), '<link rel="Glossary" href="%s">\n' % request.href(page_word_index), '<link rel="Help" href="%s">\n' % request.href(page_help_formatting), ]) output.append("</head>\n") request.write(''.join(output)) output = [] # start the <body> bodyattr = [] if keywords.has_key('body_attr'): bodyattr.append(' ') bodyattr.append(keywords['body_attr']) # Add doubleclick edit action if (pagename and keywords.get('allow_doubleclick', 0) and not keywords.get('print_mode', 0) and request.user.edit_on_doubleclick): if request.user.may.write(pagename): # separating this gains speed url = page.url(request, {'action': 'edit'}) bodyattr.append(''' ondblclick="location.href='%s'" ''' % wikiutil.escape(url, True)) # Set body to the user interface language and direction bodyattr.append(' %s' % self.ui_lang_attr()) body_onload = keywords.get('body_onload', '') if body_onload: bodyattr.append(''' onload="%s"''' % body_onload) output.append('\n<body%s>\n' % ''.join(bodyattr)) # Output ----------------------------------------------------------- # If in print mode, start page div and emit the title if keywords.get('print_mode', 0): d = { 'title_text': text, 'page': page, 'page_name': pagename or '', 'rev': rev, } request.themedict = d output.append(self.startPage()) output.append(self.interwiki(d)) output.append(self.title(d)) # In standard mode, emit theme.header else: exists = pagename and page.exists(includeDeleted=True) # prepare dict for theme code: d = { 'theme': self.name, 'script_name': scriptname, 'title_text': text, 'logo_string': request.cfg.logo_string, 'site_name': request.cfg.sitename, 'page': page, 'rev': rev, 'pagesize': pagename and page.size() or 0, # exists checked to avoid creation of empty edit-log for non-existing pages 'last_edit_info': exists and page.lastEditInfo() or '', 'page_name': pagename or '', 'page_find_page': page_find_page, 'page_front_page': page_front_page, 'home_page': home_page, 'page_help_contents': page_help_contents, 'page_help_formatting': page_help_formatting, 'page_parent_page': page_parent_page, 'page_title_index': page_title_index, 'page_word_index': page_word_index, 'user_name': request.user.name, 'user_valid': request.user.valid, 'msg': self._status, 'trail': keywords.get('trail', None), # Discontinued keys, keep for a while for 3rd party theme developers 'titlesearch': 'use self.searchform(d)', 'textsearch': 'use self.searchform(d)', 'navibar': ['use self.navibar(d)'], 'available_actions': ['use self.request.availableActions(page)'], } # add quoted versions of pagenames newdict = {} for key in d: if key.startswith('page_'): if not d[key] is None: newdict['q_'+key] = wikiutil.quoteWikinameURL(d[key]) else: newdict['q_'+key] = None d.update(newdict) request.themedict = d # now call the theming code to do the rendering if keywords.get('editor_mode', 0): output.append(self.editorheader(d)) else: output.append(self.header(d)) # emit it request.write(''.join(output)) output = [] self._send_title_called = True
def send_title(self, text, **keywords): """ Output the page header (and title). @param text: the title text @keyword page: the page instance that called us - using this is more efficient than using pagename.. @keyword pagename: 'PageName' @keyword print_mode: 1 (or 0) @keyword editor_mode: 1 (or 0) @keyword media: css media type, defaults to 'screen' @keyword allow_doubleclick: 1 (or 0) @keyword html_head: additional <head> code @keyword body_attr: additional <body> attributes @keyword body_onload: additional "onload" JavaScript code """ request = self.request _ = request.getText rev = request.rev if keywords.has_key('page'): page = keywords['page'] pagename = page.page_name else: pagename = keywords.get('pagename', '') page = Page(request, pagename) if keywords.get('msg', ''): raise DeprecationWarning( "Using send_page(msg=) is deprecated! Use theme.add_msg() instead!" ) scriptname = request.script_root # get name of system pages page_front_page = wikiutil.getFrontPage(request).page_name page_help_contents = wikiutil.getLocalizedPage( request, 'HelpContents').page_name page_title_index = wikiutil.getLocalizedPage(request, 'TitleIndex').page_name page_site_navigation = wikiutil.getLocalizedPage( request, 'SiteNavigation').page_name page_word_index = wikiutil.getLocalizedPage(request, 'WordIndex').page_name page_help_formatting = wikiutil.getLocalizedPage( request, 'HelpOnFormatting').page_name page_find_page = wikiutil.getLocalizedPage(request, 'FindPage').page_name home_page = wikiutil.getInterwikiHomePage( request ) # sorry theme API change!!! Either None or tuple (wikiname,pagename) now. page_parent_page = getattr(page.getParentPage(), 'page_name', None) # Prepare the HTML <head> element user_head = [request.cfg.html_head] # include charset information - needed for moin_dump or any other case # when reading the html without a web server user_head.append( '''<meta http-equiv="Content-Type" content="%s;charset=%s">\n''' % (page.output_mimetype, page.output_charset)) meta_keywords = request.getPragma('keywords') meta_desc = request.getPragma('description') if meta_keywords: user_head.append('<meta name="keywords" content="%s">\n' % wikiutil.escape(meta_keywords, 1)) if meta_desc: user_head.append('<meta name="description" content="%s">\n' % wikiutil.escape(meta_desc, 1)) # search engine precautions / optimization: # if it is an action or edit/search, send query headers (noindex,nofollow): if request.query_string: user_head.append(request.cfg.html_head_queries) elif request.method == 'POST': user_head.append(request.cfg.html_head_posts) # we don't want to have BadContent stuff indexed: elif pagename in [ 'BadContent', 'LocalBadContent', ]: user_head.append(request.cfg.html_head_posts) # if it is a special page, index it and follow the links - we do it # for the original, English pages as well as for (the possibly # modified) frontpage: elif pagename in [ page_front_page, request.cfg.page_front_page, page_title_index, 'TitleIndex', page_find_page, 'FindPage', page_site_navigation, 'SiteNavigation', 'RecentChanges', ]: user_head.append(request.cfg.html_head_index) # if it is a normal page, index it, but do not follow the links, because # there are a lot of illegal links (like actions) or duplicates: else: user_head.append(request.cfg.html_head_normal) if 'pi_refresh' in keywords and keywords['pi_refresh']: user_head.append( '<meta http-equiv="refresh" content="%d;URL=%s">' % keywords['pi_refresh']) # output buffering increases latency but increases throughput as well output = [] # later: <html xmlns=\"http://www.w3.org/1999/xhtml\"> output.append("""\ <!doctype html> <!--[if lt IE 7]> <html class="no-js ie6 oldie" lang="en"> <![endif]--> <!--[if IE 7]> <html class="no-js ie7 oldie" lang="en"> <![endif]--> <!--[if IE 8]> <html class="no-js ie8 oldie" lang="en"> <![endif]--> <!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]--> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <title>%(title)s</title> <meta name="description" content=""> <meta name="author" content=""> <meta name="viewport" content="width=device-width,initial-scale=1"> <link rel="stylesheet" href="%(static_url)scss/style.css"> <script src="%(static_url)sjs/libs/moin.common.js"></script> <script type="text/javascript"> <!-- var search_hint = "Search"; //--> </script> <script src="%(static_url)sjs/libs/modernizr-2.0.6.min.js"></script> """ % { 'title': text, 'static_url': django_settings.STATIC_URL }) # Links output.append('<link rel="Start" href="%s">\n' % request.href(page_front_page)) if pagename: output.append( '<link rel="Alternate" title="%s" href="%s">\n' % (_('Wiki Markup'), request.href(pagename, action='raw'))) output.append( '<link rel="Alternate" media="print" title="%s" href="%s">\n' % (_('Print View'), request.href(pagename, action='print'))) # !!! currently disabled due to Mozilla link prefetching, see # http://www.mozilla.org/projects/netlib/Link_Prefetching_FAQ.html #~ all_pages = request.getPageList() #~ if all_pages: #~ try: #~ pos = all_pages.index(pagename) #~ except ValueError: #~ # this shopuld never happend in theory, but let's be sure #~ pass #~ else: #~ request.write('<link rel="First" href="%s/%s">\n' % (request.script_root, quoteWikinameURL(all_pages[0])) #~ if pos > 0: #~ request.write('<link rel="Previous" href="%s/%s">\n' % (request.script_root, quoteWikinameURL(all_pages[pos-1]))) #~ if pos+1 < len(all_pages): #~ request.write('<link rel="Next" href="%s/%s">\n' % (request.script_root, quoteWikinameURL(all_pages[pos+1]))) #~ request.write('<link rel="Last" href="%s/%s">\n' % (request.script_root, quoteWikinameURL(all_pages[-1]))) if page_parent_page: output.append('<link rel="Up" href="%s">\n' % request.href(page_parent_page)) # write buffer because we call AttachFile request.write(''.join(output)) output = [] # XXX maybe this should be removed completely. moin emits all attachments as <link rel="Appendix" ...> # and it is at least questionable if this fits into the original intent of rel="Appendix". if pagename and request.user.may.read(pagename): from MoinMoin.action import AttachFile AttachFile.send_link_rel(request, pagename) output.extend([ '<link rel="Search" href="%s">\n' % request.href(page_find_page), '<link rel="Index" href="%s">\n' % request.href(page_title_index), '<link rel="Glossary" href="%s">\n' % request.href(page_word_index), '<link rel="Help" href="%s">\n' % request.href(page_help_formatting), ]) output.append("</head>\n") request.write(''.join(output)) output = [] # start the <body> bodyattr = [] if keywords.has_key('body_attr'): bodyattr.append(' ') bodyattr.append(keywords['body_attr']) # Add doubleclick edit action if (pagename and keywords.get('allow_doubleclick', 0) and not keywords.get('print_mode', 0) and request.user.edit_on_doubleclick): if request.user.may.write(pagename): # separating this gains speed url = page.url(request, {'action': 'edit'}) bodyattr.append(''' ondblclick="location.href='%s'" ''' % wikiutil.escape(url, True)) # Set body to the user interface language and direction bodyattr.append(' %s' % self.ui_lang_attr()) body_onload = keywords.get('body_onload', '') if body_onload: bodyattr.append(''' onload="%s"''' % body_onload) output.append('\n<body%s>\n' % ''.join(bodyattr)) # Output ----------------------------------------------------------- # If in print mode, start page div and emit the title if keywords.get('print_mode', 0): d = { 'title_text': text, 'page': page, 'page_name': pagename or '', 'rev': rev, } request.themedict = d output.append(self.startPage()) output.append(self.interwiki(d)) output.append(self.title(d)) # In standard mode, emit theme.header else: exists = pagename and page.exists(includeDeleted=True) # prepare dict for theme code: d = { 'theme': self.name, 'script_name': scriptname, 'title_text': text, 'logo_string': request.cfg.logo_string, 'site_name': request.cfg.sitename, 'page': page, 'rev': rev, 'pagesize': pagename and page.size() or 0, # exists checked to avoid creation of empty edit-log for non-existing pages 'last_edit_info': exists and page.lastEditInfo() or '', 'page_name': pagename or '', 'page_find_page': page_find_page, 'page_front_page': page_front_page, 'home_page': home_page, 'page_help_contents': page_help_contents, 'page_help_formatting': page_help_formatting, 'page_parent_page': page_parent_page, 'page_title_index': page_title_index, 'page_word_index': page_word_index, 'user_name': request.user.name, 'user_valid': request.user.valid, 'msg': self._status, 'trail': keywords.get('trail', None), # Discontinued keys, keep for a while for 3rd party theme developers 'titlesearch': 'use self.searchform(d)', 'textsearch': 'use self.searchform(d)', 'navibar': ['use self.navibar(d)'], 'available_actions': ['use self.request.availableActions(page)'], } # add quoted versions of pagenames newdict = {} for key in d: if key.startswith('page_'): if not d[key] is None: newdict['q_' + key] = wikiutil.quoteWikinameURL(d[key]) else: newdict['q_' + key] = None d.update(newdict) request.themedict = d # now call the theming code to do the rendering if keywords.get('editor_mode', 0): output.append(self.editorheader(d)) else: output.append(self.header(d)) # emit it request.write(''.join(output)) output = [] self._send_title_called = True
def send_title(self, text, **keywords): """ Override Output the page header (and title). @param text: the title text @keyword page: the page instance that called us - using this is more efficient than using pagename.. @keyword pagename: 'PageName' @keyword print_mode: 1 (or 0) @keyword editor_mode: 1 (or 0) @keyword media: css media type, defaults to 'screen' @keyword allow_doubleclick: 1 (or 0) @keyword html_head: additional <head> code @keyword body_attr: additional <body> attributes @keyword body_onload: additional "onload" JavaScript code """ request = self.request _ = request.getText rev = request.rev if keywords.has_key('page'): page = keywords['page'] pagename = page.page_name else: pagename = keywords.get('pagename', '') page = Page(request, pagename) if keywords.get('msg', ''): raise DeprecationWarning("Using send_page(msg=) is deprecated! Use theme.add_msg() instead!") scriptname = request.script_root # get name of system pages page_front_page = wikiutil.getFrontPage(request).page_name page_help_contents = wikiutil.getLocalizedPage(request, 'HelpContents').page_name page_title_index = wikiutil.getLocalizedPage(request, 'TitleIndex').page_name page_site_navigation = wikiutil.getLocalizedPage(request, 'SiteNavigation').page_name page_word_index = wikiutil.getLocalizedPage(request, 'WordIndex').page_name page_help_formatting = wikiutil.getLocalizedPage(request, 'HelpOnFormatting').page_name page_find_page = wikiutil.getLocalizedPage(request, 'FindPage').page_name home_page = wikiutil.getInterwikiHomePage(request) # sorry theme API change!!! Either None or tuple (wikiname,pagename) now. page_parent_page = getattr(page.getParentPage(), 'page_name', None) # set content_type, including charset, so web server doesn't touch it: request.content_type = "text/html; charset=%s" % (config.charset, ) # Prepare the HTML <head> element user_head = [request.cfg.html_head] # include charset information - needed for moin_dump or any other case # when reading the html without a web server user_head.append('''<meta charset="%s">\n''' % (page.output_charset)) meta_keywords = request.getPragma('keywords') meta_desc = request.getPragma('description') if meta_keywords: user_head.append('<meta name="keywords" content="%s">\n' % wikiutil.escape(meta_keywords, 1)) if meta_desc: user_head.append('<meta name="description" content="%s">\n' % wikiutil.escape(meta_desc, 1)) # add meta statement if user has doubleclick on edit turned on or it is default if (pagename and keywords.get('allow_doubleclick', 0) and not keywords.get('print_mode', 0) and request.user.edit_on_doubleclick): if request.user.may.write(pagename): # separating this gains speed user_head.append('<meta name="edit_on_doubleclick" content="%s">\n' % (request.script_root or '/')) # search engine precautions / optimization: # if it is an action or edit/search, send query headers (noindex,nofollow): if request.query_string: user_head.append(request.cfg.html_head_queries) elif request.method == 'POST': user_head.append(request.cfg.html_head_posts) # we don't want to have BadContent stuff indexed: elif pagename in ['BadContent', 'LocalBadContent', ]: user_head.append(request.cfg.html_head_posts) # if it is a special page, index it and follow the links - we do it # for the original, English pages as well as for (the possibly # modified) frontpage: elif pagename in [page_front_page, request.cfg.page_front_page, page_title_index, 'TitleIndex', page_find_page, 'FindPage', page_site_navigation, 'SiteNavigation', 'RecentChanges', ]: user_head.append(request.cfg.html_head_index) # if it is a normal page, index it, but do not follow the links, because # there are a lot of illegal links (like actions) or duplicates: else: user_head.append(request.cfg.html_head_normal) if 'pi_refresh' in keywords and keywords['pi_refresh']: user_head.append('<meta http-equiv="refresh" content="%d;URL=%s">' % keywords['pi_refresh']) # output buffering increases latency but increases throughput as well output = [] output.append("""\ <!DOCTYPE html> <html lang="%s"> <head> %s <meta name="viewport" content="width=device-width, initial-scale=1.0"> %s %s """ % ( self.cfg.language_default, ''.join(user_head), self.html_head({ 'page': page, 'title': text, 'sitename': request.cfg.html_pagetitle or request.cfg.sitename, 'print_mode': keywords.get('print_mode', False), 'media': keywords.get('media', 'screen'), }), keywords.get('html_head', ''), )) output.append("</head>\n") request.write(''.join(output)) output = [] # start the <body> bodyattr = [] if keywords.has_key('body_attr'): bodyattr.append(' ') bodyattr.append(keywords['body_attr']) # Set body to the user interface language and direction bodyattr.append(' %s' % self.ui_lang_attr()) body_onload = keywords.get('body_onload', '') if body_onload: bodyattr.append(''' onload="%s"''' % body_onload) output.append('\n<body%s>\n' % ''.join(bodyattr)) # Output ----------------------------------------------------------- # If in print mode, start page div and emit the title if keywords.get('print_mode', 0): d = { 'title_text': text, 'page': page, 'page_name': pagename or '', 'rev': rev, } request.themedict = d output.append(self.startPage()) output.append(self.interwiki(d)) output.append(self.title(d)) # In standard mode, emit theme.header else: exists = pagename and page.exists(includeDeleted=True) # prepare dict for theme code: d = { 'theme': self.name, 'script_name': scriptname, 'title_text': text, 'logo_string': request.cfg.logo_string, 'site_name': request.cfg.sitename, 'page': page, 'rev': rev, 'pagesize': pagename and page.size() or 0, # exists checked to avoid creation of empty edit-log for non-existing pages 'last_edit_info': exists and page.lastEditInfo() or '', 'page_name': pagename or '', 'page_find_page': page_find_page, 'page_front_page': page_front_page, 'home_page': home_page, 'page_help_contents': page_help_contents, 'page_help_formatting': page_help_formatting, 'page_parent_page': page_parent_page, 'page_title_index': page_title_index, 'page_word_index': page_word_index, 'user_name': request.user.name, 'user_valid': request.user.valid, 'msg': self._status, 'trail': keywords.get('trail', None), # Discontinued keys, keep for a while for 3rd party theme developers 'titlesearch': 'use self.searchform(d)', 'textsearch': 'use self.searchform(d)', 'navibar': ['use self.navibar(d)'], 'available_actions': ['use self.request.availableActions(page)'], } # add quoted versions of pagenames newdict = {} for key in d: if key.startswith('page_'): if not d[key] is None: newdict['q_'+key] = wikiutil.quoteWikinameURL(d[key]) else: newdict['q_'+key] = None d.update(newdict) request.themedict = d # now call the theming code to do the rendering if keywords.get('editor_mode', 0): output.append(self.editorheader(d)) else: output.append(self.header(d)) # emit it request.write(''.join(output)) output = [] self._send_title_called = True
def get_menu(self, dic, user_items=None): req = self.request rev = req.rev _ = req.getText page = dic['page'] page_recent_changes = getLocalizedPage(req, u'RecentChanges') page_find_page = getLocalizedPage(req, u'FindPage') page_help_contents = getLocalizedPage(req, u'HelpContents') page_help_formatting = getLocalizedPage(req, u'HelpOnFormatting') page_help_wikisyntax = getLocalizedPage(req, u'HelpOnMoinWikiSyntax') page_title_index = getLocalizedPage(req, u'TitleIndex') page_word_index = getLocalizedPage(req, u'WordIndex') page_front_page = wikiutil.getFrontPage(req) page_sidebar = Page(req, req.getPragma('sidebar', u'SideBar')) quicklink = self._menu_quick_link(page) subscribe = self._menu_subscribe(page) menu_cfg = { 'raw': { # Title for this menu entry 'title': _('Raw Text'), # href and args are for normal entries ('special': False), # otherwise ignored. # 'href': Nonexistent or empty for current page 'href': '', # 'args': {'query1': 'value1', 'query2': 'value2', } # Optionally specify this for: # <a href="href?query1=value1&query2=value2"> # If href and args are both nonexistent or empty, key is # automatically interpreted to be an action name and href # and args are automatically set. 'args': '', # 'special' can be: # 'disabled', 'removed', 'separator' or 'header' for # whatever they say, False, None or nonexistent for # normal menu display. # 'separator' and 'header' are automatically removed when # there are no entries to show among them. 'special': False, 'icon': 'fa fa-file-o' }, 'print': { 'title': _('Print View'), 'icon': 'fa fa-print' }, 'refresh': { 'title': _('Delete Cache'), 'special': not (self._is_available_action(page, 'refresh') and page.canUseCache()) and 'removed', 'icon': 'fa fa-refresh' }, 'SpellCheck': { 'title': _('Check Spelling'), 'icon': 'fa fa-check-square-o' }, 'RenamePage': { 'title': _('Rename Page'), 'icon': 'fa fa-repeat' }, 'CopyPage': { 'title': _('Copy Page'), 'icon': 'fa fa-clone' }, 'DeletePage': { 'title': _('Delete Page'), 'icon': 'fa fa-trash' }, 'LikePages': { 'title': _('Like Pages'), 'icon': 'fa fa-thumbs-o-up' }, 'LocalSiteMap': { 'title': _('Local Site Map'), 'icon': 'fa fa-sitemap' }, 'MyPages': { 'title': _('My Pages'), 'icon': 'fa fa-newspaper-o' }, 'SubscribeUser': { 'title': _('Subscribe User'), 'special': not (self._is_available_action(page, 'SubscribeUser') and req.user.may.admin(page.page_name)) and 'removed', 'icon': 'fa fa-envelope-o' }, 'Despam': { 'title': _('Remove Spam'), 'special': not (self._is_available_action(page, 'Despam') and req.user.isSuperUser()) and 'removed', 'icon': 'fa fa-fire' }, 'revert': { 'title': _('Revert to this revision'), 'special': not (self._is_available_action(page, 'revert') and rev and req.user.may.revert(page.page_name)) and 'removed', 'icon': 'fa fa-undo' }, 'PackagePages': { 'title': _('Package Pages'), 'icon': 'fa fa-suitcase' }, 'RenderAsDocbook': { 'title': _('Render as Docbook'), 'icon': 'fa fa-book' }, 'SyncPages': { 'title': _('Sync Pages'), 'icon': 'fa fa-refresh' }, 'AttachFile': { 'title': _('Attachments'), 'icon': 'fa fa-paperclip' }, 'quicklink': { 'title': quicklink[1] or _('Quick Link'), 'args': dict(action=quicklink[0], rev=rev), 'special': not quicklink[0] and 'removed', 'icon': 'fa fa-share' }, 'subscribe': { 'title': subscribe[1] or _('Subscribe'), 'args': dict(action=subscribe[0], rev=rev), 'special': not subscribe[0] and 'removed', 'icon': 'fa fa-envelope' }, 'info': { 'title': _('Info'), 'icon': 'fa fa-info-circle' }, 'Load': { 'title': _('Load'), 'icon': 'fa fa-upload' }, 'Save': { 'title': _('Save'), 'icon': 'fa fa-download' }, # useful pages 'RecentChanges': { 'title': page_recent_changes.page_name, 'href': page_recent_changes.url(req), 'icon': 'fa fa-clock-o' }, 'FindPage': { 'title': page_find_page.page_name, 'href': page_find_page.url(req), 'icon': 'fa fa-search' }, 'HelpContents': { 'title': page_help_contents.page_name, 'href': page_help_contents.url(req), 'icon': 'fa fa-question-circle' }, 'HelpOnFormatting': { 'title': page_help_formatting.page_name, 'href': page_help_formatting.url(req), 'icon': 'fa fa-question-circle' }, 'HelpOnMoinWikiSyntax': { 'title': page_help_wikisyntax.page_name, 'href': page_help_wikisyntax.url(req), 'icon': 'fa fa-question-circle' }, 'TitleIndex': { 'title': page_title_index.page_name, 'href': page_title_index.url(req), 'icon': 'fa fa-list' }, 'WordIndex': { 'title': page_word_index.page_name, 'href': page_word_index.url(req), 'icon': 'fa fa-list' }, 'FrontPage': { 'title': page_front_page.page_name, 'href': page_front_page.url(req), 'icon': 'fa fa-home' }, 'SideBar': { 'title': page_sidebar.page_name, 'href': page_sidebar.url(req), 'icon': 'fa fa-columns' }, 'editSideBar': { 'title': _('Edit SideBar'), 'href': page_sidebar.url(req), 'args': dict(action='edit'), 'special': (not self._is_editable_page(page_sidebar) and 'removed'), 'icon': 'fa fa-columns' }, } output = [] for group in self._menu: _group = {'label': _(group['label']), 'entries': []} for entry in group['entries']: data = menu_cfg.get(entry) if data: if data.get('special'): _group['entries'].append(data) else: if not (data.get('href') or data.get('args')): # It's an Action. if self._is_available_action(page, entry): query = self._get_query_string({ 'action': entry, 'rev': rev }) _entry = { 'title': data.get('title', _(entry)), 'href': u'%s%s' % (page.url(req), query), 'icon': data['icon'], } _group['entries'].append(_entry) else: continue else: # A normal menu entry. if not data.get('href'): data['href'] = page.url(req) if data.get('args'): data['href'] = u'%s%s' % ( data['href'], self._get_query_string(data['args'])) _group['entries'].append({ 'title': data.get('title', _(entry)), 'href': data['href'], 'icon': data['icon'], }) if _group['label'] == 'User': for k in user_items.keys(): if user_items[k]: _group['entries'].append({ 'title': _(user_items[k]['title']), 'href': user_items[k]['url'], 'icon': user_items[k]['icon'] }) output.append(_group) return output
def send_title(self, text, **keywords): """ An almost verbatim copy of MoinMoin.theme.__init__.ThemeBase.send_title, that replaces hard coded HTML string template with Jinja2. """ req = self.request _ = req.getText rev = req.rev if keywords.has_key('page'): page = keywords['page'] pagename = page.page_name else: pagename = keywords.get('pagename', '') page = Page(req, pagename) if keywords.get('msg', ''): raise DeprecationWarning("Using send_page(msg=) is deprecated! " "Use theme.add_msg() instead!") scriptname = req.script_root # get name of system pages page_front_page = wikiutil.getFrontPage(req).page_name page_help_contents = getLocalizedPage(req, 'HelpContents').page_name page_title_index = getLocalizedPage(req, 'TitleIndex').page_name page_site_navigation = getLocalizedPage(req, 'SiteNavigation').page_name page_word_index = getLocalizedPage(req, 'WordIndex').page_name page_help_formatting = getLocalizedPage(req, 'HelpOnFormatting').page_name page_find_page = getLocalizedPage(req, 'FindPage').page_name home_page = wikiutil.getInterwikiHomePage(req) page_parent_page = getattr(page.getParentPage(), 'page_name', None) # set content_type, including charset, so web server doesn't touch it: req.content_type = "text/html; charset=%s" % config.charset meta_keywords = req.getPragma('keywords') or "" meta_description = req.getPragma('description') or "" rss_link = self.rsslink({'page': page}) universal_edit_button = self.universal_edit_button({'page': page}) stylesheets = self.html_stylesheets({ 'print_media': keywords.get('print_mode', False), 'media': keywords.get('media', 'screen') }) gui_edit_link = self.guiEditorScript({'page': page}) context = { 'title': Markup(wikiutil.escape(text)), 'sitename': wikiutil.escape(req.cfg.html_pagetitle or req.cfg.sitename), 'charset': page.output_charset, 'meta_keywords': wikiutil.escape(meta_keywords, 1), 'meta_description': wikiutil.escape(meta_description, 1), 'robots': None, # might be "index", "noindex", or None 'refresh_seconds': None, 'refresh_url': None, 'static_base': "%s/%s/" % (self.cfg.url_prefix_static, self.name), 'stylesheets': stylesheets, 'rss_link_title': rss_link[0], 'rss_link_href': rss_link[1], 'universal_edit_button_title': universal_edit_button[0], 'universal_edit_button_href': universal_edit_button[1], 'common_js': '%s/common/js/%s.js' % (req.cfg.url_prefix_static, 'common'), 'search_hint': req.getText('Search'), 'gui_editor_link_href': gui_edit_link[0], 'gui_editor_link_text': gui_edit_link[1], 'extra_html_head': Markup(keywords.get('html_head', '')), 'page_start_href': req.href(page_front_page), 'page_alternate_title': None, 'page_alternate_href': '', 'print_alternate_title': None, 'print_alternate_href': '', 'page_up_href': None, } # search engine precautions / optimization: # if it is an action or edit/search, send query headers (noindex,nofollow): if req.query_string or req.method == 'POST': context['robots'] = "noindex" # we don't want to have BadContent stuff indexed: elif pagename in [ 'BadContent', 'LocalBadContent', ]: context['robots'] = "noindex" # if it is a special page, index it and follow the links - we do it # for the original, English pages as well as for (the possibly # modified) frontpage: elif pagename in [ page_front_page, req.cfg.page_front_page, page_title_index, 'TitleIndex', page_find_page, 'FindPage', page_site_navigation, 'SiteNavigation', 'RecentChanges', ]: context['robots'] = "index" if 'pi_refresh' in keywords and keywords['pi_refresh']: context.update({ 'refresh_seconds': keywords['pi_refresh'][0], 'refresh_url': keywords['pi_refresh'][1] }) # Links if pagename: context.update({ 'page_alternate_title': _('Wiki Markup'), 'page_alternate_href': page.url(req, querystr=dict(action='raw')) }) context.update({ 'print_alternate_title': _('Print View'), 'print_alternate_href': page.url(req, querystr=dict(action='print')) }) if page_parent_page: context['page_up'] = req.href(page_parent_page) output = StringIO() write_f_onhold = req.write req.write = lambda s: output.write(s.encode('utf-8')) if pagename and req.user.may.read(pagename): from MoinMoin.action import AttachFile AttachFile.send_link_rel(req, pagename) context['attached_links'] = Markup(output.getvalue()) req.write = write_f_onhold context['extra_links'] = [ { 'rel': "Search", 'href': "%s" % req.href(page_find_page) }, { 'rel': "Index", 'href': "%s" % req.href(page_title_index) }, { 'rel': "Glossary", 'href': "%s" % req.href(page_word_index) }, { 'rel': "Help", 'href': "%s" % req.href(page_help_formatting) }, ] template = self.j2env.get_template('bits/head.html') output = template.render(context) req.write(output) output = [] # start the <body> bodyattr = [] if keywords.has_key('body_attr'): bodyattr.append(' ') bodyattr.append(keywords['body_attr']) # Set body to the user interface language and direction bodyattr.append(' %s' % self.ui_lang_attr()) body_onload = keywords.get('body_onload', '') if body_onload: bodyattr.append(''' onload="%s"''' % body_onload) output.append('\n<body%s>\n' % ''.join(bodyattr)) # Output ----------------------------------------------------------- # If in print mode, start page div and emit the title if keywords.get('print_mode', 0): d = { 'title_text': text, 'page': page, 'page_name': pagename or '', 'rev': rev, } req.themedict = d output.append(self.startPage()) output.append(self.interwiki(d)) output.append(self.title(d)) # In standard mode, emit theme.header else: exists = pagename and page.exists(includeDeleted=False) # prepare dict for theme code: d = { 'theme': self.name, 'script_name': scriptname, 'title_text': text, 'logo_string': req.cfg.logo_string, 'site_name': req.cfg.sitename, 'page': page, 'rev': rev, 'pagesize': pagename and page.size() or 0, # exists checked to avoid creation of empty edit-log for non-existing pages 'last_edit_info': exists and page.lastEditInfo() or '', 'page_name': pagename or '', 'page_find_page': page_find_page, 'page_front_page': page_front_page, 'home_page': home_page, 'page_help_contents': page_help_contents, 'page_help_formatting': page_help_formatting, 'page_parent_page': page_parent_page, 'page_title_index': page_title_index, 'page_word_index': page_word_index, 'user_name': req.user.name, 'user_valid': req.user.valid, 'msg': self._status, 'trail': keywords.get('trail', None), # Discontinued keys, keep for a while for 3rd party theme developers 'titlesearch': 'use self.searchform(d)', 'textsearch': 'use self.searchform(d)', 'navibar': ['use self.navibar(d)'], 'available_actions': ['use self.request.availableActions(page)'], } # add quoted versions of pagenames newdict = {} for key in d: if key.startswith('page_'): if not d[key] is None: newdict['q_' + key] = wikiutil.quoteWikinameURL(d[key]) else: newdict['q_' + key] = None d.update(newdict) req.themedict = d # now call the theming code to do the rendering if keywords.get('editor_mode', 0): output.append(self.editorheader(d)) else: output.append(self.header(d)) # emit it req.write(''.join(output)) output = [] self._send_title_called = True
def header(self, dic, **kw): """ Assemble wiki header @param d: parameter dictionary @rtype: unicode @return: page header html """ # html = [ # # Pre header custom html # self.emit_custom_html(self.cfg.page_header1), # # Header # u'<div id="header">', # self.logo(), # self.searchform(dic), # self.username(dic), # u'<div id="locationline">', # self.interwiki(dic), # self.title(dic), # u'</div>', # self.trail(dic), # self.navibar(dic), # #u'<hr id="pageline">', # u'<div id="pageline"><hr style="display:none;"></div>', # self.msg(dic), # self.editbar(dic), # u'</div>', # # Post header custom html (not recommended) # self.emit_custom_html(self.cfg.page_header2), # # Start of page # self.startPage(), # ] frontpage = wikiutil.getFrontPage(self.request) findpage = getLocalizedPage(self.request, 'FindPage') helpcontents = getLocalizedPage(self.request, 'HelpContents') navigation_items = self.get_navigation_items(dic) trail_items = self.get_trail_items( dic, exclude=[i['name'] for i in navigation_items]) form = self.request.values if self.cfg.logo_markup: logo_markup = Markup(self.cfg.logo_markup) else: logo_markup = Markup(self.cfg.logo_string) user_items = self.get_user_items(dic) context = { 'page_name': dic['page'].page_name, 'logo_markup': logo_markup, 'logo_string': Markup(self.cfg.logo_string), 'user_items': user_items, 'homepage_url': self.request.href(frontpage.page_name), 'findpage_url': self.request.href(findpage.page_name), 'edit_button': self.get_edit_button(dic), 'menu_label': self.request.getText('Menu'), 'menu': self.get_menu(dic, user_items=user_items), 'helpcontents_url': self.request.href(helpcontents.page_name), 'navigation_items': navigation_items, 'trail_items': trail_items, 'search_form_action': self.request.href(dic['page'].page_name), 'search_form_label': self.request.getText('Search'), 'search_form_value': wikiutil.escape(form.get('value', ''), 1), 'msgs': self.get_msgs(dic), } template = self.j2env.get_template('bits/body_header.html') output = template.render(context) return output