mirror of https://github.com/tLDP/LDP
CMFTypes implementation.
This commit is contained in:
parent
04f818eefa
commit
91c41866c2
|
@ -0,0 +1,23 @@
|
|||
#from Products.CMFTypes.Extensions.utils import installTypes
|
||||
from Products.Lampadas.Extensions.utils import installTypes
|
||||
from Products.Lampadas import listTypes
|
||||
from StringIO import StringIO
|
||||
|
||||
PKG_NAME='Lampadas'
|
||||
|
||||
def install(self):
|
||||
out=StringIO()
|
||||
|
||||
if not hasattr(self, "_isPortalRoot"):
|
||||
print >> out, "Must be installed in a CMF Site (read Plone)"
|
||||
return
|
||||
|
||||
print >> out, "Installing %s into %s" % (listTypes(), PKG_NAME)
|
||||
|
||||
installTypes(self, out, listTypes(), PKG_NAME)
|
||||
print >> out, 'Successfully installed Lampadas content types.'
|
||||
|
||||
print >> out, 'Successfully installed %s ' % PKG_NAME
|
||||
|
||||
return out.getvalue()
|
||||
|
|
@ -0,0 +1,150 @@
|
|||
from Products.CMFCore.TypesTool import FactoryTypeInformation
|
||||
from Products.CMFCore.DirectoryView import addDirectoryViews, registerDirectory, createDirectoryView
|
||||
from Products.CMFCore.utils import getToolByName
|
||||
from Products.CMFTypes.debug import log, log_exc
|
||||
from Products.CMFTypes.utils import findDict
|
||||
from Products.CMFTypes import types_globals
|
||||
import sys, traceback
|
||||
|
||||
PRODUCT_NAME = 'Lampadas'
|
||||
SKIN_NAME = "cmft"
|
||||
|
||||
def install_tool(self, out):
|
||||
if not hasattr(self, "content_tool"):
|
||||
addTool = self.manage_addProduct[PRODUCT_NAME].manage_addTool
|
||||
addTool(PRODUCT_NAME + ' Content Tool')
|
||||
|
||||
#and the tool uses an index
|
||||
catalog = getToolByName(self, 'portal_catalog')
|
||||
try:
|
||||
catalog.addIndex('UID', 'FieldIndex', extra=None)
|
||||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
if not 'UID' in catalog.schema():
|
||||
catalog.addColumn('UID')
|
||||
except:
|
||||
print >> out, ''.join(traceback.format_exception(*sys.exc_info()))
|
||||
print >> out, "Problem updating catalog for UIDs"
|
||||
|
||||
#reindex the objects already in the system
|
||||
#this might be an 'update' and not an install
|
||||
ct = getToolByName(self, "content_tool")
|
||||
ct.index()
|
||||
try:
|
||||
catalog.manage_reindexIndex(ids=('UID',))
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
def install_subskin(self, out, skin_name=SKIN_NAME, globals=types_globals):
|
||||
skinstool=getToolByName(self, 'portal_skins')
|
||||
if skin_name not in skinstool.objectIds():
|
||||
addDirectoryViews(skinstool, 'skins', globals)
|
||||
|
||||
for skinName in skinstool.getSkinSelections():
|
||||
path = skinstool.getSkinPath(skinName)
|
||||
path = [i.strip() for i in path.split(',')]
|
||||
try:
|
||||
if skin_name not in path:
|
||||
path.insert(path.index('custom') +1, skin_name)
|
||||
except ValueError:
|
||||
if skin_name not in path:
|
||||
path.append(skin_name)
|
||||
|
||||
path = ','.join(path)
|
||||
skinstool.addSkinSelection( skinName, path)
|
||||
|
||||
|
||||
def install_types(self, out, types, package_name):
|
||||
typesTool = getToolByName(self, 'portal_types')
|
||||
for type in types:
|
||||
try:
|
||||
typesTool._delObject(type.__name__)
|
||||
except:
|
||||
pass
|
||||
typesTool.manage_addTypeInformation(FactoryTypeInformation.meta_type,
|
||||
id=type.__name__,
|
||||
typeinfo_name="%s: %s" %(package_name, type.__name__))
|
||||
# set the human readable title explicitly
|
||||
t = getattr(typesTool, type.__name__, None)
|
||||
if t:
|
||||
t.title = type.portal_type
|
||||
|
||||
|
||||
def install_validation(self, out, types, metadatatype):
|
||||
form_tool = getToolByName(self, 'portal_form')
|
||||
for type in types:
|
||||
key = type.meta_type.lower()
|
||||
form_tool.setValidators("%s_edit_form" % key, ['validate_id', 'validate_%s_edit' % key])
|
||||
|
||||
#And the metadata handler
|
||||
if metadatatype:
|
||||
form_tool.setValidators("%s_edit_form" % metadatatype.__name__.lower(), [])
|
||||
else:
|
||||
form_tool.setValidators("extensiblemetadata_edit_form", [])
|
||||
|
||||
#And references
|
||||
form_tool.setValidators('reference_edit', [])
|
||||
|
||||
def install_navigation(self, out, types, metadatatype):
|
||||
nav_tool = getToolByName(self, 'portal_navigation')
|
||||
|
||||
#Generic
|
||||
script = "content_edit"
|
||||
nav_tool.addTransitionFor('default', script , 'failure', 'action:edit')
|
||||
nav_tool.addTransitionFor('default', script, 'success', 'action:view')
|
||||
|
||||
#Metadata handling
|
||||
if metadatatype:
|
||||
mdname = metadatatype.__name__.lower()
|
||||
else:
|
||||
mdname = "extensiblemetadata"
|
||||
|
||||
nav_tool.addTransitionFor('default', '%s_edit_form' % mdname, 'failure', '%s_edit_form' % mdname)
|
||||
nav_tool.addTransitionFor('default', '%s_edit_form' % mdname, 'success', 'script:content_edit')
|
||||
|
||||
#Type Specific
|
||||
for type in types:
|
||||
key = type.meta_type.lower()
|
||||
page = "%s_edit_form" % key
|
||||
nav_tool.addTransitionFor('default', page, 'success', 'script:%s' % script)
|
||||
nav_tool.addTransitionFor('default', page, 'failure', page)
|
||||
|
||||
#And References
|
||||
nav_tool.addTransitionFor('default', 'reference_edit', 'success', 'pasteReference')
|
||||
nav_tool.addTransitionFor('default', 'reference_edit', 'failure', 'url:reference_edit')
|
||||
|
||||
def install_actions(self, out, types, metadatatype=None):
|
||||
typesTool = getToolByName(self, 'portal_types')
|
||||
for type in types:
|
||||
typeInfo = getattr(typesTool, type.__name__)
|
||||
if hasattr(type,'actions'):
|
||||
#Look for each action we define in type.actions
|
||||
#in typeInfo.action replacing it if its there and
|
||||
#just adding it if not
|
||||
new = list(typeInfo._actions)
|
||||
for action in type.actions:
|
||||
hit = findDict(typeInfo._actions, 'id', action['id'])
|
||||
if hit:
|
||||
hit.update(action)
|
||||
else:
|
||||
new.append(action)
|
||||
typeInfo._actions = tuple(new)
|
||||
|
||||
if hasattr(type,'factory_type_information'):
|
||||
typeInfo.__dict__.update(type.factory_type_information)
|
||||
typeInfo._p_changed = 1
|
||||
|
||||
|
||||
def installTypes(self, out, types, package_name, metadatatype=None):
|
||||
"""Use this for your site with your types"""
|
||||
print 'Installing types: %s', types, ' into ', package_name
|
||||
install_tool(self, out)
|
||||
install_subskin(self, out)
|
||||
install_types(self, out, types, package_name)
|
||||
install_validation(self, out, types, metadatatype)
|
||||
install_navigation(self, out, types, metadatatype)
|
||||
install_actions(self, out, types, metadatatype)
|
||||
|
|
@ -0,0 +1,222 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
|
@ -0,0 +1,34 @@
|
|||
modprefix = /usr/lib/zope/lib/python/Products
|
||||
mod = $(modprefix)/Lampadas
|
||||
|
||||
INSTALLDIR = install -d
|
||||
INSTALLMOD = install -p -m 644
|
||||
|
||||
all: build
|
||||
|
||||
build:
|
||||
|
||||
install: all
|
||||
rm -rf $(mod)
|
||||
$(INSTALLDIR) $(mod)
|
||||
cp -rp * $(mod)
|
||||
|
||||
uninstall:
|
||||
rm -rf $(mod)
|
||||
|
||||
clean:
|
||||
rm -f *.pyc
|
||||
|
||||
debug:
|
||||
zopectl stop
|
||||
zopectl start -D
|
||||
|
||||
start:
|
||||
zopectl start
|
||||
|
||||
restart:
|
||||
zopectl restart
|
||||
|
||||
stop:
|
||||
zopectl stop
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
|
||||
This is Lampadas, a set of CMF Content objects which will help you
|
||||
build a website to manage and publish documentation.
|
||||
|
||||
It works by providing a set of CMFTypes that provide the specific
|
||||
functionality. These types support complete OMF meta-data.
|
||||
|
||||
The Lampadas Document class is derived from the example DDocument
|
||||
class in the CMFTypes code.
|
||||
|
||||
REQUIRES:
|
||||
Plone 1.0a4+
|
||||
CMF 1.3
|
||||
Zope 2.5.1
|
||||
|
||||
Optional:
|
||||
on win32: win32 extensions
|
||||
http://starship.python.net/crew/mhammond/win32/Downloads.html
|
||||
|
||||
on linux: a wvWare installer
|
||||
http://download.sourceforge.net/wvware/
|
||||
|
||||
|
||||
Quickstart:
|
||||
|
||||
Add an external method to your plone site and then click its
|
||||
test tab
|
||||
|
||||
Id: LampadasInstall
|
||||
Title: Lampadas installer
|
||||
Module: Lampadas.Install
|
||||
Function: install
|
||||
|
||||
This should install everything you need and will also register the
|
||||
content objects with the portal_types tool.
|
||||
|
||||
Good luck.
|
||||
|
||||
|
||||
This README contains text from the README in the CVSTypes product.
|
|
@ -0,0 +1,43 @@
|
|||
from Products.CMFTypes import process_types
|
||||
from Products.CMFTypes.Generator import generateViews
|
||||
from Products.CMFTypes.utils import pathFor
|
||||
from Products.CMFTypes.ExtensibleMetadata import ExtensibleMetadata
|
||||
from Globals import package_home
|
||||
|
||||
from Products.CMFCore.utils import ContentInit
|
||||
import os, os.path
|
||||
|
||||
ADD_CONTENT_PERMISSION = 'Add portal content'
|
||||
PROJECT_NAME = 'Lampadas'
|
||||
|
||||
_types = {}
|
||||
|
||||
def registerType(type):
|
||||
print 'Registering %s meta_type in Lampadas' % type.meta_type
|
||||
_types[type.meta_type] = type
|
||||
|
||||
def listTypes():
|
||||
return _types.values()
|
||||
|
||||
def initialize(context):
|
||||
import cmf_types
|
||||
|
||||
print 'Initializing Lampadas product.'
|
||||
print 'dir() is ', dir()
|
||||
print 'dir(cmf_types) is ', dir(cmf_types)
|
||||
|
||||
homedir = package_home(globals())
|
||||
#edit_dir = view_dir = os.path.join(homedir, 'skins', 'project_views')
|
||||
#script_dir = os.path.join(homedir, 'skins', 'project_scripts')
|
||||
|
||||
content_types, constructors, ftis = process_types(listTypes(),
|
||||
"Lampadas",
|
||||
metadatatype=ExtensibleMetadata)
|
||||
ContentInit(
|
||||
PROJECT_NAME + ' Content',
|
||||
content_types = content_types,
|
||||
permission = ADD_CONTENT_PERMISSION,
|
||||
extra_constructors = constructors,
|
||||
fti = ftis,
|
||||
).initialize(context)
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
from AccessControl import ClassSecurityInfo
|
||||
#from Products.CMFTypes import registerType
|
||||
from Products.Lampadas import registerType
|
||||
from Products.CMFTypes.BaseContent import BaseContent
|
||||
from Products.CMFTypes.ExtensibleMetadata import ExtensibleMetadata
|
||||
from Products.CMFTypes.Field import *
|
||||
from Products.CMFTypes.Form import *
|
||||
from Products.CMFTypes.debug import log
|
||||
|
||||
|
||||
def addDDocument(self, id, **kwargs):
|
||||
o = DDocument(id, **kwargs)
|
||||
self._setObject(id, o)
|
||||
|
||||
class DDocument(BaseContent):
|
||||
"""An extensible Document (test) type"""
|
||||
|
||||
portal_type = meta_type = "DDocument"
|
||||
|
||||
type = BaseContent.type + FieldList((
|
||||
Field('teaser',
|
||||
searchable=1,
|
||||
form_info=TextAreaInfo(description="A short lead-in to the article so that we might get people to read the body",
|
||||
label="Teaser",
|
||||
rows=3)),
|
||||
Field('author'),
|
||||
Field('body',
|
||||
required=1,
|
||||
searchable=1,
|
||||
allowable_content_types=('text/plain', 'text/structured', 'text/html', 'application/msword'),
|
||||
form_info=RichFormInfo(description="Enter a valid body for this document. This is what you will see",
|
||||
label="Body Text",
|
||||
)),
|
||||
|
||||
IntegerField("number", form_info=IntegerInfo(), default=42),
|
||||
|
||||
Field('image', form_info=FileInfo()),
|
||||
|
||||
# SlotField("about",
|
||||
# form_info=SlotInfo(slot_metal="here/about_slot/macros/aboutBox",
|
||||
# )),
|
||||
))
|
||||
|
||||
|
||||
registerType(DDocument)
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
from AccessControl import ClassSecurityInfo
|
||||
#from Products.CMFTypes import registerType
|
||||
from Products.Lampadas import registerType
|
||||
from Products.CMFTypes.BaseContent import BaseContent
|
||||
from Products.CMFTypes.ExtensibleMetadata import ExtensibleMetadata
|
||||
from Products.CMFTypes.Field import *
|
||||
from Products.CMFTypes.Form import *
|
||||
from Products.CMFTypes.debug import log
|
||||
|
||||
|
||||
def addFact(self, id, **kwargs):
|
||||
o = Fact(id, **kwargs)
|
||||
self._setObject(id, o)
|
||||
|
||||
class Fact(BaseContent):
|
||||
"""A quoteable fact or tidbit"""
|
||||
portal_type = meta_type = "Fact"
|
||||
|
||||
type = BaseContent.type + FieldList((
|
||||
Field('quote',
|
||||
searchable=1,
|
||||
required=1,
|
||||
form_info=StringInfo(description="What are you quoting, what is the fact",
|
||||
label="Quote",
|
||||
)),
|
||||
|
||||
LinesField('sources', form_info=LinesInfo()),
|
||||
|
||||
Field('footnote',
|
||||
required=1,
|
||||
form_info = TextAreaInfo(description="The full footnot for this fact/quote")),
|
||||
|
||||
DateTimeField('fact_date',
|
||||
form_info=DateTimeInfo(description="When does this fact originate from",
|
||||
label="Date")),
|
||||
|
||||
Field('url',
|
||||
form_info=LinkInfo(description="When does this fact originate from",
|
||||
label="URL")),
|
||||
|
||||
))
|
||||
|
||||
registerType(Fact)
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
import DDocument
|
||||
import Fact
|
||||
#import DFolder
|
|
@ -0,0 +1,2 @@
|
|||
Refresh works with this product, but if you use this as a factory you might
|
||||
have to refresh both this and the product that is using it.
|
|
@ -0,0 +1,25 @@
|
|||
## Script (Python) "collectKeywords"
|
||||
##title=Edit content
|
||||
##bind container=container
|
||||
##bind context=context
|
||||
##bind namespace=
|
||||
##bind script=script
|
||||
##bind subpath=traverse_subpath
|
||||
##parameters=name, index
|
||||
REQUEST=context.REQUEST
|
||||
|
||||
field = context.getField(name)
|
||||
|
||||
allowed = field.Vocabulary(context)
|
||||
enforce = field.enforceVocabulary
|
||||
|
||||
previous = container.portal_catalog.uniqueValuesFor(index)
|
||||
|
||||
if enforce:
|
||||
result = allowed
|
||||
else:
|
||||
result = allowed + previous
|
||||
|
||||
|
||||
result = result.sortedByValue()
|
||||
return result
|
|
@ -0,0 +1,51 @@
|
|||
## Script (Python) "content_edit"
|
||||
##title=Edit content
|
||||
##bind container=container
|
||||
##bind context=context
|
||||
##bind namespace=
|
||||
##bind script=script
|
||||
##bind subpath=traverse_subpath
|
||||
##parameters=id=''
|
||||
REQUEST=context.REQUEST
|
||||
args = {}
|
||||
formatted = {}
|
||||
|
||||
#new_context = context.portal_factory.doCreate(context, id, **args)
|
||||
|
||||
## Look for things with text_formatting
|
||||
for key, value in REQUEST.form.items():
|
||||
if key.endswith("_text_format"): ##FRAGILE, depends on template
|
||||
formatted[key[:-12]] = value
|
||||
else:
|
||||
if key.endswith("_text"):
|
||||
args[key[:-5]] = value
|
||||
else:
|
||||
args[key] = value
|
||||
|
||||
## Pull anything with a file passed in, removing any formatting refs from before
|
||||
for key, value in REQUEST.form.items():
|
||||
if key.endswith("_file"):
|
||||
filename = getattr(value, 'filename', '')
|
||||
if filename != '':
|
||||
value.seek(0)
|
||||
#new_context.set(key[:-5], value)
|
||||
context.set(key[:-5], value)
|
||||
#Remove other formatting associated with this key
|
||||
if formatted.has_key(key[:-5]):
|
||||
del formatted[key[:-5]]
|
||||
del args[key[:-5]]
|
||||
|
||||
#Set Anything complex up and remove it from the simple set
|
||||
for key in formatted.keys():
|
||||
#Set things with content types
|
||||
#new_context.set(key, args[key], formatted[key])
|
||||
context.set(key, args[key], formatted[key])
|
||||
del args[key]
|
||||
|
||||
## EDIT the remaining fields
|
||||
|
||||
#new_context.edit(**args)
|
||||
context.edit(**args)
|
||||
|
||||
#return ('success', new_context, {'portal_status_message':context.REQUEST.get('portal_status_message', 'Content changes saved.')})
|
||||
return ('success', context, {'portal_status_message':context.REQUEST.get('portal_status_message', 'Content changes saved.')})
|
|
@ -0,0 +1,14 @@
|
|||
## Script (Python) "deleteRef"
|
||||
##title=Delete a reference
|
||||
##bind container=container
|
||||
##bind context=context
|
||||
##bind namespace=
|
||||
##bind script=script
|
||||
##bind subpath=traverse_subpath
|
||||
##parameters=oid, tid
|
||||
REQUEST=context.REQUEST
|
||||
|
||||
ct = context.content_tool
|
||||
ct.deleteReference(oid, tid)
|
||||
|
||||
return REQUEST.RESPONSE.redirect("%s/reference_edit" % ct.getObject(oid).absolute_url())
|
|
@ -0,0 +1,84 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US"
|
||||
lang="en-US"
|
||||
metal:use-macro="here/main_template/macros/master">
|
||||
<body>
|
||||
|
||||
<div metal:fill-slot="main"
|
||||
tal:define="rejection here/rejectAnonymous;
|
||||
errors python:request.get('errors', {});
|
||||
Iterator python:modules['Products.CMFPlone'].IndexIterator;
|
||||
ct here/content_tool;
|
||||
tabindex python:Iterator();">
|
||||
|
||||
|
||||
<form class="group"
|
||||
name="edit_form"
|
||||
action="content_edit"
|
||||
method="post"
|
||||
enctype="multipart/form-data"
|
||||
tal:attributes="action request/URL"
|
||||
>
|
||||
|
||||
<table class="listing"
|
||||
summary="Object References"
|
||||
cellpadding="0" cellspacing="0" width="100%">
|
||||
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
<span class="header" i18n:translate="">Referencing</span>
|
||||
</th>
|
||||
<th>
|
||||
<span class="header" i18n:translate="">Referenced By</span>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td width="65%">
|
||||
<table border="0" width="100%">
|
||||
<tbody>
|
||||
<tr tal:repeat="ref python:ct.getRefs(here)">
|
||||
<td><a href="#" tal:attributes="href python:ct.getObject(ref).absolute_url() + '/reference_edit';"
|
||||
tal:content="python: ct.getObject(ref).Title()"/>
|
||||
</td>
|
||||
<td>
|
||||
<font color="#f00000"><a href="#" tal:attributes="href string:${here/absolute_url}/deleteRef?oid=${here/UID}&tid=${ref};">X</a></font>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
<td>
|
||||
<span tal:repeat="ref python:ct.getBRefs(here)">
|
||||
<a href="#" tal:attributes="href python:ct.getObject(ref).absolute_url() + '/reference_edit';"
|
||||
tal:content="python: ct.getObject(ref).Title()"/><br/>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
</table>
|
||||
|
||||
<div class="row" tal:condition="here/cb_dataValid">
|
||||
<input class="context"
|
||||
type="submit"
|
||||
name="pasteReference"
|
||||
value="reference"
|
||||
tabindex=""
|
||||
i18n:attributes="value"
|
||||
tal:attributes="tabindex tabindex/next;" />
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Copy objects from folders and then click the reference button. This will create references.
|
||||
</p>
|
||||
<input type="hidden" name="form_submitted" value="1" tal:attributes="value template/id" />
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
Binary file not shown.
After Width: | Height: | Size: 346 B |
|
@ -0,0 +1,2 @@
|
|||
0.0.16
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>Zope</title>
|
||||
<link rel="stylesheet" type="text/css" href="/manage_page_style.css">
|
||||
|
||||
</head>
|
||||
<body bgcolor="#ffffff" link="#000099" alink="#000099" vlink="#000099">
|
||||
|
||||
<div class="form-title">
|
||||
View Contents
|
||||
</div>
|
||||
|
||||
<div class="form-help">
|
||||
This is the list of context ids
|
||||
</div>
|
||||
|
||||
<table>
|
||||
<tr tal:repeat="object here/Content">
|
||||
<td tal:define="uid python:object[0]; url python: object[1].absolute_url();">
|
||||
<a href="#" tal:attributes="href url" tal:content="uid"/>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -24,8 +24,8 @@ from Products.CMFCore.utils import getToolByName
|
|||
from Products.PloneCVSFile import factory_type_information
|
||||
from Products.CMFCore.TypesTool import ContentFactoryMetadata
|
||||
from Products.CMFCore.DirectoryView import addDirectoryViews
|
||||
from Products.PloneCVSFile import cfm_cvs_globals
|
||||
from Defaults import META_TYPE, PORTAL_TYPE
|
||||
from Products.PloneCVSFile import cmf_cvsfile_globals
|
||||
from Products.PloneCVSFile.Defaults import META_TYPE, PORTAL_TYPE
|
||||
from ZODB.PersistentMapping import PersistentMapping
|
||||
import string
|
||||
|
||||
|
@ -37,6 +37,9 @@ def install(self):
|
|||
typestool = getToolByName(self, 'portal_types')
|
||||
skinstool = getToolByName(self, 'portal_skins')
|
||||
workflowtool = getToolByName(self, 'portal_workflow')
|
||||
|
||||
out.write('factory_type_information:\n')
|
||||
out.write(str(factory_type_information))
|
||||
|
||||
# Borrowed from CMFDefault.Portal.PortalGenerator.setupTypes()
|
||||
# We loop through anything defined in the factory type information
|
||||
|
@ -56,7 +59,7 @@ def install(self):
|
|||
# We need to add Filesystem Directory Views for any directories
|
||||
# in our skins/ directory. These directories should already be
|
||||
# configured.
|
||||
addDirectoryViews(skinstool, 'skins', cfm_cvs_globals)
|
||||
addDirectoryViews(skinstool, 'skins', cmf_cvsfile_globals)
|
||||
out.write("Added 'lampadas' directory view to portal_skins\n")
|
||||
|
||||
# Now we need to go through the skin configurations and insert
|
||||
|
|
|
@ -3,6 +3,10 @@ mod = $(modprefix)/PloneCVSFile
|
|||
dtml = $(mod)/dtml
|
||||
www = $(mod)/www
|
||||
skins = $(mod)/skins
|
||||
content = $(mod)/skins/lampadas_content/
|
||||
forms = $(mod)/skins/lampadas_forms/
|
||||
templates = $(mod)/skins/lampadas_templates/
|
||||
slots = $(mod)/skins/lampadas_templates/ui_slots
|
||||
ext = $(mod)/Extensions
|
||||
|
||||
INSTALLDIR = install -d
|
||||
|
@ -35,12 +39,26 @@ install: all
|
|||
|
||||
$(INSTALLDIR) $(www)
|
||||
$(INSTALLMOD) www/fish.gif $(www)
|
||||
$(INSTALLMOD) www/logo.png $(www)
|
||||
|
||||
$(INSTALLDIR) $(skins)
|
||||
$(INSTALLMOD) skins/lampadas_templates/file_edit_form $(skins)
|
||||
|
||||
$(INSTALLDIR) $(content)
|
||||
$(INSTALLMOD) skins/lampadas_content/file_edit_form.pt $(content)
|
||||
$(INSTALLMOD) skins/lampadas_content/file_view.pt $(content)
|
||||
|
||||
$(INSTALLDIR) $(forms)
|
||||
$(INSTALLMOD) skins/lampadas_forms/folder_listing.pt $(forms)
|
||||
|
||||
$(INSTALLDIR) $(templates)
|
||||
$(INSTALLMOD) skins/lampadas_templates/header.pt $(templates)
|
||||
$(INSTALLMOD) skins/lampadas_templates/news.pt $(templates)
|
||||
|
||||
$(INSTALLDIR) $(slots)
|
||||
$(INSTALLMOD) skins/lampadas_templates/ui_slots/news_slot.pt $(slots)
|
||||
|
||||
$(INSTALLDIR) $(ext)
|
||||
$(INSTALLMOD) ext/CMFCVSInstall.py $(ext)
|
||||
$(INSTALLMOD) Extensions/CMFCVSInstall.py $(ext)
|
||||
|
||||
uninstall:
|
||||
rm -rf $(mod)
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
from Products.CMFDefault import Portal
|
||||
|
||||
import PloneCVSFile
|
||||
|
||||
from Products.CVSFile.CVSSandboxRegistry import manage_addCVSSandboxRegistryForm, \
|
||||
|
@ -10,8 +12,6 @@ from Products.ExternalFile.CreationDialog import manage_add_via_gui, \
|
|||
from Products.CMFCore.DirectoryView import registerDirectory
|
||||
from Products.CMFCore import utils, CMFCorePermissions
|
||||
|
||||
from Products.CMFDefault import Portal
|
||||
|
||||
from OMF import OMF
|
||||
from Defaults import META_TYPE
|
||||
|
||||
|
@ -50,7 +50,7 @@ this_module = sys.modules[__name__]
|
|||
|
||||
z_bases = utils.initializeBasesPhase1(bases, this_module)
|
||||
|
||||
cfm_cvsfile_globals = globals()
|
||||
cmf_cvsfile_globals = globals()
|
||||
registerDirectory('skins', globals())
|
||||
|
||||
def initialize(context):
|
||||
|
|
|
@ -17,20 +17,6 @@
|
|||
<div class="description"
|
||||
tal:content="structure here/Description"> description </div>
|
||||
|
||||
<div tal:condition="python:not getattr(here.aq_explicit, 'index_html', None) and
|
||||
here.portal_membership.checkPermission('Add portal content', here)">
|
||||
<p>
|
||||
<span i18n:translate="description_no_default_folder">
|
||||
This folder does not have a default page, therefore a list of items
|
||||
is shown instead.
|
||||
If you want to create a default page in this folder that will
|
||||
replace the item listing,
|
||||
</span>
|
||||
<a href="#" tal:attributes="href string:${here/absolute_url}/invokeFactory?id=index_html&type_name=Document"
|
||||
i18n:translate="description_create_folder_click_here">click here.</a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
<a href=""
|
||||
tal:define="parent_url python:here.navigationParent(here, template.getId());"
|
||||
|
@ -79,6 +65,20 @@
|
|||
There are currently no items in this folder.
|
||||
</p>
|
||||
|
||||
<div tal:condition="python:not getattr(here.aq_explicit, 'index_html', None) and
|
||||
here.portal_membership.checkPermission('Add portal content', here)">
|
||||
<p>
|
||||
<span i18n:translate="description_no_default_folder">
|
||||
This folder does not have a default page, therefore a list of items
|
||||
is shown instead.
|
||||
If you want to create a default page in this folder that will
|
||||
replace the item listing,
|
||||
</span>
|
||||
<a href="#" tal:attributes="href string:${here/absolute_url}/invokeFactory?id=index_html&type_name=Document"
|
||||
i18n:translate="description_create_folder_click_here">click here.</a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
0.0.21
|
||||
0.0.22
|
||||
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 1.5 KiB |
|
@ -5,11 +5,12 @@ This module instantiates data managers for all database tables.
|
|||
"""
|
||||
|
||||
import datamanager
|
||||
import datamanager.datamanagers
|
||||
import persistence
|
||||
import dataset
|
||||
from datamanager.cache import CACHE_UNLIMITED
|
||||
|
||||
dms = datamanager.DataManagers()
|
||||
dms = datamanager.datamanagers.DataManagers()
|
||||
dms.set_objects(persistence)
|
||||
dms.set_datasets(dataset)
|
||||
|
||||
|
|
|
@ -355,6 +355,7 @@ class State:
|
|||
self.session = None
|
||||
self.user = None
|
||||
self.static = 0
|
||||
self.uri = None
|
||||
|
||||
|
||||
state = State()
|
||||
|
|
|
@ -30,6 +30,7 @@ import urlparse
|
|||
import os
|
||||
import string
|
||||
|
||||
from Globals import WOStringIO
|
||||
from CoreDM import dms
|
||||
|
||||
# Only load this once. No need to support adding languages during runtime!
|
||||
|
@ -129,8 +130,8 @@ class URI:
|
|||
|
||||
page = dms.page.get_by_id(self.page_code)
|
||||
if page==None:
|
||||
print "ERROR"
|
||||
self.printdebug()
|
||||
print "ERROR: page not found."
|
||||
self.print_debug()
|
||||
return
|
||||
|
||||
# If the page specifies that it includes an object,
|
||||
|
@ -160,29 +161,34 @@ class URI:
|
|||
self.filename = string.join(data, '/')
|
||||
break
|
||||
|
||||
def printdebug(self):
|
||||
print "URI: [%s]" % self.uri
|
||||
print "Base: [%s]" % self.base
|
||||
print "Protocol: [%s]" % self.protocol
|
||||
print "Server: [%s]" % self.server
|
||||
print "Port: [%s]" % self.port
|
||||
print "Path: [%s]" % self.path
|
||||
print "Page Code: [%s]" % self.page_code
|
||||
print "Page Data: [%s]" % self.page_data
|
||||
print "Language: [%s]" % self.lang
|
||||
print "Language Extension: [%s]" % self.lang_ext
|
||||
print "Parameter: [%s]" % self.parameter
|
||||
print "Anchor: [%s]" % self.anchor
|
||||
print "ID: [%s]" % self.id
|
||||
print "Code [%s]" % self.code
|
||||
print "Letter: [%s]" % self.letter
|
||||
print "Username: [%s]" % self.username
|
||||
print "Filename: [%s]" % self.filename
|
||||
print "Data: [%s]" % self.data
|
||||
def print_debug(self):
|
||||
print self.debug_info()
|
||||
|
||||
def debug_info(self):
|
||||
info = WOStringIO()
|
||||
info.write("URI: [%s]\n" % self.uri)
|
||||
info.write("Base: [%s]\n" % self.base)
|
||||
info.write("Protocol: [%s]\n" % self.protocol)
|
||||
info.write("Server: [%s]\n" % self.server)
|
||||
info.write("Port: [%s]\n" % self.port)
|
||||
info.write("Path: [%s]\n" % self.path)
|
||||
info.write("Page Code: [%s]\n" % self.page_code)
|
||||
info.write("Page Data: [%s]\n" % self.page_data)
|
||||
info.write("Language: [%s]\n" % self.lang)
|
||||
info.write("Language Extension: [%s]\n" % self.lang_ext)
|
||||
info.write("Parameter: [%s]\n" % self.parameter)
|
||||
info.write("Anchor: [%s]\n" % self.anchor)
|
||||
info.write("ID: [%s]\n" % self.id)
|
||||
info.write("Code [%s]\n" % self.code)
|
||||
info.write("Letter: [%s]\n" % self.letter)
|
||||
info.write("Username: [%s]\n" % self.username)
|
||||
info.write("Filename: [%s]\n" % self.filename)
|
||||
info.write("Data: [%s]\n" % self.data)
|
||||
return info.get_value()
|
||||
|
||||
|
||||
if __name__=='__main__':
|
||||
import sys
|
||||
|
||||
foo = URI(sys.argv[1])
|
||||
foo.printdebug()
|
||||
foo.print_debug()
|
||||
|
|
Loading…
Reference in New Issue