Sierra Trading Post: API Demo (recursive templates)
*Update 2011-10-07: Fix for API URLs that already contain querystring "?". Fix for current/previous URLs not using hash navigation.
by Adam Patridge
HTML
<script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script src="http://jquery-jsonp.googlecode.com/files/jquery.jsonp-2.1.4.min.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js"></script>
<script src="https://rawgithub.com/tkyk/jquery-history-plugin/master/jquery.history.js"></script>
<noscript>This demo is written completely in JavaScript. If you don't have it, or have it disabled, it will be far less exciting.</noscript>
<ul class="navigation">
<li>Current API URL: <a class="currentUrl" href="#">n/a</a></li>
<li>Previous API URL: <a class="previousUrl" href="#">n/a</a></li>
<li><a class="homeUrl" href="#/api/1.0/">Home</a></li>
<li><a href="#/api/1.0/brands/">Brands</a></li>
<li><a href="#/api/1.0/products/newproducts~21/">New Items</a></li>
<li><a href="#/api/1.0/products/clearance~1/">Clearance Items</a></li>
<li><a href="#/api/1.0/products/bargain-barn/">Bargain Barn Items</a></li>
</ul>
<div class="results"></div>
<div class="loading">
<img src="http://s.stpost.com/img/large-ajax-loader-circle.gif" alt="Loading..." />
<p>
Requesting: <span class="currentRequestUrl"></span>
</p>
<p>
<a class="cancelRequest" href="#">Cancel Request</a>
</p>
</div>
<script id="arrayItemTemplate" type="text/x-jquery-tmpl">
<li>
{{if null !== $data && "object" === typeof ($data)}}
{{if $data instanceof Array}}
[
<ul>
{{tmpl($data, { getTypeDisplay: $item.getTypeDisplay, getDataClass: $item.getDataClass, formatDisplay: $item.formatDisplay }) "arrayItemTemplate"}}
</ul>
]
{{else}}
{{tmpl($data, { getTypeDisplay: $item.getTypeDisplay, getDataClass: $item.getDataClass, formatDisplay: $item.formatDisplay }) "reflectTemplate"}}
{{/if}}
{{else}}
${$item.formatDisplay($data)}
{{/if}}
</li>
</script>
<script id="reflectTemplate"...
CSS
ul { border-left: 1px solid #aaa; margin-left: 15px; list-style-type: none; }
ul ul { border-bottom: 1px solid #aaa; }
li li { margin-left: 5px; }
.type-string { color: #A31515; }
.type-string a, .type-string a:visited, .type-string a:hover { color: #A31515; }
.type-null, .type-number { color: #281; }
.navigation { list-style-type: none; border: 1px solid #666; margin: 0 0 5px 0; }
JavaScript
$(function() {
var apiHost = "api.sierratradingpost.com",
apiKey = "xe5s5rpag9y4ear9bwxsu48e",
affiliateName = "CJ",
affiliateId = "1935257",
affiliateCjSid = "5456339",
// Don't advertise your developer key. This one is heavily throttled and changed if abuse is discovered.
startApiUrl = $(".homeUrl").attr("href").substring(1),
$loading = $(".loading"),
$currentRequestUrl = $(".currentRequestUrl"),
arrayItemTemplateCompiled = $.template("arrayItemTemplate", $("#arrayItemTemplate")),
reflectTemplateCompiled = $.template("reflectTemplate", $("#reflectTemplate")),
$resultsDiv = $(".results"),
$navigationList = $(".navigation"),
$previousUrl = $(".previousUrl"),
$currentUrl = $(".currentUrl"),
templateFunctions = {
getTypeDisplay: function(itemToCheck) {
var itemType = null === itemToCheck ? "null" : typeof(itemToCheck); // typeof(null) === "object"
itemType = "object" === itemType && itemToCheck instanceof Array ? "array" : itemType; // Arrays are objects first, must ask if it is an array.
return itemType;
},
getDataClass: function(itemToCheck) {
var itemType = typeof(itemToCheck),
result = itemType;
if (null === itemToCheck) {
result = "null";
}
return result;
},
formatDisplay: function(propertyValue) {
var toSmallDateString = function(value) {
var padTwo = function(num) {
return (num < 10) ? "0" + num : String("") + num;
};
return padTwo(value.getFullYear()) + "-" + padTwo(1 + value.getMonth()) + "-" + padTwo(value.getDate()) + "," + padTwo(value.getHours()) + ":" + padTwo(value.getMinutes()) + ":" + padTwo(value.getSeconds());
...