I'm Building a widget for blogger
<script type="text/javascript">
function mycallback(json) {
for (var i = 0; i < json.feed.entry.length; i++) {
for (var j = 0; j < json.feed.entry[i].link.length; j++) {
if (json.feed.entry[i].link[j].rel == 'alternate') {
var postUrl = json.feed.entry[i].link[j].href;
break;
}
}
var postTitle = json.feed.entry[i].title.$t;
var postSummary = json.feed.entry[i].summary.$t;
var Thumb = json.feed.entry[i].media$thumbnail.url;
var item = '<div class="wrapper"><img src='+ Thumb +' /><h3><a href=' + postUrl + '>' + postTitle + '</h3></a><p>' + postSummary + '</p></div>';
document.write(item);
}
}
</script>
<script src="https://smag-soratemplates.blogspot.com/feeds/posts/summary?max-results=5&alt=json-in-script&callback=mycallback"></script>
but if there is no image in the post or cant find .media$thumbnail.url
the widget stops working , anyone know how to fix that ? or to show an alternative image?
sorry i'm a beginner
If it's failing when the thumbnail does not exist, then you can put a check for the thumbnail
<script type="text/javascript">
function mycallback(json) {
for (var i = 0; i < json.feed.entry.length; i++) {
for (var j = 0; j < json.feed.entry[i].link.length; j++) {
if (json.feed.entry[i].link[j].rel == 'alternate') {
var postUrl = json.feed.entry[i].link[j].href;
break;
}
}
var postTitle = json.feed.entry[i].title.$t;
var postSummary = json.feed.entry[i].summary.$t;
var Thumb = json.feed.entry[i].media$thumbnail.url;
if( typeof Thumb == "undefined" ) {
Thumb = '/Your custom image url';
}
var item = '<div class="wrapper"><img src='+ Thumb +' /><h3><a href=' + postUrl + '>' + postTitle + '</h3></a><p>' + postSummary + '</p></div>';
document.write(item);
}
}
</script>
<script src="https://smag-soratemplates.blogspot.com/feeds/posts/summary?max-results=5&alt=json-in-script&callback=mycallback"></script>
You need to use or(||) in the Thumb definition like that
var Thumb = json.feed.entry[i].media$thumbnail.url || 'https://i.imgur.com/5WMAvAu.gif';
Here, if json.feed.entry[i].media$thumbnail.url is undefine/false/null, Thumb is set to 'https://i.imgur.com/5WMAvAu.gif' as your default image.
You need to check that all of the values are present:
json.feed.entry[i].media$thumbnail.url
as any of these items could be null / undefined:
json
json.feed
json.feed.entry[i]
json.feed.entry[i].media$thumbnail
json.feed.entry[i].media$thumbnail.url
At the least, you should check:
if(json.feed.entry[i].media$thumbnail && json.feed.entry[i].media$thumbnail.url)
Also, it's probably worth rewriting this code as follows:
let entry = json.feed.entry[i];
to save yourself some typing (and to stop all the object look ups each time when using dots to reference nested objects).
The code then becomes:
let url = '';
if (entry.media$thumbnail && media$thumbnail.url) {
url = entry.media$thumbnail.url;
}
else {
url = 'the default image URL';
}
Thank you all i found the solution
by replacing this code
var Thumb = json.feed.entry[i].media$thumbnail.url;
with this code
if (json.feed.entry[i].media$thumbnail)
{
Thumb = json.feed.entry[i].media$thumbnail.url;
}
else
{
Thumb= "'Image url'";
}
Related
I am using the script below to show the latest 5 posts on my Blogger blog. How can I wrap the first and last 2 posts in different div containers? Currently all the 5 posts are inside a wrapper container stored in the item variable:
<script type='text/javascript'>
function mycallback(json) {
for (var i = 0; i < json.feed.entry.length; i++) {
for (var j = 0; j < json.feed.entry[i].link.length; j++) {
if (json.feed.entry[i].link[j].rel == 'alternate') {
var postUrl = json.feed.entry[i].link[j].href;
break;
}
}
var postTitle = json.feed.entry[i].title.$t;
var postAuthor = json.feed.entry[i].author[0].name.$t;
var postSummary = json.feed.entry[i].summary.$t;
var entryShort = postSummary.substring(0,400);
var entryEnd = entryShort.lastIndexOf(" ");
var postContent = entryShort.substring(0, entryEnd) + '...';
var postImage = json.feed.entry[i].media$thumbnail.url.replace('s72-c/','s1600/');
var item = '<div class="wrapper"><img src="' + postImage + '"/><h3><a href=' + postUrl + '>' + postTitle + '</h3></a><span>'+ postAuthor + '</span><p>' + postContent + '</p></div>';
document.write(item);
}
}
</script>
<script src="/feeds/posts/summary?orderby=published&max-results=5&alt=json-in-script&callback=mycallback"></script>
More generic solution would not check for last and previous to last elements checking for 3 or 4 but should be based on total length of your posts (it can be 3 it can be 10000).
Checks below should be place in your loop.
if(i === 0 || i === 1)
Always use === operator as it is typesafe.
Also group your checks in a way that is easy to understand (check for first and second in one if and for last and previous to last in another if:
if(i === json.feed.entry.length || i === json.feed.entry.length - 1) - this check is based on length of your entries, not some fixed value like 3 or 4.
This way if your displayed entries value will change in future (to ex. 10), you don't need to adjust your code here. All code you write should strive to work without such adjustments when code it uses changes.
Check desired elements through loop
// to check first or fourth element
if (i == 0 || i == 3)
// to check second or fifth element
if (i == 1 || i == 4)
Wrap them by adding HTML tages
<script type='text/javascript'>
function mycallback(json) {
for (var i = 0; i < json.feed.entry.length; i++) {
for (var j = 0; j < json.feed.entry[i].link.length; j++) {
if (json.feed.entry[i].link[j].rel == 'alternate') {
var postUrl = json.feed.entry[i].link[j].href;
break;
}
}
var postTitle = json.feed.entry[i].title.$t;
var postAuthor = json.feed.entry[i].author[0].name.$t;
var postSummary = json.feed.entry[i].summary.$t;
var entryShort = postSummary.substring(0,400);
var entryEnd = entryShort.lastIndexOf(" ");
var postContent = entryShort.substring(0, entryEnd) + '...';
var postImage = json.feed.entry[i].media$thumbnail.url.replace('s72-c/','s1600/');
var item = '<div class="wrapper"><img src="' + postImage + '"/><h3><a href=' + postUrl + '>' + postTitle + '</h3></a><span>'+ postAuthor + '</span><p>' + postContent + '</p></div>';
if (i == 0 || i == 3) document.write('<div>');
document.write(item);
if (i == 1 || i == 4) document.write('</div>');
}
}
</script>
<script src="/feeds/posts/summary?orderby=published&max-results=5&alt=json-in-script&callback=mycallback"></script>
Moving on from my previous question. Same little project. Different inquiry altogether.
Here's the updated code:
<script type="text/javascript">
function recentpostslist(json) {
document.write('<ul>');
var i;
var j;
for (i = 0; i < json.feed.entry.length; i++)
{
for (j = 0; j < json.feed.entry[i].link.length; j++) {
if (json.feed.entry[i].link[j].rel == 'alternate') {
break;
}
}
var postUrl = "'" + json.feed.entry[i].link[j].href + "'";//bs
var postTitle = json.feed.entry[i].title.$t;
var item = "<h2>" + '' + postTitle + " </h2>";
document.write(item);
}
document.write('</ul>');
}
</script>
<script src="https://xxxxxxxxxx.blogspot.com/feeds/posts/summary/-/recommended?max-results=3&alt=json-in-script&callback=recentpostslist"></script>
What it does is list the titles of a blog's 3 latest posts that have been labeled "recommended".
I figured I might declare another variable, just above the var item definition, as in...
var postContent = json.feed.entry[i].content.$t;
...and add that to the 'var item' value, as in...
var item = "<h2>" + '' + postTitle + " </h2> <p>" + postContent + "</p>";
...or something like that; my intention being to include posts' content (not just title) to what's being displayed.
But that doesn't seem to work. Am I missing something?
The URL you're using contains the word summary; if you use default instead, the json data will also contain the content, apparently.
I have a web page where I am reading Google Blogger blog category from his feed using JSON. I have two functions. First on is getting all the Blog Categories List and second one is taking Blog Categories from that and then hitting again Blog to get latest posts from that This is the text test to see that web page data is here or not.
<div id="blogCategoriesList">
<script type="text/javascript">
var blogurl = "https://googleblog.blogspot.com/";
function blogCatList(json) {
document.write('<select onchange="showThisCatPosts(this.value)">');
document.write('<option>CHOOSE A CATEGORY</option>');
for (var i = 0; i < json.feed.category.length; i++)
{
var item = "<option value='" + json.feed.category[i].term + "'>" + json.feed.category[i].term + "</option>";
document.write(item);
}
document.write('</select>');
}
document.write('<script type=\"text/javascript\" src=\"' + blogurl + '/feeds/posts/default?redirect=false&orderby=published&alt=json-in-script&callback=blogCatList&max-results=500\"><\/script>');
document.write('<br/><br/><a href=\"' + blogurl + '\" target=\"_blank\" class=\"footerLINK\">Read The Blog Online Now<\/a>');
</script>
</div>
<div id="blogCategoriesPost">
<script style='text/javascript'>
var blogurl = "https://googleblog.blogspot.com/";
var numposts = 10; // Out Of 500
var displaymore = true;
var showcommentnum = true;
var showpostdate = true;
var showpostsummary = true;
var numchars = 100;
function blogCategoriesPost(json) {
if(json.feed.entry.length < numposts ){
numposts = json.feed.entry.length;
}
for (var i = 0; i < numposts; i++) {
var entry = json.feed.entry[i];
var posttitle = entry.title.$t;
var posturl;
if (i == json.feed.entry.length) break;
for (var k = 0; k < entry.link.length; k++) {
if (entry.link[k].rel == 'replies' && entry.link[k].type == 'text/html') {
var commenttext = entry.link[k].title;
var commenturl = entry.link[k].href;
}
if (entry.link[k].rel == 'alternate') {
posturl = entry.link[k].href;
break;
}
}
var postdate = entry.published.$t;
var cdyear = postdate.substring(0, 4);
var cdmonth = postdate.substring(5, 7);
var cdday = postdate.substring(8, 10);
var monthnames = new Array();
monthnames[1] = "Jan";
monthnames[2] = "Feb";
monthnames[3] = "Mar";
monthnames[4] = "Apr";
monthnames[5] = "May";
monthnames[6] = "Jun";
monthnames[7] = "Jul";
monthnames[8] = "Aug";
monthnames[9] = "Sep";
monthnames[10] = "Oct";
monthnames[11] = "Nov";
monthnames[12] = "Dec";
document.write('<div id="mainDIV">');
document.write('<h2 class="post_heading">' + posttitle + '</h2>');
if ("content" in entry) {
var postcontent = entry.content.$t;
} else
if ("summary" in entry) {
var postcontent = entry.summary.$t;
} else var postcontent = "";
var re = /<\S[^>]*>/g;
postcontent = postcontent.replace(re, ""); // Will Show Only Text Instead Of HTML
if (showpostsummary == true) {
if (postcontent.length < numchars) {
document.write('<span class="post_summary">');
document.write(postcontent);
document.write('</span>');
} else {
//document.getElementById("catPosts").innerHTML += '<span class="post_summary">';
document.write('<span class="post_summary">');
postcontent = postcontent.substring(0, numchars);
var quoteEnd = postcontent.lastIndexOf(" ");
postcontent = postcontent.substring(0, quoteEnd);
document.write(postcontent + '...');
document.write('</span>');
}
}
var towrite = '';
document.write('<strong class="post_footer">');
if (showpostdate == true) {
towrite = 'Published On: ' + towrite + monthnames[parseInt(cdmonth, 10)] + '-' + cdday + '-' + cdyear;
}
if (showcommentnum == true) {
if (commenttext == '1 Comments') commenttext = '1 Comment';
if (commenttext == '0 Comments') commenttext = 'No Comments';
commenttext = '<br/>' + commenttext + '';
towrite = towrite + commenttext;
}
if (displaymore == true) {
towrite = towrite + '<br/>Read Full Article -->';
}
document.write(towrite);
document.write('</strong></div>');
}
}
function showThisCatPosts(BLOGCAT){
document.write('<script type=\"text/javascript\" src=\"' + blogurl + '/feeds/posts/default/-/' + BLOGCAT + '?redirect=false&orderby=published&alt=json-in-script&callback=blogCategoriesPost&max-results=500\"><\/script>');
document.write('<a href=\"' + blogurl + '\" target=\"_blank\" class=\"footerLINK\">Read The Blog Online Now<\/a>');
}
</script>
You can see a working DEMO at JSBIN. My problem is that when page load, its works perfectly showing all page data and the blog categories lists too but when I select any category then my all page data remove and only that label posts are visible. Why this is happening...??? I want to just change the posts as per label not to remove all page data...
That's the normal behaviour of document.write(). You might need to use:
document.getElementById("element_id").innerHTML = 'Stuff to Write.';
Finally I got it solved. The reason is that document.write() is bad as it write the text on page load. You can use it if you want to write some text on page load not later.
If you want to write later then have to use document.getElementById("element_id").innerHTML to write your text but if you want to write <script> tags then document.getElementById("element_id").innerHTML is not good as it will write but dont hit the SRC so use document.createElement("script") to write scripts after page load that will be runable too.
See the working DEMO of my code at JSBIN... :)
Special Thanks To: #Praveen Kumar :-)
I figured adding &outputSelector=GalleryInfo to the url would provide a higher resolution thumbnail, but that doesn't seem to work. I'm new to JSON, and the tutorial isn't very clear on the exact syntax to add to the URL to make this happen. Thanks!
<script>
function _cb_findItemsByKeywords(root)
{
var items = root.findItemsByKeywordsResponse[0].searchResult[0].item || [];
var html = [];
html.push('<table width="100%" border="0" cellspacing="0" cellpadding="3"><tbody>');
for (var i = 0; i < items.length; ++i)
{
var item = items[i];
var title = item.title;
var pic = item.galleryURL;
var viewitem = item.viewItemURL;
if (null != title && null != viewitem)
{
html.push(
'<tr id="api_microposts"><td>'
+ '<img src="' + pic + '" border="0" width="190">' + '<a href="' + viewitem + '" target="_blank">' + title +
'</a></td></tr>');
}
}
html.push('</tbody></table>');
document.getElementById("api").innerHTML = html.join("");
// Define global variable for the URL filter
var urlfilter = "";
// Generates an indexed URL snippet from the array of item filters
function buildURLArray() {
// Iterate through each filter in the array
for(var i=0; i<filterarray.length; i++) {
//Index each item filter in filterarray
var itemfilter = filterarray[i];
// Iterate through each parameter in each item filter
for(var index in itemfilter) {
// Check to see if the parameter has a value (some don't)
if (itemfilter[index] !== "") {
if (itemfilter[index] instanceof Array) {
for(var r=0; r<itemfilter[index].length; r++) {
var value = itemfilter[index][r];
urlfilter += "&itemFilter\(" + i + "\)." + index + "\(" + r + "\)=" + value ;
}
}
else {
urlfilter += "&itemFilter\(" + i + "\)." + index + "=" + itemfilter[index];
}
}
}
}
} // End buildURLArray() function
// Execute the function to build the URL filter
buildURLArray(filterarray);
url += urlfilter;
}
</script>
<!--
Use the value of your appid for the appid parameter below.
-->
<script src=http://svcs.ebay.com/services/search/FindingService/v1?SECURITY-APPNAME=*APP ID GOES HERE*&OPERATION-NAME=findItemsByKeywords&SERVICE-VERSION=1.12.0&RESPONSE-DATA-FORMAT=JSON&callback=_cb_findItemsByKeywords&REST-PAYLOAD&sortOrder=PricePlusShippingLowest&paginationInput.entriesPerPage=6&outputSelector=GalleryInfo&outputSelector=AspectHistogram&itemFilter(0).name=Condition&itemFilter(0).value(0)=New&itemFilter(1).name=MaxPrice&itemFilter(1).value=450.00&itemFilter(1).paramName=Currency&itemFilter(1).paramValue=USD&itemFilter(2).name=MinPrice&itemFilter(2).value=350.00&itemFilter(2).paramName=Currency&itemFilter(2).paramValue=USD&itemFilter(3).name=ListingType&itemFilter(3).value=FixedPrice&keywords=Moto%20x%2016gb>
</script>
It seems like you're looking for the galleryPlusPictureURL: http://developer.ebay.com/Devzone/finding/CallRef/types/SearchItem.html#galleryPlusPictureURL
Could anyone suggest performance improvements for the function I've written (below, javascript with bits of jquery)? Or point out any glaring, basic flaws? Essentially I have a javascript Google map and a set of list based results too, and the function is fired by a checkbox click, which looks at the selection of checkboxes (each identifying a 'filter') and whittles the array data down accordingly, altering the DOM and updating the Google map markers according to that. There's a 'fake' loader image in there too at the mo that's just on a delay so that it animates before the UI hangs!
function updateFilters(currentCheck) {
if (currentCheck == undefined || (currentCheck != undefined && currentCheck.disabled == false)) {
var delay = 0;
if(document.getElementById('loader').style.display == 'none') {
$('#loader').css('display', 'block');
delay = 750;
}
$('#loader').delay(delay).hide(0, function(){
if (markers.length > 0) {
clearMarkers();
}
var filters = document.aspnetForm.filters;
var markerDataArray = [];
var filterCount = 0;
var currentfilters = '';
var infoWindow = new google.maps.InfoWindow({});
for (i = 0; i < filters.length; i++) {
var currentFilter = filters[i];
if (currentFilter.checked == true) {
var filtername;
if (currentFilter.parentNode.getElementsByTagName('a')[0].textContent != undefined) {
filtername = currentFilter.parentNode.getElementsByTagName('a')[0].textContent;
} else {
filtername = currentFilter.parentNode.getElementsByTagName('a')[0].innerText;
}
currentfilters += '<li>' + $.trim(filtername) +
$.trim(document.getElementById('remhide').innerHTML).replace('#"','#" onclick="toggleCheck(\'' + currentFilter.id + '\');return false;"');
var nextFilterArray = [];
filterCount++;
for (k = 0; k < filterinfo.length; k++) {
var filtertype = filterinfo[k][0];
if (filterinfo[k][0] == currentFilter.id) {
var sitearray = filterinfo[k][1];
for (m = 0; m < sitearray.length; m++) {
var thissite = sitearray[m].split(',');
if (filterCount > 1) {
nextFilterArray.push(thissite[2] + '|' + thissite[1]
+ '|' + thissite[0]);
} else {
markerDataArray.push(thissite[2] + '|' + thissite[1]
+ '|' + thissite[0]);
}
}
}
}
if (filterCount > 1) {
var itemsToRemove = [];
for (j = 0; j < markerDataArray.length; j++) {
var exists = false;
for (k = 0; k < nextFilterArray.length; k++) {
if (markerDataArray[j] == nextFilterArray[k]) {
exists = true;
}
}
if (exists == false) {
itemsToRemove.push(j);
}
}
var itemsRemoved = 0;
for (j = 0; j < itemsToRemove.length; j++) {
markerDataArray.splice(itemsToRemove[j]-itemsRemoved,1);
itemsRemoved++;
}
}
}
}
if (currentfilters != '') {
document.getElementById('appliedfilters').innerHTML = currentfilters;
document.getElementById('currentfilters').style.display = 'block';
} else {
document.getElementById('currentfilters').style.display = 'none';
}
if (filterCount < 1) {
for (j = 0; j < filterinfo.length; j++) {
var filtertype = filterinfo[j][0];
if (filterinfo[j][0] == 'allvalidsites') {
var sitearray = filterinfo[j][1];
for (m = 0; m < sitearray.length; m++) {
var thissite = sitearray[m].split(',');
markerDataArray.push(thissite[2] + '|' + thissite[1]
+ '|' + thissite[0]);
}
}
}
}
var infoWindow = new google.maps.InfoWindow({});
var resultHTML = '<div id="page1" class="page"><ul>';
var count = 0;
var page = 1;
var paging = '<li class="selected">1</li>';
for (i = 0; i < markerDataArray.length; i++) {
var markerInfArray = markerDataArray[i].split('|');
var url = '';
var name = '';
var placename = '';
var region = '';
var summaryimage = 'images/controls/placeholder.gif';
var summary = '';
var flag = 'images/controls/placeholderf.gif';
for (j = 0; j < tsiteinfo.length; j++) {
var thissite = tsiteinfo[j].split('|');
if (thissite[0] == markerInfArray[2]) {
name = thissite[1];
placename = thissite[2];
region = thissite[3];
if (thissite[4] != '') {
summaryimage = thissite[4];
}
summary = thissite[5];
if (thissite[6] != '') {
flag = thissite[6];
}
}
}
for (k = 0; k < sitemapperinfo.length; k++) {
var thissite = sitemapperinfo[k].split('|');
if (thissite[0] == markerInfArray[2]) {
url = thissite[1];
}
}
var markerLatLng = new google.maps.LatLng(markerInfArray[1].toString(), markerInfArray[0].toString());
var infoWindowContent = '<div class="infowindow">' + markerInfArray[2] + ': ';
var siteurl = approot + '/sites/' + url;
infoWindowContent += '<strong>' + name + '</strong>';
infoWindowContent += '<br /><br/><em>' + placename + ', ' + region + '</em></div>';
marker = new google.maps.Marker({
position: markerLatLng,
title: $("<div/>").html(name).text(),
shadow: shadow,
icon: image
});
addInfo(infoWindow, marker, infoWindowContent);
markers.push(marker);
count++;
if ((count > 20) && ((count % 20) == 1)) { // 20 per page
page++;
resultHTML += '</ul></div><div id="page' + page + '" class="page"><ul>';
paging += '<li>' + page + '</li>';
}
resultHTML += '<li><div class="namehead"><h2>' + name + ' <span>' + placename + ', ' + region + '</span></h2></div>' +
'<div class="codehead"><h2><img alt="' + region + '" src="' + approot +
'/' + flag + '" /> ' + markerInfArray[2] + '</h2></div>' +
'<div class="resultcontent"><img alt="' + name + '" src="' + approot +
'/' + summaryimage +'" />' + '<p>' + summary + '</p>' + document.getElementById('buttonhide').innerHTML.replace('#',siteurl) + '</div></li>';
}
$('#filteredmap .paging').each(function(){
$(this).html(paging);
});
document.getElementById('resultslist').innerHTML = resultHTML + '</ul></div>';
document.getElementById('count').innerHTML = count + ' ';
document.getElementById('page1').style.display = 'block';
for (t = 0; t < markers.length; t++) {
markers[t].setMap(filteredMap);
}
});
}
}
function clearMarkers() {
for (i = 0; i < markers.length; i++) {
markers[i].setMap(null);
markers[i] = null;
}
markers.length = 0;
}
However, I'm suffering from performance issues (UI hanging) specifically in IE6 and 7 when the number of results is high, but not in any other modern browsers, i.e. FF, Chrome, Safari etc. It is much worse when the Google map markers are being created and added (if I remove this portion it is still slugglish, but not to the same degree). Can you suggest where I'm going wrong with this?
Thanks in advance :) Please be gentle if you can, I don't do much javascript work and I'm pretty new to it and jquery!
This looks like a lot of work to do at the client no matter what.
Why don't you do this at the server instead, constructing all the HTML there, and just refresh the relevant sections with the results of an ajax query?