[Zope3-checkins] CVS: zopeproducts/zwiki/browser - __init__.py:1.1 add.pt:1.1 comment_page.pt:1.1 configure.zcml:1.1 parents_page.pt:1.1 view_page.pt:1.1 wiki.py:1.1 wiki_icon.gif:1.1 wiki_toc.pt:1.1 wikipage.py:1.1 wikipage_icon.gif:1.1
Stephan Richter
srichter@cbu.edu
Wed, 9 Apr 2003 17:47:18 -0400
Update of /cvs-repository/zopeproducts/zwiki/browser
In directory cvs.zope.org:/tmp/cvs-serv14209/browser
Added Files:
__init__.py add.pt comment_page.pt configure.zcml
parents_page.pt view_page.pt wiki.py wiki_icon.gif wiki_toc.pt
wikipage.py wikipage_icon.gif
Log Message:
Whee, this is a big structural change. I am making this the last location
chnage for Wiki and WikiPage, so that people can start using zwiki for
Zope 3 for their sites. Before the next structural change, I will provide
tools to import and export the data in XML without loss of information.
Here are the changes:
- Created browser directory and moved everything browser-related in there.
- Moved Wiki and WikiPage broswer code into separate files.
- Added 'wiki' skin.
- Moved Wiki and WikiPage content objects into their own files.
- Adjusted tests and configuration to reflect this change.
Okay, back to working on the stylesheet stuff. :))
=== Added File zopeproducts/zwiki/browser/__init__.py ===
##############################################################################
#
# Copyright (c) 2003 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Browser Views for the zwiki for Zope 3 Product
$Id: __init__.py,v 1.1 2003/04/09 21:47:16 srichter Exp $
"""
=== Added File zopeproducts/zwiki/browser/add.pt ===
<html metal:use-macro="views/standard_macros/dialog">
<body>
<div metal:fill-slot="body">
<form action="action.html" method="POST">
<table class="TypeListing" cellpadding="3">
<caption>Add Content</caption>
<tbody tal:repeat="info view/addingInfo">
<tr>
<td class="Selector">
<input type="radio" name="type_name"
tal:attributes="value info/action; id info/action" />
</td>
<td class="TypeName">
<label style="font-weight: bold;"
tal:attributes="for info/action">
<span tal:replace="info/title" >Folder</span>
</label>
<div class="TypeDescription" tal:content="info/description">
Folders are generic containers for content, including other
folders.
</div>
</td>
</tr>
</tbody>
<tbody tal:condition="nothing">
<tr>
<td class="Selector">
<input type="radio" name="type_name" value="" />
</td>
<td class="TypeName">
<img alt="Folder" src="../../ZMI/www/document_icon.gif" />
Document
</td>
</tr>
<tr>
<td class="Selector"><br /></td>
<td class="TypeDescription">
Documents are simple textual content.
</td>
</tr>
</tbody>
<tr>
<td><br/></td>
<td>
<input type="text" name="id"
tal:condition="view/namesAccepted"
tal:attributes="value request/id | nothing"
/>
<input type="submit" value=" Add " />
</td>
</tr>
</table>
</form>
</div>
</body>
</html>
=== Added File zopeproducts/zwiki/browser/comment_page.pt ===
<html metal:use-macro="views/standard_macros/page">
<head>
<style metal:fill-slot="style_slot">
</style>
</head>
<body i18n:domain="wiki">
<div metal:fill-slot="body">
<form action="addComment.html" method="post">
<table cellspacing="0" cellpadding="2" border="0">
<tr>
<td i18n:translate="">Comment</td>
<td>
<textarea name="comment" cols="60" rows="10" />
</td>
</tr>
</table>
<input type="submit" name="submit" value="Submit"
i18n:attributes="value submit-button" />
</form>
</div>
</body>
</html>
=== Added File zopeproducts/zwiki/browser/configure.zcml ===
<zopeConfigure
xmlns="http://namespaces.zope.org/zope"
xmlns:browser="http://namespaces.zope.org/browser">
<include package=".skin" />
<!-- Browser-specific configuration -->
<browser:menu
id="add_wiki"
title="Menu of objects to be added to wikis."/>
<!-- Custom adding view. -->
<browser:view
for="zopeproducts.zwiki.interfaces.IWiki"
name="+"
class=".wiki.WikiAdding"
permission="zope.ManageContent"
allowed_attributes="addingInfo"
menu="zmi_actions"
title="Add"
>
<browser:page name="index.html" template="add.pt" />
<browser:page name="action.html" attribute="action" />
</browser:view>
<browser:page
name="toc.html"
for="zopeproducts.zwiki.interfaces.IWiki"
class=".wiki.TableOfContents"
template="wiki_toc.pt"
permission="zopeproducts.zwiki.ViewWikiPage"
menu="zmi_views"
title="TOC"/>
<browser:menuItem menu="add_content"
for="zope.app.interfaces.container.IAdding"
title="Wiki"
action="Wiki"
description="A simple Wiki."/>
<browser:icon
name="zmi_icon"
for="zopeproducts.zwiki.interfaces.IWiki"
file="wiki_icon.gif"
/>
<!-- WikiPage browser configuration -->
<browser:addform
label="Add Wiki Page"
name="AddWikiPage"
schema="zopeproducts.zwiki.interfaces.IWikiPage"
content_factory="zopeproducts.zwiki.wiki.WikiPage"
permission="zopeproducts.zwiki.AddWikiPage"
fields="source type"
class=".wikipage.EditWikiPage"
menu="add_wiki"
title="Wiki Page"/>
<browser:editform
schema="zopeproducts.zwiki.interfaces.IWikiPage"
for="zopeproducts.zwiki.interfaces.IWikiPage"
label="Change Wiki Page"
name="edit.html"
permission="zopeproducts.zwiki.EditWikiPage"
fields="source type"
class=".wikipage.EditWikiPage"
menu="zmi_views" title="Edit" />
<browser:pages
for="zopeproducts.zwiki.interfaces.IWikiPage"
class=".wikipage.ViewWikiPage"
permission="zopeproducts.zwiki.ViewWikiPage">
<browser:page name="view.html" template="view_page.pt"
menu="zmi_views" title="View" />
<browser:page name="jumpto.html" attribute="jumpTo" />
</browser:pages>
<browser:pages
for="zopeproducts.zwiki.interfaces.IWikiPage"
class=".wikipage.EditWikiParents"
permission="zopeproducts.zwiki.ReparentWikiPage">
<browser:page name="parents.html" template="parents_page.pt"
menu="zmi_views" title="Parents" />
<browser:page name="setParents.html" attribute="setParents" />
</browser:pages>
<browser:pages
for="zopeproducts.zwiki.interfaces.IWikiPage"
class=".wikipage.WikiPageComment"
permission="zopeproducts.zwiki.CommentWikiPage">
<browser:page name="commentForm.html" template="comment_page.pt"
menu="zmi_views" title="Add Comment" />
<browser:page name="addComment.html" attribute="comment" />
</browser:pages>
<browser:defaultView
name="view.html"
for="zopeproducts.zwiki.interfaces.IWikiPage"/>
<browser:icon
name="zmi_icon"
for="zopeproducts.zwiki.interfaces.IWikiPage"
file="wikipage_icon.gif"
/>
<browser:page
name="_traverse"
for="zopeproducts.zwiki.interfaces.IWikiPage"
class="zopeproducts.zwiki.traversal.WikiPageTraverser"
permission="zope.Public" />
</zopeConfigure>
=== Added File zopeproducts/zwiki/browser/parents_page.pt ===
<html metal:use-macro="views/standard_macros/page">
<head>
<style metal:fill-slot="style_slot">
</style>
</head>
<body i18n:domain="wiki">
<div metal:fill-slot="body">
<form action="setParents.html" method="post">
<table cellspacing="0" cellpadding="2" border="0">
<tr>
<td i18n:translate="">Parents</td>
<td>
<select name="parents:list" multiple="">
<div tal:repeat="parent view/availableWikis" tal:omit-tag="">
<option tal:content="parent" selected=""
tal:condition="python: parent in view.parents()">
Wiki1
</option>
<option tal:content="parent"
tal:condition="python: parent not in view.parents()">
Wiki1
</option>
</div>
</select>
</td>
</tr>
</table>
<input type="submit" name="submit" value="Reparent"
i18n:attributes="value reparent-button" />
</form>
<h3 i18n:translate="">Branch</h3>
<p tal:replace="structure view/branch" />
</div>
</body>
</html>
=== Added File zopeproducts/zwiki/browser/view_page.pt ===
<html metal:use-macro="views/standard_macros/page">
<head>
<style metal:fill-slot="style_slot">
</style>
</head>
<body i18n:domain="wiki">
<div metal:fill-slot="body">
<div id="wikipage_header">
<div id="wikipage_path"
tal:content="structure view/breadcrumbs">Wikis/WikiPage
</div>
<div id="wikipage_info">Last modified by
<b tal:content="view/author">srichter</b> on
<span tal:replace="view/modified">March 4, 2002.</span>
</div>
</div>
<div tal:replace="structure view/render">
This is the rendered Wiki
</div>
<form action="jumpto.html">
<div class="box" id="jumpto">
<div class="body">
<span i18n:translate="">Jump to:</span><input
type="text" name="jumpto"/>
</div>
</div>
</form>
</div>
</body>
</html>
=== Added File zopeproducts/zwiki/browser/wiki.py ===
##############################################################################
#
# Copyright (c) 2003 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Browser View Components for Wikis
$Id: wiki.py,v 1.1 2003/04/09 21:47:16 srichter Exp $
"""
from zope.component import getAdapter
from zope.proxy.context import ContextWrapper
from zope.app.traversing import objectName
from zope.app.browser.container.adding import Adding
class WikiAdding(Adding):
"""Custom adding view for NewsSite objects."""
menu_id = "add_wiki"
class TableOfContents:
"""Table of contents for a Wiki"""
def toc(self):
"""Generate a table of contents."""
children = []
for name, page in self.context.items():
wrapped = ContextWrapper(page, self.context, name=name)
hier = getAdapter(wrapped, IWikiPageHierarchy)
if hier.getParents() == ():
children.append((wrapped, hier.findChildren()))
return self._branchHTML(children)
def _branchHTML(self, children):
html = '<ul>\n'
for child, subs in children:
html += ' <li><a href="%s">%s</a></li>\n' %(objectName(child),
objectName(child))
if subs:
html += self._branchHTML(subs)
html += '</ul>\n'
return html
=== Added File zopeproducts/zwiki/browser/wiki_icon.gif ===
<Binary-ish file>
=== Added File zopeproducts/zwiki/browser/wiki_toc.pt ===
<html metal:use-macro="views/standard_macros/page">
<head>
<style metal:fill-slot="style_slot">
</style>
</head>
<body i18n:domain="wiki">
<div metal:fill-slot="body">
<h1 i18n:translate="">Wiki Table of Contents</h1>
<p tal:replace="structure view/toc">This is a table of contents.</p>
</div>
</body>
</html>
=== Added File zopeproducts/zwiki/browser/wikipage.py ===
##############################################################################
#
# Copyright (c) 2003 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Browser View Components for WikiPages
$Id: wikipage.py,v 1.1 2003/04/09 21:47:16 srichter Exp $
"""
import re
from urllib import quote, unquote
from zope.app.interfaces.dublincore import ICMFDublinCore
from zope.component import getAdapter, getView, getService, createObject
from zope.proxy.context import ContextWrapper
from zope.app.browser.form.widget import ListWidget
from zope.app.form.widget import CustomWidget
from zope.app.traversing import getParent, getPath, objectName
from zopeproducts.zwiki.interfaces import IWikiPageHierarchy
urlchars = r'[A-Za-z0-9/:@_%~#=&\.\-\?\+\$,]+'
urlendchar = r'[A-Za-z0-9/]'
url = r'["=]?((about|gopher|http|https|ftp|mailto|file):%s)' %urlchars
bracketedexpr = r'\[([^\n\]]+)\]'
protectedLine = r'(?m)^!(.*)$'
U = 'A-Z\xc0-\xdf'
L = 'a-z\xe0-\xff'
b = '(?<![%s0-9])' % (U+L)
wikiname1 = r'(?L)%s[%s]+[%s]+[%s][%s]*[0-9]*' % (b,U,L,U,U+L)
wikiname2 = r'(?L)%s[%s][%s]+[%s][%s]*[0-9]*' % (b,U,U,L,U+L)
wikilink = r'!?(%s|%s|%s|%s)' % (wikiname1,wikiname2,bracketedexpr,url)
localwikilink = r'!?(%s|%s|%s)' % (wikiname1, wikiname2, bracketedexpr)
interwikilink = r'!?((?P<local>%s):(?P<remote>%s))' % \
(localwikilink, urlchars+urlendchar)
class SourceTypeWidget(ListWidget):
size = 1
def renderItems(self, value):
name = self.name
# get items
types = getService(self.context, "WikiSourceTypeRegistry")
items = types.getAllTitles()
# check if we want to select first item
if (not value and getattr(self.context, 'firstItem', False)
and len(items) > 0):
value = items[0]
cssClass = self.getValue('cssClass')
rendered_items = []
count = 0
for item_value in items:
item_text = self.textForValue(item_value)
if item_value == value:
rendered_item = self.renderSelectedItem(
count, item_text, item_value, name, cssClass)
else:
rendered_item = self.renderItem(
count, item_text, item_value, name, cssClass)
rendered_items.append(rendered_item)
count += 1
return rendered_items
class EditWikiPage(object):
type = CustomWidget(SourceTypeWidget)
class ViewWikiPage:
"""A rendered View of the wiki page."""
def breadcrumbs(self):
"""Get the path of this page."""
hier = getAdapter(self.context, IWikiPageHierarchy)
path = hier.path()
html = []
for page in path:
html.append('<a href="%s">%s</a>' %(getPath(page),
objectName(page)))
return ' / '.join(html)
def author(self):
"""Get user who last modified the Wiki Page."""
creators = getAdapter(self.context, ICMFDublinCore).creators
if not creators:
return 'unknown'
return creators[0]
def modified(self):
"""Get last modification date."""
date = getAdapter(self.context, ICMFDublinCore).modified
if date is None:
date = getAdapter(self.context, ICMFDublinCore).created
formatter = self.request.locale.getDateTimeFormatter('medium')
return formatter.format(date)
def jumpTo(self, jumpto):
"""Try to get quickly to another Wiki page"""
wiki = getParent(self.context)
if jumpto in wiki:
return self.request.response.redirect(getPath(wiki)+'/'+jumpto)
else:
return self.request.response.redirect('.')
def renderWikiLinks(self, source):
"""Add Wiki Links to the source"""
html = str(source)
html = re.sub(protectedLine, self._protectLine, html)
# html = re.sub(interwikilink, self._interwikilinkReplace, html)
html = re.sub(wikilink, self._wikilinkReplace, html)
return html
def render(self):
"""Render the wiki page source."""
types = getService(self.context, "WikiSourceTypeRegistry")
source = types.createObject(self.context.type,
self.context.source)
view = getView(source, None, self.request)
html = view.render(self.context)
html = self.renderWikiLinks(html)
return html
def _protectLine(self, match):
return re.sub(wikilink, r'!\1', match.group(1))
def _wikilinkReplace(self, match, allowed=0, state=None, text=''):
# tasty spaghetti regexps! better suggestions welcome ?
"""
Replace an occurrence of the wikilink regexp or one of the
special [] constructs with a suitable hyperlink
To be used as a re.sub repl function *and* get a proper value
for literal context, 'allowed', etc, enclose this function
with the value using 'thunk_substituter'.
"""
# In a literal?
if state is not None:
if within_literal(match.start(1), match.end(1)-1, state, text):
return match.group(1)
# matches beginning with ! should be left alone
if re.match('^!', match.group(0)):
return match.group(1)
m = morig = match.group(1)
wiki = getParent(self.context)
# if it's a bracketed expression,
if re.match(bracketedexpr, m):
# strip the enclosing []'s
m = re.sub(bracketedexpr, r'\1', m)
# extract a (non-url) path if there is one
pathmatch = re.match(r'(([^/]*/)+)([^/]+)', m)
if pathmatch:
path, id = pathmatch.group(1), pathmatch.group(3)
else:
path, id = '', m
# or if there was a path assume it's to some non-wiki
# object and skip the usual existence checking for
# simplicity. Could also attempt to navigate the path in
# zodb to learn more about the destination
if path:
return '<a href="%s%s">%s%s</a>' % (path, id, path, id)
# otherwise fall through to normal link processing
# if it's an ordinary url, link to it
if re.match(url,m):
# except, if preceded by " or = it should probably be left alone
if re.match('^["=]', m): # "
return m
else:
return '<a href="%s">%s</a>' % (m, m)
# it might be a structured text footnote ?
elif re.search(r'(?si)<a name="%s"' % (m),text):
return '<a href="#%s">[%s]</a>' % (m,m)
# a wikiname - if a page (or something) of this name exists, link to it
elif m in wiki:
return '<a href="%s/%s">%s</a>' % (getPath(wiki), quote(m), m)
# otherwise, provide a "?" creation link
else:
return '%s<a href="%s/+/AddWikiPage=%s">?</a>' %(
morig, getPath(wiki), quote(m))
def _interwikilinkReplace(self, match, allowed=0, state=None, text=''):
"""Replace an occurrence of interwikilink with a suitable hyperlink.
To be used as a re.sub repl function *and* get a proper value
for literal context, 'allowed', etc.
"""
# matches beginning with ! should be left alone This is a bit naughty,
# but: since we know this text will likely be scanned with
# _wikilink_replace right after this pass, leave the ! in place for it
# to find. Otherwise the localname will get wiki-linked.
if re.match('^!', match.group(0)):
return match.group(0)
localname = match.group('local')
remotename = match.group('remote') # named groups come in handy here!
# NB localname could be [bracketed]
if re.match(bracketedexpr,localname):
localname = re.sub(bracketedexpr, r'\1', localname)
# look for a RemoteWikiURL definition
if hasattr(self.aq_parent, localname):
localpage = getattr(self.aq_parent,localname)
# local page found - search for "RemoteWikiUrl: url"
m = re.search(remotewikiurl, str(localpage))
if m is not None:
# NB: pages are stored html-quoted XXX eh ? they are ?
# something's not right somewhere.. I have lost my grip on
# this whole quoting issue.
remoteurl = html_unquote(m.group(1))
# we have a valid inter-wiki link
link = '<a href="%s%s">%s:%s</a>' % \
(remoteurl, remotename, localname, remotename)
# protect it from any later wiki-izing passes
return re.sub(wikilink, r'!\1', link)
# otherwise, leave alone
return match.group(0)
class EditWikiParents:
def parents(self):
hier = getAdapter(self.context, IWikiPageHierarchy)
return hier.parents
def availableWikis(self):
wiki = getParent(self.context)
return wiki.keys()
def setParents(self, parents):
hier = getAdapter(self.context, IWikiPageHierarchy)
hier.reparent(parents)
return self.request.response.redirect('./@@parents.html')
def _branchHTML(self, children):
html = '<ul>\n'
for child, subs in children:
html += ' <li><a href="../%s">%s</a></li>\n' %(objectName(child),
objectName(child))
if subs:
html += self._branchHTML(subs)
html += '</ul>\n'
return html
def branch(self):
hier = getAdapter(self.context, IWikiPageHierarchy)
children = hier.findChildren()
return self._branchHTML(children)
class WikiPageComment:
def comment(self, comment):
types = getService(self.context, "WikiSourceTypeRegistry")
source = types.createObject(self.context.type, self.context.source)
view = getView(source, None, self.request)
comment = view.createComment(comment, self.context.getCommentCounter())
self.context.comment(comment)
return self.request.response.redirect('.')
=== Added File zopeproducts/zwiki/browser/wikipage_icon.gif ===
<Binary-ish file>