Warning

This document hasn't been checked for compatibility with current versions of Plone. Use at your own risk.

Portlet to display a random Photo

by Christian Ledermann last modified Dec 06, 2009 10:13 PM
This Portlet displays a random Photo. It needs either CMFPhoto and CMFPhotoAlbum or plain plone 2.1 or higher.

A Portlet is a Pagetemplate which contains a macro named portlet.

Create a Pagetemplate named portlet_rndphoto in your custom Folder. For CMFPhoto and CMFPhotoAlbum, place the following code into it:

 <html xmlns:tal="http://xml.zope.org/namespaces/tal"
        xmlns:metal="http://xml.zope.org/namespaces/metal"
        i18n:domain="rndphoto">

  <body>

  <div metal:define-macro="portlet">

      <div class="portlet" id="portlet-rndphoto"
           tal:define="presults python:container.portal_catalog(portal_type=['Photo', 'ZPhoto'], 
                                                                path='/'.join(here.getPhysicalPath()),
                                                                review_state=['published','visible'])"
           tal:condition="presults"
           tal:on-error="nothing" >

          <h5 i18n:translate="box_rndphoto">Random Photo</h5>

          <div class="portletBody"  tal:on-error="nothing">
            <tal:block tal:repeat="n python:range(3)" > 
            <tal:block tal:define="pobj python:random.choice(presults).getObject()">

              <div class="portletContent odd">

                    <a href="" 
                       tal:attributes="href string:${pobj/absolute_url}/view"
                        tal:condition="python: pobj.portal_type in ['Photo']">
                        <b tal:content=" string:${pobj/title_or_id}" /> <br/>
                        <img tal:attributes="src string:${pobj/absolute_url}/variant/thumbnail" alt="" />
                    </a>
                     <a href="" 
                       tal:attributes="href string:${pobj/absolute_url}/view"
                        tal:condition="python: pobj.portal_type in ['ZPhoto']">
                        <b tal:content=" string:${pobj/title_or_id}" /> <br/>
                        <img tal:attributes="src string:${pobj/absolute_url}?size=thumb" alt="" />
                    </a>
              </div>
               <div class="portletContent even">

                   <span tal:omit-tag=""  i18n:domain="plone" i18n:translate="posted_by">Posted by</span>

                            <span class="link-user">
                                <a href=""
                                  tal:attributes="href python:here.portal_membership.getHomeUrl(pobj.Creator())"
                                   tal:on-error="nothing"
                                   tal:content="string:${pobj/Creator}">
                                    Author
                                </a>
                            <span tal:omit-tag=""  i18n:domain="plone" i18n:translate="label_published">Published</span>:
                            <span tal:replace="string:${pobj/Date}" />
                            </span>

              </div>
          </tal:block>
         </tal:block>
      </div>
    </div>
  </div>

  </body>
 </html>

Go to your Plone root or the folder you want to display the portlet in and add to the right/left_slots property here/portlet_rndphoto/macros/portlet.

Explanation

The statement <tal:block tal:define="pobj python:random.choice(presults).getObject()">

returns a random result

of the catalogquery:

  tal:define="presults python:container.portal_catalog(portal_type='Photo',
                                      path='/'.join(here.getPhysicalPath()),
                                      review_state=['published','visible']);

The path=... restricts the results of the query to the current folder and its sub-folders. If no photos are found in this path the tal:condition="presults" makes sure that the portlet is not displayed. You can choose how much Photos to display by adjusting the value of tal:repeat="n python:range(3)"

To get unique photos use:

            <tal:block tal:define="rndPhotos python:random.sample(presults, min(len(presults),3))">
            <tal:block tal:repeat="rndPhoto rndPhotos">
              <div class="portletContent odd" tal:define="pobj rndPhoto/getObject">

This works with CMFPhoto/CMFPhotoalbum and probably PlonePhotoAlbum, but it can be easily customized to be used with other photoalbum products. For demonstration purposes I included the code for ZPhotoslides, but since ZPhotos do not support workflow it does not return any results for ZPhotos.

See a demo at trashpicts.com

Plone 2.1

(Code used for vanrees.org) To display plone's default Images instead, you can use the following variant:

  <html xmlns:tal="http://xml.zope.org/namespaces/tal"
        xmlns:metal="http://xml.zope.org/namespaces/metal"
        i18n:domain="vanrees">
    <body>

      <div metal:define-macro="portlet">
        <div class="portlet" id="portlet_randomphoto"
             tal:define="presults python:container.portal_catalog(Type='Image',
                         review_state=['published','visible'],
                         path='/plone/photos')"
             tal:condition="presults"
             tal:on-error="nothing" >
          <h5 i18n:translate="box_rndphoto">Random Photo</h5>
          <div class="portletBody"  
               tal:on-error="nothing">
            <tal:block 
               tal:define="pobj 
                           python:random.choice(presults).getObject()">
              <div class="portletContent odd">

                <a href="" 
                   tal:attributes="href string:${pobj/absolute_url}/view">
                  <b tal:content=" string:${pobj/Title}" />
                  <br/>
                  <img 
                     tal:attributes="src 
                                     string:${pobj/absolute_url}/image_thumb" 
                     alt="" />
                </a>
              </div>
            </tal:block>
          </div>
        </div>
      </div>