Google custom search - manual load/execute from url params - javascript

Getting some odd behavior from google custom search that I can't seem to suss out. Maybe someone has a clue.
I'm putting together a Magento site, which has its own internal search engine - but is limited to product only. I want to implement google custom search results on the search results page as well. I figure I should be able to simply execute a search based on the query vars in the url (to return all the non-product content), as such:
<section style="min-height:600px">
<div style="background-color:#DFDFDF; min-height:800px; width:100%;">
<div id="cse">Loading</div>
</div>
<script src="http://www.google.com/jsapi" type="text/javascript"></script>
<script type="text/javascript">
//<![CDATA[
$(document).ready( function(){
console.log('search initiated');
var t = window.setTimeout( function(){ customSearch(); }, 5000 );
});
function customSearch(){
var q = urlParams()['q'];
if (q != undefined && q != ""){
console.log('q : %s', q); //outputs successfully
google.load('search', '1');
google.setOnLoadCallback(function () {
var customSearchControl = new google.search.CustomSearchControl(MY CUSTOM ID KEY);
var cseDrawOptions = new google.search.DrawOptions();
cseDrawOptions.setAutoComplete(true); //unknown if this is required...
customSearchControl.draw('cse',cseDrawOptions);
customSearchControl.execute(q);
}, true);
}
}
function urlParams(){
var vars = [];
var hash;
var index = window.location.href.indexOf('?');
if( index != -1 ){
var hashes = window.location.href.slice(index + 1).split('&');
for(var i = 0; i < hashes.length; i++){
hash = hashes[i].split('=');
vars.push(hash[0]);
vars[hash[0]] = hash[1].replace(/\+/g, " ");
}
}
return vars;
}
//]>
</script>
</section>
I'll note that I've pulled all other content out of the logic (but its implementation in magento is identical).
So the behavior goes like this: page loads fine (I'm delaying the google search with a timeout for testing purposes ). Assuming there is a query var in the url the console traces out as expected. Then the page just gets wiped out, with no content back from google. "Wiped out"... meaning all elements on teh page disappear, or are getting overwritten by a new page that google loads. As if the search control isn't creating an iframe - its just replacing the page with a <body>-less html page.
I've ready a number of articles on the subject, and gone over the API - this code looks like it should work. But clearly isn't.
What am I missing?
Cheers -
UPDATE
Continued messing around with this has revealed that for whatever reason :
google.load('search', '1');
google.google.setOnLoadCallback( console.log('loaded') )
Was the cause of the replaced page issue. The responded page, however contained links to the search module that google is hosting. And if I manually linked those files (forgoing a google.load) then I could run a search as expected:
<script src="http://www.google.com/jsapi" type="text/javascript"></script>
<script src="http://www.google.com/uds/?file=search&v=1" type="text/javascript"></script>
<script type="text/javascript">
//<![CDATA[
... search logic
Then I found an alternate syntax on the google developers page that seemed to work as expected:
$(document).ready( function(){
google.load("search", "1", {"callback" : customSearch});
});
function customSearch(){
var q = urlParams()['q'];
if (q != undefined && q != ""){
var cseControl = new google.search.CustomSearchControl('MY CUSTOM KEY');
var cseDrawOptions = new google.search.DrawOptions();
cseDrawOptions.enableSearchResultsOnly()
cseControl.draw('cse', cseDrawOptions);
cseControl.execute(q);
}
}
Which works as expected. Only real problem at this point is the host of
Unsafe JavaScript attempt to access frame with URL http://mydomain from frame with URL http://www.google/cse?...
That now gets thrown.
I don't know how the two different versions of load syntax changes anything... but it seemed to of. Whatever the case, I'm unclear as to how to resolve these cross domain errors.
Thoughts would be great.

Nothin huh?
Well - I've basically worked out a good solution, using an alternate method that I think will be more flexible in the long run. Using googles RESTful API and simple jquery .ajax call, I can obtain good, controllable results with no cross-domain errors:
<div id="cse">Loading</div>
<script>
//https://developers.google.com/custom-search/v1/getting_started
//https://developers.google.com/custom-search/v1/using_rest#query-params
//https://developers.google.com/custom-search/v1/cse/list
var _url = "https://www.googleapis.com/customsearch/v1";
var _key = 'AIzaSy... your api key here';
var _cx = '001809... your engine id';
var _q = urlParams()['q']; //query param
jQuery(document).ready(function() {
$j.ajax({
url : _url,
type : 'GET',
dataType : 'jsonp',
data :{
key : _key,
cx : _cx,
q :_q
},
success : function(data, textStatus, jqXHR){ responseHandler(data); },
error : function(jqXHR, textStatus, errorThrown){ console.log('error: %s'), errorThrown},
beforeSend : function(){ console.log('sending request')},
crossDomain : true
});
});
function responseHandler( response, status) {
console.log(response);
var cse = $j('#cse'); // render vars as needed...
for (var i = 0; i < response.items.length; i++) {
var item = response.items[i];
cse.append( "<br>" + item.htmlTitle);
}
}
function urlParams(){
var vars = [];
var hash;
var index = window.location.href.indexOf('?');
if( index != -1 ){
var hashes = window.location.href.slice(index + 1).split('&');
for(var i = 0; i < hashes.length; i++){
hash = hashes[i].split('=');
vars.push(hash[0]);
vars[hash[0]] = hash[1];
}
}
return vars;
}
</script>
And you can too;D
Cheers

Related

Correct Javascript to get JSON info from Facebook Graph Query

I am trying to get the URL for all the photos of a facebook page.
How do I get the 'source' URL for this query and JSON structure:
https://developers.facebook.com/tools/explorer/145634995501895/?method=GET&path=19292868552%3Ffields%3Dalbums.fields(photos.fields(source))&version=v2.1
I am using this success callback from a JSONP request:
function(response) {
for (i = 0; i < **???response.albums.data.length???**; i++) {
alert(**???response.albums.data[i].photos.data[i].source???**)
}
}
Can you help me find the right structure for the parts with the astericks? Because it has two [i]'s i think i'm getting confused..
You need to make sure that you have this in your head:
<script type='text/javascript' src='//connect.facebook.net/en_US/sdk.js'></script>
<script type='text/javascript' src='workFromPage.js'></script>
Now on workFromPage.js
var pre = onload;
onload = function(){
if(pre)pre();
if(!FB)reload();
var photoURLs = [];
// change userId
// make sure you test for login and wrap around code below, if needed
FB.api('/userId/albums', function(resp){
if(resp && !resp.error){
for(var i in resp){
FB.api('/'+resp[i].id+'/photos', function(r){
if(r && !r.error){
for(var n in r){
photoURLs.push(r[n].source);
}
// access photoURLs here
}
}
}
}
}
}

ajax request headers without jquery

I have created the following JavaScript function to load images of a vehicle, or load the alternate image if it is not available. The problem is that this page is 1kb, meanwhile it has to load the entire jquery library at 85+kb just for this one function. So my question is, is there some way to accomplish the same without having to load the jQuery library?
function GetImages() {
var Query = location.search;
//If query exists
if ((Query != "") && (Query != "?")){
var chunks = Query.split("=");
//If passed the right parameter
if (chunks[0] == "?unit") {
var Unit = chunks[1];
for (var i=1; i<11; i++) {
var unitimageURL = "/pics/"+Unit+"-"+i+".png";
$.ajax({
type: 'HEAD',
url: unitimageURL,
async: false,
success: function() {
$('.pictures').append("<img src="+unitimageURL+" width=150 height=90 alt='Unit "+Unit+" Picture "+i+"'> ");
if ((i == 4) || (i ==8)) {
$('.pictures').append("<br>");
}
},
error: function() {
$('.pictures').append("<img src=nopic2.png width=150 height=90 alt='Unit "+Unit+" Picture "+i+"'> ");
if ((i == 4) || (i ==8)) {
$('.pictures').append("<br>");
}
}
});
}
}
}
else {
alert("No query");
}
}
Yes, there is a way - the good old var oRequest = new XMLHttpRequest(); way!
Don't forget to to set all the needed callbacks, check response statuses and everything will be fine.
To create a HEAD request, just specify "HEAD" as parameter to .open() method.
You will also need document.createElement() to append the results to your page (or you may use .innerHTML property as well.
Also, documentation like this http://www.tutorialspoint.com/ajax/what_is_xmlhttprequest.htm may be handy.

Inserting Google Adwords Conversion Tracking with Javascript or jQuery

I'm pretty new to javascript, and therein probably lies my problem. I'm trying to track AdWords conversions that occur within a widget on our site. The user fills in a form and the result from the widget is published in the same div without a page refresh. The issue I'm having is when I try to appendChild (or append in jQuery) both script elements in Google's code (shown below) the page gets 302 redirected to a blank Google page (or at least that's what it looks like through FireBug).
I'm able to provide a callback method for the results of the form, and that's where I'm trying to insert the AdWords tracking code. For reference, this is the code provided by Google:
<script type="text/javascript">
/* <![CDATA[ */
var google_conversion_id = 993834405;
var google_conversion_language = "en";
var google_conversion_format = "3";
var google_conversion_color = "ffffff";
var google_conversion_label = "bSpUCOP9iAIQpevy2QM";
/* ]]> */
</script>
<script type="text/javascript" src="http://www.googleadservices.com/pagead/conversion.js">
</script>
<noscript>
<div style="display:inline;">
<img height="1" width="1" style="border-style:none;" alt="" src="http://www.googleadservices.com/pagead/conversion/993834405/?label=bSpUCOP9iAIQpevy2QM&guid=ON&script=0"/>
</div>
</noscript>
Pretty standard stuff. So, what I'm trying to do is insert this into the results page using the callback method (which is provided). Frankly, I'm redirected no matter when I try to insert this code using js or jQuery (either on original page load or in the callback) so maybe the callback bit is irrelevant, but it's why I'm not just pasting it into the page's code.
I've tried a number of different ways to do this, but here's what I currently have (excuse the sloppiness. Just trying to hack my way through this at the moment!):
function matchResultsCallback(data){
var scriptTag = document.createElement('script');
scriptTag.type = "text/javascript";
scriptTag.text = scriptTag.text + "/* <![CDATA[ */\n";
scriptTag.text = scriptTag.text + "var google_conversion_id \= 993834405\;\n";
scriptTag.text = scriptTag.text + "var google_conversion_language \= \"en\"\;\n";
scriptTag.text = scriptTag.text + "var google_conversion_format \= \"3\"\;\n";
scriptTag.text = scriptTag.text + "var google_conversion_color \= \"ffffff\"\;\n";
scriptTag.text = scriptTag.text + "var google_conversion_label \= \"bSpUCOP9iAIQpevy2QM\"\;\n";
scriptTag.text = scriptTag.text + "/* ]]> */\n";
$('body').append(scriptTag);
$('body').append("<script type\=\"text\/javascript\" src\=\"http://www.googleadservices.com/pagead/conversion.js\" />");
//I have also tried this bit above using the same method as 'scriptTag' with no luck, this is just the most recent iteration.
var scriptTag2 = document.createElement('noscript');
var imgTag = document.createElement('img');
imgTag.height = 1;
imgTag.width = 1;
imgTag.border = 0;
imgTag.src = "http://www.googleadservices.com/pagead/conversion/993834405/?label=bSpUCOP9iAIQpevy2QM&guid=ON&script=0";
$('body').append(scriptTag2);
$('noscript').append(imgTag);
}
The really odd thing is that when I only insert one of the script tags (it doesn't matter which one), it doesn't redirect. It only redirects when I try to insert both of them.
I've also tried putting the first script tag into the original page code (as it's not making any calls anywhere, it's just setting variables) and just inserting the conversions.js file and it still does the redirect.
If it's relevant I'm using Firefox 3.6.13, and have tried the included code with both jQuery 1.3 and 1.5 (after realizing we were using v1.3).
I know I'm missing something! Any suggestions?
Nowadays it is convenient to use the Asynchronous Tag at http://www.googleadservices.com/pagead/conversion_async.js that exposes the window.google_trackConversion function.
This function can be used at any time. For example after submitting a form, like in your case.
See https://developers.google.com/adwords-remarketing-tag/asynchronous/
Update 2018
Situation changed and it seems that you have more options now with the gtag.js: https://developers.google.com/adwords-remarketing-tag/
If you're using jQuery in your pages, why don't you use the getScript method of the same to poll the conversion tracking script after setting the required variables?
This is what I usually do, once I've received a success response from my AJAX calls.
var google_conversion_id = <Your ID Here>;
var google_conversion_language = "en";
var google_conversion_format = "3";
var google_conversion_color = "ffffff";
var google_conversion_label = "<Your Label here>";
var google_conversion_value = 0;
if (100) {
google_conversion_value = <Your value here if any>;
}
$jQ.getScript( "http://www.googleadservices.com/pagead/conversion.js" );
This works just fine for me. If you want a more detailed example:
$.ajax({
async: true,
type: "POST",
dataType: "json",
url: <Your URL>,
data: _data,
success: function( json ) {
// Do something
// ...
// Track conversion
var google_conversion_id = <Your ID Here>;
var google_conversion_language = "en";
var google_conversion_format = "3";
var google_conversion_color = "ffffff";
var google_conversion_label = "<Your Label here>";
var google_conversion_value = 0;
if (100) {
google_conversion_value = <Your value here if any>;
}
$.getScript( "http://www.googleadservices.com/pagead/conversion.js" );
} // success
});
If you use other libraries such as Mootools or Prototype, I'm sure they have similar in-built methods. This AFAIK is one of the cleanest approaches.
this simple code worked for me (the $.getScript version didn't).
var image = new Image(1,1);
image.src = 'http://www.googleadservices.com/pagead/conversion/' + id + '/?label=' + label + ' &guid=ON&script=0';
// This takes care of it for jQuery. Code can be easily adapted for other javascript libraries:
function googleTrackingPixel() {
// set google variables as globals
window.google_conversion_id = 1117861175
window.google_conversion_language = "en"
window.google_conversion_format = "3"
window.google_conversion_color = "ffffff"
window.google_conversion_label = "Ll49CJnRpgUQ9-at5QM"
window.google_conversion_value = 0
var oldDocWrite = document.write // save old doc write
document.write = function(node){ // change doc write to be friendlier, temporary
$("body").append(node)
}
$.getScript("http://www.googleadservices.com/pagead/conversion.js", function() {
setTimeout(function() { // let the above script run, then replace doc.write
document.write = oldDocWrite
}, 100)
})
}
// and you would call it in your script on the event like so:
$("button").click( function() {
googleTrackingPixel()
})
In your Adwords account - if you change the conversion tracking event to "Click" instead of "Page Load" it will provide you with code that creates a function. It creates a snippet like this:
<!-- Google Code for Developer Contact Form Conversion Page
In your html page, add the snippet and call
goog_report_conversion when someone clicks on the
chosen link or button. -->
<script type="text/javascript">
/* <![CDATA[ */
goog_snippet_vars = function() {
var w = window;
w.google_conversion_id = <Your ID Here>;
w.google_conversion_label = "<Your value here if any>";
w.google_remarketing_only = false;
}
// DO NOT CHANGE THE CODE BELOW.
goog_report_conversion = function(url) {
goog_snippet_vars();
window.google_conversion_format = "3";
window.google_is_call = true;
var opt = new Object();
opt.onload_callback = function() {
if (typeof(url) != 'undefined') {
window.location = url;
}
}
var conv_handler = window['google_trackConversion'];
if (typeof(conv_handler) == 'function') {
conv_handler(opt);
}
}
/* ]]> */
</script>
<script type="text/javascript"
src="//www.googleadservices.com/pagead/conversion_async.js">
</script>
Then in your code you just call:
goog_report_conversion();
Or for a link or image click:
click here
After trying everything the link Funka provided (http://articles.adamwrobel.com/2010/12/23/trigger-adwords-conversion-on-javascript-event) was what worked for me. Like he said it's scary to overwrite document.write, but
It seems like this is what you have to do unless you can load the script before the page load.
Since the script uses document.write so it needs to be re-written
document.write = function(node){ // exactly what document.write should of been doing..
$("body").append(node);
}
window.google_tag_params = {
prodid: pageId,
pagetype: pageTypes[pageType] || "",
value: "234324342"
};
window.google_conversion_id = 2324849237;
window.google_conversion_label = "u38234j32423j432kj4";
window.google_custom_params = window.google_tag_params;
window.google_remarketing_only = true;
$.getScript("http://www.googleadservices.com/pagead/conversion.js")
.done(function() {
// script is loaded.
});
See https://gist.github.com/c7a316972128250d278c
As you have seen, the google conversion tag only calls on a redraw. I had to make sure it was called when a part of a page was redrawn. (Due to some bad website design that I could not fix at the moment.) So I wrote a function to call from an onClick event.
Essentially, all you have to do is to call doConversion();
Here is what we ended up with:
// gothelp from from http://www.ewanheming.com/2012/01/web-analytics/website-tracking/adwords-page-event-conversion-tracking
var Goal = function(id, label, value, url) {
this.id = id;
this.label = label;
this.value = value;
this.url = url;
};
function trackAdWordsConversion(goal, callback) {
// Create an image
var img = document.createElement("img");
// An optional callback function to run follow up processed after the conversion has been tracked
if(callback && typeof callback === "function") {
img.onload = callback;
}
// Construct the tracking beacon using the goal parameters
var trackingUrl = "http://www.googleadservices.com/pagead/conversion/"+goal.id;
trackingUrl += "/?random="+new Date().getMilliseconds();
trackingUrl += "&value="+goal.value;
trackingUrl += "&label="+goal.label;
trackingUrl += "&guid=ON&script=0&url="+encodeURI(goal.url);
img.src = trackingUrl;
// Add the image to the page
document.body.appendChild(img);
// Don't display the image
img.style = "display: none;";
}
function linkClick(link, goal) {
try {
// A function to redirect the user after the conversion event has been sent
var linkClickCallback = function() {
window.location = link.href;
};
// Track the conversion
trackAdWordsConversion(goal, linkClickCallback);
// Don't keep the user waiting too long in case there are problems
setTimeout(linkClickCallback, 1000);
// Stop the default link click
return false;
} catch(err) {
// Ensure the user is still redirected if there's an unexpected error in the code
return true;
}
}
function doConversion() {
var g = new Goal(YOUR CODE,YOUR_COOKIE,0.0,location.href);
return linkClick(this,g);
}
I tried all the ways to manually include conversion.js, it all loaded the script, but didn't further execute what we needed inside the script, there's a simple solution.
Just put your conversion code in a separate HTML, and load it in an iframe.
I found code to do that at http://www.benjaminkim.com/ that seemed to work well.
function ppcconversion() {
var iframe = document.createElement('iframe');
iframe.style.width = '0px';
iframe.style.height = '0px';
document.body.appendChild(iframe);
iframe.src = '/track.html'; // put URL to tracking code here.
};
then just call ppcconversion() wherever in the JS you like to record it.
All I do is return the code (or in our case, an image) along with the "success" message in the callback.
When a contact form is submitted, or a registration form filled out and submitted, we post to a php script using jQuery, then output a "thank-you" message to a div:
"$first_name, Thanks for requesting more information. A representative will contact you shortly."
... followed by the 1x1 gif Google provides.
Here's the jQuery:
$.post('script.php',{'first_name':first_name,'last_name':last_name,'email':email,'phone1':phone1,'password':password,},function(data){
var result=data.split("|");
if(result[0] ==='success'){
$('#return').html(result[1] + $result[2]);
And the php...
echo 'success|'.$first_name.', Thanks for requesting more information.
A representative will contact you shortly.|<img height="1" width="1" alt="" src="http://www.googleadservices.com/pagead/conversion/xxxxxxxx/imp.gif?value=0&label=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&script=0"/>';
You might need to throw in a "document.location.reload();" if it isn't being picked up by google
For anyone still looking for a good solution to this, Google supports AJAX Conversions natively now through their Google Analytics API.
You can do it by making a event API call in Google Analytics. What you do is setup an Analytics event, tie it to a goal, then import that goal into AdWords as a conversion. It's a bit of a lengthy process but it's a clean solution.
Check out This Page for a tutorial
This works for me:
window.google_trackConversion({
google_conversion_id: 000000000,
conversion_label : "xxxxxxxxxxxx",
google_remarketing_only: false,
onload_callback : function(){
//do something :)
}
});

How to use bit.ly for Twitter

I'm developing a J2EE website with spring framework.
I want my website to share with Twitter but I couldn't succeed using bit.ly API. the function makes bit.ly link but in Twitter's share page I only see the full link.
How can I send the bit.ly link to Twitter?
The bit.ly response which I get from firebug:
BitlyCB.getBitlyUrl({"errorCode": 0, "errorMessage": "", "results": {"http://twitter.com/home?status=http://www.google.com": {"userHash": "dodUFu", "hash": "9KnUl2", "shortUrl": "http://bit.ly/dodUFu", "shortCNAMEUrl": "http://bit.ly/dodUFu", "shortKeywordUrl": ""}}, "statusCode": "OK"})
If you try http://twitter.com/home?status=http://www.google.com you can understand me.
My code is below:
<script type="text/javascript" charset="utf-8"
src="http://bit.ly/javascript-api.js?version=latest&login=mylogin&apiKey=mykey"></script>
<a class="_ffShare_"
onclick="onlyShortenUrl('http://twitter.com/home?status=http://mypage');">
<img src="http://yakup-laptop:8080/images/theme/default/twitter.png"></img>
</a>
function onlyShortenUrl(longUrl){
//single shortener
BitlyCB.getBitlyUrl = function(data) {
var shortUrl = extractShortUrl(data);
window.open(shortUrl,'_blank');
return shortUrl;
}
return BitlyClient.call('shorten', {'longUrl': longUrl}, 'BitlyCB.getBitlyUrl');
}
function extractShortUrl(data){
//bitly util method probably not useful standalone
var shortUrl = '';
var first_result;
// Results are keyed by longUrl, so we need to grab the first one.
for (var r in data.results) {
first_result = data.results[r]; break;
}
for (var key in first_result) {
shortUrl = r ;
}
return shortUrl;
}
Try changing:
for (var key in first_result) {
shortUrl = r ;
}
to
shortUrl = first_result.shortUrl;
If that doesn't work, please include the output (at that same point) of first_result:
console.log(first_result);

How to dynamically read RSS

I want to read multiple RSS feeds using jQuery.
I'm trying to write a flexible function that will just take the RSS URL and it will output only its TITLE AND IMAGE how to do that for multiple RSS URLs?
The easiest way would be to use the Google AJAX Feed API. They have a really simple example, which suits what you want nicely:
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("feeds", "1");
function initialize() {
var feed = new google.feeds.Feed("http://www.digg.com/rss/index.xml");
feed.load(function(result) {
if (!result.error) {
var container = document.getElementById("feed");
for (var i = 0; i < result.feed.entries.length; i++) {
var entry = result.feed.entries[i];
var div = document.createElement("div");
div.appendChild(document.createTextNode(entry.title));
container.appendChild(div);
}
}
});
}
google.setOnLoadCallback(initialize);
</script>
<div id="feed"></div>
Of course, you can mix jQuery with the API instead of using native DOM calls.
Have you seen this JQuery plug-in: http://plugins.jquery.com/project/jFeed
A little late to the party but I actually did something similar to this using the deviantART gallery feed and displaying the latest thumbnail. I wrapped it up into a couple of functions for easy use:
function keratin_callback(elem, data)
{
if (!data
|| !data.entries
|| data.entries.length < 1
|| !data.entries[0].mediaGroups
|| data.entries[0].mediaGroups.length < 1
|| !data.entries[0].mediaGroups[0].contents
|| data.entries[0].mediaGroups[0].contents.length < 1
|| !data.entries[0].mediaGroups[0].contents[0].thumbnails
|| data.entries[0].mediaGroups[0].contents[0].thumbnails.length < 1) {
$("<span>Data returned from feed not in expected format.</span>").appendTo(elem);
return;
}
var entry = data.entries[0];
$("<img>").attr("src", entry.mediaGroups[0].contents[0].thumbnails[0].url)
.appendTo(elem)
.wrap("");
}
function keratin(elem, url)
{
//keratin written by adam james naylor - www.adamjamesnaylor.com
if (!elem || elem.length < 1) return; //no element found
$.ajax({
//you could use document.location.protocol on the below line if your site uses HTTPS
url: 'http:' + '//ajax.googleapis.com/ajax/services/feed/load?v=1.0&num=10&callback=?&q=' + encodeURIComponent(url + '&cache=' + Date.UTC()),
dataType: 'json',
success: function(data) {
if (!data || !data.responseData) {
return keratin_callback(elem, null);
}
return keratin_callback(elem, data.responseData.feed);
}
});
}
$(document).ready(function() {
keratin($('#da_gallery'), 'http://backend.deviantart.com/rss.xml?q=gallery%3Adeusuk%2F28671222&type=deviation')
});
Full details here: http://www.adamjamesnaylor.com/2012/11/05/Keratin-DeviantART-Latest-Deviation-Widget.aspx

Categories

Resources