The modern_cms theme
moin 1.5
modern_cms15.py - use this for moin 1.5 branch
1 """
2 Modern based cms theme
3 ======================
4
5 If you want to use a wiki as a tool to create a regular site easily,
6 this theme is for you. The wiki looks like a plain site to visitors or
7 users without edit rights, and a wiki to users with edits rights.
8
9 This is also a replacement for the readonly theme that was part of release 1.2.
10
11
12 Problems
13 --------
14 Some actions are not available for visitors:
15
16 - Show Raw Text
17 - Show Print Preview
18 - Show Like Pages
19 - Show Local Site Map
20 - Delete Cache
21
22 Most of these are not really needed for a visitor. Print style sheet is
23 used transparently when you print a page. Like Pages and Local Site Map
24 should be available, but are not really needed if you have a good
25 search.
26
27 Missing page will suggest visitors to create a new page, but they will
28 always fail because they don't have acl rights. This should be fixed in
29 other place.
30
31
32 Install
33 -------
34
35 1. Put in your wiki/data/plugin/theme/
36
37 2. Prevent visitors from writing using acl::
38
39 acl_rights_before = (u"WikiAdmin:read,write,delete,revert,admin "
40 u"EditorsGroup:read,write,delete,revert ")
41 acl_rights_default = u"All:read "
42
43 Remember that some ACL you put on a page will override the default ACL!
44
45 3. Make it the default and only theme on your site::
46
47 theme_default = 'modern_cms'
48 theme_force = True
49
50
51 Compatibility
52 --------------
53 Tested with release 1.5.1, should work with any 1.5 release.
54
55
56 Legal
57 -----
58 @copyright (c) 2005 Nir Soffer <nirs@freeshell.org>
59 @copyright (c) 2006 Thomas Waldmann
60 @license: GNU GPL, see COPYING for details
61
62 """
63
64 from MoinMoin.theme import modern
65
66 class Theme(modern.Theme):
67
68 name = "modern" # uses "modern" CSS and images
69
70 def shouldShowEditbar(self, page):
71 """ Hide the edit bar if you can't edit """
72 if self.request.user.may.write(page.page_name):
73 return modern.Theme.shouldShowEditbar(self, page)
74 return False
75
76 def pageLastName(self, name):
77 """ This should be in the Page class, but its not """
78 return name[name.rfind('/') + 1:]
79
80 def shortenPagename(self, name):
81 """ Shorten page names
82
83 This is a modified copy from theme/__init__.py. Modified to
84 show only the last name of a page, even if there is room for
85 the full name.
86 """
87 name = self.pageLastName(name)
88 maxLength = self.maxPagenameLength()
89 if len(name) > maxLength:
90 half, left = divmod(maxLength - 3, 2)
91 name = u'%s...%s' % (name[:half + left], name[-half:])
92 return name
93
94 def footer(self, d, **keywords):
95 """ same as modern footer, but no pageinfo """
96 page = d['page']
97 html = [
98 # End of page
99 self.endPage(),
100
101 # Pre footer custom html (not recommended!)
102 self.emit_custom_html(self.cfg.page_footer1),
103
104 # Footer
105 u'<div id="footer">',
106 self.editbar(d),
107 self.credits(d),
108 self.showversion(d, **keywords),
109 u'</div>',
110
111 # Post footer custom html
112 self.emit_custom_html(self.cfg.page_footer2),
113 ]
114 return u'\n'.join(html)
115
116 def execute(request):
117 return Theme(request)
moin 1.3
1 """
2 Modern based cms theme
3 ======================
4
5 If you want to use a wiki as a tool to create a regular site easily,
6 this theme is for you. The wiki looks like a plain site to visitors or
7 users without edit rights, and a wiki to users with edits rights.
8
9 This is also a replacement for the readonly theme that was part of release 1.2.
10
11
12 Problems
13 --------
14 Some actions are not available for visitors:
15
16 - Show Raw Text
17 - Show Print Preview
18 - Show Like Pages
19 - Show Local Site Map
20 - Delete Cache
21
22 Most of these are not really needed for a visitor. Print style sheet is
23 used transparently when you print a page. Like Pages and Local Site Map
24 should be available, but are not really needed if you have a good
25 search.
26
27 Missing page will suggest visitors to create a new page, but they will
28 always fail because they don't have acl rights. This should be fixed in
29 other place.
30
31
32 Install
33 -------
34
35 1. Put in your wiki/data/plugin/theme/
36
37 2. Prevent visitors from writing using acl::
38
39 acl_rights_before = (u"WikiAdmin:read,write,delete,revert,admin "
40 u"EditorsGroup:read,write,delete,revert ")
41 acl_rights_default = u"All:read "
42
43 Remember that acl you put on a page will override the default acl!
44
45 3. Make it the default and only theme on your site::
46
47 theme_default = 'modern_cms'
48 theme_force = True
49
50
51 Compatibility
52 --------------
53 Tested with release 1.3.5, should work with any 1.3 release.
54
55
56 Legal
57 -----
58 @copyright (c) 2005 Nir Soffer <nirs@freeshell.org>
59
60 This program is free software; you can redistribute it and/or modify
61 it under the terms of the GNU General Public License as published by
62 the Free Software Foundation; either version 2 of the License, or
63 (at your option) any later version.
64
65 This program is distributed in the hope that it will be useful,
66 but WITHOUT ANY WARRANTY; without even the implied warranty of
67 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
68 GNU General Public License for more details.
69
70 You should have received a copy of the GNU General Public License
71 along with this program; if not, write to the Free Software
72 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
73 """
74
75 from MoinMoin import wikiutil, config
76 from MoinMoin.Page import Page
77 from MoinMoin.theme import modern
78
79
80 class Theme(modern.Theme):
81
82 # Uses modern CSS and images
83 name = "modern"
84
85 def shouldShowEditbar(self, page):
86 """ Hide the edit bar if you can't edit """
87 if self.request.user.may.write(page.page_name):
88 return modern.Theme.shouldShowEditbar(self, page)
89 return False
90
91 def navigation(self, d):
92 """ Return page navigation interface
93
94 e.g. Parent/Child/Child, where each part is a link to that part. Some
95 people call this bread crumbs.
96 """
97 if not config.allow_subpages:
98 return ''
99 links = []
100 parents = d['page'].page_name.split('/')[:-1]
101 parts = []
102 for name in parents:
103 parts.append(name)
104 leaf = '/'.join(parts)
105 link = Page(self.request, leaf).link_to(self.request, name)
106 links.append(link)
107 links = '/'.join(links)
108 return u'<div id="navigation">\n%s\n</div>\n' % links
109
110 def title(self, d):
111 """ Return page title with optional navigation interface """
112 _ = self.request.getText
113 title = '<h1 id="title">%s</h1>'
114 if d['title_link']:
115 # Page views
116 name = d['title_text']
117 content = ('<a title="%(title)s" href="%(href)s">%(text)s</a>') % {
118 'title': _('Click to do a full-text search for this title'),
119 'href': d['title_link'],
120 'text': wikiutil.escape(self.pageLastName(name)),
121 }
122 return self.navigation(d) + title % content
123 else:
124 # Search results and other actions
125 return title % wikiutil.escape(d['title_text'])
126
127 def pageLastName(self, name):
128 """ This should be in the Page class, but its not """
129 if not config.allow_subpages:
130 return name
131 return name[name.rfind('/') + 1:]
132
133 def shortenPagename(self, name):
134 """ Shorten page names
135
136 This is a modified copy from theme/__init__.py. Modified to
137 show only the last name of a page, even if there is room for
138 the full name.
139 """
140 name = self.pageLastName(name)
141 maxLength = self.maxPagenameLength()
142 if len(name) > maxLength:
143 half, left = divmod(maxLength - 3, 2)
144 name = u'%s...%s' % (name[:half + left], name[-half:])
145 return name
146
147 def editbar(self, d):
148 """ Return edit bar interface
149
150 This is a copy of modern editbar, modified to remove the
151 'Show Parent' link.
152 """
153 page = d['page']
154 if not self.shouldShowEditbar(page):
155 return ''
156
157 # Use cached editbar if possible.
158 cacheKey = 'editbar'
159 cached = self._cache.get(cacheKey)
160 if cached:
161 return cached
162
163 # Make new edit bar
164 request = self.request
165 _ = self.request.getText
166 link = wikiutil.link_tag
167 quotedname = wikiutil.quoteWikinameURL(page.page_name)
168 links = []
169 add = links.append
170
171 # Page actions
172 if page.isWritable() and request.user.may.write(page.page_name):
173 add(link(request, quotedname + '?action=edit', _('Edit')))
174 else:
175 add(_('Immutable Page', formatted=False))
176
177 add(link(request, quotedname + '?action=diff',
178 _('Show Changes', formatted=False)))
179 add(link(request, quotedname + '?action=info',
180 _('Get Info', formatted=False)))
181 add(self.subscribeLink(page))
182 add(self.actionsMenu(page))
183
184 # Format
185 items = '\n'.join(['<li>%s</li>' % item for item in links
186 if item != ''])
187 html = u'<ul class="editbar">\n%s\n</ul>\n' % items
188
189 # cache for next call
190 self._cache[cacheKey] = html
191 return html
192
193
194 def execute(request):
195 return Theme(request)
Patches
Better visible Login
I suggest this simple patch that only makes the userpreferences/login bold, so that they are better visible. This is a reaction to repeated problems of users to find the login button. This is not much but maybe it helps nonetheless?-- ThiloPfennig 2006-12-02 20:44:22
Exclude Actions for Visitors
Sometimes it might not be intended behaviour that some user can e.g. look at the revision history of a page. You can prevent that by the following patch (against MoinDesktop 1.5.5a-1).
- Add a new default entry "visitor_actions_excluded" to multiconfig.py
1 --- multiconfig_old.py 2006-10-15 15:41:00.000000000 +0200
2 +++ multiconfig.py 2006-12-03 17:57:08.000000000 +0100
3 @@ -179,6 +179,7 @@
4 acl_rights_valid = ['read', 'write', 'delete', 'revert', 'admin']
5
6 actions_excluded = [] # ['DeletePage', 'AttachFile', 'RenamePage']
7 + visitor_actions_excluded = []
8 allow_xslt = 0
9 attachments = None # {'dir': path, 'url': url-prefix}
10 auth = [authmodule.moin_cookie]
- Add this code to wikiaction.py
1 --- wikiaction_old.py 2006-10-15 15:20:00.000000000 +0200
2 +++ wikiaction.py 2006-12-03 19:36:40.000000000 +0100
3 @@ -902,6 +902,8 @@
4
5 def getHandler(request, action, identifier="execute"):
6 # check for excluded actions
7 + if (request.user.valid == 0) and (action in request.cfg.visitor_actions_excluded):
8 + return None
9 if action in request.cfg.actions_excluded:
10 return None
11
Maybe you want to apply also this patch to have nicer error messages: MoinMoinBugs/ActionsExcludedTriggerError
- Now you can forbid certain actions to visitors (non-logged-in-users) by setting the wikiconfig.py as follows:
actions_excluded = ['AttachFile', 'RenamePage'] # Generally forbidden actions on the wiki visitor_actions_excluded = [ 'info', 'revert'] # Forbidden actions for visitors which should only view a web-page
-- OliverSiemoneit 2006-12-03 18:50:09
Discussion
If a user is not able to write on a page currently the editbar is completly switched off. So he can't subscribe to such a page and he can't add a link. So may be we should change this behaviour to the actions he can do. -- ReimarBauer 2006-11-16 20:38:13
If a user is logged in he can't see the last changes stamp on the page as it is done for modern -- ReimarBauer 2006-12-03 07:36:33
Please note that the intention of modern_cms is to enable one or a few web master people to edit the site while looking like a normal web site (and not like a wiki) to everybody else.
Aha. for me it just always was THE standard theme for MoinMoin -- ThiloPfennig 2006-12-03 14:05:40
I do prefer if I am logged in using modern_cms the behaviour should be like modern and only if I am not logged in it should behave like a normal web site (and not like a wiki). -- ReimarBauer 2006-12-03 16:08:20
Therefore: Wouldn't it be better to check in line 72 of modern_cms15.py if the user is a unknown, not logged in user instead of "is he allowed to write on the page"? Because the line of demaraction is know-unknown user. There might be also cases where a know, logged-in user has no write rights. But this causes the theme to treat him like an unknown user deleting the editbar with the user now being unable to add quicklinks, subscriptions etc... . But if you are logged in you want to have normal wiki behaviour (displayed'immutable page' instead of no editbar) as Reimar mentioned above. So I suggest following change to line 72: if self.request.user.valid == 1): Or am I making a mistake?? -- OliverSiemoneit 2006-12-03 20:48:59
I would not set demarcation between known/unknown. I would solve this via ACL. Because if anybody registers he is known. This does not mean that I want him to read all versions. This depends on the group he belongs. I would add smebody to a specific group like VersionreaderGroup to allow him to read a version. My suggestion always was to have a general possibility to have a link between ACL and Actions, so that I can set an ACL for each page. I do not think that i makes much sense to have another access control mechanism -- ThiloPfennig 2006-12-04 23:15:01
- Moreover: The availability of actions should also be restricted. It is not enough just to hide the editbar. If the user has some experience, it's an easy task for him if he recognize that this is propably a Moin wiki and to append "?action=info" to a page to see the whole revision history! I don't think that is intended behaviour. Maybe we should introduce some new wikiconfig.py setting for CMS-themes like cms_actions_excluded and check the list in wikiaction.py getHandler (don't know if this is the central point where the decision on allowed actions is made) to prevent that happening or have some other solution for that.. (see patch above for a first try)
Related Issues
FeatureRequests/DisableUserCreation and the given instructions there
FeatureRequests/MakeInvitations and the given patch there
HelpOnAccessControlLists for more information how to hide certain pages (e.g. Fullsearch..)
ActionMarket/ApprovePageAction to control the publication process of pages better so that only approved pages are open for public reading.