You are here: Home Blog Topics plone 3

plone 3

Apr 09, 2013

How to enable User Folders in Plone

by Mike Cullerton — last modified Apr 09, 2013 03:22 PM

User Folders are an option in Plone. You can turn them on In the Security settings area of Site Setup (Plone Control Panel). Here's how I enabled User Folders in Plone from within my product.

I needed to enable the User Folders feature of Plone from within my product. My first thought was to use a Generic Setup profile, but the solution was setuphandlers.py.

I inspected the Enable User Folders button on the Security settings page of Site Setup, and saw the attribute was named enable_user_folders. I tried to find a generic setup profile I could edit.

The closest I got was adding enable_user_folders to properties.xml. This turned the attribute on in the ZMI, but not in Site Setup and User Folders were not enabled.

Then I found a reference to

security.enable_user_folders

in a setuphandlers.py file from the Rhaptos git repo.

So, I added these lines to setupVarious in my setuphandlers.py.
from plone.app.controlpanel.security import ISecuritySchema
site = context.getSite()
security = ISecuritySchema(site)
security.enable_user_folders = True

Now, when I install my product, User Folders are enabled automatically.

Note that you need to make sure setupVarious is turned on in configure.zcml.

<genericsetup:importStep
    name="your.package"
    title="your.package special import handlers"
    description=""
    handler="your.package.setuphandlers.setupVarious"
    />

 Hope this helps someone.

 

Sep 01, 2011

Fix for 404 Not Found Error for @@manage-portlets

by Chris Crownhart — last modified Sep 01, 2011 12:35 PM

In the midst of upgrading a Plone site from 2.5.x to 3.3.x (and eventually to 4.x), we discovered certain custom content types were returning a 404 error when accessing the @@manage-portlets page.

This one took a while to track down, so I thought I would write down our solution.  It turned out to be easy.  We simply added an interface to our custom content type's class as follows:

First import the necesary modules:

from zope.interface import implements
from plone.portlets.interfaces import ILocalPortletAssignable

 

Then we added an implements line to our class:

class SiteFolderCT(BaseFolder):
    """An Archetype for an SiteFolder application"""
    implements(ILocalPortletAssignable)
    <the rest of the class code...>

 

I hope this helps out others.

Sep 13, 2010

Adding a Zope 3 permission to Plone

by Mike Cullerton — last modified Sep 13, 2010 04:15 PM

We recently migrated a Plone 2 site to Plone 3. This site had more than a hundred skins files. While migrating one of them to a Zope 3 browser view, we needed a new permission to protect the view, and at first it wasn't apparent how to do it. But, of course, it ended up as easy as 1-2-3.

Quick Overview

We recently migrated a Plone 2.1 site to Plone 3.3. While moving a skins file to a browser view, we needed a new permission to protect the browser view. Browser views need a named Zope 3 style permission, so the old Zope 2 style permission wouldn't work. It ended up taking 3 steps; declare the permission in zcml, assign the permission to a role in rolemap.xml, and use the permission to protect your view.

 

Step-by-step

Step 1: Declare the permission in ZCML

Most people declare the permissions in permissions.zcml and include that file in configure.zcml. But you can declare the permission in configure.zcml and just include permissions.zcml. Note that id is the zope 3 style identifier, and title is the zope 2 style identifier. The title shows up on the security tab in the ZMI.

src/your.product/your/product/browser/permissions.zcml:

    <permission 
       id="myproduct.myNewPermission"
       title="MyProduct: My New Permission"
       />

 

Step 2: Assign the permission to a role

Assign the permission to a role in rolemap.xml. Here, I assign my new permission to the manager role.

src/your.product/your/product/profiles/default/rolemap.xml:

    <permission name="MyProduct: My New Permission">
       <role name="Manager" />
    </permission>

 

Step 3: Protect your view with the new permission

In configure.zcml protect your view with the new permission. Here, I'm protecting the class MyClass in the file common.py. We chose to put the permissions from Step 1 into permissions.zcml, so we include it here. Note that the permission must be the same as the id in Step 1.

src/your.product/your/product/browser/configure.zcml:

<include file="permissions.zcml" />
<browser:page
    for="Products.CMFPlone.interfaces.IPloneSiteRoot"
    name="myName"
    class=".common.MyClass"
    permission="myproduct.myNewPermission"
    />

 

As usual, the community developer manual at http://plonemanual.twinapex.fi/ was very helpful.

Jun 22, 2010

Injecting Plone variables into javascript

by Mike Cullerton — last modified Jun 22, 2010 09:00 AM

I needed access to Plone variables (specifically portal_url) from within javascript. So, I created a browser view and python script that outputs the necessary variables, and registered the view in jsregistry.xml. This turned out to be a rather simple solution.

 

Step 1: Create a class to output the javascript

I created a file in src/my.product/my/product/browser called CommonUtils.py and added a class GlobalJS with a __call__ method that returns a string containing the javascript. __call__ sets the content-type, creates the string containing the variable, and returns the string.

class GlobalJS(BrowserView):
 
    def __call__(self,REQUEST,RESPONSE):
        RESPONSE.setHeader('Content-Type', 'application/javascript')
        js_string = "var portal_url = '%s';" % (self.context.portal_url())
        return js_string

 

Step 2: Create a browser view pointing to the class

In src/my.product/my/product/browser/configure.zcml, I added a browser view pointing to GlobalJS, gave it a name, and added a permission. Note that the name of the file containing GlobalJS is CommonUtils.py

<browser:view 
     for="*"
     name="global_js.js" 
     class=".CommonUtils.GlobalJS"
     permission="zope2.View"
     />

 

Step 3: Register the view in javascript registry

Here, I register the browser view in src/my.product/my/product/profiles/default/jsregistry.xml. I needed access to portal_url before jquery was loaded, so I added the insert-before property. Note that the id is the same as the name registered in the browser view.

<javascript 
    id="global_js.js"
    cacheable="True" compression="safe" cookable="True"
    enabled="True" expression=""  inline="True" insert-before="jquery.js"/>

 

Now, global_js.js is loaded on every page and I have access to portal_url from within javascript.

Hope this helps someone.

Jan 26, 2010

Overriding the Title tag in Plone 3

by Mike Cullerton — last modified Jan 26, 2010 12:20 PM

The default title for a Plone 3 site has the page title on the left and portal title on the right, separated by an em dash. I needed to change that for a project. This how-to describes a process for overriding the page title of a buildout based Plone 3 site.

Quick Overview

You need to override the plone.htmlhead.title viewlet and create a class to render your title. The default version of the viewlet is defined in [eggs]/plone/app/layout/configure.zcml, and the class is defined in common.py. You'll need a few more things from common.py too. Override the viewlet in your own [theme]/browser/configure.zcml file, and add the location of your new class.

Getting Started

I needed to override a viewlet, but didn't know which one. A quick grep found a reference to the plone.htmlhead viewlet manager, and then one to the plone.htmlhead.title viewlet. Viewlets are found in the plone/app/layout/viewlets/configure.zcml file within the eggs area of your buildout. Here is the specific code in configure.zcml.

...
<browser:viewlet
name="plone.htmlhead.title"
manager=".interfaces.IHtmlHead"
class=".common.TitleViewlet"
permission="zope2.View"
/>
...

In this case, the plone.htmlhead.title viewlet references a class called .common.TitleViewlet. This means a file--in the same directory as configure.zcml, named common.py contains a class named TitleViewlet. Here is the TitleViewlet code from common.py.

class TitleViewlet(ViewletBase):

...

def index(self):
portal_title = safe_unicode(self.portal_title())
page_title = safe_unicode(self.page_title())
if page_title == portal_title:
return u"<title>%s</title>" % (escape(portal_title))
else:
return u"<title>%s &mdash; %s</title>" % (
escape(safe_unicode(page_title)),
escape(safe_unicode(portal_title)))

In the index method at the bottom, Plone sets the value of the <title> tag.

If the page title and the portal title are the same, the portal title is used. If not, both are used, with page title on the left and portal title on the right.

We needed to switch it, so that portal title was on the left, and page title was on the right.

What we did

To override the title viewlet, I created an entry in my theme's browser/configure.zcml file.

<!-- Our custom title viewlet --> 
<browser:viewlet
name="plone.htmlhead.title"
manager="plone.app.layout.viewlets.interfaces.IHtmlHead"
class=".myTitleViewlet.TitleViewlet"
layer=".interfaces.IThemeSpecific"
permission="zope2.View"
/>

Notice that there is a new layer statement, and that the manager line includes the complete path to IHtmlHead. The class statement now points to our new class containing code to override the title.

Here is the code from myTitleViewlet.py.

from zope.interface import implements
from zope.component import getMultiAdapter
from zope.viewlet.interfaces import IViewlet
from zope.deprecation.deprecation import deprecate

from Products.CMFPlone.utils import safe_unicode
from Products.Five.browser import BrowserView
from cgi import escape

from plone.app.layout.viewlets.common import ViewletBase

class TitleViewlet(ViewletBase):

...

def index(self):
portal_title = safe_unicode(self.portal_title())
page_title = safe_unicode(self.page_title())
if page_title == portal_title:
return u"<title>%s</title>" % (escape(portal_title))
else:
return u"<title>%s | %s</title>" % (
escape(safe_unicode(portal_title)),
escape(safe_unicode(page_title)))

I needed some of the imports from the top of common.py, and added one of my own for ViewletBase. The only code that really changed is the else clause, where the order of portal_title and page_title are switched, and the em dash is replaced by a pipe (|).

A great reference for overriding the <title> tag is HTML Head Title page which is part of the Plone Theme Reference.

 
 
Copyright © 2003-2017 Core Software Group | 303/809-1001 | Fort Collins, Colorado | All rights reserved.