YANHTIWIDHTD: "Recent Photos" (aka Photostream) Widget

darryldarryl Registered Users Posts: 997 Major grins
OMGWTFLOLBBQ!! (10/23/2009) -- SMUGMUG HAS FINALLY IMPLEMENTED THIS. EVERYBODY PLEASE REMOVE THIS NASTY HACK AND JUST USE THE BUILT-IN HOMEPAGE WIDGET:
http://blogs.smugmug.com/release-notes/2009/10/23/animoto-better-viewing-and-homepage-goodies-for-all-october-22-2009/

(Now let's hope they add Recent Galleries soon too so JT can finally stop listing all 260 of his albums on the front page of http://jt.smugmug.com/ ! I kid because I love, guys!)

NOTICE (4/28/2009) -- [post=880843]Andy says[/post] they're have a Recent Photos "in the plans" (not "in the works"), so you might want to hold off on installing this.

Yet Another Nasty Hack That I Wish I Didn't Have To Do (#4 [post=659999]in[/post] [post=826860]a[/post] [post=688574]series[/post]?)

Took my "[post=688574]Recent Galleries[/post]" hack. Changed it to point at the RSS feed for Recent Photos. Removed all the gallery stuff to just display photos. Banged head on wall to figure out right CSS settings. Decided I didn't want to give up Popular Photos, so figured out how to create new Box that appears before Gallery Categories.

Ended up with this:

http://darryl.smugmug.com/

CSS:
/* For styling the new recentPhotos box */
#recentPhotos .boxSettings {
    padding: 10px;
}
#recentPhotos .note, #smugMaps .note {
    font-size: 11px;
}
#recentPhotos .boxBottom  {
    padding: 0;
}
#recentPhotos .boxBottom .photo {
    float: left;
    display: inline;
    width: 114px;
    height: 115px;
    clear: none;
    text-align: center;
    margin: 10px 5px 0 5px;
}

Header Javascript:
// RECENT PHOTOS HACK

// This hack inserts a new Recent Photos section ahead of your Gallery Categories section.
// Recent Photos are obtained via RSS, and yes, you can use different feeds that 
// return photos.
//
// RSS parsing code from Paul Sobocinski found here:
// http://www.xml.com/pub/a/2006/09/13/rss-and-ajax-a-simple-news-reader.html?page=5

// Specify how many recent photos you'd like to see (multiples of 6 work well)

var rsscount = 6;

// ImageCount needs to be "padded" if you have a lot of private galleries mixed in 
// with your public galleries

imagecount = rsscount + 6  ;

// Specify your RSS feed for Recent Photos - if your website is http://foo.smugmug.com then your XXXXXX is 
// foo.smugmug.com and your username (YYYYYY) would be foo.  If you're implementing this on a custom domain, then XXXXX 
// is your custom domain, and your username should be whatever your "hidden" foo.smugmug.com name is.

var rssurl = "http://XXXXXX/hack/feed.mg?Type=nicknameRecentPhotos&Data=YYYYYY&format=rss200&ImageCount=" + imagecount ; 

// Specify the section ID you want Recent Photos to load above.
// categoriesBox = displaying Categories, galleriesBox = displaying Galleries
// You could also put it above the userBio, featuredBox (Featured Galleries), 
// keywordsBox, mapBox, and datesBox.  Whatever you choose, the section
// *must* be showing on your home page or things will break.

var sectionBefore = 'categoriesBox' ;

// Specify the name you want to call your Recent Photos section.  (Maybe you like the sound
// of 'Photostream' better.)

var recentTitleText = 'Recent Photos' ;

// This calls the actual script.  You'll want to be careful about modifying anything below.

function checkhomepage() {
    if (YD.hasClass(document.body, "homepage")) {
        getRSS();
    }
}

YE.on(window, "load", checkhomepage) ;

//OBJECTS

//objects inside the RSS2Item object
function RSS2Enclosure(encElement)
{
	if (encElement == null)
	{
		this.url = null;
		this.length = null;
		this.type = null;
	}
	else
	{
		this.url = encElement.getAttribute("url");
		this.length = encElement.getAttribute("length");
		this.type = encElement.getAttribute("type");
	}
}

function RSS2Guid(guidElement)
{
	if (guidElement == null)
	{
		this.isPermaLink = null;
		this.value = null;
	}
	else
	{
		this.isPermaLink = guidElement.getAttribute("isPermaLink");
		this.value = guidElement.childNodes[0].nodeValue;
	}
}

function RSS2Source(souElement)
{
	if (souElement == null)
	{
		this.url = null;
		this.value = null;
	}
	else
	{
		this.url = souElement.getAttribute("url");
		this.value = souElement.childNodes[0].nodeValue;
	}
}

//object containing the RSS 2.0 item
function RSS2Item(itemxml)
{
	//required
	this.title;
	this.link;
	this.description;

	//optional vars
	this.author;
	this.comments;
	this.pubDate;

	//optional objects
	// this.category;
	this.enclosure;
	this.guid;
	this.source;

	var properties = new Array("title", "link", "description", "author", "comments", "pubDate");
	var tmpElement = null;
	for (var i=0; i<properties.length; i++)
	{
		tmpElement = itemxml.getElementsByTagName(properties[i])[0];
		if (tmpElement != null)
			eval("this."+properties[i]+"=tmpElement.childNodes[0].nodeValue");
	}

	// this.category = new RSS2Category(itemxml.getElementsByTagName("category")[0]);
	this.enclosure = new RSS2Enclosure(itemxml.getElementsByTagName("enclosure")[0]);
	this.guid = new RSS2Guid(itemxml.getElementsByTagName("guid")[0]);
	this.source = new RSS2Source(itemxml.getElementsByTagName("source")[0]);
}

//objects inside the RSS2Channel object
function RSS2Category(catElement)
{
	if (catElement == null)
	{
		this.domain = null;
		this.value = null;
	}
	else
	{
		this.domain = catElement.getAttribute("domain");
		this.value = catElement.childNodes[0].nodeValue;
	}
}

//object containing RSS image tag info
function RSS2Image(imgElement)
{
	if (imgElement == null)
	{
	this.url = null;
	this.link = null;
	this.width = null;
	this.height = null;
	this.description = null;
	}
	else
	{
		imgAttribs = new Array("url","title","link","width","height","description");
		for (var i=0; i<imgAttribs.length; i++)
			if (imgElement.getAttribute(imgAttribs[i]) != null)
				eval("this."+imgAttribs[i]+"=imgElement.getAttribute("+imgAttribs[i]+")");
	}
}

//object containing the parsed RSS 2.0 channel
function RSS2Channel(rssxml)
{
	//required
	this.title;
	this.link;
	this.description;

	//array of RSS2Item objects
	this.items = new Array();

	//optional vars
	this.language;
	this.copyright;
	this.managingEditor;
	this.webMaster;
	this.pubDate;
	this.lastBuildDate;
	this.generator;
	this.docs;
	this.ttl;
	this.rating;

	//optional objects
	// this.category;
	this.image;

	var chanElement = rssxml.getElementsByTagName("channel")[0];
	var itemElements = rssxml.getElementsByTagName("item");

	for (var i=0; i<itemElements.length; i++)
	{
		Item = new RSS2Item(itemElements[i]);
		this.items.push(Item);
		//chanElement.removeChild(itemElements[i]);
	}

	var properties = new Array("title", "link", "description", "language", "copyright", "managingEditor", "webMaster", "pubDate", "lastBuildDate", "generator", "docs", "ttl", "rating");
	var tmpElement = null;
	// this.category = new RSS2Category(chanElement.getElementsByTagName("category")[0]);
	this.image = new RSS2Image(chanElement.getElementsByTagName("image")[0]);
}

//PROCESSES

//uses xmlhttpreq to get the raw rss xml
function getRSS() {

    recentTitle = document.createElement("h3") ;
    recentTitle.id = 'recentTitle' ;
    recentTitle.className = 'title notopmargin' ;
    recentTitle.innerHTML = recentTitleText ;

    spacerDiv = document.createElement("div");
    spacerDiv.className = "spacer";

    recentBoxTop = document.createElement("div") ;
    recentBoxTop.className = 'boxTop' ;
    recentBoxTop.appendChild(recentTitle) ;
    recentBoxTop.appendChild(spacerDiv) ;
  
    var recentBox = document.createElement("div");
    recentBox.id = 'recentPhotos' ;
    recentBox.className = 'box' ;
    recentBox.appendChild(recentBoxTop) ;

    var catBox = document.getElementById(sectionBefore) ;
    catBox.parentNode.insertBefore(recentBox,catBox);

	//call the right constructor for the browser being used
	if (window.ActiveXObject)
		xhr = new ActiveXObject("Microsoft.XMLHTTP");
	else if (window.XMLHttpRequest)
		xhr = new XMLHttpRequest();
	else
		alert("not supported");

	//prepare the xmlhttprequest object
	xhr.open("GET",rssurl,true);
	xhr.setRequestHeader("Cache-Control", "no-cache");
	xhr.setRequestHeader("Pragma", "no-cache");
	xhr.onreadystatechange = function() {
		if (xhr.readyState == 4)
		{
			if (xhr.status == 200)
			{
				if (xhr.responseText != null)
					processRSS(xhr.responseXML);
				else
				{
					alert("Failed to receive RSS file from the server - file not found.");
					return false;
				}
			}
			else
				alert("Error code " + xhr.status + " received: " + xhr.statusText);
		}
	}

	//send the request
	xhr.send(null);
}

//processes the received rss xml
function processRSS(rssxml)
{
	RSS = new RSS2Channel(rssxml);
	showRSS(RSS);
}

//shows the RSS content in the browser
function showRSS(RSS)
{

    recentList = document.createElement("div");
    recentList.id = 'recentPhotosList' ;

//populate the items

    for (var i=0; i<rsscount && i<RSS.items.length; i++)
    {
        galimage = RSS.items[i].description;
        galimage = galimage.replace(/^.+src="(.*?)" .*/, "$1") ;
        galimage = galimage.replace(/(.*-)Th(-\d+)?(\.\w+)/i, "$1Ti$2$3") ;

        caption = RSS.items[i].title ;
        caption = caption.replace(/darryl's photo/, '') ;

        // Fix up date formatting

        if (RegExp.$4>12) { meridian = 'pm'; hrs = RegExp.$4-12 } else { meridian = 'am'; hrs = RegExp.$4-0 } ;

        fixdate = "updated: " + RegExp.$2 + " " + RegExp.$1 + ", " + RegExp.$3 + " " + hrs + ":" + RegExp.$5 + meridian + " PST" ;

        photoBox = document.createElement("div");
        photoBox.className = "photo";

        photoLink = document.createElement("a");
        photoLink.setAttribute("href", RSS.items[i].link);
        photoLink.className = "photoLink" ;
        photoBox.appendChild(photoLink);

        photoImg = document.createElement("img");
        photoImg.setAttribute("border", "0");
        photoImg.setAttribute("alt", caption);
        photoImg.setAttribute("title", caption);
        photoImg.src = galimage;
        photoImg.className = "imgBorder";
        photoLink.appendChild(photoImg);

        recentList.appendChild(photoBox);
    
        // insertAfter(miniBox, divTags[0].childNodes[divTags[0].childNodes.length-2]);

    }

    spacerDiv1 = document.createElement("div");
    spacerDiv1.className = "spacer";

    recentBoxBottom = document.createElement("div") ;
    recentBoxBottom.className = 'boxBottom' ;
    recentBoxBottom.appendChild(recentList) ;
    recentBoxBottom.appendChild(spacerDiv1) ;

// HERE'S WHERE YOU CHOOSE WHETHER YOU WANT RECENT PHOTOS TO "POP UP" BEFORE ANOTHER 
// SECTION, LIKE categoriesBox

    recentBox = YD.get('recentPhotos');
    recentBox.appendChild(recentBoxBottom) ;

    //we're done
    return true;
}

var xhr;

Comments

  • devbobodevbobo Registered Users, Retired Mod Posts: 4,339 SmugMug Employee
    edited July 24, 2008
    darryl wrote:
    Body Tag:
    <body onload="doOnLoad();">
    

    Hey Darryl,

    Looks good...instead adding the body tag stuff, how about adding the following line of code to your javascript block...
    YE.on(window, "load", getRSS);
    

    Cheers,

    David
    David Parry
    SmugMug API Developer
    My Photos
  • AndyAndy Registered Users Posts: 50,016 Major grins
    edited July 24, 2008
    darryl wrote:
    NOTICE -- [post=880843]Andy says[/post] they're have a Recent Photos in the works
    :nono

    I said "in the plans" which means we're talking about 'em."

    "in the works" means it's being worked on, which I did not say :D
  • darryldarryl Registered Users Posts: 997 Major grins
    edited July 24, 2008
    devbobo wrote:
    Looks good...instead adding the body tag stuff, how about adding the following line of code to your javascript block...

    Thanks David -- incorporated above.
    andy wrote:
    I said "in the plans" which means we're talking about 'em."

    "in the works" means it's being worked on, which I did not say

    Sorry Andy -- I suppose it was a wishful reading of your post. :-}

    I think I was just surprised to see you chiming in on such a geeky original request. (Extra divs? What was I thinking!?)
  • darryldarryl Registered Users Posts: 997 Major grins
    edited October 24, 2009
    OMGWTFLaughing.gifBBQ!! SMUGMUG HAS FINALLY IMPLEMENTED THIS. EVERYBODY PLEASE REMOVE THIS NASTY HACK AND JUST USE THE BUILT-IN HOMEPAGE WIDGET:
    http://blogs.smugmug.com/release-notes/2009/10/23/animoto-better-viewing-and-homepage-goodies-for-all-october-22-2009/

    (Now let's hope they add Recent Galleries soon too so JT can finally stop listing all 260 of his albums on the front page of http://jt.smugmug.com/ ! I kid because I love, guys!)
Sign In or Register to comment.