独自ビューレットの作成 [Plone4.0]
サイドメニューポートレットの作成
サイドメニュー用に指定したフォルダ内の 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" tal:content="view/title" /> <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>
グループメンバー変更テンプレート
各サイトの管理者用にサイト管理者グループを定義する。このグループには全ての権限(Managerロール)を与えず、Editor、 Contributor、Reviewerロールを与える。このグループメンバーは、サイトのすべてのコンテンツ編集に加え、主にグループメンバーの変更 (Manage users 権限要)、共有の変更ができ、ZMIへのアクセスはできないといった運用を想定する。
デフォルトのグループメンバー変更テンプレートを、少しカスタマイズしたものを別名で定義する。ビューレット名を site-admin-group-members、テンプレート名を site-admin-group-members.pt とする。
実際に利用する際は、次のURLを呼び出すことで利用できる。
http://(サイトURL)/@@site-admin-group-members?groupname=(グループID)
configure.zcmlの設定
プロダクトの browser ディレクトリの configure.zcml ファイルを次のように編集してビューレットを登録する。
+ <browser:page
+ name="site-admin-group-members"
+ for="Products.CMFPlone.interfaces.IPloneSiteRoot"
+ class="plone.app.controlpanel.usergroups.GroupMembershipControlPanel"
+ permission="zope2.ManageUsers"
+ template="site-admin-group-members.pt"
+ />
</configure>
site-admin-group-members.pt の定義
プロダクトの browser ディレクトリに usergroup site-admin-group-members.pt を plone.app.controlpanel 内の usergroups_groupmembership.pt をコピーする形で作成し、例えば次の点を修正してみる。
- テンプレート名の修正
次の点を修正しておく。
- tal:define="template_id string:@@usergroup-groupmembership;
+ tal:define="template_id string:@@site-admin-group-members;
- ユーザIDを表示しない
次の部分を2か所変更する。
- <tal:userid tal:condition="not:view/email_as_username">
+ <tal:userid tal:condition="nothing">
(<span tal:replace="this_user/getId | default" />)
</tal:userid>
- 編集バーを削除
次の部分を変更する。
- <div id="edit-bar">
+ <div id="edit-bar" tal:condition="nothing">
- グループが存在しない場合のメッセージを削除
次の部分を変更する。
- <tal:ifnogroups tal:condition="not:view/group | nothing">
+ <tal:ifnogroups tal:condition="nothing">
- グループ概要に上がるリンクを削除
次の部分を変更する。
<a href=""
+ tal:condition="nothing"
class="link-parent"
tal:attributes="href string:$portal_url/@@usergroup-groupprefs"
i18n:translate="label_up_to_groups_overview">
Up to Groups Overview
</a>
- グループの場合はリンクを張らない
次の部分を2か所変更する。
- <a href="" tal:attributes="href python:'prefs_group_details?' + view.makeQuery(groupname=this_user.getGroupName())" >
+ <span>
:
- </a>
+ </span>