ビューレット・ポートレットのカスタマイズ [Plone3.3]

Plone2.5 まではテンプレートとして提供されていたものが、Plone3.1から一部はPlone View Customizationsとして提供されている。portal_view_customizations よりロゴのテンプレートを変更して、みかけ上の表示などを変更する。browser ディレクトリで差し替えたものは、プロダクトを Products ディレクトリに格納するだけで反映される。

準備

プロダクトとして作成する場合に必要になる。

browser ディレクトリの作成

プロダクトのルートに browser ディレクトリを次のような構成として作成する。

browser/
  |--__init__.py
  |--configure.zcml
  • __init__.py
    空のファイルとして作成しておく。
  • configure.zcml
    次のように作成する。
    <configure xmlns="http://namespaces.zope.org/zope"
               xmlns:browser="http://namespaces.zope.org/browser"
               xmlns:plone="http://namespaces.plone.org/plone">
    
    </configure>

browserディレクトリの読込

プロダクトのルートの configure.zcml に上記で作成した browser ディレクトリを読み込むよう次のように追記しておく。

<include package=".browser" />

 

サイドメニューポートレットの作成

sidemenu.JPGサイドメニュー用に指定したフォルダ内の index.html ページとフォルダタイプ一覧を表示するポートレットを作成する。

configure.zcmlの設定

プロダクトの browser ディレクトリの configure.zcml ファイルを次のように編集してポートレットを登録する。

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

      :

+      <plone:portlet
+          name="portlets.lmenu"
+          interface=".lmenu.ILMenuPortlet"
+          assignment=".lmenu.Assignment"
+          renderer=".lmenu.Renderer"
+          addview=".lmenu.AddForm"
+          editview=".lmenu.EditForm"
+          />

   </configure>

lmenu.py作成

プロダクトの browser ディレクトリに lmenu.py としてテンプレートから呼び出すメソッドなどを定義する。

from zope import schema
from zope.component import getMultiAdapter
from zope.formlib import form
from zope.interface import implements

from plone.app.portlets.portlets import base
from plone.memoize import ram
from plone.memoize.compress import xhtml_compress
from plone.memoize.instance import memoize
from plone.portlets.interfaces import IPortletDataProvider
from plone.app.portlets.cache import render_cachekey

from Acquisition import aq_inner
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
from Products.CMFCore.utils import getToolByName
from Products.CMFPlone import PloneMessageFactory as _

from plone.app.vocabularies.catalog import SearchableTextSourceBinder
from plone.app.form.widgets.uberselectionwidget import UberSelectionWidget

class ILMenuPortlet(IPortletDataProvider):

    name = schema.TextLine(
            title=_(u"Title"),
            description=_(u""),
            required=True)

    root = schema.Choice(
            title=_(u"label_navigation_root_path", default=u"Root node"),
            description=_(u''),
            required=False,
            source=SearchableTextSourceBinder({'is_folderish' : True},
                                              default_query='path:'))

class Assignment(base.Assignment):
    implements(ILMenuPortlet)

    def __init__(self, name=u"", root=None):
        self.root = root
        self.name = name

    @property
    def title(self):
        return _(u"Side Menu")

class Renderer(base.Renderer):

    _template = ViewPageTemplateFile('lmenu.pt')

    @property
    def available(self):
        return len(self._data())

    def title(self):
        return self.data.name

    def menu_list(self):
        return self._data()

    @memoize
    def _data(self):
        context = aq_inner(self.context)
        catalog = getToolByName(context, 'portal_catalog')
        urltool = getToolByName(context, 'portal_url')
        query = str(urltool.getPortalPath()) + str(self.data.root)
        mtop = catalog(id = 'index.html',
                       portal_type=['Document','Topic'],
                       path = { 'query' : query, 'depth' : 1,})
        mfolder = catalog(portal_type='Folder',
                          path = { 'query' : query, 'depth' : 1,},
                          sort_on = 'getObjPositionInParent')
        menu = mtop + mfolder
        return menu

    def render(self):
        return self._template()

class AddForm(base.AddForm):
    form_fields = form.Fields(ILMenuPortlet)
    form_fields['root'].custom_widget = UberSelectionWidget
    label = _(u"Add Side Menu")
    description = _(u"This portlet displays Side Menu.")

    def create(self, data):
        return Assignment(root=data.get('root', u""), name=data.get('name', u"Menu"))

class EditForm(base.EditForm):
    form_fields = form.Fields(ILMenuPortlet)
    form_fields['root'].custom_widget = UberSelectionWidget
    label = _(u"Edit Side Menu Portlet")
    description = _(u"This portlet displays Side Menu.")

lmenu.ptの作成

プロダクトの browser ディレクトリに lmenu.pt としてテンプレートを定義する。

<dl class="portlet portletNews"
    tal:omit-tag=""
    i18n:domain="plone">

    <div id="menu">
    <div class="l-menu-head">
    <h2 tal:content="view/title">title</h2>
    </div>

    <ul class="l-menu">
    <tal:items tal:repeat="item view/menu_list">
      <li>
        <a tal:define="class python:item.getURL() in context.absolute_url() and 'on' or ''"
           tal:attributes="href item/getURL;
                           class class">
        <span tal:replace="item/pretty_title_or_id">Title</span>
        </a>
      </li>
    </tal:items>
    </ul>
    <div class="l-menu-footer"></div>
    </div>

</dl>

Ploneへのポートレット表示

プロダクトのプロファイルとして portlets.xml を次のように作成して、ポートレットとして追加できるようにする。

<?xml version="1.0"?>
<portlets>
 <portlet title="Side Menu" addview="portlets.lmenu"
    description="A portlet for side menu">
  <for interface="plone.app.portlets.interfaces.IColumn"/>
 </portlet>
</portlets>

 

Plone View Customizations

フッターを変更する

ZMI の plone で portal_view_customizations を選択し、plone.footer を編集する。工学では次のように、ログイン、ログアウトリンクもフッター内に設ける。

<div id="portal-footer" metal:define-macro="portal_footer" i18n:domain="plone">

  <div class="footer-name">
    (c) Kyoto University, Graduate School of Engineering. All Rights Reserved.
  </div>
  <div class="footer-login"
       tal:define="isAnon python:context.portal_membership.isAnonymousUser()">
    <a class="in"
       tal:define="login_url python:context.portal_url() + '/login_form'"
       tal:attributes="href python:login_url"
       tal:condition="isAnon"
       i18n:translate=""
       tal:content="string:Log in">
    Log in
    </a>
    <a class="out"
       tal:define="logout_url python:context.portal_url() + '/logout'"
       tal:attributes="href python:logout_url"
       tal:condition="not: isAnon"
       i18n:translate=""
       tal:content="string:Log out">
    Log out
    </a>
  </div>

</div>

colophonを表示しない

URL/@@manage-viewlets にアクセスして plone.colophon を隠す。

bylineを表示しない

URL/@@manage-viewlets にアクセスして plone.belowcontenttitle.documentbyline を隠す。

ページタイトルの下のカテゴリを表示しない

URL/@@manage-viewlets にアクセスして plone.belowcontenttitle.keywords を隠す。

履歴を表示しない

URL/@@manage-viewlets にアクセスして plone.belowcontentbody.contenthistory を隠す。

パーソナルバーを表示しない

URL/@@manage-viewlets にアクセスして plone.personal_bar を隠す。

検索ボックスに「現在のセクション内のみ」を表示しない

ZMI の plone で portal_view_customizations を選択し、plone.searchbox を編集する。

- <div class="searchSection">
+ <div class="searchSection" tal:condition="nothing">

検索ボックスのtitle属性「サイトを検索」を表示しない

CSS の適用がうまくいかないため変更する。plone.searchbox を編集する。

- title="Search Site"
  accesskey="4"
- i18n:attributes="title title_search_site;"

ドキュメントアクションを表示しない

URL/@@manage-viewlets にアクセスして plone.abovecontenttitle.documentactions を隠す。

パンくずに「ホーム→」を表示しない

portal_view_customizations で plone.path_bar を編集する。

- <span id="breadcrumbs-you-are-here" i18n:translate="you_are_here">You are here:</span>
- <a i18n:translate="tabs_home" tal:attributes="href view/navigation_root_url">Home</a>
- <span tal:condition="view/breadcrumbs" class="breadcrumbSeparator">
-     <tal:ltr condition="not: view/is_rtl">&rarr;</tal:ltr>
-     <tal:rtl condition="view/is_rtl">&raquo;</tal:rtl>
- </span>

言語ポートレット表示

Plone3.3でポートレットに追加できないようになっているため、これを利用できるようにする。プロダクトのプロファイル portlets.xml に次のように追記(ない場合は作成)する。ただしいつまでサポートされるかは不明。

   <?xml version="1.0"?>
   <portlets>

     :

 +  <portlet
 +    addview="portlets.Language"
 +    title="Language"
 +    description="A portlet which allows language selection."
 +    />

   </portlets>