Posts for July 2012

  • Last modified Aug. 1, 2012, 4:03 p.m.
    Posted July 31, 2012, 4:43 p.m. by admin

    After recently upgrading a site from Plone 3 to Plone 4 I noticed that when visiting the portal_view_customizations page was spitting an AttributeError.

    Easily fixed I thought. Apparently not so.

    I got there after a couple of hours digging in debug mode. Here's my solution:

    The error I was getting form Plone was:

    AttributeError: type object 'IThemeQPloneSkinLite' has no attribute 'isOrExtends'
    

    This is a product that was already uninstalled. To fix the issue I had to place the original qPloneSkinLite product in the products directory.

    Then start up a Zope debug session:

    # ./bin/instance debug
    

    Execute the following code, replacing PORTAL with the path to your Plone portal relative to the Zope root.

    sm = app.PORTAL.getSiteManager()
    adapters = sm.registeredAdapters()
    
    for reg in adapters:
        if reg.name.find('qPloneSkinLite') >= 0:
        print 'Unregistering %s %s' % (reg.name, str(reg))
        if sm.unregisterAdapter(factory=reg.factory, required=reg.required, provided=reg.provided, name=reg.name):
            print 'Success'
        else:
            print 'Failure'
    
    import transaction
    transaction.commit()
    

    The key is the reg.name.find('qPloneSkinLite') line. If your unwanted adapter is a different one you can view all the registered adapters by running

    sm = app.PORTAL.getSiteManager()
    adapters = sm.registeredAdapters()
    
    for reg in adapters:
        print reg 
    

    Remember to remove the offending product code from your products directory afterwards!

    Worked for me! :)

  • Last modified July 20, 2012, 4:28 p.m.
    Posted July 20, 2012, 4:13 p.m. by admin

    So I have been meaning to do this for a while but have only just managed to get around to it.

    The code by which this very blog is implemented is now available as a Django app. Hooray!

    I implemented my own blog app not liking what was already available for Django. There were some good ones out there, but they did too much when all I required was a simple system that took care of comments, tags and most importantly allowed me to create posts using a rich text editor that supported the uploading of inline images. I also needed something that displayed code blocks with syntax highlighting. With those goals in mind I started implementing my requirements.

    The result: django-richtext-blog!

    I had always intended to release it to the wider community but needed to spend time packaging it up and providing some documentation.

    The very blog you're reading is implemented with this app, so if you like what you see, give it a try!

    The simplest way to get it installed is to run:

    $ pip install django-richtext-blog
    

    Providing your python environment provides pip. Then just follow the instructions to get the app running in Django.

    Currently it only runs under Django 1.3 due to dependencies. In the future I plan to make it Django 1.4 compatible.

    Python Package Index listing:

    http://pypi.python.org/pypi/django-richtext-blog

    GitHub project page:

    https://github.com/timmygee/django-richtext-blog

    Issues and bugs can be reported to the project issues tracker.

    If you have any queries about the app please get in touch with me at my contact page.

  • Posted July 4, 2012, 7:37 p.m. by admin

    After recently performing an upgrade of a fairly old Plone 3 site to Plone 4.1.3 my client noticed that all the icons for the default Plone content types were missing from the "Add New" drop-down menu.

    After some considerable investigation I put it down to 2 things.

    1. The new Plone 4 "sunburst" theme seems to have dropped icon references in portal_types in favour of defining the icon in CSS instead.
    2. Plone 3 portal_types used an "icon" field to specify the icon image that should go with the menu item but Plone 4 uses an icon expression defined in TAL instead.

    This icon expression (or icon_expr as the field is known) is blank after the Plone 3 to 4 migration. This is why there is no icon next to the content type name in the drop down menu.

    I should say at this point that the theme for my migrated site is based on "Plone Classic Theme" (known as "Plone Default" in Plone 3) and this may well be why I have this missing icons problem.

    It's a simple fix really:

    1. Navigate to portal_types in your plone portal.
    2. Click on "Folder" to bring up the properties for the Folder content type.
    3. Add to the icon_expr field the following TAL expression: string:${portal_url}/folder_icon.gif
    4. Repeat for the rest of the default content types using the appropriate TAL expression from the below list

      Folder
      : string:${portal_url}/folder_icon.gif
      Topic
      : string:${portal_url}/topic_icon.gif
      Event
      : string:${portal_url}/event_icon.gif
      File
      : string:${portal_url}/file_icon.gif
      Image
      : string:${portal_url}/image_icon.gif
      News
      Item: string:${portal_url}/newsitem_icon.gif
      Document
      : string:${portal_url}/document_icon.gif
      Link
      : string:${portal_url}/link_icon.gif

    Or because I couldn't be bothered with such a repetitive task a wrote a script that does this for you!

    Just add a new Python Script at the root of your site, add the below code and run it!

    # Import a standard function, and get the HTML request and response objects.
    from Products.PythonScripts.standard import html_quote
    request = container.REQUEST
    response =  request.response
    
    # Return a string identifying this script.
    print "This is the", script.meta_type, '"%s"' % script.getId(),
    if script.title:
        print "(%s)" % html_quote(script.title),
    print "in", container.absolute_url()
    
    if not hasattr(context, 'portal_type') or context.portal_type != 'Plone Site':
        print 'This script must be run in a Plone Site context!'
        return printed
    
    icon_exprs = {
        'Folder': 'string:${portal_url}/folder_icon.gif',
        'Topic': 'string:${portal_url}/topic_icon.gif',
        'Event': 'string:${portal_url}/event_icon.gif',
        'File': 'string:${portal_url}/file_icon.gif',
        'Image': 'string:${portal_url}/image_icon.gif',
        'News Item': 'string:${portal_url}/newsitem_icon.gif',
        'Document': 'string:${portal_url}/document_icon.gif',
        'Link': 'string:${portal_url}/link_icon.gif'
        }
    
    types_tool = context.portal_types
    
    for portal_type, icon_expr in icon_exprs.items():
        if portal_type not in types_tool:
            print 'WARNING: Default plone portal_type %s not in portal_types tool. Not updating icon' % portal_type
            continue
        print 'INFO: Updating icon_expr for %s to %s' % (portal_type, icon_expr)
        types_tool[portal_type].manage_changeProperties(icon_expr=icon_expr)
    
    return printed
    
  • Last modified July 4, 2012, 1:34 p.m.
    Posted July 4, 2012, 1:30 p.m. by admin

    I am using this post to maintain a list of the useful but somewhat obscure commands for the exim MTA. Mostly for my reference but others might find it useful too.

    Display all mail messages in the queue:

    # exim -bp
    

    Unfreeze all messages in the queue. This forces exim to try and send all frozen messages:

    # exim -qff
    

    Clear a single mail message from the queue:

    # exim -Mrm {message-id}
    

    Clear all mail messages from the queue:

    # exim -bp | awk '/^ *[0-9]+[mhd]/{print "exim -Mrm " $3}' | bash