Forum OpenACS Development: Photo-Album Includelet for Xowiki

I am about to embark on re-working a site I created some years ago which makes extensive use of photos.

Whilst in the past I hacked away at the OpenACS structures and templates, recently I have been using xowiki quite heavily because it allows me to do almost everything I could imagine needing to do without having to hack away at anything!

The golden goose for me therefore would be a photo-album includlet for xowiki so that album viewing and navigation functionality could simply be dropped into an xowiki page and styled.

I have looked at the photo-album ajax interface kindly provided by Solution Grove, and whilst this is an excellent interface for organising photos and controlling the application, its layout and the use of the java 'lightbox' style of display is not appropriate for my objectives.

If anyone knows of a photo-album xowiki includlet project already in progress I would be very grateful to hear about it before I begin! 😊

Failing that, if anyone can give me some tips or suggestions as to the best place to start, which code to target for re-use, and any existing components that would give me a head start, I would be most grateful. Having begun to develop some familiarity with YUI3, it is my intention to incorporate some asynchronous Javascript capability to smooth and speed up the navigation capability (by for example retrieving the mid-sized image asynchronously when the thumbnail is clicked instead of refreshing the whole page, and maybe improving the thumbnail page navigation features as well).

My present assumption is that there is no such thing at present, and I plan to start by analysing the existing xowiki categories includelet in an effort to understand the way it all fits together.

If anyone can guide me I would be most grateful, and if anyone would like to work with me on it, so much the better.

I apologise in advance to Jeff Davis and Gustaf Neuman because I rather suspect that my chances of success without some input from them is minimal!

Many thanks
Richard

Collapse
Posted by Gustaf Neumann on
A quick solution might be to use the {{yui-carousel}} includelet which displays the images of an xowiki instance with the YUI 2 carousel. Are you aware of this? It does not use all bells and whistles of the evolving yui-carousel functionality, but i think it is straightforward to extend this if needed.
Collapse
Posted by Richard Hamilton on
Gustaf,

No I was not aware of this, and now that I have had a look at it I am very excited by the possibilities. Thank you.

I have created an experimental page with a single image on it, but have run into a problem:

Error in includelet 'yui-carousel':
::xotcl::__#0G: unable to dispatch method 'pretty_link'
while executing
"$entry pretty_link -download true"
(procedure "render" line 57)
invoked from within
"next"
(procedure "render" line 5)
::xotcl::__#0E ::xowiki::includelet::decoration=portlet->render
invoked from within
"$includelet render"

The url for the page is:
http://dev.oakmasters.com:8000/xowiki/available_includelets

Is this caused by something I have omitted to do?

I have studied your code and am beginning to 'get it', but I am not yet familiar enough with xotcl to know the kind of problems that create method dispatch issues. Is this a problem with the image object or a more fundamental issue? I have found the method in the links-procs.tcl and I am not really sure where to start troubleshooting to work out why this method fails on the image object.

I should mention that before I added an image object to the page, the empty YUI carousel rendered just fine. As soon as I added a child object of type image (as per the includelet code), the pretty_link method choked.

Also, I am concerned that with a very large number of images on many pages, the files may become difficult to manage since there are no folders in an xowiki admin page. I can add categories to organise the photos for display controlled by a menu, but I am concerned about the admin situation.

In the past I have used photo-album to organise images hierarchically in the admin pages and public viewing, and to use the images arbitrarily in other pages by hyperlinking them within the html. Of course this simply causes the browser to grab the image as a seperate request, whereas the yui-carousel includelet is doing all the work on the server. Is there a way to emulate the hierarchical organisation of the photo-album package in xowiki?

If not, could the yui-carousel be populated from the photo-album? Is it be feasible to enable photo-album content items (images) to be allocated to xowiki page objects as additional child objects, without disrupting their existing object relationships within the photo-album application?

Alternatively, is a lightweight {{adp /photo-album/includelet_viewer.adp {album nnnn} }} a realistic possibility for me as a means of ducking the object-tcl challenge for the time being?

Regards and many thanks
Richard

Collapse
Posted by Gustaf Neumann on
it was simply a bug introduced in june; just add the one line, that i fixed yesterday (see http://fisheye.openacs.org/changelog/OpenACS/?cs=MAIN%3Agustafn%3A20101031172542)

What amounts of photos you want to handle (and how many folders, how many photos per folder, are subfolders wanted/needed/not necessary)?

In principle, one could subclass yui-carousel to get photos from different sources (such as the photo-album), finally it needs just the image urls (and maybe titles etc.) but selecting the right album might not be end-user friendly (if you just new a few albums, this might be fine). Another issue are the navigation structures, which are handled by yui-carousel (and similar js widgets) by themselves.

About including: one can certainly include every adp/tcl pair in an xowiki page. Problems might arise be from the navigation structures inside the adp, here it depends often how flexible the adp can be configured. I am not aware with the details of the photo-album, the 122 files in photo-album/www are too much for me to check now.

Collapse
Posted by Richard Hamilton on
Gustaf,

Thank you, I'll do a cvs update from HEAD to grab the change.

We need around 11 folders with the capability to have up to around 60 images in each folder.

Subfolders are not essential but may be useful later to group images by project within category.

On the subject of sourcing the images from photo-album, I can see what you mean about the navigation issue. The includelet would need to know a lot about the structures within photo-album. Alternatively, photo-album could be coded to export or maintain some kind of trivial structure map for the includelet to refer to. Either way this could be ugly if not done carefully.

As far as the {{adp ..... }} is concerned, I was considering adding specific adp/tcl pairs for image display only, so I would maintain control of the nav links. However I have no sense of how big a job this might be.

I think the simplest option is undoubtedly as you have suggested. How could I improve the organisation of this many files?

Regards
Richard

Collapse
Posted by Richard Hamilton on
Gustaf,

I have now had a chance to play with the {{yui-carousel}} and I can see what a lovely, clean and elegant solution this makes for simple slideshows.

I originally thought that the carousel picked up images that were children of the xowiki::page but I now see that it makes a slideshow of all images in the xowiki instance. I can see therefore that if you want multiple galleries, you would simply create an xowiki instance for each gallery to organise your images.

I have never tried, so I don't know, but I assume that a single ACS Category tree can be mapped to more than one xowiki instance so that any navigation system could be preserved between instances?

Nevertheless, I the functionality I'd like more closely resembles the YUI demo with the AJAX updated strip of thumbnails with larger image below.

http://developer.yahoo.com/yui/examples/carousel/csl_dynload2.html

I think I will work on integrating this with OpenACS photo-album package so that the thumbnail and intermediate image sized image pages are effectively combined through AJAX. I think that the viewer you have put in the yui-carousel will make a lovely solution for the photo-album full-sized slideshow, perhaps with deferred image loading to smooth things along, so I will add that as well.

What I'd love to do after that is to work on a way of enabling this to be included in an xowiki page using an includelet.

If I code so that the navigation is handled through AJAX calls after the page is loaded, then the navigation issue would be eased. I would however probably need to be able to pass a value through to my includelet that had been passed url-encoded to the xowiki page. Can this be done?

In the case of ADP (notionally using @notation@):

{{adp photo-album {album @album_id@} }}

In the case of xowiki includelet:

{{photo-album -album @album_id@ -mode @mode@ }}

Links created by the includelet could be of the form:

/xowikiinstance/xowikipage?album_id=7364&photo_id=6253

Is this feasible or totally nuts!? 😊

Regards
Richard

Collapse
Posted by Dave Bauer on
NOTE:
THe current content repository image type has built in thumbnail and other size handlers similar (but simpler) than photo album.

This works for any image that is stored in the CR with image or image subtype content type.

If you address the image with the image.vuh handler ie: mysite.com/image/${image_id}/${size_name} and the size_name is configured (there is a procedure for this) it will generate the size and link it to the original image on the fly.

Collapse
Posted by Richard Hamilton on
Thank very much. What is that used for currently?

From what I can see, the {{yui-carousel}} includelet passes the full-sized image and the Javascript arranges the resize in the browser. I guess I would have to do the same if I create a new album view page that includes the YUI2 carousel?

Do you think the photo-album application should be updated to use this CR functionality rather than its own?

I cannot find a YUI3 carousel. Do you know if there is one?

Regards
Richard

Collapse
Posted by Dave Bauer on
I would basically not use Photo album at all, unless you somehow are tied to it.

For new code I would just create a CR folder, or use a existing folder ie, from xowiki, to store the images.

Even if you wanted some sort of "album" functionality, I would recommend implementing that as a plain CR folder, or a subtype of cr_folder, or using some sort of tag or categorization scheme. This would be much easier to use and get the images back out.

I basically took the image upload handling features (except for unzipping) from photo album and added them to the CR, so yes you could adapt photoalbum, and simplify it.

Collapse
Posted by Richard Hamilton on
Hmmm. I'll need to get clearer on a few things to do that.

I am tied to photo album in so far as I need three sizes, thumbnail, midsize, and full-size images, with the latter two slideshowable.

Regards
Richard

Collapse
Posted by Dave Bauer on
See

ad_proc -private image::get_convert_to_sizes {
} {
   List of sizes to convert an image to. List of maximum width x height.
   @author Dave Bauer (mailto:dave@solutiongrove.com)
   @creation-date 2006-08-27
 
} {
   #TODO make a parameter in content repository
        # avatar size to match gravatar.com
   return [list thumbnail 150x150 view 500x500 avatar 80x80]

Which apparently, I didn't make a parameter yet :)

Quick solution is to just add whatever sizes you want there.

Longer solution is to add the parameter to CR and use that.

Note these are square dimensions b/c it will make either dimension no larger than those sizes which retaining the aspect ratio of the original.

Collapse
Posted by Richard Hamilton on
Ok, well I could begin by having a look at adding the parameters! Probably could be a comma delimited list of max dimensions:

{avatar 80,thumbnail 150,view 500}

I would still need the bulk upload feature though. Perhaps I could rip that out and adapt it.

Which CR user interface do you use when working on things like this? xowiki?

I am not exactly clear exactly where and how the user interface for the batched image uploads would best live. Should that be a feature added to xowiki (bulk upload of content items) or added elsewhere?

Also, do we have a way to organise the display of xowiki objects in the admin pages into folders? I suppose if that were possible then there would be no reason at all not to go that route.

Richard

Collapse
Posted by Richard Hamilton on
Dave,

Last night I worked through the data model and confirmed that the photo album application does in fact use the CR. The only thing I can see that differs from your suggestion is that albums are of content_type pa_album instead of the more general content_type content_folder.

As the data model is basically sound it seems a shame to discard so much proven code. I think it would be ideal to have the existing code as a means of entering and organising images complete with Ajax ui already built, and be able to export images to an xowiki instance such that the exported images appear as xowiki::File entries. This would preserve the current bulk upload capability whilst allowing images to be used in xowiki.

I have mapped the data structure which I will post below for reference.

Richard

Collapse
Posted by Richard Hamilton on
-4
|
-100 content_folder - Name, pages
|
|_______989 ::xowiki::FormPage - Name, xowiki:916
|         |
|        1386 ::xowiki::File - Name, file02.jpg
|
|
979 content_folder - Name, photo-album_966
|
1040 pa_album - Name, myAlbum
|
1268 pa_photo - Name, file01.jpg
Collapse
Posted by Richard Hamilton on
As an experiment last night I tried changing the parent_id of the pa_photo cr_item 1268 from the pa_album 1040 to the ::xowiki::FormPage 989. I adjusted the name field to have the file: prefix and ensured that the content type was image/pjpeg. However, xowiki throws method dispatch errors presumably because the oo inheritance has not been constructed.

I'd like to be able to export images to an xowiki instance by creating a second cr_item for each exported image that is a child of the target xowiki instance. I don't know how to do this?

Collapse
Posted by Richard Hamilton on
Actually, the better way around might be to create an import function within xowiki that allows the selection of a pa_album from which all pa_photos would be imported. This way you could create an xowiki instance and import the contents of an existing photo album. Ideally this would simply be new pointers to the same content since we wouldn't want to store the images twice.

Regards
Richard

Collapse
Posted by Dave Bauer on
I don't have any opinions or advice on integrating with xowiki really.

I'd make the parameter a Tcl list, like it is now that's easier to deal with.

You don't even need the { } around the parameter value.

I have an idea for bulk uploads but I never implemented it. Processing a zip file into a bunch of CR objects should be pretty straightforward and might be something reusable.

Collapse
Posted by Richard Hamilton on
Yes. Where do you think such a general bulk CR upload tool should correctly sit? Subsite administration? User homepage?

I will have to ask Gustaf how one would make an existing CR item visible to an xowiki instance (so that it appeared in xowiki admin as an xowiki object). Is it a matter of flagging it as an instance of xowiki::object and how might this be achieved?

R.

Collapse
Posted by Jim Lynch on
If this:

{avatar 80,thumbnail 150,view 500}

is looked upon as a string, then it would need parsing to take apart into its elements.

If it's (interpreted as) a tcl list, the items (4) are:
- avatar
- 80,thumbnail
- 150,view
- 500
because a tcl list is delimited by space.

Notice in Dave's function he's actually constructing a list to return. Dave, is there another function that takes this list and does something with it?

If the answer is yes, then having a different form would involve conversion from the list Dave returns, and also conversion to it.

Richard, is what you want for this to be more englishlike and more readable?

-Jim

Collapse
Posted by Michael Aram on
Richard,

I was also thinking about implementing something like an xowiki-based photo album application, but did not have the time yet (and probably will not in the near future).

However I want to share some thoughts, i.e. what my approach would maybe look like:

1) Using XoWiki-Folders (i.e. FormPages based on the folder.form) as albums. (alternatively, define a new form album.form similar to the folder.form)
2) Using the page_order field to define the order among the photos in the album.
3) Optionally defining an {{albums}} includelet, which can be used on the wiki startpage to display the subfolders (i.e. albums) in a special way (teaser image,...)
3) Defining a special index page for the "album folders", which holds another new includelet "grid-view", which displays the folder's photos as "thumbnails" in a typical "gallery style".
4) Using yui-carousel for the "sideshow" mode of the album.

In fact, I think it would be great to focus on the possibility to create albums, slideshows, etc. for ANY type of xowiki page (not only images). For example, if you allow not only images, but also pages to be used by the "slideshow" includelet, this would be super flexible (e.g. the user could add "separator pages" for each island in a sailing trip album).

Please note, that many of the features mentioned above are still under development, which means one would have to digg into the xowiki code, maybe enable experimental features like the Menubar, etc...

Collapse
Posted by Gustaf Neumann on
Before you are wondering, what Michael Aram is talking about: xowiki has several new functionalities, many of those are not committed to the public cvs. One of those are the folder-procs, which provide means for organizing xowiki content in folders. The main reason, why the folder-procs are not in the public cvs is that these contains code, which i am not content with, therefore i was quiet about it. But maybe, i will remove/deactivate these parts and commit to cvs, to make the communication easier. With the folder-procs, one can activate the menu-bar and the folder display.

To see this in action, look at http://alice.wu-wien.ac.at:8000/xowiki/images/carousel-test

The code has as well bulk-upload, etc. I am these weeks very busy (xotcl 2.0, most busy time at the university, new study programs, external evaluations, fighting for budgets, track chair on a large conference, etc.), but maybe i can spend some time in the evening on that.

-gustaf neumann

PS: Richard, you should check from time to time your mailbox.

Collapse
Posted by Richard Hamilton on
Gustaf,

Thank you for the reply. I am very sorry that I missed the posts in between my own. That was because I was posting them from my cellphone in a moving car which took me a while! 😊

I am stunned by the new capabilities. That looks absolutely amazing. If at any stage I can be of assistance please let me know.

Regards and many thanks
Richard

Collapse
Posted by Gustaf Neumann on
i have committed the two experimental file menu-procs and folder-procs to cvs. To activate it, set the package parameter MenuBar to 1.
Collapse
Posted by Richard Hamilton on
Oh fantastic, thank you. I shall do that immediately!

Regards
Richard

Collapse
Posted by Richard Hamilton on
Well that sounds like a list of excellent ideas! I'd love to work towards those goals, and whilst it will take me a little while to become familiar with coding using xotcl, I am more than willing to devote the time to learning how to.

I am not sure what the next step would be, so shall I wait to hear from you or is there something I can be working on?

Regards
Richard

Collapse
Posted by Richard Hamilton on
Photo Album objects seem to be associated with three content_types. However, curiously the package names associated with these are not all 'photo_album' as might have been expected:

The basic photo-album package registers the following:

object_type              package_name
~~~~~~~~            ~~~~~~~~~
pa_album                  pa_album
pa_photo                  pa_photo

A comment in the code mentions that the former content_type pa_image has been deprecated in favour of using the general content repository content_type 'image'. The 'image' type is therefore not in fact registered by the photo-album package and its package name is also 'image':

object_type              package_name
~~~~~~~~            ~~~~~~~~~~~~
image                        image

A later addition intended to act as a simple clipboard for creating presentations adds this:

object_type              package_name
~~~~~~~~            ~~~~~~~~~~~~
photo_collection        photo_album

I am not entirely sure what the intended standard is with respect to setting the package_name attribute, but certainly where a package owns a content type I would have expected the package_name attribute to reflect that relationship.

Nevertheless, pa_album and pa_photo as content_types are used in a way analogous to the new ::xowiki::Folder for grouping content items together. A pa_album contains pa_photos, and a pa_photo always contains three cr_items which point to revisions of the originally uploaded image, the autogenerated 'view' image, and the autogenerated thumbnail image.

-4
|
-100 content_folder - Name, pages
|
|
979 content_folder - Name, photo-album_966
|
1040 pa_album - Name, myAlbum
|
1268 pa_photo - Name, file01.jpg
|
|___1270 view
|
|___1271 base
|
|___1272 thumbnail

When I start working on an includelet to provide an alternative to photo-album within xowiki, do you think it will be reasonable to create an ::xowiki::Folder for each image uploaded, and have the content repository autogenerate the thumnail and the view image for each uploaded image according to parameters passed in the includelet declaration?

i.e.

{{xophoto_album -autogenerate {view width "" thumb width ""} }}

(NB. This assumes aspect ratio to be preserved)

There seems to be a good case for generating thumbnails and intermediate 'view' sized images on the server in order to reduce the bandwidth requirements for the intended YUI based photo-display carousel. Otherwise, the server would have to send all the full sized images across to the browser and the browser would have to do the re-sizing.

My plan is to present an initial set of thumbnails in a carousel with a single view image on display (similar to existing photo-album but using asynchronous requests instead of refreshing the whole page). User action would then trigger additional thumbnails and view images to be retrieved from the server as required, as per this YUI2 demo:

http://developer.yahoo.com/yui/examples/carousel/csl_dynload2.html

The base image display would be a separate display mode which becomes a simple slideshow of full sized images (as per the existing {{yui-carousel}} includelet), with each being loaded asynchronously 'under the fold' and being displayed when ready.

At this stage I would be grateful for comments and suggestions.

Regards
Richard

Collapse
Posted by Dave Bauer on
Package_name refers to pl/sql package for the pl/sql procedures associated with that type. On postgresql its the first half of the function names ie: image__new.

If you want the content repository to generate thumbnails, a simple solution is to use the image content type and reference the image urls like so:

mysite.com/image/${image_id}/thumbnail

This will generate the resized image on the first reference and just download the correct size thereafter.

There are also image::* tcl procedures to do this if you want to generate the thumbnails on upload.

Collapse
Posted by Richard Hamilton on
Dave,

Thank you. It would be great to have the creation of thumbnails and potentially intermediate sized images completely abstracted into the content repository. I have spent the last hour or so hacking away at an example image in an effort to get it to show up in an xowiki instance, but I think it won't unless it is a subtype of an xowiki content type such as ::xowiki::File.

Perhaps the question I need to ask is how easy would it be to extend the functionality you have described to work on ::xowiki::File objects of mime type 'image/pjpeg'?

Collapse
Posted by Richard Hamilton on
So am I correct in thinking that once an image is uploaded, you call:

image::resize [ -item_id item_id ] [ -revision_id revision_id ] [ -size_name size_name ]

and the CR automatically creates the new sizes and stores them as children of the item_id.

To retrieve them you call:

image::get_size_item_id [ -item_id item_id ] [ -size_name size_name ]

specifying the appropriate image size or use the virtual url handler you described.

R.

Collapse
Posted by Dave Bauer on
Yes you have it correct.
Collapse
Posted by Richard Hamilton on
I have been testing some new display options for the xowiki yui-carousel includelet which makes good use of the content repository image re-sizing features.

Along the way I have been testing performance with quite large numbers of thumbnails, and I happened to notice that the imagemagick default quality for a 90 x 60 .jpg thumbnail results in a 25KB+ image. This is way too big since I can produce a thumbnail visually indistinguishable from it in about 2.5KB using Photoshop.

As a quick and dirty performance improvement I can simply manually re-process the cached thumbnail files, but I thought it might be a useful addition to enable the required default output quality to either be passed in when the procs are called or put in an OpenACS kernel parameter alongside the path to ImageMagick.

Any thoughts?

Regards
Richard

Collapse
Posted by Torben Brosten on
Hi Richard,

The only thought I have is try GraphicsMagick in place of ImageMagick since it's geared more to speed and conserving resources.

cheers,

Torben

Collapse
Posted by Richard Hamilton on
Torben,

Thank you for the reply.

ImageMagick has many command-line parameters and one of them is '-quality'. You pass it a number between 1 and 100 where 1 is poorest and 100 is best. It is supposed to default to the detected quality of the original but I suspect that this is not happening.

My suggestion really is in terms of exposing this option through the OpenACS CR API regardless of the image processor used.

Regards
Richard

Collapse
Posted by Richard Hamilton on
Further to earlier post, I have been playing around with the files and have discovered that most of the data in these thumbnails is color profile data.

If I vary the -quality parameter, the image size doesn't change much, but if I remove the colour profile information my 28KB thumbnail drops to 2.5KB as expected.

An embedded profile in a thumbnail is really not necessary, however the CR and xowiki code is designed to work at any image size. I wonder therefore if it be handy to be able to pass through to the image resize proc whether or not to remove the color profile. Certainly, this could then be supported as a parameter in the yui-carousel includelet.

My version of ImageMagick is old and so I have to do:

convert +profile '' -quality 45% in.jpg out.jpg

For newer versions you can use the -strip parameter.

I will try compiling GraphicsMagick as Torben suggested because ImageMagick won't compile on my (rather old!) linux distribution.

Regards
Richard

Collapse
Posted by Dave Bauer on
OK, here is what I recommend.

Change the return style from image::convert_to_sizes to return something like this:

[list [list thumbnail {-strip -resize 150x150} view {-strip -resize 500x500]]

and fix the callers to intepret the new format. Since this is a private procedure and it is only called in two places, and only one place actually uses the dimensions part of the size specification.

Collapse
Posted by Richard Hamilton on
Dave,

That sounds like a good suggestion. The only problem I foresee with that is that putting -strip in there will cause an error on earlier versions of ImageMagick.

It would also be useful to apply a change to the xowiki specific image resizing code.

Regards
Richard