Plone:(原型)使新闻项目和事件变得文件夹化
Plone: (Archetypes) Make News Item and Event to be folderish
我知道我可以使用 collective.folderishtypes 添加要使用的新类型(文件夹),而不是默认的新闻项目和事件。但我想将现有的新闻项目和事件转换为文件夹内容类型,并使其尽可能简单。是否有可能以一种简单的方式覆盖(猴子修补?)默认类型(结果是现有对象具有文件夹行为)?
或者解决这个问题的好方法是什么?我也只需要解决现有的对象,并且不要混淆重复的内容类型,例如:添加新的新闻项目、新闻项目文件夹...等等。另外,如果可能的话,保持现有列表(如最新事件)的工作。
我没有测试过这个,但是基于 collective.folderishtypes
documentation ("How to migrate non-folderishtypes to folderish ones") 你应该能够在你的 Plone 站点根目录上调用 @@migrate-btrees
视图将非文件夹内容类型迁移到文件夹内容类型。
警告:在尝试迁移之前备份数据库,并在将其应用于生产数据之前先在开发环境中进行测试。
我没有使用 collective.folderish 的经验,不过描述听起来很有希望,可惜它似乎不适合你。
如果我需要解决这个问题并且不是保留历史记录的要求(工作流程和content-history),我会创建一个新的文件夹类型使用相同的字段,为每个事件和新闻创建一个新类型的实例并将 field-values 复制过来。
这会改变 modification-date,但可以通过将 mod-date 复制到 publication-date-field(如果尚未使用)并执行 'Latest news/events'-listings 来克服collections 按 pub-date.
排序
但是如果你想保留历史并且让 mod-date 保持不变,你可以为每个 news/event-item 创建一个文件夹,将项目放入文件夹,将项目设置为 default-view文件夹并将文件夹重命名为与项目相同的 ID。这将使文件夹和项目在 UI 中显示为一个项目,并且指向该项目的链接不会中断,因为文件夹位于目标位置。
我用 browser-view-script 测试了这个。 las,由于我无法在短时间内找到原因,添加文件夹并将项目移动到一个 script-run 中是行不通的。所以需要调用 browser-view 三次:
from Acquisition import aq_parent, aq_inner
from Products.Five.browser import BrowserView
class View(BrowserView):
report = ''
def __call__(self):
portal = self.context
catalog = portal.portal_catalog
news_items = catalog.searchResults(portal_type='News Item')
event_items = catalog.searchResults(portal_type='Event')
items = news_items + event_items
for i, item in enumerate(items):
self.processItem(item, i, len(items))
return self.report
def processItem(self, item, i, itemsAmount):
item = item.getObject()
item_id = item.id
parent = aq_parent(aq_inner(item))
folder = None
folder_id = item_id + '-container'
if item_id == parent.id:
if i == itemsAmount-1: self.report += '\
Nothing to do, all ' + str(itemsAmount) + ' items have the same id as their parent.'
else:
if parent.id == folder_id:
parent = getParent(parent)
folder = parent[folder_id]
folder.setDefaultPage(item_id)
parent.manage_renameObject(folder.id, item_id)
if i == itemsAmount-1: self.report += '\
Step 3/3: Renamed ' + str(itemsAmount) + ' folder-ids.'
else:
try:
folder = addFolder(parent, folder_id)
if i == itemsAmount-1: self.report += '\
Step 1/3: Added ' + str(itemsAmount) + ' folders.'
folder.setTitle(item_id) # set same title as item has
folder.reindexObject()
except:
folder = parent[folder_id]
try:
cutAndPaste(item, folder)
if i == itemsAmount-1: self.report += '\
Step 2/3: Moved ' + str(itemsAmount) + ' items into folders.'
except:
pass
def addFolder(parent, folder_id):
parent.invokeFactory('Folder', folder_id)
folder = parent[folder_id]
folder.setTitle(folder_id)
folder.reindexObject()
return folder
def cutAndPaste(item, folder):
""" Move item into folder. """
parent = aq_parent(aq_inner(item))
clipboard = parent.manage_cutObjects([item.id])
folder.manage_pasteObjects(clipboard)
folder.reindexObject()
def getParent(item):
return aq_parent(aq_inner(item))
免责声明:
- 每次创建新的 event/news-item 时,您也需要执行此过程,其中 event-listener.
- 最好为流程的每个步骤创建新的 event-listener,并在上一步结束后开始下一个步骤。
- 假定文件夹的 temporary-id(由 item-id 和任意后缀“-container”组成)不存在于项目的 parent 中。虽然这不太可能发生,但您可能也想在脚本中捕获该异常。
我知道我可以使用 collective.folderishtypes 添加要使用的新类型(文件夹),而不是默认的新闻项目和事件。但我想将现有的新闻项目和事件转换为文件夹内容类型,并使其尽可能简单。是否有可能以一种简单的方式覆盖(猴子修补?)默认类型(结果是现有对象具有文件夹行为)?
或者解决这个问题的好方法是什么?我也只需要解决现有的对象,并且不要混淆重复的内容类型,例如:添加新的新闻项目、新闻项目文件夹...等等。另外,如果可能的话,保持现有列表(如最新事件)的工作。
我没有测试过这个,但是基于 collective.folderishtypes
documentation ("How to migrate non-folderishtypes to folderish ones") 你应该能够在你的 Plone 站点根目录上调用 @@migrate-btrees
视图将非文件夹内容类型迁移到文件夹内容类型。
警告:在尝试迁移之前备份数据库,并在将其应用于生产数据之前先在开发环境中进行测试。
我没有使用 collective.folderish 的经验,不过描述听起来很有希望,可惜它似乎不适合你。
如果我需要解决这个问题并且不是保留历史记录的要求(工作流程和content-history),我会创建一个新的文件夹类型使用相同的字段,为每个事件和新闻创建一个新类型的实例并将 field-values 复制过来。
这会改变 modification-date,但可以通过将 mod-date 复制到 publication-date-field(如果尚未使用)并执行 'Latest news/events'-listings 来克服collections 按 pub-date.
排序但是如果你想保留历史并且让 mod-date 保持不变,你可以为每个 news/event-item 创建一个文件夹,将项目放入文件夹,将项目设置为 default-view文件夹并将文件夹重命名为与项目相同的 ID。这将使文件夹和项目在 UI 中显示为一个项目,并且指向该项目的链接不会中断,因为文件夹位于目标位置。
我用 browser-view-script 测试了这个。 las,由于我无法在短时间内找到原因,添加文件夹并将项目移动到一个 script-run 中是行不通的。所以需要调用 browser-view 三次:
from Acquisition import aq_parent, aq_inner
from Products.Five.browser import BrowserView
class View(BrowserView):
report = ''
def __call__(self):
portal = self.context
catalog = portal.portal_catalog
news_items = catalog.searchResults(portal_type='News Item')
event_items = catalog.searchResults(portal_type='Event')
items = news_items + event_items
for i, item in enumerate(items):
self.processItem(item, i, len(items))
return self.report
def processItem(self, item, i, itemsAmount):
item = item.getObject()
item_id = item.id
parent = aq_parent(aq_inner(item))
folder = None
folder_id = item_id + '-container'
if item_id == parent.id:
if i == itemsAmount-1: self.report += '\
Nothing to do, all ' + str(itemsAmount) + ' items have the same id as their parent.'
else:
if parent.id == folder_id:
parent = getParent(parent)
folder = parent[folder_id]
folder.setDefaultPage(item_id)
parent.manage_renameObject(folder.id, item_id)
if i == itemsAmount-1: self.report += '\
Step 3/3: Renamed ' + str(itemsAmount) + ' folder-ids.'
else:
try:
folder = addFolder(parent, folder_id)
if i == itemsAmount-1: self.report += '\
Step 1/3: Added ' + str(itemsAmount) + ' folders.'
folder.setTitle(item_id) # set same title as item has
folder.reindexObject()
except:
folder = parent[folder_id]
try:
cutAndPaste(item, folder)
if i == itemsAmount-1: self.report += '\
Step 2/3: Moved ' + str(itemsAmount) + ' items into folders.'
except:
pass
def addFolder(parent, folder_id):
parent.invokeFactory('Folder', folder_id)
folder = parent[folder_id]
folder.setTitle(folder_id)
folder.reindexObject()
return folder
def cutAndPaste(item, folder):
""" Move item into folder. """
parent = aq_parent(aq_inner(item))
clipboard = parent.manage_cutObjects([item.id])
folder.manage_pasteObjects(clipboard)
folder.reindexObject()
def getParent(item):
return aq_parent(aq_inner(item))
免责声明:
- 每次创建新的 event/news-item 时,您也需要执行此过程,其中 event-listener.
- 最好为流程的每个步骤创建新的 event-listener,并在上一步结束后开始下一个步骤。
- 假定文件夹的 temporary-id(由 item-id 和任意后缀“-container”组成)不存在于项目的 parent 中。虽然这不太可能发生,但您可能也想在脚本中捕获该异常。