Matte: Theme HOWTO: Album View
The Matte album view allows people to view the media items within a shared album.
In many ways it is analogous to an album slide show. The primary purpose of the album
view is to allow a user to view the media items within an album. Thus it must provide
a way for the user to move between the items within the album in some way, and can
also support showing detailed information about each item.
An album in the Woosh browse view.
Sample album data model
The album data model includes the album the item is shared in
(a <m:album>
element). The album will have the items within the album
available (as child <m:item>
elements) but those items will not
have their detailed metadata elements available (i.e. they will not have
<m:metadata>
elements).
Here is a sample of the album data model:
Woosh - Dissection
Here is a dissection of the Woosh album theme so you can see where the elements come from
the Matte XML data model.
An album in the Woosh album view.
The Woosh theme presents an album with all media items displayed as thumbnails in a
scrolling widget at the top of the page (#3). Clicking on individual thumbnails loads a full-size
version of that item in the center of the page (#4), and also displays detailed information about
that item in another widget on the right side of the page. (#5) Let's take a look at the numbered
items from this snippet in more detail:
-
Page title: Woosh displays the album name and the
album date as the page title.
-
Album date: Albums can have a user-specifed date
(the @album-date
attribute). If the album has been
modified, it will have a @modify-date
. An album will
always have a @creation-date
for the date it was
created. Knowing this, Woosh attempts to display the user-specified
album date. If the album does not have an album date, it looks
for the album's modification date. If it does not have a
modification date, it uses the album creation date.
The overall XSLT that generates the title (name and date)
looks like this:
- <xsl:template match="m:album" mode="title">
- <xsl:value-of select="@name"/>
- <xsl:if test="string-length(@name) > 0">
- <xsl:text> - </xsl:text>
- </xsl:if>
- <xsl:variable name="date">
- <xsl:choose>
- <xsl:when test="@album-date">
- <xsl:value-of select="@album-date"/>
- </xsl:when>
- <xsl:when test="@modify-date">
- <xsl:value-of select="@modify-date"/>
- </xsl:when>
- <xsl:when test="@creation-date">
- <xsl:value-of select="@creation-date"/>
- </xsl:when>
- </xsl:choose>
- </xsl:variable>
- <xsl:value-of select="date:format-date(substring($date, 1, 19), 'yyyy.MM.dd')"/>
- </xsl:template>
-
Thumbnail navigation: here Woosh generates
thumbnails for all the items in the album dynamically using
JavaScript on the client's browser. To do this, it generates
an array of data based on all the items available in the album.
Matte provides an XSLT template that is useful for this
purpose:
- <!--
- Template: m:item, mode album-data
-
- Render album data JavaScript array. The data array is ordered
- as follows:
-
- 0: itemId
- 1: original width
- 2: original height
- 3: collection-relative path
- 4: name
- 5: comment
- 6: create date
- 7: icon width
- 8: icon height
- 9: mime type
- -->
- <xsl:template match="m:item" mode="album-data">
- <xsl:text>[</xsl:text>
- <xsl:value-of select="@item-id"/>
- <xsl:text>,</xsl:text>
- <xsl:value-of select="@width"/>
- <xsl:text>,</xsl:text>
- <xsl:value-of select="@height"/>
- <xsl:text>,"</xsl:text>
- <xsl:call-template name="javascript-string">
- <xsl:with-param name="output-string" select="@path"/>
- </xsl:call-template>
- <xsl:text>","</xsl:text>
- <xsl:call-template name="javascript-string">
- <xsl:with-param name="output-string" select="@name"/>
- </xsl:call-template>
- <xsl:text>","</xsl:text>
- <xsl:if test="m:comment">
- <xsl:call-template name="javascript-string">
- <xsl:with-param name="output-string" select="normalize-space(m:comment)"/>
- </xsl:call-template>
- </xsl:if>
- <xsl:text>","</xsl:text>
- <xsl:value-of select="date:format-date(substring(@creation-date,1,19),'dd MMM yyyy')"/>
- <xsl:text>",</xsl:text>
- <xsl:value-of select="@icon-width"/>
- <xsl:text>,</xsl:text>
- <xsl:value-of select="@icon-height"/>
- <xsl:text>,"</xsl:text>
- <xsl:value-of select="@mime"/>
- <xsl:text>"]</xsl:text>
- <xsl:if test="position() != last()">
- <xsl:text>,</xsl:text>
- </xsl:if>
- </xsl:template>
The way Woosh calls this template is like this:
- var imageData = [
- [-1,-1,-1,"dummy/path","dummy name","dummy comment","dummy date"],
- <xsl:apply-templates select="$display-album/m:item" mode="album-data"/>
- ];
Which generates JavaScript like this:
- var imageData = [
- [-1,-1,-1,"dummy/path","dummy name","dummy comment","dummy date"],
- [8,1024,683,"_6A_1392.jpg","_6A_1392.jpg","","17 Dec 2006",,,"image/jpeg"],
- [10,1024,683,"IMG_0868.jpg","IMG_0868.jpg","","17 Dec 2006",,,"image/jpeg"],
- [12,512,768,"IMG_0848.jpg","IMG_0848.jpg","","17 Dec 2006",,,"image/jpeg"],
- [14,1024,683,"_19_1404.jpg","_19_1404.jpg","","17 Dec 2006",,,"image/jpeg"],
- [16,1024,683,"IMG_0871.jpg","IMG_0871.jpg","","17 Dec 2006",,,"image/jpeg"],
- [18,512,768,"IMG_5164.jpg","IMG_5164.jpg","","17 Dec 2006",,,"image/jpeg"]
- ];
In order to generate URLs to Matte resources, such as the
thumbnail images, the JavaScript needs to know the server path
it should use. Matte makes this available to themes, so Woosh
generates some more JavaScript data to pass this to the client:
- <xsl:variable name="root-album" select="/x:x-data/x:x-model/m:model/descendant::m:album[1]"/>
- <script type="text/javascript">
- var albumKey = '<xsl:value-of select="$root-album/@anonymous-key"/>';
- var webContext = '<xsl:value-of select="$web-context"/>';
- var serverName = '<xsl:value-of select="$server-name"/>'
- var serverPort = '<xsl:value-of select="$server-port"/>'
- var myLang = '<xsl:value-of select="$user-locale"/>'
- </script>
Now the client has all the information it needs to dynamically
generate the thumbnail images. The JavaScript (simplified here)
looks like this:
- var albumKey = '2XlxVfKHja3CFGtMlyG57ofbchw';
- var webContext = '/matte';
- var serverName = 'localhost'
- var serverPort = '8080'
- var myLang = 'en_US'
- for ( var i = 0; i < imageData.length; i++ ) {
- var data = imageData[i];
- var url = webContext +"/media.do?id="+data[0]
- +"&albumKey=" +albumKey
- +"&size=THUMB_NORMAL&quality=GOOD";
- var alt = data[4] ? data[4] : data[3];
- var img = document.createElement("img");
- img.setAttribute("src", url);
- img.setAttribute("alt", alt);
- img.className = "tb-thumbnail";
- $('slider-container').appendChild(img);
- }
Here you can see Woosh is generating <img> elements for each item,
setting the src
attribute to the Matte /media.do
URL for generating images. Woosh has hard-coded the media size to be a
normal sized thumbnail.
-
Full size image: The process of generating full-size images is similar
to how the thumbnails images are generated. Woosh does it in this
way (again, simplifed here):
- function displayImage(imageNumber) {
- var newImg = document.createElement("img");
- var newImgUrl = webContext
- +"/media.do?id="+imageData[imageNumber][0]
- +"&albumKey=" +albumKey
- +"&size=" +imgSize
- +"&quality=" +imgCompress;
- var title = imageData[imageNumber][4]
- ? imageData[imageNumber][4]
- : imageData[imageNumber][3];
- newImg.title = title;
- newImg.alt = title;
- newImg.onload = function() {
- handleDisplayImageLoad(newImg, imageNumber);
- }
- newImg.src = newImgUrl;
- }
-
- function handleDisplayImageLoad(newImg, imageNumber) {
- $('image-frame').appendChild(newImg);
- updateImageInfo(imageNumber);
- }
Note the call to updateImageInfo()
at the
bottom. We discuss that next.
-
Image detail information: Matte themes can utilize another
URL for generating detailed information about a single media item.
The URL is /viewMediaItemInfo.do
and Woosh uses this
via an AJAX call to populate this information here.
The updateImageInfo()
method uses the Prototype
Ajax.Updater
class to call the detail URL and place the
result into the page. The JavaScript looks like this:
- function updateImageInfo(imageNumber) {
- Element.addClassName('ii-imageMetaFrame', 'updating');
- new Ajax.Updater(
- {success : 'ii-imageMetaFrame'},
- webContext +'/viewMediaItemInfo.do',
- {
- method : 'get',
- parameters : "albumKey="+albumKey +"&itemId=" +imageData[imageNumber][0]
- +"&themeId=" +themeId,
- onSuccess : function(t) {
- Element.removeClassName('ii-imageMetaFrame', 'updating');
- },
- onComplete : function() {
- workingUpdaterAjaxHandler.manualStop();
- }
- });
- }
The @anonymous-key
of the album being viewed and
the @item-id
of the item you want to view the details for
are passed to the /viewMediaItemInfo.do
URL (as the
albumKey
and itemId
URL parameters, respectively).
Next: Detail View
Continue next with information on how the
Detail View handles returning
the detailed information for a single item.