Archive for the 'Plone' Category

Drag-n-drop page design for end users

Yesterday, with help from Godefroid Chapelle, I managed to get CompositePack working with p4aPortfolio (the new name for ArtistPortfolio).

While the previous frontpage was composed of static blocks (recordings, events, bands, etc.), with CompositePack integration it’s now possible to drag-n-drop viewlets on the portfolio frontpage to re-arrange their placement.

You can also add new viewlets or delete existing ones, without having to jump through hoops to get the job done.

This means that for the end user (non-technical artists), they can very easily decide what should be displayed most prominently on their portfolio page.

For example, maybe they are not gigging very much but producing a lot of new songs, so they could move the ‘Events’ viewlet to the bottom of the page, and move the ‘Recent audio files’ viewlet higher up on the page.

Alternatives

I had also looked at CMFContentPanels and the recently released ListingPages product to provide this functionality but nothing came close to the intuitiveness of drag-n-dropping that CompositePack provides.

Issues

If you want to add a general viewlet that is not attached to a particular piece of content, for example a viewlet that displays all MP3s that have been added anywhere in a Member’s folder (and not just a particular folder), you have to associate that viewlet with the type ‘Plone Site’, and then it can be added as ‘Portal’ instead of ‘Content’.

The problem with this is that currently, when you select ‘Portal’ it adds the element to the page right away and chooses the default viewlet which may or may not be the one you want. So you have to go back and select the viewlet after you’ve already added it. Not the most intuitive interface and definitely should be improved.

A workaround for the time being is to use the general categories that appear in the navigation portlet as ‘placeholders’ so that if the user selects an object of type ‘Recordings’, they can select among several viewlets: ‘recordings in this folder’, ‘recordings in this members folder’, ‘recordings for the whole site’.

It really doesn’t matter which particular object they select, but just that they select one that has these ‘global’ viewlets associated with it.

New feature ideas

Add another option in the dropdown menu called ‘Add new item to this folder’. If the viewlet is showing a folderish object, one should be able to not only edit that object but add new items into that folder.

As it is right now, if I’m viewing the frontpage and want to add a new recording, I have to first click on the ‘Recordings’ folder (in the left navigation) and then choose ‘Add CD’. I should be able to do this directly from the recordings viewlet on the frontpage.

Self-contained member folders

I wanted to make it possible for artists to create a portfolio in a
Plone site and have that same portfolio become their actual website.
This requires tweaking a few aspects of how Plone works:

  • Domain name
  • Skin
  • Navigation (navtree and breadcrumb trail)
  • Search
  • Portlets

Domain name

Using the Virtual Host Monster, I created a mapping for the user winnie:

winnie.domain.com -> /ac/Members/winnie/portfolio/
(”ac” is the ID of my Plone site)

Now when I go to winnie.domain.com, it redirects me to Winnie’s portfolio page.

Skin

Since each artist would like to have his/her own logo, colors and other
branding, we can use an access rule to change the skin depending on
whether the user is viewing the artist’s folder using the specific
domain name, or whether they are browsing to the site via the portal
site.

Set skin:

winnie.domain.com -> change to the skin_winnie
www.domain.com/Members/winnie/portfolio -> use the default site skin

So that I don’t have to create an access rule for each and every
member, I place one script in the Members folder and set it to the
access rule:

subdomain = context.REQUEST.BASE0.split("/")[2].split(".")[0] if subdomain == "www":    context.changeSkin("Plone Default")

else:    newskin = "skin_" + subdomain    context.changeSkin(newskin)

What this does is get the subdomain from the REQUEST
environment variable BASE0 (could also use SERVER_URL here), and then
if it is equal to “www” (meaning we are just browsing to the artist’s
folder), then keep the normal site skin. But if the subdomain is
anything other than “www” (i.e. “winnie”), then we change the skin. We are assuming
that the skin is named the same as the subdomain with “skin_” prepended.

Navigation

The problem with using VHM to send the user to a specific artist
folder in the Plone site, is that the navigation tree and breadcrumb
trail still show the parent
folders. We want to give the impression that you are not in a portal
site, but viewing an individual artist’s site, so we need to “hide”
these unnecessary navigational elements.

Breadcrumb trail

We will just eliminate the breadcrumb trail since it’s not
really necessary for a small artist site. In portal_skins/skin_winnie/ploneCustom.css we change
the visibility property of portal-breadcrumbs:

#portal-breadcrumbs {/* The path bar, including breadcrumbs and add to favorites */    background-color: white;    visibility: hidden;}

Navigation Tree

And to make sure that the left navtree shows only the folders for Winnie’s portfolio page, we need to add a topLevel property to the Members folder.
In the ZMI, go to Members -> Properties

Add new property:
name: topLevel
type: int
value: 4

TODO:

  1. make an ‘Up one level’ or ‘Home’ link at the top of the navtree,
    so that the user can get back to the frontpage. Or find out how to do
    this in the navtree_properties. Preferably we shouldn’t have to edit
    the portlet_navigation.
  2. look at PloneSolutions’ TreeNavPortlet which is a much better implementation of the navtree. Wait until it’s separated from the PlonePortlet product.

Search

When a user is viewing the artist’s portfolio page using the specific
domain name (i.e. winnie.jazkarta.com) we want the search box to only
search the individual artist folder, not the whole site. The search box
should search the whole site if we browse to the artist’s folder via
the portal site. As in the following:

Search box displayed on page:

winnie.domain.com -> limit the search to the path /ac/Members/winnie/portfolio
www.domain.com/Members/winnie/portfolio -> do not limit the search path.

I’ve explained how to do this at the bottom of this howto on the Plone.org website.

Portlets

We don’t want to display all the sitewide portlets when viewing an
artist’s folder, so we probably need to override them by modifying the
left_slots and right_slots properties for the Members folder, and then
add some tal:condition statements to check to see how the user is
accessing the artist folder.

Show portlets:

winnie.domain.com -> don’t show the sitewide portlets since the artist wants the user to stay on their page
(but maybe show one called “Related artists” or something like that)
www.domain.com/Members/winnie/portfolio -> use the sitewide portlets to encourage users to visit other areas of the site

PIL reinstall fun

I just updated to the latest Plone 2.0.5 which required updating to
Python 2.3.4. This meant that I had to reinstall all of the custom
python libraries in site-packages.

The CMFPhoto product was unable to resize images, and gave the error ‘IOError: decoder jpeg not available’.

So I did a search on my hosting provider zettai.net for the keyword “PIL” and found this page: How to Install PIL on FreeBSD. It was a bit tricky since I had already installed PIL without doing all of these things.

From the ~/src/Imaging-1.1.4 directory:

I had to include the -f flag to tell it to force a rebuild.

/home/jazkarta/zope/py/bin/python setup.py build -f
/home/jazkarta/zope/py/bin/python setup.py install

Modify the newsletter to only include content from the current folder and below

Below you can see the diff. I added some more content types to check
for, removed the publish state (only because it’s easier while
testing), and added a path criterion which looks in the parent of the
CMFNewsletter object.

===================================================================RCS file: /cvsroot/collective/CMFNewsletter/Newsletter.py,vretrieving revision 1.37diff -r1.37 Newsletter.py164,167c164,171< crit.edit(('Document', 'News Item', 'Event', 'PlonePopoll'))< self.addCriterion('review_state', 'String Criterion')< crit = self.getCriterion('review_state')< crit.edit(('published'))---> crit.edit(('ATAudio', 'News Item', 'Event', 'Link', 'ATAmazon', 'ATAudioFolder', 'BandPortfolio'))> # self.addCriterion('review_state', 'String Criterion')> # crit = self.getCriterion('review_state')> # crit.edit(('published'))> crit.addCriterion('path', 'String Criterion')> crit = self.getCriterion('path')> current_path= '/'.join((self.aq_parent).getPhysicalPath())> crit.edit(current_path) 

Learning python

I consider myself a python newbie, although I must admit that when
I’m reading other people’s python code, it looks fairly
straightforward. I still need to get some of the fundamentals down, and
have therefore designed an independent study for myself including the
following lessons.

Some other more project related tasks:

  • Try out the Customization Policy and SetupWidget examples from
    the sample chapter from Cameron Cooper’s new book that David Convent
    sent me.
  • Try subclassing the ATEvent content type in ATContentTypes to allow for an event to be linked to a place (Venue) object.

Products to evaluate

I’ve been downloading more products than I have time to evaluate. First
priority is to get the ArtistPortfolio product that I’m working on
ready for a public release.

Then I will turn my attention to re-setting up the testing instance (to
be at testing.jazkarta.com) which will have the following products
available. My hope is that if I make the site publicly accessible,
others will try out the products and help submit bug reports.

Plone products to evaluate

coming soon to a testing.jazkarta.com site near you!

WYSIWYG Editors

Mailing lists

E-Commerce


Installation and multi-site configuration

Hit counters / Ratings

  • mxmCounter ‰ÛÒ count the number of times a page gets hit
  • ATRatings
  • CMFRatings


Webmail

  • PloneWebmail ‰ÛÒ can set up email account on fastimap.com


Member registration

  • CMFMember
  • CMFMemberExample


Misc products

  • PloneMap
  • PloneFormMailer
  • GroupStaging

Quotas

  • QuotaAW
  • ATContentTypes (quota features)

Licensing

  • CMFMetadata (Creative Commons)
  • PloneCC


External content from other sites

  • CMFSin + CMFSinParsers
  • PloneRSSSearch
  • PloneAtom
  • pybloglines
  • CMFFeed

Photos

  • ZPhotoSlides
  • CMFPhoto + CMFPhotoAlbum
  • FSPhoto


Resource Library

  • ATAmazon
  • ATBookmarks
  • CMFLinkChecker


Customer Support

  • MailManager - Zope product to handle customer support requests

Skins/CSS

  • CSSManager
  • Colorz

Workflow

  • PortalTransitions ‰ÛÒ email artists when their portfolios are published
  • DCWorkflowDump
  • DCWorkflowGraph

Troubleshooting

  • VerboseSecurity
  • PloneErrorReporting
  • DocFinderTab
  • ZopeTestCase
  • WebDAVLogger

Dynamic pages

  • CompositePack
  • DynamicPageView
  • CMFContentPanels

Multilingual

  • LinguaPlone
  • PloneTranslations
  • PloneLanguageTool

Newsletter

  • CMFNewsletter
  • PloneNewsletter
  • PloneGazette

Portlets

  • PlonePortlets
  • PloneExtendedPortlets
  • SimplePortlet

Chat

  • PloneChat
  • PloneIM

Calendaring

  • CalendarX
  • PloneiCalendar
  • Calendaring

Groups

  • TeamSpaces
  • GrufSpaces
  • MxmGroups

User folders

  • ExUserFolder
  • LDAPUserFolderExt

Speed / Performance

  • CMFSquidTool
  • SpeedPack

File system

  • PloneLocalFolderNG
  • PloneSingleFolderFS
  • Railroad

Search

  • TextIndexNG

ATAudio and ID3

Yesterday I released a new version (0.3.5) of ATAudio, but with some
reservation since the ID3 tag extraction mysteriously stopped working.

What is very strange is that the ID3 tag extraction works when
uploading the MP3 file via WebDAV, but not when uploading in the web
browser.

What is even more strange is that the Title field is successfully extracted, but not the artist, album and year fields.

I’ve called on the pyfu master Sean Treadway to shed some light on
this, since he is the mastermind behind the ID3Storage component.

More to come as this mystery unfolds…

Calendaring has excellent iCal support

I’ve just installed the most recent version of Calendaring and ATContentTypes (both in the collective), and have to say it is very slick what you can do with this product. I can do the following using iCal and Plone:

  • Create a calendar in iCal and publish it to a Plone site via WebDAV. The events appear in the calendar view and as normal Event objects
  • I can add a new event in iCal and when I refresh the calendar, it sends the new event to the Plone site. It’s smart enough to know that if I edit an existing event to update the event instead of duplicating it. This must be because each event has a unique ID.
  • Using iCal, I can subscribe to a calendar that is being hosted on a Plone site. This can be done by clicking on the Event icon when you are viewing the calendar, which launches iCal and auto-subscribes. This works better in Safari than in Firefox. Firefox wants you to download the .ics file first, after which you would double-click on it to open
    it up in iCal. A workaround for this would be to change the http:// to webcal:// which would tell Firefox to use another program (i.e. iCal) to handle the file. (DONE)
  • I can add an event in the Plone interface and in iCal do a refresh of the subscribed calendar. The event that I just added in Plone will now appear on my iCal calendar. I can also set it to auto-refresh every 15 min. This means that the artist’s fans don’t have to keep clicking on refresh, nor do they even have to visit the artist’s website. All they have to do is launch their iCal program and it will automatically grabs all the most recent event postings from the artist’s calendar hosted on the Plone site.

What is missing:

  • There is no two-way synchonization. That is, if I publish a calendar from iCal, and then add an event to that calendar in Plone, it won’t be synchronized back to the iCal calendar that I have published. You can certainly add events both in the Plone site and via iCal, and those who have subscribed to the calendar will see these events (no matter where they were entered), but the person who published the calendar will not see the events. A simple workaround is simply to subscribe to the same calendar that you have published, and use that one to view ALL the events (incl. the ones that are posted from the Plone site).
  • Recurring events don’t work in Plone. If you make a recurring event in iCal, it will show up as a single event in Plone. UPDATE: See this post in which Tom Hoffman mentions that Programmers of Vilnius will be adding recurring events functionality as part of a contract job.
  • Filtering the events by the event type / keywords. The CalendarX product does this, so I don’t think it would be too difficult to add to Calendaring.
  • Nesting the calendars. For example, an artist is in several bands and if you subscribe to a single band calendar then you only see the events of that particular band, but you can also subscribe to the artists’s calendar which will show you the events from all the bands that the artist is in. UPDATE: See Jeff Kowalczyk’s post regarding this.

WebDAV woes

You can read about my findings trying to find a good solution for uploading audio files from iTunes into Zope via WebDAV.

CalendarX

Yesterday, I gave CalendarX a
run-through and exchanged a few emails with +lupa+, the author. Right
now, what I’m thinking of is using CalendarX as the sitewide calendar
because it allows for filtering of events by keyword (concerts, jam
sessions, festivals, workshops, etc.) and then use Calendaring for the
individual artist and band calendars, since they don’t necessarily need
the filtering features, but the iCal integration is very important.

I’m not too keen on having to support two calendar solutions, but since
only the site administrator needs to know CalendarX, it shouldn’t be
too bad. The event objects are persistent so even if another better
calendar solution comes along, or these three merge, the objects will
still be accessible.