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
Beispiel #2
0
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
Beispiel #3
0
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
Beispiel #4
0
    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>
&nbsp;
<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('''
&nbsp;
<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('''
&nbsp;
<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()
Beispiel #5
0
	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
Beispiel #7
0
    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
Beispiel #8
0
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
Beispiel #9
0
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
Beispiel #10
0
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>]&nbsp;' % (
                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)
Beispiel #11
0
    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
Beispiel #12
0
    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
Beispiel #14
0
    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
Beispiel #15
0
    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
Beispiel #16
0
    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