There are some blogger are not fully satisfied with my
tutorial on how to create a simple widgets installer. They wanted to learn extra.
You required learning about using the JSON-feeds and after all you wanted to
learn how to make the widget customizable.
I trust you will like
this tutorial. I will train you how to make a customizable Table Of Contents
Widget and how to generate an installer for this widget.
For the reason of this tutorial it will be an extremely
simple widget. If we make it too sophisticated, the code will be more
complicated and less easy to understand. Our purpose is to take you by the hand
and make you understand everything that happens. You can work from there to
develop this widget into something helpful for yourself.
Now talk about TOC widget and how it works.
The TOC-widget will get the posts-feed from your blog, with
a maximum of 100 posts. It will display a list of the posttitles. You can
customize 3 settings: the widget title, the number of posts to display, and
whether or not to sort the posts alphabetically.
What the Installer has to do
We will create an Installer. The Installer is a
HTML-document with a form that contains a few fields and a few buttons and some
javascript. It is best to host this installer from a webserver where you can
upload HTML-pages to. I experienced big trouble with the Blogger page elements
trying to embed the installer directly into the sidebar: Blogger messes
everything up in a horrific way. So what we will do is add a simple button to
the blog, and this button will invoke the widget installer. A visitor of your
blog can then enter his/her data into the fields, push the Install-button, and
the widget will be installed to his/her blog.
Okay, how do I get this done?
Step 1: Create a javascript function that retrieves a
JSON-feed from Blogger
Step 2: Define javascript variables for the number of posts
to display and for sorting
Step 3: Create a javascript function for displaying the
table of contents
Step 4: Combine steps 1 to 3 into a Table Of Contents Widget
and add it to your Blog
Step 5: Check that everything works as it should
Step 6: Create an input form for the Widget Installer
Step 7: Create a javascript function that builds the widget
Step 8: Combine steps 6 and 7 into a Widget Installer
Step 9: Upload the Installer and add a button to your Blog
Step 10: Test and debug the Installer
Well, it's not as difficult as it looks, and not as easy as
you hope. Somewhere in between.
Step 1: Retrieving the JSON-feed from Blogger.
To retrieve the JSON-feed from Blogger, we will use the
following line of javascript:
<script
src="http://YOURBLOGNAME.blogspot.com/feeds/posts/default?alt=json-in-script&max-results=100&callback=showtoc"></script>
Replace YOURBLOGNAME with the name of your blog. This line
of javascript asks Blogger to return the feed of your posts in JSON-format.
JSON means: JavaScript Object Notation. The feed is returned as a set of
Javascript Objects, and that makes it easy to handle for us in step 3. We also
tell Blogger to return a maximum of 100 results (Blogger won't allow for more
than 100, and the default size of feeds is 25). And finally we tell Blogger to
send the JSON-feed to a Javascript function called showtoc. We'll write this
function in step 3.
Step 2: Create variables for the Table of Contents
We will create 2 Javascript variables, using the following
code:
<script style="text/javascript">
var numposts = 20;
var sortposts =
true;
</script>
The variable numposts is the number of posts you want to show
in the Table of Contents. If you set it to 20, the 20 most recent posts will be
displayed.
The variable sortpost is a boolean variable, and can be true
or false. If it is true, the posttitles will be sorted. If it is false, the
posts will be in chronological order, from newest to oldest.
For your information: these variables make the widget
customizable, as we will see later.
Step 3: Create a javascript function for displaying the
table of contents.
Now we have to write the javascript function showtoc that we
met in step 1. It takes a JSON-object (our feed) as input, rips the posttitles
from it, and stores them in an array. If you don't know what an array is: it's
a stack of data. We push the posttitles on this stack, and then we can sort
them and display them on the screen. Take a look at the code, I have added
comments, so even if you are new to Javascript you can get an idea of what is
happening.
<script style="text/javascript>
function showtoc(json) {
// create an array
to hold all posttitles
var toc = new
Array();
// get the number
of entries that are in the feed
// if there are
more entries in the feed than we want to show, take the number we want to show
var numentries =
json.feed.entry.length;
if (numentries >
numposts) numentries = numposts;
// main loop gets
all the entries from the feed
for (var i = 0; i
< numentries; i++) {
// if current
value of i is bigger than number of entries in feed, then stop the loop
if (i ==
json.feed.entry.length) break;
// get the entry
from the feed
var entry =
json.feed.entry[i];
// get the
posttitle from the entry
var posttitle =
entry.title.$t;
// add the post
to the array
toc.push(posttitle);
}
// sort the array
if needed
if (sortposts)
toc.sort();
// write all posts
to the page
for (var i = 0; i
< numentries; i++)
document.write('<br/>' + toc[i] + '<br/>');
}
</script>
Step 4: Create the Widget
Open Notepad or any texteditor, and cut and paste the code
from steps 3, 2 and 1 (in that order) to Notepad, and save the file to your
desktop (better be safe than sorry). The Widget code is this:
<script style="text/javascript>
function showtoc(json) {
// create an array
to hold all posttitles
var toc = new
Array();
// get the number
of entries that are in the feed
// if there are
more entries in the feed than we want to show, take the number we want to show
var numentries =
json.feed.entry.length;
if (numentries >
numposts) numentries = numposts;
// main loop gets
all the entries from the feed
for (var i = 0; i
< numentries; i++) {
// if current
value of i is bigger than number of entries in feed, then stop the loop
if (i ==
json.feed.entry.length) break;
// get the entry
from the feed
var entry =
json.feed.entry[i];
// get the
posttitle from the entry
var posttitle =
entry.title.$t;
// add the post
to the array
toc.push(posttitle);
}
// sort the array
if needed
if (sortposts)
toc.sort();
// write all posts
to the page
for (var i = 0; i
< numentries; i++)
document.write('<br/>' + toc[i] + '<br/>');
}
</script>
<script style="text/javascript">
var numposts = 20;
var sortposts =
true;
</script>
<script src="http://YOURBLOGNAME.blogspot.com/feeds/posts/default?alt=json-in-script&max-results=100&callback=showtoc"></script>
Now, go to your Blog Layout and open the Page Elements tab,
click Add a Page Element and select a HTML/Javascript Element. Copy the Widget
code from Notepad and paste it into the Page Element, and Save.
Probably Blogger will mess things up: it did so when I
pasted the code into the Page Element. So you probably have to correct the code
manually. If you have done so, save again and view your Blog. You will see the
20 most recent posttitles sorted alphabetically. Your Widget works!
Step 5: Check that everything works as it should.
Now go and play with the widget. Set numposts to 10, or to
50 if you like and see what happens. Also switch sortposts from true to false
and back again. Just make sure that you understand how the widget works.
If you reached this step, your widget should work fine. I
tested it on my testblog, and it executes fine.
Step 6: Create an input form for the widget installer.
Now that our widget is ready, we will start with our widget
installer. For this installer we need a HTML-form with several fields and
buttons. We need an input field for the Widget Title, so that the user can
customize his/her own widget title. The Widget Title is a required field for
adding the widget to Blogger. We'll also need an input field for the user's
blogname. This is needed so that the user will get his/her own feed, and not
yours. We also need an input field for the number of posts that the user wants
to display. And a checkbox that has to be checked if the user wants his/her
table of contents to be sorted. Finally there are the buttons: Reset to clear
all fields, Customize to create the customized widgetcode, and Install to
install the customized widget to the user's blog.
There is also a textarea in the form, that is hidden from
view. This textarea will be used for storing the customized widgetcode. This
textarea is required for passing the widget code to Blogger.
Here we go with the code:
<form method="POST"
action="http://beta.blogger.com/add-widget"
target="_blank">
<span style="width:130px;">Widget
Title</span>: <input type="text" size=30
name="widget.title" value="Table of
Contents"/><br/>
<span style="width:130px;">Blog
url</span>: http://<input type="text" size=10
name="iblogurl"
value="yourblogname"/>.blogspot.com<br/>
<span style="width:130px;">Number of
posts</span>: <input type="text" size=3
name="inumposts" value="20"/><br/>
<span style="width:130px;">Sort
posts</span>: <input type="checkbox"
name="isortposts" checked/><br/>
<br/>
<input type="button"
value="Customize" onclick="javascript:customize();">
<input type="button" value="Reset"
onclick="javascript:defaultvalues();">
<input type="submit" disabled
name="go" value="Install Widget"/>
<br/>
<textarea name="widget.content"
style="display:none"></textarea>
</form>
Now just for the fun of it: wrap this form inside a
HTML-document (using Notepad), save it to your desktop, and view it in your
browser. You will have a nice (but not-working) preview of your widget
installer. You can enter data into the fields, you can click buttons, but
nothing will happen - yet. Wrapping it inside HTML? Oh, yes, that goes like
this:
<html>
<body>
<form method="POST" action="http://beta.blogger.com/add-widget"
target="_blank">
<span style="width:130px;">Widget
Title</span>: <input type="text" size=30
name="widget.title" value="Table of
Contents"/><br/>
<span style="width:130px;">Blog
url</span>: http://<input type="text" size=10
name="iblogurl"
value="yourblogname"/>.blogspot.com<br/>
<span style="width:130px;">Number of
posts</span>: <input type="text" size=3
name="inumposts" value="20"/><br/>
<span style="width:130px;">Sort
posts</span>: <input type="checkbox" name="isortposts"
checked/><br/>
<br/>
<input type="button"
value="Customize" onclick="javascript:customize();">
<input type="button" value="Reset"
onclick="javascript:defaultvalues();">
<input type="submit" disabled
name="go" value="Install Widget"/>
<br/>
<textarea name="widget.content"
style="display:none"></textarea>
</form>
</body>
</html>
We have to write 2 javascript functions that respond to
buttons being pressed. One to reset the form to its default values, and one to
create the widget code. Let's start with a function for resetting the form
field. The function defaultvalues() will set the form to its default values
when the Reset button is clicked. Here is the code:
function defaultvalues() {
document.getElementsByName("widget.title")[0].value =
"Table of Contents";
document.getElementsByName("iblogurl")[0].value =
"yourblogname";
document.getElementsByName("inumposts")[0].value =
"20";
document.getElementsByName("isortposts")[0].checked
= true;
document.getElementsByName("go")[0].disabled = true;
}
This function looks up the formfields by there name, and
sets their contents. The last line greys out the Install-button, so that we can
only click it if we have customized the widget settings.
The second function we will create is the function
customize(), that is invoked when the user clicks the Customize-button. The
code of this function is:
function customize() {
// Get input values
var blogurl =
document.getElementsByName("iblogurl")[0].value;
var numposts =
document.getElementsByName("inumposts")[0].value;
var sortposts =
document.getElementsByName("isortposts")[0].checked;
// Generate
widgetcode
var txtarea =
document.getElementsByTagName("textarea")[0];
txtarea.value =
"\<script style='text/javascript'\>";
txtarea.value =
txtarea.value + "function showtoc(json) { ";
txtarea.value =
txtarea.value + "var toc = new Array(); ";
txtarea.value = txtarea.value
+ "var numentries = json.feed.entry.length; ";
txtarea.value =
txtarea.value + "if (numentries \> numposts) numentries = numposts;
";
txtarea.value =
txtarea.value + "for (var i = 0; i \< numentries; i++) { ";
txtarea.value =
txtarea.value + "if (i == json.feed.entry.length) break; ";
txtarea.value =
txtarea.value + "var entry = json.feed.entry[i]; ";
txtarea.value =
txtarea.value + "var posttitle = entry.title.$t; ";
txtarea.value =
txtarea.value + "toc.push(posttitle); } ";
txtarea.value =
txtarea.value + "if (sortposts) toc.sort(); ";
txtarea.value =
txtarea.value + "for (var i = 0; i \< numentries; i++) ";
txtarea.value =
txtarea.value + "document.write('\<br/\>' + toc[i] +
'\<br/\>'); } ";
txtarea.value =
txtarea.value + "\</script\>";
txtarea.value =
txtarea.value + "\<script style='text/javascript'\>";
txtarea.value =
txtarea.value + "var numposts = " + numposts + "; ";
if (sortposts) {
txtarea.value = txtarea.value + "var sortposts = true; "; }
else {
txtarea.value = txtarea.value + "var sortposts = false; "; };
txtarea.value =
txtarea.value + "\</script\>";
txtarea.value =
txtarea.value + "\<script src='http://" + blogurl +
".blogspot.com/feeds/posts/default?alt=json-in-script&max-results=100&callback=showtoc'\>\</script\>";
// Show add button
var addbutton =
document.getElementsByName("go")[0];
addbutton.disabled = false;
}
What happens here - you won't believe it - is that this
javascript-function writes the javascript-code for the widget! Now that is kind
of Baron of Munchhaussen, if you are familiar with this German nobleman who
pulled himself out of the water by his own neck. The entire widget-code
(without the comments) is written into the textarea of the form and the
Install-button is enabled.
Step 8: Create the Widget Installer
From steps 6 and 7 we can now create the widget installer.
Open Notepad, and create a textfile with the following content:
<html>
<script style="text/javascript">
function customize() {
// Get input values
var blogurl =
document.getElementsByName("iblogurl")[0].value;
var numposts =
document.getElementsByName("inumposts")[0].value;
var sortposts =
document.getElementsByName("isortposts")[0].checked;
// Generate
widgetcode
var txtarea =
document.getElementsByTagName("textarea")[0];
txtarea.value =
"\<script style='text/javascript'\>";
txtarea.value =
txtarea.value + "function showtoc(json) { ";
txtarea.value =
txtarea.value + "var toc = new Array(); ";
txtarea.value =
txtarea.value + "var numentries = json.feed.entry.length; ";
txtarea.value =
txtarea.value + "if (numentries \> numposts) numentries = numposts;
";
txtarea.value =
txtarea.value + "for (var i = 0; i \< numentries; i++) { ";
txtarea.value =
txtarea.value + "if (i == json.feed.entry.length) break; ";
txtarea.value =
txtarea.value + "var entry = json.feed.entry[i]; ";
txtarea.value =
txtarea.value + "var posttitle = entry.title.$t; ";
txtarea.value =
txtarea.value + "toc.push(posttitle); } ";
txtarea.value =
txtarea.value + "if (sortposts) toc.sort(); ";
txtarea.value =
txtarea.value + "for (var i = 0; i \< numentries; i++) ";
txtarea.value =
txtarea.value + "document.write('\<br/\>' + toc[i] +
'\<br/\>'); } ";
txtarea.value =
txtarea.value + "\</script\>";
txtarea.value =
txtarea.value + "\<script style='text/javascript'\>";
txtarea.value =
txtarea.value + "var numposts = " + numposts + "; ";
if (sortposts) {
txtarea.value = txtarea.value + "var sortposts = true; "; }
else {
txtarea.value = txtarea.value + "var sortposts = false; "; };
txtarea.value =
txtarea.value + "\</script\>";
txtarea.value = txtarea.value +
"\<script src='http://" + blogurl +
".blogspot.com/feeds/posts/default?alt=json-in-script&max-results=100&callback=showtoc'\>\</script\>";
// Show add button
var addbutton =
document.getElementsByName("go")[0];
addbutton.disabled = false;
}
function defaultvalues() {
document.getElementsByName("widget.title")[0].value =
"Table of Contents";
document.getElementsByName("iblogurl")[0].value =
"yourblogname";
document.getElementsByName("inumposts")[0].value =
"20";
document.getElementsByName("isortposts")[0].checked = true;
document.getElementsByName("go")[0].disabled = true;
}
<body>
<form method="POST"
action="http://beta.blogger.com/add-widget"
target="_blank">
<span style="width:130px;">Widget
Title</span>: <input type="text" size=30
name="widget.title" value="Table of
Contents"/><br/>
<span style="width:130px;">Blog
url</span>: http://<input type="text" size=10
name="iblogurl"
value="yourblogname"/>.blogspot.com<br/>
<span style="width:130px;">Number of
posts</span>: <input type="text" size=3
name="inumposts" value="20"/><br/>
<span style="width:130px;">Sort
posts</span>: <input type="checkbox"
name="isortposts" checked/><br/>
<br/>
<input type="button"
value="Customize" onclick="javascript:customize();">
<input type="button" value="Reset"
onclick="javascript:defaultvalues();">
<input type="submit" disabled
name="go" value="Install Widget"/>
<br/>
<textarea name="widget.content"
style="display:none"></textarea>
</form>
</body>
</html>
Save this file as widgetinstaller.html to your desktop, and
launch it in your browser. You have to allow for scripts and active content,
but then you will see that your installer really works!
Step 9: Upload it and create a button to launch the
installer
Upload the widgetinstaller.html file to one of your folders
with your ISP webhost.
Now add a HTML-page element to your blog, give it an
appropriate title, and add some text to describe the widget.
Then add a button using the following code:
<form action="_self"><input
type="button" value="Add Table of Contents to Blog"
onclick="window.open('http://YOURHOST/widgetinstaller.html','popupwindow','width=500,
height=500'); return false" /></form>
Save the page element and view your Blog.
Step 10: Test and debug.
Now play around to check if everything works as it should.
Congratulations! You are done!
Beyond this point you are completely at your own risk!
If you want to improve this widget, here are some ideas:
- Add an option to display a postsummary
- Add CSS-styling to the widget
- Add CSS-styling to the widget-installer
- Add a preview-pane to the widget-installer
- Add the post url to the posttitle
- Add the date to the posttitle
That’s all. Share this post and reply your comments below in addition to get more updates from us subscribe to our RSS feeds.
No comments:
Post a Comment