Vanilla 1 is no longer supported or maintained. If you need a copy, you can get it here.
HackerOne users: Testing against this community violates our program's Terms of Service and will result in your bounty being denied.

Flickr integration without server side code

DavidKDavidK New
edited March 2007 in Vanilla 1.0 Help
I've written the code for a Flickr extension that doesn't require any server side processing. It uses the JSON format of the Flickr API, and the way I've written it would only require the end user to input thheir Flickr username rather than their RSS feed. I'd like a hand in bringing this extension to the Vanilla community, especially as a friend is hosting Vanilla on my server and I want to give him this extension so that my server load decreases ;) In essence... if you have UI code already comprised of JavaScript, HTML and perhaps CSS. How should I go about packaging that to make it an extension for Vanilla? Things that need to be in the package: User Account -> Field to store their Flickr username. Admin Control -> Field to store the quantity of thumbnails rendered. Admin Control -> Field to store the number of thumnails per row. Member Info Page -> JavaScript to do all the snazziness, accessing the three fields above. Member Info Page -> HTML to render the container that the JavaScript writes to. If anyone knows where I should start, then please let me know. I'm new to Vanilla (as in, this is my first post and I'm not running it), I just want to provide you all with an extension that works well and has a benefit of increasing performance of Vanilla (which in turn helps my server). Cheers David K


  • Options
    There's also the flickr badge, albeit rather limited. Eg.
    <script type="text/javascript" 
    But anyhow, I'd recommend looking at Mark's Flickrizer extension for a good, simple example of the user account field and member info page html. It might be easiest to simply have an easily edited value inside the extension for the adminstration options, though. Creating a whole UI and storing mechanism for two integers seems a little impractical.
  • Options
    DavidKDavidK New
    edited December 2006
    That user_id bit is the ugly bit ;)

    The JavaScript I've written converts a friendly username (in my case 'the boy on the bike') into the Flickr user_id (in my case 13442381@N00). So the differentiator is that the user isn't expected to know anything other than their username... they don't have to look up weird identifiers or dig around for RSS feed URL's.

    Also, because the JavaScript is inline, no part of the page will wait upon an external resource before loading. So pages render instantly, and then only when everything local is fetched does the onload event fire and the Flickr images get written to the page. So the user experience is really good as your site always appears responsive even at those times that Flickr does go slightly slower.

    Anyhow, anyone wanting to see how I did it can look at the blog entry I knocked up this morning:

    And there's a demo here:

    I'll look at the Flickrizer extension in a little while and see what sense I can make of it :) Thanks for the tip.
  • Options
    MarkMark Vanilla Staff
    edited December 2006
    First of all, I wouldn't limit the number of thumbnails per row - I'd just let it flow with whatever space is available (as my current one does).

    I'm also not going to bother with the quantity of thumbnails to render. The rest can be easily accomplished by reviewing the existing Flickrizer extension:

    <?php /* Extension Name: Flickrizer Extension Url: Description: Allows users to add their flickr photostream to their account Version: 0.1 Author: Mark O'Sullivan Author Url: */ // Define the required Customizations for this extension $Context->Configuration['CUSTOMIZATION_FLICKR_URL'] = ''; $Context->SetDefinition('CUSTOMIZATION_FLICKR_URL', 'Flickr RSS Url'); $Context->SetDefinition('CUSTOMIZATION_FLICKR_URL_DESCRIPTION', 'You can add your recent Flickr photostream to your account by providing the url to your flickr rss feed.'); $Context->SetDefinition('FlickrPhotostream', 'Flickr Photostream'); // Attach to the user account being viewed if there is no postback action if ($Context->SelfUrl == 'account.php' && ForceIncomingString('PostBackAction', '') == '') { // Retrieve the photostream before the page is rendered so errors can be trapped properly function Account_RetrieveFlickrPhotostream(&$Account) { // If there is a flickr stream defined, retrieve the feed $FlickrRSSUrl = $Account->User->Customization('CUSTOMIZATION_FLICKR_URL'); if ($FlickrRSSUrl != '') { $FlickrRSS = OpenURL($FlickrRSSUrl, $Account->Context); if ($FlickrRSS) { $Images = array(); $Titles = array(); $Links = array(); $Lines = explode("\n", $FlickrRSS); $Length = count($Lines); $FoundLinks = 0; for ($i = 0; $i < $Length; $i++) { if (strpos($Lines[$i], '<media:thumbnail url="') !== false) { $Image = trim(str_replace('<media:thumbnail url="', '', $Lines[$i])); $Images[] = substr($Image, 0, strpos($Image, '"')); } elseif (strpos($Lines[$i], '<media:title>') !== false) { $Title = trim(str_replace(array('<media:title>','</media:title>'), array('', ''), $Lines[$i])); $Titles[] = $Title; } elseif (strpos($Lines[$i], '<link>') !== false) { $FoundLinks++; if ($FoundLinks > 2) { $Link = trim(str_replace(array('<link>', '</link>'), array('',''), $Lines[$i])); $Links[] = $Link; } } } $ImageCount = count($Images); $TitleCount = count($Titles); $LinkCount = count($Links); if ($ImageCount == $TitleCount && $TitleCount == $LinkCount && $ImageCount > 0) { $Photostream = '<h2>'.$Account->Context->GetDefinition('FlickrPhotostream').'</h2> <div id="FlickrStream" class="clearfix">'; for ($i = 0; $i < $ImageCount; $i++) { $Photostream .= '<a href="'.$Links[$i].'" style="background-image: url('.$Images[$i].');" title="'.$Titles[$i].'">&nbsp;</a>'; } $Photostream .= '</div>'; $Account->DelegateParameters['FlickrPhotostream'] = $Photostream; } } } } // Render the photos, which have been stored in the FlickrPhotos Delegate Parameter function Account_RenderFlickrPhotostream(&$Account) { if (array_key_exists('FlickrPhotostream', $Account->DelegateParameters)) { echo $Account->DelegateParameters['FlickrPhotostream']; } } $Context->AddToDelegate('Account', 'Constructor', 'Account_RetrieveFlickrPhotostream'); $Context->AddToDelegate('Account', 'PostProfileRender', 'Account_RenderFlickrPhotostream'); $Head->AddStylesheet('extensions/Flickrizer/style.css'); } ?>

    Yours would be quite similar:

    <?php /* Extension Name: Flickrizer 2 Extension Url: Description: Allows users to add their flickr photostream to their account Version: 0.1 Author: You Author Url: n/a */ // Define the required Customizations for this extension $Context->Configuration['CUSTOMIZATION_FLICKR_USERNAME'] = ''; // Note: By defining a Configuration variable that begins with "CUSTOMIZATION_", you are adding a // customization to the user accounts page. This means that an input will now appear on that // "Personal Information" form under "Other Settings" // Now we make a couple of dictionary entries for the labels that will appear around the customization // input: $Context->SetDefinition('CUSTOMIZATION_FLICKR_USERNAME', 'Flickr Username'); $Context->SetDefinition('CUSTOMIZATION_FLICKR_USERNAME_DESCRIPTION', 'You can add your recent Flickr photostream to your account by providing your flickr username.'); // Attach to the user account being viewed if there is no postback action if ($Context->SelfUrl == 'account.php' && ForceIncomingString('PostBackAction', '') == '') { // I'm assuming your javascript will render it's thumbs to the screen by identifying an element and // then adding contents to the page after it using some wacky DOM navigation. I also made your js // file a php file because you're going to need to render the javascript dynamically so you can get // the user's name. $Head->AddScript('extensions/Flickrizer2/functions.php?user_id='.ForceIncomingInt("u", $Context->Session->UserID)); } ?>

    Your functions.php file will need to be modelled after one of the ajax pages, like so:

    <?php // Description: File used by Flickrizer 2 extension to get some dynamic information to be rendered by javascript. include('../../appg/settings.php'); include('../../conf/settings.php'); include('../../appg/init_ajax.php'); $UserID = ForceIncomingInt('user_id', 0); // Don't bother doing anything if the user isn't valid if ($UserID > 0) { // Retrieve a full user object for the requested user_id: $um = $Context->ObjectFactory->NewContextObject($Context, 'UserManager'); $User = $um->GetUserById($UserID); // Get the user's CUSTOMIZATION_FLICKR_USERNAME setting: $FlickrUsername = $User->Customization('CUSTOMIZATION_FLICKR_USERNAME'); // Only render the stuff if the flickr username was entered by the user if (ForceString($FlickrUsername, '') != '') { // Set a definition for the heading above the flickr thumbnails - this would then have // to be used in your javascript somewhere. $Context->SetDefinition('FlickrPhotostream', 'Flickr Photostream'); // Render your javascript, using the $FlickrUsername where necessary // ... } } // Finally, clean up the context object $Context->Unload(); ?>

    None of this code has been tested, and obviously you've still got to fill in your javascript...

    Hope this helps!
  • Options
This discussion has been closed.