Skip to content. | Skip to navigation

Personal tools

Navigation

You are here: Home / Tips / Content Type

Content Type

Content Type 稱為「內容型別」,或以 Type 和「型別」簡稱之,它以表單形式模擬日常工作的流程。對程式員而言,它是內容管理系統的核心工具,善用內容型別的特性,能夠處理多數的實務工作。

透過型別所建立的物件 (object) 在系統裡稱為項目 (item),像 front-page 首頁是 Page 型別的項目,像 news 目錄裡被新增的每一則新聞,就是 News Item 型別的項目。以一則新聞為例,分析它的內容架構,發現包含有 1) 標題 2) 報導者 3) 發佈時間 4) 新聞內容 等項目,程式員可以把這些項目設計成欄位,以便填寫和顯示,把這樣的設計流程予以規範,我們稱為內容型別框架,目的是方便開發者建立客製化的內容型別。

不過,Plone 世界裡並不是只有一套內容型別框架,在 Plone 5 之前,廣被使用的是 Archetypes 框架,以 AT 當作縮寫字,例如 ATContentType 模組,從名稱就提示它是採用 Archetypes 框架。由於 Archetypes 在功能及效能上都有些侷限,新的 Dexterity 框架在 Plone 5 之際取代了 Archetypes,一般也用 DX 當作縮寫字。

註:兩者的比較,可參考 David Glick 在 PloneConf 2010 PSM 2010 的簡報,Zejc Zupan 的效能實測

預設內容型別

Plone 預設提供的內容型別包括:Page, News Item, Event, Image, File, Link, Folder, Collection,在 4.x 版本裡,它們使用 Archetypes Framework 建置而成,在 5.x 版本後,它們使用 Dexterity Framework 建置而成,型別定義在 plone.app.contenttypes/content.py 裡。大抵分成 Folderish 和 Non-Folderish 兩類型別,預設的呈現邏輯不同。下拉選單的程式邏輯由 plone.app.contentmenu 提供。型別的名稱,技術上可以使用空白,像 News Item 這樣,但實務上會造成困擾

內容型別框架的優點

內容型別至少提供下列的好處:

  • 自動產生表單的編輯和顯示畫面。
  • 提供內建的 Field/Widget/Validator 函式庫。
  • 提供 Reference 機制,協助建立內容之間的關聯。

即使內容型別框架無法解決所有類型的問題,它也能夠有效滿足八成應用場合的需求,實務上,我們會先利用內容型別框架處理主要的核心問題,再考慮開發週邊的流程功能。

基礎型別與繼承關係

如果預設內容型別無法滿足實際需求,程式員可以依據原型定義來擴充,建立自製的型別。在 plone.dexterity/content.py 裡,找得到 Item 和 Container 型別定義,它們是預設型別的原型。

plone.app.content 提供 helper base class,可用來建立基本內容型別,像是 container 或 item,以此基礎,可以再建立預設或客製的內容型別。plone.app.content 也提供 folder_contents、tableview、NameChooser、INameFromTitle 之類的服務。

Default View

Dublin Core 和 Type 資訊可以顯示在 Header 裡,可能成為安全漏洞,移除 DocString 是種變通方法。

File to view or download

deafult MIME type Magic Show

Locally Allowed Types

根目錄之外的子目錄,能夠個別指定預設可被新增的內容型別。我們可以局面修改型別的欄位或功能,甚至建置全新的內容型別,以滿足應用程式的實際需求。

想要控制哪些型別可以被新增

your_folder.setLocallyAllowedTypes(['Image'])
your_folder.setConstrainTypesMode(1)

Short Name Renaming

每個項目都會擁有識別碼 (Id),它是構成項目網址的一部份,例如 /mysite/news/news-item-1 這樣的網址,其中 news-item-1 就是項目的識別碼。

識別碼的決定方式,通常和標題文字有關,例如標題內容 My First Item 文字,儲存後的項目識別碼會是 my-first-item。

有些字元是不允許的 bad_id=re.compile(r'[^a-zA-Z0-9-_~,.$\(\)# @]').search

Normalizing Unicode Text to Filename

Renaming Content

folder.manage_renameObject(old_id, new_id)

http://plone.293351.n2.nabble.com/File-object-migration-how-to-change-id-of-new-object-programatically-2-5-5-td4174543.html

Assign ID When Editing Dexterity Types

Archetype Automatic ID Rename after Title Change

Remove Preference Settings and Assign on the Settings tab

Get Rid of .html on ID: collective.googlenews Site Map Three Digit

Change ID Accordingly When Unpublished

Content Quality 通常可透過 Spelling 或 Link Integrity 檢查來維護。

Icon

修改圖示

navigation: 取消圖檔的預設顯示

Programmatically Adding / Updating

批次建立型別項目的方法,可以分成 Permission-aware 和 Permission-bypassing 兩類,也可以依 Dexterity 和 Archetypes 使用不同的工具,在 Creating Objects Updating Objects 文件裡有詳細說明。

Python Script Creating Content When Installing

Dexterity Container and Items

Image

Creating Pattern

Add Dexterity Support: collective.documentviewer

class IMyFile(model.Schema, IFile)

When you clone ttw, I guess it uses class plone.dexterity.content.Item in the fti? You can enable documentviewer on all dexterity content types in this case, in one of your module configure.zcml, you can add:

<class class="plone.dexterity.content.Item">
  <implements interface="plone.app.contenttypes.interfaces.IFile" />
</class>

don't need plone.app.contenttypes at all:

<field name="myfile" marshal:primary="true"
       type="plone.namedfile.field.NamedBlobFile">

新增 Content Type 定義後,除了重新啟用之外,還可以從 portal_setup 的 Import 選擇執行模組的 Types Tool: Import types tool's type information objects. Products.CMFCore.exportimport.typeinfo.importTypesTool 步驟。

預設是選定目錄位置後,再新增項目,但有人提出新增流程的調整建議

Migration

Archetype News Item to Dexterity

開發中的 plone.app.contenttypes 目的是取代 ATContentTypes,透過 plone.app.contenttypes 能讓模組支援 Dexterity 型別,不過 revision 並沒有被保留。如果昇級遇到 document_view AttributeError: widget 可試 @@fix_base_classes。

安裝 plone.app.contenttypes 要注意版本及相依模組的關係,其中 plone.app.event 版本也要依據 Plone 4.2 (1.0.x) Plone 4.3 (1.1.x 或 1.2.x) 或 Plone 5.x (2.0.x) 來選定 KGS,Plone 4.3.3 搭配 Products.GenericSetup 1.7.4,但 plone.app.contenttypes 1.1b4 開始要求 Products.GenericSetup 1.7.5 以上,這在 Plone 4.3.4 預設才有滿足。安裝 Plone 4.3.10 預設的 versions.cfg 已指定合適的相依版本,直接 eggs += plone.app.contenttypes 就會安裝 1.1.1 版本,如果需要安裝 plone.app.widgets 已指定 1.8.0 版本。

接下來,依據是否需要 plone.app.widgets 套件,來決定 plone.app.event 的版本。完全不需要 p.a.widgets 的話,可指定 p.a.event 1.1.4 版本,在 develop.cfg 裡 [versions] plone.app.event = 1.1.4 就行。想要安裝 p.a.widgets 的話,又分 1.5.x 和 1.7.x 兩種版本。

plone.app.event 1.1.x 開始要求 plone.app.portlets >= 2.5.1 <3.0 版本。在 plone.app.event 1.2.x 正式穩定前,想要搭配 plone.app.widgets (1.5.x) 的話,必須使用它的 versions.cfg 和 github 程式碼,或是使用 Plone 4.3.x (例 4.3.6) 搭配 p.a.contenttypes 1.1.x (必要時,要檢查 setup.py 取消 p.a.event 的版本限制) p.a.event 1.2.x plone.app.widgets 1.x (例 1.8.0) 的組合。

Plone  p.a.contenttypes p.a.event p.a.portlets p.a.jquery p.a.widgets
4.2                     1.0.x
4.3.3  1.1.x            1.2.x     2.5.1        1.8.3
4.3.7  1.1b5            1.1.5     2.5.4        1.7.2.1
4.3.10 1.1.1            1.1.6     2.5.5        1.7.2.1
5.0.5  1.2.16           2.0.10    3.1.3        1.9.1.2    2.0.5
5.0.7  1.2.22           2.0.12    3.1.5        1.9.1.2    2.0.7

像 plone.app.event 1.2.x 可能只在 github 取得,在 develop.cfg 裡的語法範例:

plone.app.event = git git@github.com:plone/plone.app.event.git branch=1.2.x

plone.app.event 在 1.2 版本後,要求 plone.app.widgets 安裝 (可能未限定版本,或是要求 1.4.0 以上),而 plone.app.widgets 1.5.0 開始,要求安裝 plone.app.jquery >= 1.8.0,而 plone.app.jquery 1.8.3 還有待確認能否跟 collective.cover 相容。

[sources]
plone.app.event = git git@github.com:plone/plone.app.event.git branch=1.1.x
plone.app.contenttypes = git git@github.com:plone/plone.app.contenttypes.git branch=1.1.x

[buildout]
eggs +=
    ...
    plone.app.contenttypes
plone.app.portlets = 2.5.1

plone.app.versioningbehavior 1.1.

plone.formwidget.querystring 1.1.2.

plone.app.portlets 2.5.1.

plone.formwidget.recurrence 1.2.3.

plone.formwidget.datetime 1.0.

plone.event 1.1.

icalendar 3.7.

collective.elephantvocabulary 0.2.4.

Products.DateRecurringIndex 2.1.

plone.app.event 也要留意,重新編輯 Event Item 時,是否遇到 TypeError: can't compare offset-naive and offset-aware datetime 錯誤。

plone.formwidget.datetime 1.3 額外要求 plone.app.locales >= 4.3.9,解法是把 plone.app.locales 指定 4.3.9。

昇級後 News/aggregator/folder_summary_view (使用 Products/CMFPlone/skins/plone_content/folder_listing.pt) 可能遇到 AttributeError: getText 錯誤,刪除後重新建立 Collection 就行。Events/aggregator 雖然沒有顯示錯誤的問題,但在 Collection Portlet 裡無法新增它,處理方式同樣是刪除後重新建立就行。

不過,也有人想要用 Deco 來取代預設的基本型別。安裝 plone.app.contenttypes 只會停用 Archetypes 但不能從檔案系統移除,要另下工夫,同時支援 Archetypes 和 Dexterity

Plone 4.3.7 + plone.app.contenttypes 1.1b5 啟用後: Autocomplete widget 1.2.8, Content tree widget 1.0.9 Dexterity Content Types 2.0.16, Dexterity versioning support 1.2.0, Querystring formwidget 1.1.5, Relation Field 1.2.1, collective.z3cform.datetimewidget 1.2.7, plone.app.event 1.1.5, plone.app.intid: install utility 1.0.5 plone.formwidget.datetime default profile 1.2, plone.formwidget.recurrence 1.2.6

一般使用 profiles/default/types/MyType.xml 檔名慣例,技術上也可使用 profiles/default/types/mytype.xml 這樣的檔名,搭配下列設定內容:

<object name="mytype"
 ...
<property name="factory">mytype</property>
<property name="add_view_expr">string:${folder_url}/++add++mytype</property>

有些模組的 Type 名稱較複雜,例如 Cover 使用 'collective.cover.content' 為名稱值。

如果 Type 不是透過 Title 來決定 ID 就要 (?) 指定 marshall 用來代表主要欄位

Related content
Data Access Tips