This is mainly a note for others looking to do the same. I'm sure this is documented somewhere, but I thought I'd put it here (mainly for my own record!).

I needed to set a specific view for a folder in Plone. I had created a view called 'registration' that was configured via a grok directive:

class RegistrationForm(form.SchemaForm):
    grok.name('registration')
    grok.require('zope2.View')
    grok.context(IRegistrationFolder)

    schema = IAttendee
    ignoreContext = True

    label = _(u"Register for Plone Conference 2010")
    description = _(u"A description about the registration")
    ....

I then created a marker interface in interfaces.py:

from zope.interface import Interface

class IRegistrationFolder( Interface ):
    """ marker interface for the registration folder """

I then created a regular Folder in Plone called 'Registration' and published it. I then went into the Zope Management Inferface and found the folder and then clicked on the 'Interfaces' tab and then checked the checkbox by 'netsight.ploneconf2010_registration.interfaces.IRegistrationFolder' and hit 'Add'.

This then allows me to go to /registration/@@registration and get my view on that folder.

However I wanted to go one step further and make @@registration the default view for the folder so that I can just go to /registration and show my new view. Geir Baekholt pointed out to me on #plone on IRC that the default view name is stored in a property on the folder called 'layout'.

So I went back to the ZMI to my folder and clicked on the 'Properties' tab and added a string property called 'layout' and set it to '@@registration'.

Now when I go to /registration (or click on 'Registration' in the navigation on the site) I get my custom view.

Nice and easy, and not need to subclass Folder just to add a default view, or create a RegistrationsFolder content type.

Yesterday morning I came in to work to find that my (previously fine) plone 3 buildout kept failing to rebuild. After much debugging and googling, I tracked it down to the fact that over the weekend a new alpha version of plone.recipe.zope2instance was put up on pypi (4.0a1). Buildout merrily downloaded the new version which, by its own admission, introduces changes which can break plone 3 (see the changelog):

http://pypi.python.org/pypi/plone.recipe.zope2instance/#changelog

Now, you could argue this is my fault for not pinning my versions. In my defence, I had pinned the majority of versions but had left out major recipes like plone.recipe.zope2instance, assuming they were safe.

The upside to this issue was my discovery of buildout's 'prefer-final' option, which causes it to pick older, final releases over newer, alpha ones. You can add this option to the [buildout] section of your buildout file as follows:

[buildout]
parts = zope2
        instance
        ...

prefer-final = true
...

According to the buildout user guide, this option will default to 'true' in future versions of zc.buildout:

http://pypi.python.org/pypi/zc.buildout#preferring-final-releases

As whizzy as Plone 3's AJAX drag-and-drop folder re-ordering is, it's fairly unusable when you have a large number of items and need to move an item from the very bottom to the very top (or vice versa).

Doing a little AJAX debugging reveals that the heavy loading of this drag-drop functionality is actually done by a simple skin script, folder_position.py, which you can actually pass all manner of arguments into.

Moving an item to the top of a folder as as easy as calling the aforementioned script on a folder, passing 'position' as 'top' and 'id' as the id of the object you want to move e.g.

http://mysite/myfolder/folder_position?position=top&id=banana

You could also pass in 'position=bottom' to move it to the bottom.

A request we often get from customers is to make all links to PDF files in their Plone site open in a new window. This prevents the confusing situation where some browsers load the PDF inside the browser window, causing the user to accidently quit the browser when trying to close the PDF file.

As long as the PDF files in question have the '.pdf' extension, then this snippet of jquery usually does the trick:

jQuery("#content a[ @href $= '.pdf']").attr('target', '_blank');

In a standard (Plone 3.1) site, when you go to folder contents, any Images and Files that are included in the listing automatically have "/view" appended to their hyperlink (so that you get the content view rather than the raw data). If you subclass ATImage, you don't get this by default which causes problems for content creators (they click on an Image and can't get to the "edit" tab).

The solution is to add your custom types to the site properties field "typesUseViewActionInListings".

The folder_contents template (code defined in plone/app/content/browser/foldercontents.py) uses this to determine which URLs to append '/view' on to.

I always forget how to do things like this as I do not have to do them very often so I thought I would blog about it.

We've had a couple of projects here at Netsight where customers have required customised image content types in their plone sites. All very easy to do but an issue arrives when you want to be able to use this new content type in Kupu.

Say you created a new Image content type called CustomImage and added one in your plone site. Then you create a new page in your site and want to use this image in that page. To be able to use your new content type in kupu you need to modify new kupu.xml. If you do not already have a modified kupu.xml the easiest way to create one is to got to portal_setup in the zmi and export 'Kupu Settings' then move this into the 'default' folder inside 'profiles' in you content types product.

Add the following line (replace CustomImage with your own content type's name):

     	<type>CustomImage</type>

into the following location like so:

	<resource id="mediaobject" mode="whitelist">
		<type>CustomImage</type>
		<type>Image</type>
	</resource>

Once you have reinstalled your product (and reindexed the catalog) you should be able to insert an image, that already exists and is your new content type, into a kupu document.

To be able to upload an image from inside kupu you'll need to do another step. You have to override what content type is created when you upload from within kupu. In profiles/default create a new file called contenttyperegistry.xml and add the following code (replacing 'CustomImage' with your image content type name).

<?xml version="1.0"?>
<object name="content_type_registry" meta_type="Content Type Registry">

  <predicate name="ATImage_ext" content_type_name="CustomImage"
     predicate_type="extension">
   <argument value="jpg,jpeg,png,gif"/>
  </predicate>
  <predicate name="image" content_type_name="CustomImage"
     predicate_type="major_minor">
   <argument value="image"/>
   <argument value=""/>
  </predicate>

</object>

Once again after reinstalling your product and reindexing the catalog, you should be able to upload your new custom image content type from within kupu.

I hope this is useful to more people that just me.

Adrian

Back in the days of Plone 2.x, page templates used to be able to just access Zope's DateTime module like this:

<b tal:content="DateTime()" />

This would give you the current date and time.

In Plone 3.x, this ability disappeared. Now, I'm confident that people wiser than I made this decision, but sometimes I want it back. Imagine my delight when, whilst perusing Plone's advanced search form, I found this little beauty:

<form tal:define="DateTime python:modules['DateTime'].DateTime">
...
</form>

Ker-ching.

Here's what to do:

wget http://www.ijg.org/files/jpegsrc.v6b.tar.gz
tar zxvf jpegsrc.v6b.tar.gz
cd jpeg-6b/
./configure
make
sudo mkdir /usr/local/include
sudo make install-lib
wget http://effbot.org/media/downloads/Imaging-1.1.6.tar.gz
tar zxvf Imaging-1.1.6.tar.gz
cd Imaging-1.1.6
python setup.py build --force
python selftest.py
sudo python setup.py install

The simplest way I've found so far, which is not as simple as it should be, is as follows:

1. Add a getCustomNavQuery method to your folderish content type(s). If you don't have a custom folder type, you may just be able to create a python script which works globally (I haven't tried this). The method should read as follows:

   def getCustomNavQuery(self):
       return {'is_default_page': [True, False, None, ],
               }

This will make default pages appear in the default navigation portlet. Unfortunately, at this stage they will never have the 'selected' style.

2. To give default pages the selected style, you need to override/extend the default navigation portlet. I won't detail how to do this here, but the only part of it you need to customise is the page template 'navigation_recurse.pt'.

In this file, you will find a bunch of definitions at the top. You need to replace this line:

is_in_path      node/currentParent;

with this:

is_in_path      python: node['currentParent'] or (item_url in request.get('URL0', None));

That should work. If it doesn't, I'm sorry.

If you're in a page template and want to access something a little more complicated without writing a view class, try looking in this egg:

plone.app.layout[version].egg/plone/app/layout/globals/configure.zcml

It lists the global browser classes accessible from any page template (such as @@plone_portal_state) and points you to the classes where everything is defined.

Some very useful stuff in there (for instance @@plone_tools)