Page Template: user_info
Basic user information page template
<html><body>
<div
tal:omit-tag=""
tal:define="
userName request/userName|nothing;
userObj python: here.portal_membership.getMemberById(userName);
getPortrait nocall: here/portal_membership/getPersonalPortrait;
getFolder nocall: here/portal_membership/getHomeFolder
">
<p tal:condition="not: userName">
No username selected.
</p>
<p tal:condition="not: userObj">
That username does not exist.
</p>
<table tal:condition="userObj">
<tr>
<td>
<img src=""
tal:replace="structure python: getPortrait(userName)" />
</td>
<td>
<ul>
<li>
<i>Username:</i>
<span tal:replace="userName" />
</li>
<li>
<i>Full name:</i>
<span tal:replace="userObj/fullname" />
</li>
<li
tal:define="home python: getFolder(userName)"
tal:condition="home">
<i>Home folder:</i>
<a href=""
tal:attributes="href home/absolute_url"
tal:content="home/absolute_url">Folder</a>
</li>
<li>
<i>Email:</i>
<a href=""
tal:define="email userObj/email"
tal:attributes="href string:mailto:$email"
tal:content="email">Email</a>
</li>
<li>
<i>Last login time:</i>
<span tal:replace="userObj/last_login_time" />
</li>
</ul>
</td>
</tr>
</table>
</div>
</body>
</html>
Page Template: test_context
An example Page Template showing the contexts
<html><head />
<body>
<h1>Debug information</h1>
<h2>CONTEXTS</h2>
<ul>
<tal:block
tal:repeat="item CONTEXTS">
<li
tal:condition="python: item != 'request'"
tal:define="context CONTEXTS;">
<b tal:content="item" />
<span tal:replace="python: context[item]" />
</li>
</tal:block>
</ul>
<h2>REQUEST</h2>
<p tal:replace="structure request" />
</body>
</html>
Page Template: user_info
A more advanced version of the user information Page Template
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US"lang="en-US"
i18n:domain="plone"
metal:use-macro="here/main_template/macros/master">
<body>
<div metal:fill-slot="main">
<tal:block
tal:define="
getPortrait nocall: here/portal_membership/getPersonalPortrait;
getFolder nocall: here/portal_membership/getHomeFolder
">
<table>
<tal:block
tal:repeat="userObj here/portal_membership/listMembers">
<metal:block
metal:use-macro="here/user_section/macros/userSection" />
</tal:block>
</table>
</tal:block>
</div>
</body>
</html>
Page Template: user_section
The macro for displaying each user's information.
<div metal:define-macro="userSection"tal:define="userName userObj/getUserName">
<tr>
<td>
<img src=""
tal:replace="structure python: getPortrait(userName)" />
</td>
<td tal:define="prop nocall: userObj/getProperty">
<ul>
<li>
<i>Username:</i>
<span tal:replace="userName" />
</li>
<li>
<i>Full name:</i>
<span tal:replace="python: prop('fullname')" />
</li>
<li
tal:define="home python: getFolder(userName)"
tal:condition="home">
<a href=""
tal:attributes="href home/absolute_url">Home Folder</a>
</li>
<li>
<i>Email:</i>
<a href=""
tal:define="email python: prop('email')"
tal:attributes="href string:mailto:$email"
tal:content="email">Email</a>
</li>
<li>
<i>Last login time:</i>
<span tal:replace="python: prop('last_login_time')" />
</li>
</ul>
</td>
</tr>
</div>
Python: zpt.py
A script to syntax check Page Templates, without having to load it into Plone.
#!/usr/bin/pythonfrom Products.PageTemplates.PageTemplate import PageTemplate
import sys
def test(file):
raw_data = open(file, 'r').read()
pt = PageTemplate()
pt.write(raw_data)
if pt._v_errors:
print "*** Error in:", file
for error in pt._v_errors[1:]:
print error
if __name__=='__main__':
if len(sys.argv) < 2:
print "python check.py file [files...]"
sys.exit(1)
else:
for arg in sys.argv[1:]:
test(arg)
Page Template: google_ad_portlet
A portlet for showing Google ads.
<div metal:define-macro="portlet"><div class="portlet">
<script type="text/javascript"><!--
google_ad_client = "yourUniqueValue";
google_ad_width = 120;
google_ad_height = 600;
google_ad_format = "120x600_as";
//--></script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>
</div>
Script Python: recentlyChanged
A script that examines all objects passed to the script and then find out what is new.
##title=recentlyChanged##parameters=objects
from DateTime import DateTime
now = DateTime()
difference = 5 # as in 5 days
result = []
for object in objects:
diff = now - object.bobobase_modification_time()
if diff < difference:
dct = {"object":object,"diff":int(diff)}
result.append(dct)
return result
External Method: readFile
An External Method that reads a file from the file server
def readFile(self):fh = open(r'c:\Program Files\Plone\Data\Extensions\README.txt', 'rb')
data = fh.read()
return data
Validator Script: validEmail
A script to validate email
email = context.REQUEST.get('email_address', None)if not email:
state.setError('email_address', 'An email address is required', new_status='failure')
if state.getErrors():
state.set(portal_status_message='Please correct the errors shown.')
return state
Controller Python Script: sendEmail
A send email script
mhost = context.MailHostemailAddress = context.REQUEST.get('email_address')
administratorEmailAddress = context.email_from_address
comments = context.REQUEST.get('comments')
# the message format, %s will be filled in from data
message = """
From: %s
To: %s
Subject: Website Feedback
%s
URL: %s
"""
# format the message
message = message % (
emailAddress,
administratorEmailAddress,
comments,
context.absolute_url())
mhost.send(message)
screenMsg = "Comments sent, thank you."
state.setKwargs( {'portal_status_message':screenMsg} )
return state
Page Template: feedbackForm
A form for providing feedback to users.
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US"lang="en-US" i18n:domain="plone"
metal:use-macro="here/main_template/macros/master">
<body>
<div metal:fill-slot="main"
tal:define="errors options/state/getErrors;">
<p>Please send us any feedback you might have about the
site.</p>
<form method="post" tal:attributes="action template/id;">
<fieldset>
<legend class="legend"
i18n:translate="legend_feedback_form">Website
Feedback</legend>
<div class="field"
tal:define="error_email_address errors/email_address|nothing;"
tal:attributes="class python:test(error_email_address, 'field error', 'field')">
<label i18n:translate="label_email_address">Your email
address</label>
<span class="fieldRequired" title="Required"
i18n:attributes="title"
i18n:translate="label_required">(Required)</span>
<div class="formHelp"
i18n:translate="label_email_address_help">Enter your
email address.</div>
<div tal:condition="error_email_address">
<tal:block i18n:translate=""
content="error_email_address">Error</tal:block>
</div>
<input type="text" name="email_address"
tal:attributes="tabindex tabindex/next; value request/email_address|nothing" />
</div>
<div class="field">
<label i18n:translate="label_feedback_comments">
Comments</label>
<div class="formHelp" id="label_feedback_comments_help"
i18n:translate="label_feedback_comments_help">Enter the
comments you have about the site.</div>
<textarea name="comments" rows="10"
tal:content="request/comments|nothing"
tal:attributes="tabindex tabindex/next;" />
</div>
<div class="formControls">
<input class="context" type="submit" tabindex=""
name="form.button.Submit" value="Submit"
i18n:attributes="value"
tal:attributes="tabindex tabindex/next;" />
</div>
</fieldset>
<input type="hidden" name="form.submitted" value="1" />
</form>
</div>
</body>
</html>
CSS: ploneCustom.css
NASA Maestro CSS
body {background: #343434;
}
#visual-portal-wrapper {
width: 680px;
margin: 1em auto 0 auto;
}
#portal-top {
background: url("/header.jpg") transparent no-repeat;
padding: 162px 0 0 0;
position: relative;
}
#portal-logo {
background: transparent;
background-image: none;
margin: 0;
position: absolute;
top: 130px;
left: 5px;
z-index: 20;
}
#portal-logo a {
padding-top: 25px;
height /**/: 25px;
width: 375px;
}
#portal-globalnav {
background: url("/listspacer.gif") transparent;
padding: 0;
height: 21px;
border: 0;
margin: 0 0 1px 6px;
clear: both;
}
#portal-globalnav li {
display: block;
float: left;
height: 21px;
background: url("/liststart.gif") transparent no-repeat;
padding: 0 0 0 33px;
margin: 0 0.5em 0 0;
}
#portal-globalnav li a {
display: block;
float: left;
height: 21px;
background: url("/listitem.gif") transparent right top;
padding: 0 33px 0 0;
border: 0;
line-height: 2em;
color: black;
font-size: 90%;
margin: 0;
}
#portal-globalnav li a:hover,
#portal-globalnav li.selected a {
background-color: transparent;
border: 0;
color: #444;
}
#portal-personaltools {
clear: both;
margin-left: 6px;
border-top-color: #776a44;
border-top-style: solid;
border-top-width: 1px;
}
#portal-breadcrumbs {
clear: both;
}
#portal-breadcrumbs,
#portal-columns,
.documentContent {
background: white;
margin-left: 6px;
}
.documentContent {
margin: 0;
font-size: 100%;
}
.screenshotThumb {
float:right;
}
#portal-footer {
margin: -1px 0 0 6px;
padding: 0.8em 0;
border: 1px solid #ddd;
border-style: solid none none none;
background: white;
color: #666;
font-size: 90%;
}
#portal-footer a {
color: #333;
text-decoration: underline;
}
dt {
color: #ECA200;
}
.documentDescription {
font-size: 110%;
}
#portal-breadcrumbs img {
display: none;
}
li.reqlist {
margin-top: 0;
margin-bottom: 0;
}
Script (Python): mail.py
Mail a message to all reviewers in a site
##parameters=state_change# the objects we need
object = state_change.object
mship = context.portal_membership
mhost = context.MailHost
# the message format, %s will be filled in from data
message = """
From: noreply@yourwebsite.com
To: %s
Subject: New item submitted for approval - %s
%s
URL: %s
"""
for user in mship.listMembers():
if "Reviewer" in mship.getMemberById(user.id).getRoles():
if user.email:
msg = message % (
user.email,
object.TitleOrId(),
object.Description(),
object.absolute_url()
)
mhost.send(msg)
External Method: importUsers
This script runs through a CSV file and adds in users based on that information.
# An external method to import userimport csv
# the full path to your csv file
fileName = "/var/zope.zeo/Extensions/test.csv"
def importUsers(self):
reader = csv.reader(open(fileName, "r"))
pr = self.portal_registration
pg = self.portal_groups
out = []
# if your csv file contains a header line that
# explains the contents of each column
ignoreLine = 1
for row in reader:
if ignoreLine:
ignoreLine = 0
continue
# check we have exactly 4 items
assert len(row) == 4
id, name, email, groups = row
groups = groups.split(',')
# make a password
password = pr.generatePassword()
try:
# add in member
pr.addMember(id = id,
password = password,
roles = ["Member",],
properties = {
'fullname': name,
'username': id,
'email': email,
}
)
# groups are separated by commas
for groupId in groups:
group = pg.getGroupById(groupId)
group.addMember(id)
out.append("Added user %s" % id)
except ValueError, msg:
# if we skipped this user for a reason, tell the person
out.append("Skipped %s, reason: %s" % (id, msg))
# return something
return "\n".join(out)
External Method: fixUsers
A script that runs through all the users and sets the editor property to Epoz.
def fixUsers(self):pm = self.portal_membership
members = pm.listMemberIds()
out = []
for member in members:
# now get the actual member
m = pm.getMemberById(member)
# get the editor property for that member
p = m.getProperty('wysiwyg_editor', None)
out.append("%s %s" % (p, member))
if p is not None and p != 'Epoz':
m.setMemberProperties({'wysiwyg_editor': 'Epoz',})
out.append("Changed property for %s" % member)
return "\n".join(out)
Script (Python): getGroups
A script to get all the ousers in the group for an object
##parameters=object=None# object is the object to find all the members of the same group for
users = []
# get the creator
userName = object.Creator()
user = context.portal_membership.getMemberById(userName)
pg = context.portal_groups
# loop through the groups the user is in
for group in user.getGroups():
group = pg.getGroupById(group)
# loop through the users in each of those groups
for user in group.getGroupUsers():
if user not in users and user != userName:
users.append(user)
return users
Script (Python): scriptObjectCreation
A script to generate content types programmatically.
##title=Create##parameters=
# create with a random id
newId = context.generateUniqueId('Folder')
# create a object of type Folder
context.invokeFactory(id=newId, type_name='Folder')
newFolder = getattr(context, newId)
# create a new Document type
newFolder.invokeFactory(id='index.html', type_name='Document')
# get the new page
newPage = getattr(newFolder, 'index.html')
newPage.edit('html', '<p>This is the default page.</p>')
# return something back to the calling script
return "Done"
Script (Python): getCatalogResults
A script to search the catalog
##title=Get Catalog Results##parameters=
return context.portal_catalog.searchResults(REQUEST=context.REQUEST)
Page Template: testResults
A page to show the results
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US"lang="en-US"
metal:use-macro="here/main_template/macros/master"
i18n:domain="plone">
<body>
<div metal:fill-slot="main">
<ul tal:define="results here/getCatalogResults">
<li tal:repeat="result results">
<a href=""
tal:attributes="href result/getURL"
tal:content="result/Title" />
<span tal:replace="result/Description" />
</li>
</ul>
</div>
</body>
</html>
Page Template: testForm
A form to search the internet
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US"lang="en-US"
metal:use-macro="here/main_template/macros/master"
i18n:domain="plone">
<body>
<div metal:fill-slot="main">
<p>Select a content type to search for</p>
<form method="post" action="testResults">
<select name="Type">
<option tal:repeat="value python:here.portal_catalog.uniqueValuesFor('Type')" tal:content="value" />
</select>
<br />
<input type="submit" class="context">
</form>
</div>
</body>
</html>
Python: header.py
A script that reads the headers of a web page, useful for testing caching.
#!/usr/bin/pythonimport sys
from httplib import HTTP
from urlparse import urlparse
def getHeaders(url, method):
p = list(urlparse(url))
if not p[0]:
url = 'http://' + url
p = list(urlparse(url))
h = HTTP(p[1])
h.putrequest(method, p[2])
h.putheader('Accept-Encoding', 'gzip, deflate')
h.endheaders()
reply = h.getreply()
print "Status:", reply[0]
print "Status message:", reply[1]
hdrs = reply[2].headers
hdrs.sort()
for header in hdrs:
print header[:-1]
def usage():
print """Usage: headers.py URL [method]
URL - the URL to get headers for, http:// default
method - GET default
"""
sys.exit()
if __name__=='__main__':
if len(sys.argv) < 2: usage()
method = 'GET'
if len(sys.argv) > 2:
method = sys.argv[2]
getHeaders(sys.argv[1], method)