While the Pando "Send-to-Web" preview is quick and easy, it doesn't always fit exactly as desired into an existing site design. If you'd like to design your own package previews, one easy way to do this is using the Pando Javascript API. The API makes the package metadata available to Javascript, so you need not write any server-side code to generate custom package previews. In addition to the information in the "Send-to-Web" preview, the Package Info Web Service also gives you real-time reports of the number of downloads and the expiration date.
For comparison, here is how to do previews in PHP.
Let's say we want to be able to display a package preview containing the thumbnail, title, number of times downloaded and number of days to expiration (or days since expiration). We want the title and thumbnail to link to the package URL only if it is not expired. We want it to look something like:

Since we'll be writing Javascript to generate our HTML preview, it helps to have a good sense of what we expect that output to look like before we start.
<table class="pandopackage"><tr>
<td class="packagethumb" align="center" valign="center">
<a href="[Package URL]"><img src="[Thumbnail URL]" alt=""></a>
</td>
<td class="packagemeta" valign="center">
<span class="ptitle"><a href="[Package URL]">Title</a></span>
<p>
Downloaded <strong>N</strong> times<br>
<span style="color: green;">Expires in X days</span><br>
</p>
</td>
</tr></table>
Note: For this example we're using a table based layout primarily because the Pando thumbnail is a variable size (maximum size is 100 pixels x 75 pixels, but it can be smaller in any dimension). If we want to center the thumbnail image both vertically and horizontally in a way that works in most browsers, a table cell is the most reliable way.
Accompanied with the following css, we get a nicely formatted image preview:
table.pandopackage {
border: 1px solid green;
float: left;
margin-right: 10px;
}
.pandopackage td.packagethumb {
width: 100px;
height: 75px;
text-align: center;
}
.pandopackage .packagethumb img {
border: 0;
vertical-align:middle;
}
.pandopackage td.packagemeta {
margin: 0 0 0 10px;
padding: 0;
width: 150px;
font-family: Verdana, Arial, sans-serif;
font-size: 11px;
}
.pandopackage .packagemeta span.ptitle {
font-family: 'Lucida Grande', Arial, sans-serif;
font-size: 14px;
font-weight: bold;
margin: 0 1em 0 0;
}
In order to generate the HTML with the appropriate metadata for our preview, we'll need a callback function for PandoAPI.js to call that can accept the packageInfo array and construct the appropriate HTML. The following callback function will calculate the number of days till/since expiration, determine whether the package is expired, generate a title and thumbnail string (only wrapped in an anchor tag if the image is not expired), get the number of package downloads and construct an HTML string that looks like our target HTML. You can follow along in the comments:
function printPackageCallBack(packageInfo) {
//Get number of days till expiration (negative = expired)
var days = Math.round( (new Date(packageInfo['expirationDate']) - new Date()) / 86400000);
//store expiration status
var expired = (days >= 0) ? 0 : 1;
//use absolute values of days for a readable string
days = Math.abs(days);
//get title from package info
var title = packageInfo['title'];
if (title.length > 30) {
title = title.substring(0,28) + '...';
}
//generate img tag with thumbnail from package info
var thumb = "<img src='"+ packageInfo['thumbnailURL'] +"' alt='' />";
//generate anchor tag from package URL; assumes packageKey is set
var packageA = "<a href='" + PandoAPI.getPackageURL(packageId,packageKey) + "'>";
//get appropriately pluralized X day(s) string
var daystring = days +' day'+ ( (days > 1) ? ('s') : ('') );
//get # of downloads from package info
var dl = packageInfo['downloads'];
//if package is not expired, link the title and thumbnail to the package URL
// and set the expiration days string accordingly
if(!expired) {
title = packageA + title + '</a>';
thumb = packageA + thumb + '</a>';
daystring = '<span style="color: green;">Expires in '+ daystring +'</span><br />';
//otherwise, do not link the title/thumbnail, and set expiration string accordingly
} else if (!packageInfo['expirationDate']) {
daystring = '<span style="color: green;"><strong>Never expires</span></strong><br />'
title = packageA + title + '</a>';
thumb = packageA + thumb + '</a>';
} else {
daystring = '<span style="color: red;">Expired '+ daystring +' ago</span><br />';
}
//generate human-friendly Downloaded X times / Never Download string
if(dl > 0)
dlstring = 'Downloaded <strong>'+dl+'</strong> time'+( (dl > 1) ? ('s') : ('') );
else
dlstring = 'Never downloaded';
//write out the package preview
out = ("\r\n<table class='pandopackage'>\r\n<tr>\r\n\t<td valign='center' align='center'
class='packagethumb'>\r\n\t\t"+ thumb + '\r\n\t</td>\r\n\t<td valign="center"
class="packagemeta">\r\n\t\t<span class="ptitle">'+ title +'</span>\r\n\t\t<p>\r\n\t\t'
+ dlstring +'<br />\r\n\t\t'+ daystring +'\r\n\t\t</p>\r\n\t</td>\r\n</tr>\r\n</table>'
);
document.write(out);
}
Now, if we call PandoAPI.getPacakgeInfo with a package id, key and the above callback function, it will write directly into our page:
<script type="text/javascript">
PandoAPI.getPackageInfo('5AEDE982393976A10050F2EC7C20C3C5EFDE0BBB',
printPackageCallBack,
'C51E9F2767B6747A9C9841AF7EEB9CC0E967D5B37CEC05B8C9DF310A03958AD2');
</script>
That works fine, but document.writes are a little crude and the function call is a little tricky to construct correctly. Also, if the javascript fails to load (e.g., due to a temporary service outage), it could stop our entire page from loading from the point where we include the script. A common practice is to put remotely-dependent javascript code just above the </body> tag, so if it fails to load, it doesn't affect the rest of the page. However, if we do this, we could only write our package preview to the end of the page.
To make the function call to generate the preview a little simpler, we can write a wrapper function that accepts the package URL as an input (which is easy to acquire), parses out the package id and key and then invokes PandoAPI.getPackageInfo with the correct parameters. E.g.,
function parsePandoUrl(url) {
var parts = url.split('?',2);
var args = parts[1];
parts = args.split('&');
for(var i=0; i<parts.length; i++) {
if(parts[i].match(/^id=[A-Z0-9]*/))
packageId = parts[i].substring(3);
if(parts[i].match(/^key=[A-Z0-9]*/))
packageKey = parts[i].substring(4);
}
}
function showPackage(url) {
parsePandoUrl(url);
PandoAPI.getPackageInfo(packageId,printPackageCallBack,packageKey);
}
Now we can display a package preview for a particular package URL, like so:
<script type="text/javascript">
showPackage('http://cache.pando.com/soapservices/package.pando?
id=5AEDE982393976A10050F2EC7C20C3C5EFDE0BBB
&key=C51E9F2767B6747A9C9841AF7EEB9CC0E967D5B37CEC05B8C9DF310A03958AD2');
</script>
And finally, in order to be able to call this function just before the closing <body> tag, we can change our call to document.write in the callback function to instead modify the "innerHTML" contents of an existing element on the page. For this example, we'll assume there's an empty <div> tag with the id of "packagedetails" somewhere on the page. We can then swap out document.write with:
document.getElementById('packagedetails').innerHTML = out;
Here is a stand-alone HTML implementation. [final custom javascript] [final custom css]. Feel free to use these on your web site as is, or extend them any way you like!
If you have questions, or want to share what you've come up with, post a comment below!
Comments
In the callback function, if
In the callback function, if the package has infinite expiration, you'll get "Expired NaN days ago". I've solved it adding this code after the if(!expired):
} else if (!packageInfo['expirationDate']) {
daystring = '<span style="color: green;"><strong>Never expires</span></strong><br />'
title = packageA + title + '</a>';
thumb = packageA + thumb + '</a>';
}
Somebody corrects it!
-David
David, Good point! I didn't
David,
Good point! I didn't have a "never expires" package available when I built this example. I'll come back and revise it when I have a moment.
Scott
I've found another thing
I've found another thing that may result into a bug. The function that parses the URL splits the parts from the "&" symbol. I'm putting this preview in a BBCode, and the (PHP) board automatically converts the "&" in "& ;", so the function doesn't work. Altought it's easy to fix, it may cause confusion.
-David
If the package you want to
If the package you want to post has a long title, the box will get deformed. For me, this code fixed that problem:
if (title.length > 30) {
title = title.substring(0,28) + '...';
}
-David
Could you do a tutorial for
Could you do a tutorial for dummies? lmao oooh i don't understand any of this!!! :(
Plz could you do what i suggested above or like... upload all the necesary files and tell me what folders to put them in etc. so i could modify them so i've got at least a rubbish one that actually works. Thanks ;)
Well, the easiest thing to
Well, the easiest thing to do is just use the cut-and-paste "Send to Web" preview widget straight out of the Pando app. Perhaps you could describe your particular scenario a little? I might be able to write something up that targets more specifically what it is you want to do. Things that would be helpful to know:
* HTML "mock up" of what you want the end result for a package to look like
* Server context (which scripting language(s) are you using? Are you using a particular CMS or framework?)
* What is the source of the packages you are publishing? Are they your own? User submitted? Etc.
- Scott
David, Thanks for your
David,
Thanks for your helpful feedback. I've included your code snippets into the example code on the page (and in the linked static versions at the end) for folks.
I am currently using SMF. I
I am currently using SMF. I would just like the default one to work first so then i could edit the CSS and the images etc. later. The packeges are user submitted.
As i say... i would just like the bog-standard package preview,and if you could show me how to do it or do it and tell me where to uplod the files. E.G. Specific folders if needed that'd be so helpful. Thanks :)
awyett, Have you tried
awyett,
Have you tried copying the three files linked under "Bringing it all together"? You need the HTML file, the CSS file and the JS file linked. To make life easier, I just dumped the css and javascript into one big HTML file which you can get from here. Just click the link and then save the HTML file to your hard drive.
should i separate the
should i separate the html/javascript/css parts??? if so... what should i call them? should i put them in he same folder? and how would i link it to my forum?
awyett, This is just a
awyett,
This is just a simple example showing you how the tools work, not a fully practical example. The answer to your questions depends pretty specifically on your particular environment and more specifically what it is you want to do.
What's wrong with asking users to provide the generic "Send-to-Web" preview? This should be much easier to implement. If you want to go the javascript route, you'll definitely need to link the .js file in to your template and it'd probably be easier to maintain the css separately, so you'd have to link that in too. If you're not sure how to do that, I'd first learn a little more about how to integrate custom javascript and css into SMF. Figuring out how to embed multiple previews in a page given the above code is tricky.
Because SMF is php based, it'd probably be a LOT easier to use php to generate previews based on the package URL instead of using javascript.
Hello, it is possible to
Hello, it is possible to know the raised bytes a file with pando api? the idea is to create a progress bar that indicates the raised percentage of of a file until this complete one, so that at the moment only file size is known the file
Robin, I think you mean the
Robin,
I think you mean the "uploaded" bytes of the file. And no. You can only get the total file size, not the progress of an incomplete upload from the web services API.
oh thanks, are one hurts
oh thanks, are one hurts that not it can
What would you like to do?
What would you like to do? Perhaps we can think of another way to do what you want.
- Laird Popkin, CTO, Pando Networks
hello thanks for your
hello thanks for your answer, which I want is to make a bar under a box with the information of upload of pando
in my forum to know whatever is the percentage of ascent that has a file in the pando server like this
when it begins that it marks zero and as is risen the file is filled the bar
how to translate pando
how to translate pando