2012/01/11

Map Should Be Art Work

黃清琦老師的演講裡,他提到「地圖應該可以包含藝術美感的元素,而不只是客觀數據的呈現,有時候必須加入製圖人的主觀美學意見」。舉的例子是,從 GIS 精準的角度,標示的點可能出現在不符規範的位置,例如某個城市被標在河湖裡,此時適度地移標是必要的。臺灣輿圖暨解說圖研究的完成,是以台灣地形圖為基礎來整合舊的史地資料,必須假設長期以來地形未變,如果有局部的資料顯示地形隨時間曾改變,則需要修正。

2011/12/29

KeyError: 'constrainTypesMode'

Here is an excerpt of error I run into:

URL: plone/app/layout/viewlets/contentactions.pt
Line 32, Column 8
Expression: <StringExpr u'plone.contentmenu'>
...
URL: plone/app/contentmenu/contentmenu.pt
Line 1, Column 0
Expression: <PathExpr standard:u'view/menu'>
...
KeyError: 'constrainTypesMode'

It turns out from my typo in content/mytype.py, by the time when I hesitate whether if using a folderish type:

-ArticleSchema = folder.ATContentTypeSchema.copy()
+ArticleSchema = folder.ATFolderSchema.copy()

Files to Edit for Adding Archetypes Type

除了用 zopeskel 來建立 Content Type 的方法,手動編輯檔案的話,下列是相關檔案的順序列表:

interfaces/__init__.py
interfaces/mytype.py
content/configure.zcml
content/mytype.py
profiles/default/factorytool.xml
profiles/default/types.xml
profiles/default/types/mytype.xml
config.py
browser/configure.zcml
browser/mytype.py
browser/templates/mytype.pt
locales/

2011/12/27

typesUseViewActionInListings in Plone PropertiesTool

In my archetypes-based project, I create a folderish type Book to contain Chapter type. One of the last steps is to add Chapter type in typesUseViewActionInListings field.

For GenericSetup, it is in profiles/default/propertiestool.xml:

<property name="typesUseViewActionInListings" type="lines">
 <element value="Image"/>
 <element value="File"/>
 <element value="Chapter"/>
</property>

Note that if Book added to that field, it will be bothering when you browse Book items in Contents tab.

2011/12/19

Collective TinyMCE Templates

collective.tinymcetemplates is a TinyMCE Plugin for templates and snippets. It works with Plone 4.1.3. You can see a "Insert predefined template content" icon added:

Transmogrifier Export in Action

transmogrifier 可以匯入或匯出 Plone 網站的內容,之前的經驗以匯入 CSV 或 PostgreSQL 資料為主,現在完成匯出到 PostgreSQL 的實作。

以 develop.cfg 為例,要修改的內容如下:

eggs +=
    psycopg2
    SQLAlchemy == 0.6.5
    zope.sqlalchemy
    plone.app.transmogrifier

客製 myproj.transmogrifier 的內容摘要如下:

myproj.transmogrifier/configure.zcml

  <transmogrifier:registerConfig
    name="myproj.transmogrifier.exportContent"
    title="MyProject Export Content"
    description="Transmogrifier Pipeline config to export contents."
    configuration="confs/export.cfg"
    />

  <!-- register our blueprints -->
  <utility
    component=".contentexport.ContentExporterSection"
    name="myproj.transmogrifier.contentexporter"
    />

myproj.transmogrifier/browser/configure.zcml

<configure
    xmlns="http://namespaces.zope.org/zope"
    xmlns:browser="http://namespaces.zope.org/browser"
    xmlns:zcml="http://namespaces.zope.org/zcml">

    <browser:page
        for="*"
        class=".contentexport.ContentExport"
        name="content-export"
        permission="cmf.ManagePortal"
        />
<configure>

myproj.transmogrifier/browser/contentexport.py

class ContentExport(BrowserView):

    def __call__(self):
        transmogrifier = ITransmogrifier(self.context)
        transmogrifier('myproj.transmogrifier.exportContent')
        self.request.response.write('exported')

myproj.transmogrifier/confs/export.cfg

[transmogrifier]
pipeline =
    contentexport

[contentexport]
blueprint = myproj.transmogrifier.contentexporter
dsn = postgresql://myuser:mysecret@localhost:5432/mydb
portal-types = News Item, Event
review-states = published

另外,還有 myproj.transmogrifier/models.py 和 myproj.transmogrifier/contentexport.py 兩個主檔,分別負責資料庫連線和匯出工作。

2011/12/18

Search Portlet for Current Section

By default, Plone provides a searchbox viewlet and a search portlet. With the viewlet, you can decide whether to search only within the current section. However, the porlet does not apply this behavior. My requirement could be illustrated by this screenshot:

Here are the files to be modified:

$ diff plone/app/portlets/portlets/search.py
55a56,61
>     def folder_path(self):
>         context_state = getMultiAdapter((self.context, self.request),
>                                          name=u'plone_context_state')
>         folder = context_state.folder()
>         return '/'.join(folder.getPhysicalPath())
>

$ diff plone/app/portlets/portlets/search.pt
29a30,44
>
>         <div class="searchSection">
>             <input id="searchbox_currentfolder_only"
>                    class="noborder"
>                    type="hidden"
>                    name="path"
>                    tal:attributes="value view/folder_path"
>                    />
>             <label for="searchbox_currentfolder_only"
>                    i18n:translate="label_searchbox_currentfolder_only"
>                    style="cursor: pointer">
>                 only in current section
>             </label>
>         </div>
>