Blogger Hacks, Categories, Tips & Tricks

Monday, November 21, 2005
Category Integration Between Sites
Update 2/1/06: There is a new version of this service, Freshtags 0.5. See the Freshblog Intro, and check out the Freshtags site to get up-to-date code and information. Read on here if you're interested in the development of Freshtags and the initial roll-out, but be aware that the code posted here has been superceded.
_____
Pushing the envelope on the "tags for categories" method once again, Freshblog is pleased to announce a new sidebar menu for categories, using .js, that creates a list of recent posts in a category when you select that category from the list. The menu, developed by Greg from Vent, provides plenty of room for discussion and development, & makes strides towards the interactivity that is possible in the blogsphere. Here's the usual Freshblog what? why? how?, along with an invite for testing, feedback and discussion.

What: A sidebar menu of categories that generates a scroll-box menu of post titles below it when you choose a category. The >> symbol below the drop-down takes you to the anchor_tag + selected_tag page on del.icio.us. The scroll-box menu loads when you pick a category, shows post titles that are in that category, & lets you jump straight to the post page from the
sidebar. In-blog category navigation is born!!

NB: "anchor tag" is optional, and is the tag that is common to all posts in your blog. Handy if you have multiple blogs, or don't want all your tags listed on your blog.

Why: I've had some negative feedback re: taking people off-site to your post-list in del.icio.us. (even though, as I said a whole bunch in the beginning, all they can click on there are your posts, and they'll be right back!!) We want this to look integrated & slick, & we want the integration to keep people on your site, in your template, knee-deep in your ideas.

How: If you already bookmark your posts on del.icio.us for categories, you're home free. Just add one .js code chunk for the head of your template, edited to reflect your del.icio.us username and most frequently used _anchor_ tag, and one customiseable code chunk for your sidebar. Change the widths of the menu to suit, and you're all set.

Benefits: Readers see your post titles in your categories on your site, instead of going offsite.
When they select a post from the dropdown, they're taken direct to the post page, and the drop-down box stays open so that they can navigate direct to other posts in the same category if they choose to. Excellent.

Development:

The most exciting feature of this system grows out of the page reload. You'll notice that when you choose a category from the drop-down, the page reloads & the URL now ends in the selected tag. In addition to passing tags between archive & post pages on your blog, readers can pass tags between blogs. As an example, if you select "culture" as a category from the drop down box in my sidebar, a text box will appear containing the titles of posts that I have tagged "culture." This box will stay open on post, archive and main pages on Freshblog.... but hey, let's pass the tag!! Greg's Vent! blog runs this script too, and we share a category called "culture." If you've selected "culture" in the Freshblog sidebar and you visit Vent!, you'll find the "culture" category there pre-selected and the drop-down pre-expanded. If a number of blogs all operated using this script, you could navigate between them and be repeatedly presented with pre-expanded menus of relevant content in your area of interest.

The benefits of picking up on your readers' interests as they land on your page are obvious - you can show them relevant content in the navigation. But what if they arrive by search engine? Not to worry: this code will scan their search query for your tags. If any are found, it will quietly expand that category in your sidebar, showing your readers titles of related posts. Works with most search engines, include Google, Yahoo and MSN. To see it in action, visit Greg's Speccy Blog via Google, where a search for the phrase "exposed the writhing worms of drugs" returns only one result. You'll note that when you choose that link, the "drugs" category in the sidebar at Speccy will pre-expand for your navigating pleasure. Alternatively, do a Google search for "Freshblog" & visit this site from the results page. You'll notice that the category menu for posts in the category "Freshblog" is pre-expanded.

As a consequence of upgrading your archive menu code to pass tags, you'll also have the chance to add an archive count to your archive list, so that readers can see the relative activity of your blog from month-to-month at a glance. Using a bookmarklet to tag your archive pages, and a revised code for the archive drop-down menu, you can illustrate your posting volume in your archive menu. I have yet to implement the archive count at Freshblog, but you can see it in action at Speccy.

Code Snippets:

For your template head (add username and anchortag to replace the red text):

<script type="text/javascript">
// set parameters
del_user = "username";
anchor = "anchortag";

// Fetch tag set from delicious

document.write('<script type="text/javascript"
src="http://del.icio.us/feeds/json/tags/'+del_user+'/'+anchor+'?sort=freq&count=100">');
document.write('<\/script>');

// Fetch archive posts from delicious

document.write('<script type="text/javascript"
src="http://del.icio.us/feeds/json/'+del_user+'/'+anchor+'_archive?sort=freq&count=100">');
document.write('<\/script>');
</script>

<script type="text/javascript"
src="http://ghill.customer.netspace.net.au/tags/flex-tag_list.js">
</script>

For your category drop-down menu:

<script type="text/javascript">
list_side_tags(1); // drop-list
write_tagged_posts(10, 22); // 10 high, 22 wide
</script>

This menu will accept arguments for customisation as follows:

list_side_tags(x) where x is the number of rows in your scroll box.
write_tagged_posts(y, z) where y is the number of rows and z is the width in characters.

For your archive drop-down menu:

<select name="archivemenu"
onchange="document.location.href=this.options[this.selectedIndex].value;"
size="1">
<option selected="selected">- Select Month -</option>');
<BloggerArchives>
<script type="text/javascript">
u = "<$BlogArchiveURL$>"; n = "<$BlogArchiveName$>";
document.write('<option value="'+u+document.location.search+'">'+n);
c=archive_count(u);
show_count(c);
</script>
</option>
</BloggerArchives>
</select>

Bookmarklet to "tag" your archive pages:

javascript:anchor="anchortag";count=prompt('enter post
count');document.location.href='http://del.icio.us/api/posts/add?url='+document.location.href+'&description='+anchor+':'+tidy(document.title)+'&tags='+anchor+'_archive&extended='+count;
function tidy(descr){pos = descr.indexOf(':');return
descr.substr(pos+1);}

Insert your chosen anchortag at the appropriate place in the script.

Alternative:

See Greg's Speccy blog for a set-up that will work for blogs with less posts / less tags. If you'd like the code for that set-up, please leave a request & your contact info in the comments.

Discussion / Request for Feedback & Testing:

This doesn't change the input of the tags for categories system, but Greg's script does some significant and welcome things with the output. For discussion, please leave comments & trackbacks on this post, & help us take the del.icio.us tags as categories system to the next level.

This is oh-so beta at the moment, and all feedback is appreciated. The possibilities for extension and development include supporting multiple tags, a delicious-style cloud presentation and an integration with other blog category systems / sites that order content with tags... Greg is looking for more ideas and feedback, & you're the audience for the job!

What about SEO? Does the "URL?tag" format create multiple URL's for the same page and therefore weaken a page in an engine?

Apparently not so you'd notice. Sure, having multiple URLs pointing to the same physical page does "water down" your rank. So you wouldn't want your homepage split 150 different ways. But if it's targetted and useful, then given the way that Google heavily weights the URL for search rankings, it could be a help if used sparingly (eg foo-blog.com/ vs foo-blog.com?tags=lightning_strikes).

Secondly, the only way that Google would see the "tagged" version (in light of the earlier discussion about spiders not seeing javascript and the hand-coded "noscript" alternative menu) would be if someone hard-coded a URL in that way to bring a visitor to your blog in pre-expanded mode. I guess this would be done (if at all) consciously/deliberately so would bring focus. Also, the doubling up of anchor text and URL would be a powerful association from google's view - almost like a rel=tag link!

So, as long as your linkers agreed with you about which are your "power tags" and used them judiciously, it would help. The way that js is hidden from spiders will protect you from having a mass diffusion across hundreds of URLs.

And hey, what do we call it? There's some new tag functions at work here, that Greg's defined as follows:
  • tag-fixing: the act of "hard-coding" a tag into a URL.
  • tag-passing: the act of a reader carrying forwards their selected tag.
  • tag-grabbing: the act of extracting a tag out of something that's not actually a tag e.g. search query, prior page etc.
Chime in with your feedback, responses, and requests to test. We're very interested in the possibilities of passing tags between blogs as a way of generating dynamic spheres of similar content that can customise the blogosphere, and allow readers to surf between sites while staying within categories. Exciting!!

Posted at 5:15 PM by John.
23 Comments:
<    >
Anonymous Anonymous said...
So ... if I'm grokking this right then any page that puts tags= or q= in the URL can pass tags to my blog? They don't need to be running the script too?

And those tags will be picked up and used by my blog to show post titles?

Cool ...

<    >
Blogger John said...
I believe that is the case, yes!! As long as you're running the script at your end... So an offsite URL wanting to showcase your work in a certain area could link in with "url?tag", and pop the sidebar of your blog to show the posts that have that tag... Pretty cool, huh?

<    >
Blogger Greg said...
Sure - that's exactly right. I can even "hard-code" the tag into the URL ("tag-fixing"):

Freshblog with blogtech pre-selected

If you don't like this particular implementation you can write up your own code and the different sites/blogs will play nice. Just remember to put:

tags=tag1+tag2+tag3

in the query string of the URL and away you go!

-Greg.

<    >
Blogger Greg said...
Presenting Tags on Your Blog.

Further to what John wrote above, the same hack comes in two different flavours:

* Select lists (as you can see on Freshblog and Vent). Here, you link to the script flex-tags_list.js. The functions you call are:

list_side_tags(x) - displays the tags
write_tagged_posts(x,y) - displays the titles of posts (if a tag is selected).

[where x is the number of rows in the box (x=1 means it's a drop-down style) and y is the width of the box.]

You can put these different functions wherever you like on your page. This allows the possibility of having your tags listed on the left and your post titles on the right. Or you could have repetition - a ten row select box in the sidebar and a one row drop-down in footer. You could even have a different presentation depending on whether it's your Main, Archive or Post page using Blogger's conditional tags. That's the idea - it's entirely tweakable!

* Flat lists (check out Speccy). This uses the script found at: flat-nested_list.js.

It writes out tags (and posts) as unordered list items. With this approach, you just need to use the one function:

list_side_tags()

and it will list your tags and "nest" the post titles under the appropriate tag. This works better with a modest number of tags and posts ie when tags are used more like traditional categories.

If there's demand for it, the next one will be a cloud view, modelled after the delicious tagroll.

Of course, we're looking for other ideas, so if you've got some thoughts about how to best integrate tags into blog navigation, we're all ears!

Cheers,

-Greg.

<    >
Blogger Johan Sundström said...
Love your work, Greg, and thanks for the beautiful tutorial; it's a very comfy way into the match indeed. One feature request: add an unescape() of the tag in fetch_query_tag() to get ugly junk such as %20 in the tag lister. (I unfortunately can't paste the code here; Blogger for some reason doesn't accept the <pre> tag.) Feel free to pick up my version as is; I donate any rights you might want.

It will return '' (which evaluates as false in javascript, by the way) if it finds no tags, or an empty tag, and otherwise the tag name itself, as found in the tags query argument, referrer or the q attribute of the referrer, much as I expect yours was intended to (yours would pick something from the referrer if it just got an empty tags query argument when there were other later query attributes).

<    >
Blogger Greg said...
Thanks, Johan! That is fantastic. (John, make sure Johan gets full marks for doing his homework ...)

Your code is far more elegant and robust than my slap-dash effort - highlighting the benefits of a public code review. I will certainly use this in the next release.

You've also given me some useful info (like, that's how javascript does regular expressions!). This should help me take it to the next level in tag-grabbing in a much more scalable way. I was thinking of a sort of cascading approach:

(already implemented)

1) tags=... in the URL
2) tags=... in the referrer
3) q=... in the referrer

(proposed)

4) ?... in the referrer

This would attempt to grab a tag out of anywhere in the query string. Useful for a broader range of web apps eg search engines that don't use "q".

5) /.../ in the referrer

This would grab a tag out of the directories part of the URL (ie after the domain but before query string). It seems a few blogs and wikis put the category in the directory eg. foo-blog.com/politics or wikipedia.org/wiki/lightning. I think technorati does this too?

6) ...blah.com

This would try tag-grabbing in the subdomain. Might get lucky with blogspot and other free hosting services.

Is that a good idea? Or will the false matches drive people crazy? My intuition suggests not, given that the consequence of a false match are fairly modest. Readers might be puzzled about the pre-selected tags but hey - at least they're paying attention to the navigation!

What else could help anticipate user interest? Time of day? IP address range? Some sort of IP->location thingy? Tag from last time (stored in a cookie)?

Taken to it's extreme, the principle that "it's better to give people something rather than nothing" suggests that if no tag is grabbed, the function should return a random tag - perhaps weighted by frequency.

Even if it's wrong (and honestly, how wrong could it be? It's still on your blog!), at least it might prompt readers to change the selected tag ...

Thanks again, Johan, for your excellent codage. I'd like to get some clarification on the above and then I'll incorporate your code with the extra grab attempts.

Unless someone kindly beats me to it :-)

Cheers,

-Greg.

<    >
Blogger Greg said...
More praise for Johan: I really like your implementation of tag listing on your ecmanaut blog.

* writeScript function is a neater way to write out the requisite javascript for fetching delicious' JSON objects.
* the drop-down tag selector (a la Vent) teamed with the flat post titles (a la Speccy) looks great.
* the use of the delicious icon to indicate where the ">>" takes you is tres chic.

I hope you don't mind if some of these ideas find their way into subsequent versions of my script?

Cheers,

-Greg.

<    >
Blogger Singpolyma said...
This script looks very nice... however it will be counter-intuitive for more novice site navigators. I must admit I was a tad confused at first when I selected a tag from the list and the page reloaded to 'apparently' the same page. A version à la AJAX would be nice, but I doubt possible? Especially since that would mess up your refferrer URLs...

<    >
Blogger Greg said...
Thanks, Stephen.

Re: Same Page. I originally thought wouldn't it be great to get all the posts on the same topic onto the same page. Sort of like a Blogger archive page, but for tags instead of time. I think the only way it could be done would be to convince Blogger that all the posts on a particular topic fell on days in the same month (or archive period), so you could set up a mapping like "January=Culture", "February=Politics", "March=Tech" etc.

But this throws up a slew of technical problems, enough to warrant abandoning Blogger as a suitable platform. (Not least of all the Librarian's Dilemma, whereby the same post might appear on the Tech and Culture page.)

So, in the end, I opted for something that would leave the page "untouched" except for the sidebar ie where users expect the navigation to happen.

But, is there some way to highlight that the navigation has changed? Make it more prominent, or get people to notice it? I'm open to suggestions.

Re: AJAX. I'm sure wonderful clever things could be done with this - just not by me. :-) I wouldn't put it past Johan though ...

-Greg.

<    >
Blogger Singpolyma said...
I've got it working the way I wanted it to work for my blog, see my post here:
http://singpolyma-tech.blogspot.com/2005/11/in-blog-tag-viewing.html

<    >
Blogger Greg said...
I like. I like a lot.

Re: multi-tags. Good implementation - I like the idea of accumulating tags as you go. One thought - if I "re-select" a tag, it should be dropped from the list ie "tags=google+base+google" should be "tags=base".

Re: tagged post page. It's quite ingenious and the listing looks a helluva lot nicer than the delicious page or even the blogger search results.

My only reservations are:

1) It still looks a bit like search results rather than (attenuated) posts.

Is there any way to trick blogger into formatting it like proper posts? Ie allowing html, date headers, comment counts etc? Or even applying the css to it?

2) It requires stuffing the first 200 characters of each post into the "notes" field of your delicious tag. That's not a bad idea; it just might get a bit laborious "backfilling" posts.

Maybe we need a "tagspider" that crawls over your blog and populates your delicious account ... this would also be a handy way to get the archive pages populated with the "post count" ...

Hmm. Back in the day (before JSON) I made a script that used wget and grep to grab tag information from your delicious homepage.

If anyone wants to build such a spider I'm happy to share code.

In any case, this does solve the "what's changed?" problem and is an important contribution. Thanks!

Cheers,

-Greg.

<    >
Blogger Johan Sundström said...
You're very welcome, Greg; I'm much in favour of all of my improvements / tweaks going back into your mainline code, should you want them there.

I would only add support for picking up tags from "known" referrer tag schemes (scraping relevant bits from sites whose URL layout you are familiar with, or the more or less commonly used ones such as those already in place), and stay off the wilder guesswork.

For the case where no tag is selected, I would actually rather have a custom (a parameter passed would probably be a good way) default label, i e "Pick a category:" show up on top (which would not repost the page if selected).

The Fade Anything Technique is a good way of showing which part of a page has been changed. I have been pondering doing a version with that which uses some AJAX to switch categories, without reloading the entire page.

That of course has the drawback of not showing up in referrers to knit blogs together, but I'm not sure of how often I would miss the feature. (The best feature here IMO is really the search referrer listen-in code, anyway.)

<    >
Blogger Johan Sundström said...
Regarding AJAX, I've been pondering a hack that pulls in posts from your own blog into something like a post archive, but it has the drawback on being rather reliant on your post template to work well. (Since you have to load, parse and splice the content parts of your item pages into the page flow to get it to work well. Doable, but I would prefer an open API to Blogger to solve the issue.)

Naïve solutions that just go fetch all entries of a category would probably be painful to the user too, assuming they would run on John's BlogTech tag, for instance, asking away for hundreds of post pages at once, so it would have to be something closer to the foldable Blogger backlinks lists, and if they loaded the whole page into themselves, what have we gained over clicking the link to them to see the post, really?

I'm not as skeptical as I might sound, I just think there might not be as much to gain from doing these really whacky scriptwrangling techniques. I spent a bit too much time getting Blogger's backlinks code to work on all Blogger pages, which in my version admittedly got even hairier than this hack would become, but that reminded me of the importance of surveying what you want to achieve and what the cost for that is.

Not all hacks are worth the time we invest in them, and especially not, if we weigh in the side effects of the number of browsers we lock out of each feature, by not testing the result to make sure it works reliably under other circumstances than with Own Favourite Browser version Mine. I'm sure my own blog is a horrendous reader experience for non-Firefox visitors, and that is really a step backwards toward the bad "best seen in FooBar Browser" icon days. I'm at least somewhat ashamed of playing around too much for the fun of it, the way I presently do; the web ought to be more about accessibility and portability.

<    >
Blogger Greg said...
Johan, you don't need to feel ashamed for playing around with this sort of stuff for the fun of it - that is the essence of hackery!

RE: AJAX. I'm only dimly aware of this, but I think anything that makes for a better user experience is good. But I do think there's a lot of value to be had in getting the most out of URLs, referrers etc (and also seeing them in your logs), so it's probably a trade-off between convenience for users and anticipating what they want.

Re: tag-grabbing. OK, I might limit it to "/search/..." (eg technorati), "/wiki/..." (eg wikipedia) - any others? (eg. "category" or "archive") How do other blogging platforms do categories?

Re: prompt. The earlier version of this did have a "select category" or similar default statement. Maybe that should return in the next release (as a parameter).

Re: Fade Anything Technique. I like! It certainly emphasises that a change has been made. Again, a parameter to select the highlight colour should be passed.

Request for Advice: when doing this kind of scripting, am I better off passing parameters to the js functions (like the height/width info), or is it better code to use global variables (like del_user and anchor)?

I figure that the number of parameters/options will grow, and I'd like some guidelines on making them global variables or passed parameters or something else.

Lastly, here's a thought I had about category integration across blogs: "tag piggybacking". Ie the publisher can select another delicious account (in addition to their own) to augment their tagspace (and hence posts).

Why? Well, when you're just starting out, it might communicate to your readers how you're positioning your content, before you've had a chance to build it up.

Or maybe you'd want to include the tags (or just a subset via anchor tags) of a prominent blogger, work colleague or even a group/shared blog of which you're a member.

It could also be used transiently ie you could have "guest tags" on your blog for a week, to help cross-promote a friend or collaborator. (Perhaps on exchange.)

I guess this would come in two flavours: fully integrated (their tags are entirely rolled in with yours, producing a virtual "super user"); and demarcated (separate lists, counts, labels etc).

While it may drive traffic away from your site, it could also make your blog richer and more useful hence gain you traffic. And, much like linking/blogrolls etc, what comes around goes around.

Thoughts?

Cheers,

-Greg.

<    >
Blogger Johan Sundström said...
Feedback on this would have become a bit unwieldy in a pop-up form at Freshblog; I took the liberty of going for a complete blog post instead.

<    >
Blogger Singpolyma said...
RE: Multi-tags - good idea, I was trying to think of a way to 'restart' a tag query somehow, I think that would work nicely :)

RE: Formatting tags page like proper posts... that would probably be pretty easy, I should think. Just change the .js to output the same tags as would be output by the blogger template for the post (ie with >h2 clas="post-title"< etc instead of just >ul<) but that wouldn't allow for the dates and comment counts... not sure how doing that would work.

RE: Putting post contents into del.icio.us extended field... perhaps a problem for others, I've been doing this since I started

RE: default label (ie 'Pick a category') mine does this, if no tag is selected the top item is '- Tags -'

RE: passing parameters - passing them to the function could actually be nicer, but that might be hard to implement since the JSON data must be pulled in again every time if you do it that way?

A question for anyone who knows... if I start making my rel=tag links point to my tags.html?tags= page, will technorati still pick it up?

<    >
Blogger Johan Sundström said...
Another thought on the topic of multiple tags: it could be useful somehow supporting both tag unions (| URL separator?) and intersections (+ URL separator?). ∪ and ∩ are good entities for mathematically inclined people, but I'm not sure of how a good user interface able to pick both sorts would look. :-) I don't think this is an application for which it would add much value (even though it would be somewhat cool) being able to toss up something handling "advanced" set algebra like (blog|blogger)+(tools|utilities), even though the feature is cute. Especially considering that a user interface capable of rendering such queries would by all reasonable bets be really horrible.

<    >
Blogger Singpolyma said...
The problem with supporting tag unions would be that to retrieve those you have to use the del.icio.us search, which as of yet is not supported through any feeds/apis that i know of...

<    >
Blogger Greg said...
At the risk of sprinkling yet more comments around the place ...

RE: set operations in delicious.

I emailed delicious a couple of months ago with some suggestions about the union/intersection thing. (For my money, +=or=union, but I recognise that the boat has already sailed on that issue). Haven't heard back. :-)

I would also like set operations at the user level (using + and | as above), for blogrolling, comment scouring and other purposes:

http://del.icio.us/thetan+joeblow/culture

That means something to me; but alas not to delicious. Ditto:

http://del.icio.us/thetan|joeblow/culture|art

etc

C'mon delicious - you know it makes sense!

Re: Technorati pickup. On my understanding, no. The tag name has to be in the directory structure, not just the query string of the URI. (I'm prepared to be wrong though.) The main thing is that you get your tag into your atom feed.

Re: stuffing your "notes" (or "extended") field in delicious.

I've taken to doing this too. Check out my script for populating it in Speccy:

%script type="text/javascript">
var re = /\r\n/gi;

var url_txt = "http://ghill.customer.netspace.net.au/speccy/2005/11/put-your-money-where-your-mouth-is.html";
var title_txt = "Speccy: Put Your Money Where Your Mouth Is";
var tags_txt = anchor+" spoilt_rotten";
var date_txt = "Friday, November 25: ";
var notes_txt = document.getElementById("113290348918118900").innerHTML.substr(0,240).replace(re, " "); // grab first 240 chars

var del_url = encodeURI('http://del.icio.us/'+del_user+'?url='+url_txt+'&title='+title_txt+'&tags='+tags_txt+'¬es='+date_txt+notes_txt);

document.write('%a href="'+del_url+'" target="_blank">%small>Tag%/small>%/a>');
%/script>

NB: most of the ..._txt = strings are populated by Blogger with tags like <$BlogDateHeader$> etc. Each post is given a unique ID by Blogger using the built-in tag:

%p class="main-text" id="113290348918118900">From time to time, I get vitriolic, h ...

Surely there must be an easier way! I've been experimenting with wget and grep to build a tag spider to backfill my posts:

* Record archive count on each archive page
* stuff first 200+ characters into the notes field
* Maybe even tag comments a la Johan's comment blogging ideas?

Will let you know how I get on.

Cheers,

-Greg.

<    >
Blogger Tolk said...
Wait, if I put

{script type="text/javascript"}
list_side_tags(1); // drop-list
write_tagged_posts(10, 22); // 10 high, 22 wide
{/script}

({=< just changed it for html-reasons)

in my sidebar it just cuts off everything that is supposed to come afterwards. I really don't know where the mistake is. Any idea? I'll leave it with the mistake for a while so you can have a look at it. Your help would be greatly appreciated!
Tolk

<    >
Blogger Greg said...
Herzlich Willkommen! Wie geht's?

You have to put:

anchor="";

after your del_user declaration. Also, make sure that there are no line breaks (enters/returns etc) in your various:

{script type="...

statements.

Viel Glueck!

Tschuess,

-Greg.

<    >
Blogger Tolk said...
Thanks! It works!

<    >
Blogger John said...
HCGPM: Try the updated program description / code that comes with Freshtags 0.5, and let me know if you run into any more problems.


eXTReMe Tracker