Commit 26e7a3da authored by Andreas Jung's avatar Andreas Jung

removed the ZopeTutorial

parent 9b8ecc03
......@@ -26,6 +26,8 @@ Zope Changes
Features added
- removed ZopeTutorial (Elvis is now really dead)
- ZClasses are deprecated and should no longer be used.
- ZGadyFlyDA/Gadfly is deprecated
......
......@@ -67,17 +67,6 @@ web applications.
</p>
</li>
<li>
<p>
There is a built-in interactive <strong>Zope Tutorial</strong> which
gets you started with some simple tasks using the Zope managment
interface. To use the tutorial, go to any Folder and select
<em>Zope Tutorial</em> from the add list and click the <em>Add</em>
button. Provide a name for the tutorial and click <em>Add</em> to
begin working with the tutorial.
</p>
</li>
<li>
<p>
<a href="manage_importObject?file=Examples.zexp&amp;set_owner:int=1">Import</a>
......@@ -90,8 +79,8 @@ applications that you can copy and modify.
<li>
<p>
Go to the main <a href="http://www.zope.org/Documentation/" target="_new">
Documentation Overview</a> on Zope.org. Here you will find pointers to
official and community contributed documentation.
Documentation Overview</a> on <a href="http://www.zope.org" target="_new">Zope.org</a>.
Here you will find pointers to official and community contributed documentation.
</p>
</li>
......
Zope Tutorial 1.2
Bug Fixes
* Fix niglet in step 7.
Zope Tutorial 1.1
Features
* Updates lessions to use ZPT in place of DTML. This required
extensive reworking in some lessons.
* Update the examples .zexp file.
* Updated likes to the Zope book to refer to the current online
version.
* Updated the glossary.
* Added a ZPT reference link feature for the glossary.
Zope Tutorial 1.0a6
Bug Fixes
* Rearranged things a bit for 2.2 release.
* Improved missing cookie behavior.
* Improved descriptions of management screen navigation.
* Many typos and nits fixed in lessons and examples.
Known Limitations
* Requires Zope 2.1.6 or higher.
* Works better with HTTP cookies.
Zope Tutorial 1.0a5
Features
* Changed the way examples are installed. Now the examples are
installed by adding a Zope object. This resolves a lot of security
issues.
* Added some preliminary API docs, and an API documentation
infrastructure.
Bug Fixes
* Miscellaneous restructuring and fixing.
Known Limitations
* Requires Zope 2.1.6 or higher.
* Requires HTTP cookies.
Zope Tutorial 1.0a4
Features
* Added an introduction.
* Improved installation location and verification.
Bug Fixes
* More information about how to navigate between management
screens.
* Many typos fixed thanks to Karl Ulbrich.
Known Bugs
* Requires Zope 2.1.6 or higher.
Zope Tutorial 1.0a3
Features
* Glossary greatly improved and linked into lessons.
Bug Fixes
* Install now correctly sets up gadfly database.
* Some DTML typos fixed thanks to Didier Georgieff.
Known Bugs
* Requires Zope 2.1.6 or higher.
Zope Tutorial 1.0a2
Features
* Improved PRE formatting. Examples now look nice.
* Improved examples navigation, no longer requires Javascript.
* Added more information to the glossary.
* Added feedback link.
Bug Fixes
* Grammar and typo fixes.
Known Bugs
* Requires Zope 2.1.6 or higher.
Zope Tutorial 1.0a1
Initial preview release.
\ No newline at end of file
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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
#
##############################################################################
import OFS.Folder
from HelpSys.HelpTopic import TextTopic
from Globals import HTML, DTMLFile, MessageDialog
from cgi import escape
import DateTime
import DocumentTemplate
import StructuredText
import re
pre_pat=re.compile(r'<PRE>(.+?)</PRE>', re.IGNORECASE|re.DOTALL)
tutorialExamplesFile='ZopeTutorialExamples.zexp'
class TutorialTopic(TextTopic):
"""
A Tutorial Help Topic
"""
def __init__(self, id, title, text):
self.id=id
self.title=title
text=str(StructuredText.HTML(text))
self.obj=HTML(pre_pat.sub(clean_pre, text))
index_html=DTMLFile('dtml/lessonView', globals())
def checkInstallation(self, REQUEST):
"""
Returns false if the tutorial examples are not correctly
installed. Also sets the 'hide_next' variable in the request
if the examples are not installed.
"""
ok=0
if REQUEST.has_key('tutorialExamplesURL'):
url=REQUEST['tutorialExamplesURL']
base=REQUEST['BASE1']
if url.index(base) == 0:
url=url[len(base):]
try:
self.getPhysicalRoot().unrestrictedTraverse(url)
ok=1
except:
pass
if not ok:
REQUEST.set('hide_next', 1)
return ok
def lessonURL(self, id, REQUEST):
"""
URL of the examples for a lesson
"""
try:
return '%s/lesson%d' % (REQUEST['tutorialExamplesURL'], id)
except KeyError:
return ""
def tutorialShowLesson(self, id, REQUEST):
"""
Navigate management frame to a given lesson's screen.
"""
url=self.lessonURL(id, REQUEST)
if not url or not self.checkInstallation(REQUEST):
REQUEST.set('hide_next', 0)
return """\
<p class="warning">
Zope cannot find the tutorial examples.
You should install the tutorial examples before
continuing. Choose "Zope Tutorial" from the product
add list in the Zope management screen to install
the examples.
</p>
<p class="warning">
If you have already installed the tutorial, you can either
follow along manually, or reinstall the tutorial examples.
Note: make sure that you have cookies turned on in your browser.
</p>
"""
return """\
<SCRIPT LANGUAGE="javascript">
<!--
window.open("%s/manage_main", "manage_main");
//-->
</SCRIPT>
<p class="information">
<a href="%s/manage_main" target="manage_main"
onClick="javascript:window.open('%s/manage_main', 'manage_main').focus()"
>Show lesson examples</a> in another window.
</p>""" % (url.replace('"', '\\"'), escape(url, 1),
escape(url, 1).replace("'", "\\'"))
tutorialNavigation=DTMLFile('dtml/tutorialNav', globals())
class GlossaryTopic(TutorialTopic):
"""
A Tutorial Glossary Help Topic
"""
def __init__(self, id, title, text):
self.id=id
self.title=title
self.obj=HTML(text)
index_html=DTMLFile('dtml/glossaryView', globals())
def formatted_content(self, REQUEST):
"""
Custom stx formatting for tutorial topics
"""
text=self.obj(self, REQUEST)
text=str(StructuredText.HTML(text))
pre_pat.sub(clean_pre, text)
return text
def apiLink(self, klass, REQUEST):
"""
Returns the URL to a API documentation for a given class.
"""
names=klass.split('.')
url="%s/Control_Panel/Products/%s/Help/%s.py#%s" % (REQUEST['SCRIPT_NAME'],
names[0], names[1], names[2])
return '<a href="%s">API Documentation</a>' % url
def dtmlLink(self, tag, REQUEST):
"""
Returns the URL to a DTML Reference page for a given tag.
"""
url="%s/Control_Panel/Products/OFSP/Help/dtml-%s.stx" % (REQUEST['SCRIPT_NAME'], tag)
return '<a href="%s">DTML Reference</a>' % url
def zptLink(self, tag, REQUEST):
"""
Returns the URL to a ZPT Reference page for a given topic.
"""
url="%s/Control_Panel/Products/PageTemplates/Help/%s.stx" % (REQUEST['SCRIPT_NAME'], tag)
return '<a href="%s">ZPT Reference</a>' % url
addTutorialForm=DTMLFile('dtml/tutorialAdd', globals())
def addTutorial(self, id, REQUEST=None, RESPONSE=None):
"""
Install tutorial examples.
"""
id=str(id)
ob=OFS.Folder.Folder()
ob.id=id
ob.title='Zope Tutorial Examples'
id=self._setObject(id, ob)
folder=getattr(self, id)
# make sure that Gadfly is initialized
try:
from Products.ZGadflyDA.DA import data_sources
data_sources()
except:
raise 'Bad Request', 'The ZGadflyDA product must be installed!'
# work around old Zope bug in importing
try:
folder.manage_importObject(tutorialExamplesFile)
except:
folder._p_jar=self.Destination()._p_jar
folder.manage_importObject(tutorialExamplesFile)
# acquire REQUEST if necessary
if REQUEST is None:
REQUEST=self.REQUEST
# Set local roles on examples
changeOwner(folder, REQUEST['AUTHENTICATED_USER'])
# Run lesson setup methods -- call Setup.setup methods in lesson folders
examples=folder.examples
for lesson in examples.objectValues():
if hasattr(lesson, 'Setup'):
lesson.Setup.setup(lesson.Setup, REQUEST)
if RESPONSE is not None:
e=(DateTime.DateTime('GMT') + 365).rfc822()
RESPONSE.setCookie('tutorialExamplesURL', folder.absolute_url() + '/examples',
path='/',
expires=e)
RESPONSE.redirect(folder.absolute_url() + '/examples')
def changeOwner(obj, owner):
"""
Recursively changes the Owner of an object and all its subobjects.
"""
for user, roles in obj.get_local_roles():
if 'Owner' in roles:
obj.manage_delLocalRoles([user])
break
obj.manage_setLocalRoles(owner.getId(), ['Owner'])
for subobj in obj.objectValues():
changeOwner(subobj, owner)
def clean_pre(match):
"""
Reformat a pre tag to get rid of extra indentation
and extra blank lines.
"""
lines=match.group(1).split('\n')
nlines=[]
min_indent=None
for line in lines:
indent=len(line) - len(line.lstrip())
if min_indent is None or indent < min_indent:
if line.strip():
min_indent=indent
for line in lines:
nlines.append(line[min_indent:])
while 1:
if not nlines[0].strip():
nlines.pop(0)
else:
break
while 1:
if not nlines[-1].strip():
nlines.pop()
else:
break
return "<PRE>%s</PRE>" % '\n'.join(nlines)
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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
#
##############################################################################
import TutorialTopic
import App.Common
import os.path
import os
import stat
from DateTime import DateTime
from urllib import quote_plus
from cgi import escape
import re
from HelpSys import APIHelpTopic
def initialize(context):
# abuse registerClass to get a tutorial constructor
# in the product add list
context.registerClass(
None,
meta_type='Zope Tutorial',
constructors=(TutorialTopic.addTutorialForm, TutorialTopic.addTutorial),
)
from App.Product import doInstall
if not doInstall():
return
# create tutorial help topics
lesson_path=os.path.join(App.Common.package_home(globals()), 'tutorial.stx')
glossary_path=os.path.join(App.Common.package_home(globals()), 'glossary.stx')
help=context.getProductHelp()
# test to see if nothing has changed since last registration
if help.lastRegistered is not None and \
help.lastRegistered >= DateTime(os.stat(lesson_path)[stat.ST_MTIME]):
return
help.lastRegistered=DateTime()
# delete old help topics
for id in help.objectIds('Help Topic'):
help._delObject(id)
# create glossary
text=open(glossary_path).read()
text=term_pat.sub(defineTerm, text)
glossary=TutorialTopic.GlossaryTopic('tutorialGlossary',
'Zope Tutorial Glossary', text)
context.registerHelpTopic('tutorialGlossary', glossary)
# create lessons
f=open(lesson_path)
lines=[]
id=0
while 1:
line = f.readline()
if (line.strip() and line.find(' ') != 0) or line=='':
# new topic
if lines:
id = id + 1
topic_id = 'topic_%02d' % id
text=''.join(lines[1:])
text=term_pat.sub(glossaryTerm, text)
topic=TutorialTopic.TutorialTopic(topic_id, lines[0].strip(), spacestrip(text))
context.registerHelpTopic(topic_id, topic)
lines=[line]
else:
lines.append(line)
if line == '':
break
f.close()
def spacestrip(txt):
""" dedent text by 2 spaces !
We need this to workaround a nasty bug in STXNG.
STXNG creates empty <pre>..</pre> when then text start
if a level > 1. This fix is lame. The problem should be fixed
inside STXNG
"""
l = []
for x in txt.split("\n"):
if len(x)>2 and x[:2]==' ':
l.append(x[2:])
else: l.append(x)
return '\n'.join(l)
# Glossary functions
# ----------------
term_pat=re.compile('\[(.*?)\]')
terms=[]
def glossaryTerm(match):
"""
A linked glossary term
"""
name=match.group(1)
if name in terms:
return """<a href="../tutorialGlossary#%s">%s</a>""" % \
(quote_plus(name), escape(name))
return """[%s]""" % name
def defineTerm(match):
"""
Define a glossary term
"""
name=match.group(1)
terms.append(name)
return """<a name="%s"></a>\n\n<strong>%s</strong>""" % \
(quote_plus(name), escape(name))
<dtml-var standard_html_header>
<style type="text/css">
PRE {
background-color : #FFFFAA;
border : thin solid;
white-space : pre;
padding-bottom : 10pt;
padding-left : 10pt;
padding-right : 10pt;
padding-top : 10pt;
}
.feedback {
font-size: 9pt;
}
.warning {
font-size: 9pt;
font-weight: bold;
color: red;
}
.information {
font-size: 9pt;
font-weight: bold;
}
</style>
<h2>&dtml-title;</h2>
<dtml-var expr="formatted_content(REQUEST)">
<p class="feedback">Comments on this lesson?
<a href="mailto:zdp@zope.org?subject=&dtml.url_quote_plus-title;">Email feedback</a>.
</p>
<dtml-var standard_html_footer>
<dtml-var standard_html_header>
<style type="text/css">
PRE {
background-color : #FFFFAA;
border : thin solid;
white-space : pre;
padding-bottom : 10pt;
padding-left : 10pt;
padding-right : 10pt;
padding-top : 10pt;
}
.feedback {
font-size: 9pt;
}
.warning {
font-size: 9pt;
font-weight: bold;
color: red;
}
.information {
font-size: 9pt;
font-weight: bold;
}
</style>
<h2>&dtml-title;</h2>
<dtml-var obj>
<hr>
<dtml-var tutorialNavigation>
<dtml-var standard_html_footer>
<dtml-var manage_page_header>
<dtml-var "manage_form_title(this(), _,
form_title='Add Zope Tutorial',
)">
<p class="form-help">
This tutorial show you the basics of using Zope. You will
learn how to create and manage Zope resources by builting
a web site devoted to tracking Elvis sightings. Each lesson
includes working examples in Zope that allow you to learn
by hands on experimentation.
</p>
<p class="form-help">
The tutorial assumes that you are familiar with basic Internet
technologies such as <a href="http://www.w3.org/MarkUp/Guide/">HTML</a>,
URLs, and web browers.
</p>
<form action="addTutorial" method="post">
<table cellspacing="0" cellpadding="2" border="0">
<tr>
<td align="left" valign="top">
<div class="form-label">
Id
</div>
</td>
<td align="left" valign="top">
<input type="text" name="id" size="40" value="" />
</td>
</tr>
<tr>
<td align="left" valign="top">
</td>
<td align="left" valign="top">
<div class="form-element">
<input class="form-element" type="submit" name="submit"
value=" Add " />
</div>
</td>
</tr>
</table>
</form>
<dtml-var manage_page_footer>
<dtml-unless "id=='tutorialGlossary'">
<dtml-call "REQUEST.set('ids', aq_parent.objectIds())">
<dtml-call "ids.remove('tutorialGlossary')">
<dtml-call "REQUEST.set('i', ids.index(id))">
<table width="100%" border="0" padding="0" spacing="0">
<tr valign="top"><td width="50%" align="right">
<dtml-if "i > 0">
<form action="../<dtml-var "ids[i-1]" url_quote>">
<div class="form-element">
<input class="form-element" type="submit" value=" &lt; Back ">
</div>
</form>
</dtml-if>
</td>
<td width="50%">
<dtml-unless hide_next>
<dtml-if "i < _.len(ids) -1 ">
<form action="../<dtml-var "ids[i+1]" url_quote>">
<div class="form-element">
<input class="form-element" type="submit" value=" Next &gt; ">
</div>
</form>
</dtml-if>
</dtml-unless>
</td></tr></table>
</dtml-unless>
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment