<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><atom:link rel="hub" href="http://tumblr.superfeedr.com/" xmlns:atom="http://www.w3.org/2005/Atom"/><description>Some Tools for Tumblr. Notes on Tumblr development, Tumblr themes, and the Tumblr API.</description><title>Post-Theory</title><generator>Tumblr (3.0; @post-theories)</generator><link>http://blog.post-theory.com/</link><item><title>Hi there. Today I found out about your Pretty Tag Cloud Maker and I have to say it looks fantastic. Cheers for that and thanks. Just a small problem, once I have pasted the code on the HTML area of the tumblr page, every change I make relating to the tags, like change the name of a tag or add a new one. doesn't seem to synch with the script. I tried to paste the code again but it doesn't work. Am I doing something wrong? (by the way, I ask anonymously because my tumblr is NSFW). Thanks again.</title><description>&lt;p&gt;Dear Anon, please read in the “&lt;a href="http://post-theory.com/pretty-cloud/maker#help"&gt;Help&lt;/a&gt;” section, FAQ questions 4 and 5.&lt;/p&gt;</description><link>http://blog.post-theory.com/post/38409073761</link><guid>http://blog.post-theory.com/post/38409073761</guid><pubDate>Thu, 20 Dec 2012 15:40:06 -0600</pubDate></item><item><title>it doesn't seem that you can exclude a tag that has a hyphen in it, is there a way to fix this?</title><description>&lt;p&gt;To whoever Anon asked, this should be fixed now.&lt;/p&gt;</description><link>http://blog.post-theory.com/post/38400523718</link><guid>http://blog.post-theory.com/post/38400523718</guid><pubDate>Thu, 20 Dec 2012 13:46:00 -0600</pubDate><category>tag cloud</category><category>fixes</category><category>updates</category></item><item><title>hi there! is it possible to make the tag cloud widget show specific tags that we want instead of just omitting tags that we don't want?</title><description>&lt;p&gt;No, that defeats the purpose!&lt;/p&gt;
&lt;p&gt;If you just want to list certain tags on your tumblr, you should just do it manually by adding the links yourself to your page :)&lt;/p&gt;
&lt;p&gt;Just add a bunch of links like:&lt;/p&gt;
&lt;pre&gt;&lt;a href="/tagged/sometag"&gt;sometag&lt;/a&gt;, &lt;a href="/tagged/anothertag"&gt;anothertag&lt;/a&gt;, ...&lt;/pre&gt;
&lt;p&gt;And so forth.&lt;/p&gt;</description><link>http://blog.post-theory.com/post/34683009598</link><guid>http://blog.post-theory.com/post/34683009598</guid><pubDate>Tue, 30 Oct 2012 22:44:00 -0500</pubDate></item><item><title>I&amp;#8217;m slightly bored &amp;#8212; I need a new coding project to work on.
Anyone out there have ideas...</title><description>&lt;p&gt;I&amp;#8217;m slightly bored &amp;#8212; I need a new coding project to work on.&lt;/p&gt;
&lt;p&gt;Anyone out there have ideas / suggestions / want help on a project?&lt;/p&gt;</description><link>http://blog.post-theory.com/post/25131495535</link><guid>http://blog.post-theory.com/post/25131495535</guid><pubDate>Thu, 14 Jun 2012 20:52:13 -0500</pubDate></item><item><title>I&amp;#8217;ve been thinking about social networks and social media sites.
It occurs to me that today,...</title><description>&lt;p&gt;I&amp;#8217;ve been thinking about social networks and social media sites.&lt;/p&gt;
&lt;p&gt;It occurs to me that today, you get way more &lt;em&gt;social SPAM&lt;/em&gt; from your &amp;#8220;friends&amp;#8221; / blogs / twitters / etc you follow, than you ever get Spam in your email Inbox.&lt;/p&gt;
&lt;p&gt;And what can we do about this phenomena?&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Edit&lt;/strong&gt;: &lt;/em&gt;&lt;a href="http://blog.linvo.org/"&gt;ivogeorgiev&lt;/a&gt; tells me it&amp;#8217;s not &amp;#8220;Spam&amp;#8221; but &amp;#8220;unwanted content&amp;#8221;.&lt;/p&gt;
&lt;p&gt;I mean what&amp;#8217;s the difference? Email Spam is &amp;#8220;unwanted content&amp;#8221; as well, and they&amp;#8217;ve figured out pretty well how to separate the wheat from the chaff on that front.&lt;/p&gt;
&lt;p&gt;Surely there is a way to apply the same kind of Spam filtering logic to the &amp;#8220;unwanted content&amp;#8221; on social sites like Tumblr, Facebook, Twitter etc.  For example Facebook offers some kinds of &amp;#8220;filtering&amp;#8221; abilities but honestly, putting things on lists, or Facebook&amp;#8217;s tendency to &amp;#8220;help&amp;#8221; your Feed by boosting Posts with more &amp;#8220;activity&amp;#8221; (comments, likes, etc) &amp;#8212; this does &lt;em&gt;not&lt;/em&gt; a Social Spam Filter make.&lt;/p&gt;</description><link>http://blog.post-theory.com/post/24944956726</link><guid>http://blog.post-theory.com/post/24944956726</guid><pubDate>Thu, 14 Jun 2012 12:04:00 -0500</pubDate><category>thinking out loud</category></item><item><title>HI, I'm a web developer and the co-founder of Essence Labs Creative Agency. I just wanted to give you a little idea that popped into my head when reading the post about the tumblr api. You should try making a static page that automatically fetches posts using ajax and the v1 tumblr api, and then have that be placed in a random order. That might work better than the cron job so this way each user gets a different page. Don't know if it will work too well, but its worth a shot! What do you think?</title><description>&lt;p&gt;The issue with AJAX and the Tumblr API is the cross-site domain restrictions in browsers.  The main page is at “foo.tumblr.com” and the information is at “api.tumblr.com”.  Firefox and Chrome won’t allow cross-subdomain AJAX calls like this.&lt;/p&gt;
&lt;p&gt;You *can* use JSONP as a workaround for the cross-site scripting issue, but I find it inelegant and ugly.&lt;/p&gt;
&lt;p&gt;But more to the point, when you need to load possibly hundreds of posts, the Tumblr API server is just too slow to get the results on the page in a reasonable amount of time.&lt;/p&gt;
&lt;p&gt;Experiments from my webserver (which has a super duper fast pipe) shows an average of over 2.0 seconds to load 250 posts from the Tumblr API.  This slows to over 3.5 seconds on my personal computer and home internet line.  This is just too slow.&lt;/p&gt;
&lt;p&gt;On the other hand, I can pre-emptively download the information from the API, extract what I need, cache the result in a “static” JavaScript file on my webserver and deliver it to the end client in just 100’s of milliseconds.  And so this is how I plan to solve this problem, using the Tumblr static “Pages” to load a specially generated JavaScript file (or JSON or whatever) with the required “shuffled post information” and display it with a tiny amount of JavaScript.&lt;/p&gt;
&lt;p&gt;This offers a better end experience to users.&lt;/p&gt;
&lt;p&gt;Thoughts?&lt;/p&gt;</description><link>http://blog.post-theory.com/post/21256961710</link><guid>http://blog.post-theory.com/post/21256961710</guid><pubDate>Tue, 17 Apr 2012 00:31:00 -0500</pubDate><category>tumblr api</category><category>tumblr criticisms</category><category>tumblr hacks</category></item><item><title>Re: Ivogeorgiev on Undocumented Features</title><description>&lt;a href="http://blog.post-theory.com/post/18132446503/undocumented-features-are-not-cool"&gt;Re: Ivogeorgiev on Undocumented Features&lt;/a&gt;: &lt;p&gt;&lt;a class="tumblr_blog" href="http://blog.linvo.org/post/21231451021/post-theory-undocumented-features-are-not-cool"&gt;ivogeorgiev&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a class="tumblr_blog" href="http://blog.post-theory.com/post/18132446503/undocumented-features-are-not-cool"&gt;felix-bonkoski&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;So, in writing my theme, I wanted a way to put a “Reblog” and “Like” link on each post on the &lt;em&gt;main page&lt;/em&gt; of the blog without users having to “click-through” to the “/post” page, and use Tumblr’s silly &lt;em&gt;&lt;iframe&gt;&lt;/em&gt; in the upper right corner.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Interesting. I discovered a similar thing, but at the end, ended up including the iframe for each single post, setting opacity: 0, and aligning/scaling it so that it matches my button positions. Does the desired effect, only until I realized I cannot highlight my heart button when the post is liked, because I don’t and can’t know if the post is liked. After some research, I found out that there IS a way to do it, only I don’t know how.&lt;/p&gt;
&lt;p&gt;Edit: no, there seems to be no way. At least nobody has done it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Right. The “reblog” is easy.  The “Like” button is tricky — not to “make it work” but to show whether or not the Post is already “Liked” or not.&lt;/p&gt;
&lt;p&gt;Reading the contents of Tumblr’s own iframe to determine, say, which image they are using &lt;em&gt;could&lt;/em&gt;give the result, but most browsers today prohibit inspecting the embedded iframe’s HTML with JavaScript for security reasons. Similarly, you cannot load the iframe’s content with AJAX because of security restrictions.  Perhaps with JSONP? I don’t know, haven’t tried to hack it out further.  And then yes, any “solution” would still be an ugly hack, likely to break whenever Tumblr’s whimsy programmers decided to mix things up a bit.&lt;/p&gt;
&lt;p&gt;What &lt;strong&gt;really&lt;/strong&gt; needs to happen is to just incorporate these functions into the Tumblr Theme Engine. It would probably be like, &lt;em&gt;a few hours work&lt;/em&gt; for some Tumblr employee to implement this.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I also thought about scanning the notes of every post to check if you have liked it. Terribly inefficient, but it should happen fast enough for posts with 0-20 notes. It would have to be disabled for posts with more than 100 notes (or at least scan only the first 100 ones). Also, it would put a lot of queries on the Tumblr servers.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Yes, this is not a very robust technique.  And Tumblr doesn’t look kindly on “page scraping” in general.  Nor is there a way in the Tumblr API to fetch more than the most recent 50 notes for a post — &lt;em&gt;at all!&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;But who cares, if they don’t want this they better improve their support - I have never heard a story of a theme designer who got in touch with the tumblr programmers. &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Oh — well I have at least tried to get in touch with the Tumblr folks, on several occaisons.&lt;/p&gt;
&lt;p&gt;And at least on the &lt;a href="https://groups.google.com/forum/?fromgroups#!forum/tumblr-api"&gt;Tumblr API Google Group&lt;/a&gt;, there is one Tumblr Employee (&lt;a href="http://blog.johnbunting.me/"&gt;John Bunting&lt;/a&gt;) who monitors the discussion in the group and is able to provide some feedback. However, he seems fairly powerless in the overall Tumblr structure to get any *real* changes made, although he has been helpful in fixing some bugs, etc. (The &lt;a href="https://groups.google.com/forum/?fromgroups#!forum/tumblr-themes"&gt;Tumblr Theme Google Group&lt;/a&gt; seems to be completely unmoderated by any Tumblr employees).&lt;/p&gt;
&lt;p&gt;I’ve also sent emails to the Tumblr staff a several times about bugs in the API and Theme engine, and requests for features, etc.  I usually get what looks to be a “real response from a real human” back — but nobody ever follows through to fix any of the problems I mention.&lt;/p&gt;
&lt;p&gt;On the whole, Tumblr &lt;strong&gt;seriously&lt;/strong&gt; needs to improve their support for developers. This is means listening to feedback, answering questions, fixing bugs and problems quickly and promptly.&lt;/p&gt;
&lt;p&gt;For now - it’s really a giant headache.&lt;/p&gt;</description><link>http://blog.post-theory.com/post/21256692714</link><guid>http://blog.post-theory.com/post/21256692714</guid><pubDate>Tue, 17 Apr 2012 00:23:00 -0500</pubDate><category>tumblr criticisms</category><category>tumblr themes</category><category>tumblr is lame</category></item><item><title>My House Caught Fire</title><description>&lt;p&gt;On Tuesday Night, my house caught fire.  Everyone in my family is OK but a lot of our stuff is totally ruined. As you can imagine, this is very stressful. We&amp;#8217;re staying with my uncle &amp;amp; aunt for now, but I have very limited internet access here.  I will update everyone as soon as I can.&lt;/p&gt;</description><link>http://blog.post-theory.com/post/21004526193</link><guid>http://blog.post-theory.com/post/21004526193</guid><pubDate>Thu, 12 Apr 2012 21:55:00 -0500</pubDate></item><item><title>Tag Cloud Update</title><description>&lt;p&gt;I added a few new updates / features to my &lt;a href="http://post-theory.com/tumblr-tag-cloud-javascript" title="Tumblr Tag Cloud Script"&gt;Basic Tumblr Tag Cloud&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;
&lt;p&gt;Added the ability to change the &amp;#8220;case&amp;#8221; of your tags to Lower-case, Upper-case, and Title-case for display purposes.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Improved the default &amp;#8220;Alphabetical&amp;#8221; sorting code to better handle non-English Latin-script languages.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Added &amp;#8220;language&amp;#8221; option to specify a language &amp;#8220;locale&amp;#8221;, which can improve Alphabetical sorting and Case transforming on Tags for many languages, including non-Latin-script languages.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;These additions (and some other new neato new things) will also be added to the &lt;a href="http://post-theory.com/pretty-cloud/maker" title="Pretty Tag Cloud Maker"&gt;&amp;#8220;Pretty&amp;#8221; Tag Cloud&lt;/a&gt; in the next few days.&lt;/p&gt;
&lt;p&gt;Also, I can always use &lt;a href="http://blog.post-theory.com/ask"&gt;more feedback&lt;/a&gt; from people. Please?&lt;/p&gt;</description><link>http://blog.post-theory.com/post/20580524949</link><guid>http://blog.post-theory.com/post/20580524949</guid><pubDate>Fri, 06 Apr 2012 04:17:00 -0500</pubDate><category>post theory</category><category>updates</category><category>tag cloud</category><category>gratuitous self promotion</category></item><item><title>Job - Tumblr API Lead</title><description>&lt;a href="http://tumblr.theresumator.com/apply/34qREQ/API-Lead.html?source=Tumblr+Jobs+Page"&gt;Job - Tumblr API Lead&lt;/a&gt;: &lt;p&gt;&lt;a class="tumblr_blog" href="http://blog.johnbunting.me/post/20346452120/job-tumblr-api-lead"&gt;codingjester&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a class="tumblr_blog" href="http://dashbuddy.tumblr.com/post/20345264949/job-tumblr-api-lead"&gt;dashbuddy&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Fantastic to see this job up, I really wish I had the skills because I can’t imagine a more engaging job right now!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Yep! We’re looking for someone to help us hack on the API! Check it out! It’s gonna be fun ;)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I’d apply if I wasn’t 17 lol :P&lt;/p&gt;</description><link>http://blog.post-theory.com/post/20534314927</link><guid>http://blog.post-theory.com/post/20534314927</guid><pubDate>Thu, 05 Apr 2012 12:28:03 -0500</pubDate></item><item><title>A Small Tumblr Hacking Project, and What I Learned</title><description>&lt;p&gt;Recently I&amp;#8217;v been working on writing some &amp;#8220;back end&amp;#8221; code for a Tumblr blog that wants to do some non-standard things using Tags.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;m all about trying to hack the Tumblr platform: hacking with the Tumblr API &amp;amp; doing unorthodox things in Tumblr themes.&lt;/p&gt;
&lt;p&gt;The project is called &lt;strong&gt;Lensblr&lt;/strong&gt; (&lt;a href="http://lensblr.com"&gt;&lt;a href="http://lensblr.com"&gt;http://lensblr.com&lt;/a&gt;&lt;/a&gt;)  I&amp;#8217;m not directly involved with creating the site. I&amp;#8217;m just writing some devious back-end stuff to create added functionality.&lt;/p&gt;
&lt;p&gt;The project caught my attention because navigation &amp;amp; view of the Tumblr is done exclusively through use of the &lt;em&gt;/tagged/foobar&lt;/em&gt; pages. There is no view of the &amp;#8220;main post feed&amp;#8221;.  It&amp;#8217;s an interesting idea towards creating a custom Tumblr website.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Magical Post Tags&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;One goal of the designer was to automatically add/remove specific tags from posts, based on set criteria.  In this case, the criteria is rather simple:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;
&lt;p&gt;Based on the number of &amp;#8220;notes&amp;#8221; a post gets, add/remove tags that &amp;#8220;move&amp;#8221; the post to/from different pages on the Tumblr.&lt;/p&gt;
&lt;p&gt;For example, after a post reaches 50 notes, we want to remove the tag the displays the post on one page, and move it to another page called &amp;#8220;Featured Posts&amp;#8221;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;This is easily implemented using cron job that runs a script to analyze the posts on the blog, and use the Tumblr API to &amp;#8220;retag&amp;#8221; the posts as needed.&lt;/p&gt;
&lt;p&gt;Of course, this kind of tag modification for changing how a site is presented could be extended and extrapolated to do lots of interesting things, based on any number of factors. It&amp;#8217;s a promising idea.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Magical Post Shuffling and Randomization&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A second goal of the designer behind &lt;a href="http://lensblr.com"&gt;Lensblr&lt;/a&gt; was to implement a way so that posts on a particular /tagged/ Page could be randomly shuffled, such that older posts would sometimes reach the first page.&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;The principle is more &lt;em&gt;equal exposure of content&lt;/em&gt;, regardless or whether or not that content was posted 2 months ago or an hour ago.&lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;li&gt;Not all content is Timely; and most people never make it past the 1st or 2nd page of a blog.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Fortunately, you can modify the Published Date on posts using the Tumblr API.  And when viewing posts through the standard &amp;#8220;Posts&amp;#8221; interface (mounted at / ), this works rather well. You are able to shuffle posts around so that older and newer posts get equal chance of exposure on the 1st or 2nd page of the blog.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Unfortunately&lt;/strong&gt;, Tumblr seems to have a bug/limitation with sorting posts by &amp;#8220;Time&amp;#8221; on the &lt;em&gt;/tagged/foobar&lt;/em&gt; pages:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;If a post is on page 3 of &lt;em&gt;/tagged/foobar&lt;/em&gt;, even modifying the post&amp;#8217;s Publish Date is not enough to &lt;strong&gt;ever&lt;/strong&gt; bounce it up to page 1.  The post is &amp;#8220;&lt;strong&gt;stuck&lt;/strong&gt;&amp;#8221; on page 3 forever. (or page 4, 5&amp;#8230; etc as more posts are added).&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Interestingly, on the individual pages &lt;em&gt; /tagged/foobar/page/X&lt;/em&gt;  the posts *are* sorted chronologically &amp;#8212; but only relative to the other posts on that page.&lt;/p&gt;
&lt;p&gt;Based on this, I&amp;#8217;ve concluded that while Tumblr &amp;#8220;sorts by Time&amp;#8221; it only does so &lt;em&gt;per page&lt;/em&gt;; the actual posts that are put on a given page comes from &amp;#8220;sorting by Post ID&amp;#8221;.  It&amp;#8217;s a bit inconsistent.&lt;/p&gt;
&lt;p&gt;So although we had a sound principle and strategy, implemented the code to &amp;#8220;shuffle&amp;#8221; the posts around &amp;#8212; it just doesn&amp;#8217;t work within Tumblr&amp;#8217;s buggy / limited system.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Working within Tumblr&amp;#8217;s Limitations&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Tumblr does not provide Developers with many good means for representing blog Content with different &amp;#8220;views&amp;#8221; or in different ways. Using Tags seems to be the only practical way to achieve these ends, for now.&lt;/p&gt;
&lt;p&gt;Things that are &lt;strong&gt;not&lt;/strong&gt; particularly useful:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;
&lt;p&gt;The &amp;#8220;Static Pages&amp;#8221;&lt;/p&gt;
&lt;p&gt;While these can contain arbitrary HTML completely separate from the main &amp;#8220;Theme&amp;#8221; they are rather useless from the perspective of creating / loading dynamic content, or content that changes with high frequency (say once a day).&lt;/p&gt;
&lt;p&gt;&amp;#8220;Pages&amp;#8221; are &lt;strong&gt;&lt;em&gt;not&lt;/em&gt;&lt;/strong&gt; accessible through the Tumblr API, so making automatic changes to these Pages with code is not possible.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The Tumblr API&lt;/p&gt;
&lt;p&gt;The API is OK if you are developing an application for the desktop or a mobile device. It lets you do *most* things you might want to do to create a &amp;#8220;Tumblr Experience&amp;#8221; on a mobile device, or say a &amp;#8220;Tumblr Posting / Editing&amp;#8221; program on the Desktop.&lt;/p&gt;
&lt;p&gt;Where the API is &lt;strong&gt;not&lt;/strong&gt; particularly useful is in trying to create dynamically generated content on web pages.&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;
&lt;p&gt;Tumblr only supports OAuth1.0 (they should really upgrade to an OAuth2.0 interface)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Tumblr does not support CORS, a technology that allows controlled &amp;#8220;cross-site&amp;#8221; AJAX calls.  Without CORS, as a developer you are limited to using rather ugly JSONP callbacks, and then only HTTP &amp;#8220;GET&amp;#8221; commands.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The available methods in the Tumblr API in many cases do not provide sufficient means to request the specific information you want:  first, there are not enough &amp;#8220;filters&amp;#8221; to select the data you want, no literally no means to control the &amp;#8220;output&amp;#8221; received from the API.  For example, if all I want is the list of &amp;#8220;Tags&amp;#8221; from posts on a blog - I still have to download *all that other data* which has no use for me. That adds up rather quickly to a *lot* of transferred data.&lt;/p&gt;
&lt;p&gt;The API needs better methods of &amp;#8220;selecting&amp;#8221; the types of posts to return, and then needs to implement a way to filter down the data returned to only what you require in order to make the API useful in the context of creating dynamic web pages.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The API Server is just plain &lt;em&gt;slow&lt;/em&gt;. Response times I observe are often in the range of 600-800&amp;#160;ms for simple requests (say &amp;#8220;grab 50 posts&amp;#8221;), and up to 2000-3000&amp;#160;ms for larger requests (say, &amp;#8220;grab 200 posts&amp;#8221;).&lt;br/&gt;&lt;br/&gt;Part of the problem is the before-mentioned lack of ability to &amp;#8220;filter down&amp;#8221; to just the data you need.&lt;br/&gt;&lt;br/&gt;Another part of the problem is that the API Servers refuse to use &lt;strong&gt;HTTP Keep-Alive&lt;/strong&gt; if you will be requesting multiple pieces of data in quick succession.  The API Server should enable Keep-Alive.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;&lt;br/&gt;So Why Bother?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Because Tumblr is a great &lt;em&gt;social&lt;/em&gt; platform. You bother trying to create custom/specialized Tumblr pages to create a unique &amp;#8220;Web Experience&amp;#8221; while at the same time being able to &lt;em&gt;take advantage&lt;/em&gt; of the &lt;em&gt;social&lt;/em&gt;aspects that Tumblr can provide to your Page and your Content.&lt;/p&gt;
&lt;p&gt;As a Developer however &amp;#8212; this is all rather frustrating.&lt;/p&gt;
&lt;p&gt;Anyway, Tumblr just put up a &lt;a href="http://tumblr.theresumator.com/apply/34qREQ/API-Lead.html?source=Tumblr+Footer"&gt;Job Listing for API Lead&lt;/a&gt;. Perhaps that is a sign that things will get better in the near future.&lt;/p&gt;
&lt;p&gt;But for now, it&amp;#8217;s all pretty &lt;em&gt;&lt;strong&gt;foobar&lt;/strong&gt;&lt;/em&gt;&lt;strong&gt;.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;br/&gt;&lt;/strong&gt;&lt;/p&gt;</description><link>http://blog.post-theory.com/post/20399580877</link><guid>http://blog.post-theory.com/post/20399580877</guid><pubDate>Tue, 03 Apr 2012 02:44:00 -0500</pubDate><category>tumblr api</category><category>tumblr criticisms</category><category>tumblr development</category><category>tumblr hacks</category><category>coding</category></item><item><title>Using Google WebFonts, and Being too Smart for my own Good</title><description>&lt;p&gt;This issue came up on a recent project web project I&amp;#8217;ve been working on.&lt;/p&gt;
&lt;p&gt;In the project, I allow users to choose from a subset of fonts provided by the &lt;a href="http://www.google.com/webfonts"&gt;Google WebFonts API&lt;/a&gt; to style their Text in a pretty font.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Problem - International Support&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I get a message from a Czech user, requesting support for fonts that display the Czech language properly.  (The Czech script uses various characters found in the &amp;#8220;Extended Latin&amp;#8221; Unicode blocks)&lt;/p&gt;
&lt;p&gt;Luckily, I find on Google Webfonts that you can specifically request fonts with various script subsets.&lt;/p&gt;
&lt;p&gt;For example, suppose you want the font &amp;#8220;Poiret One&amp;#8221; with the Latin-Extended character set, you can request:&lt;/p&gt;
&lt;pre&gt;fonts.googleapis.com/css?family=Poiret+One&amp;amp;subset=latin,latin-ext&lt;/pre&gt;
&lt;p&gt;Splendid - sorta.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A naive approach to offering better &amp;#8220;international support&amp;#8221;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In my naive approach:&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;I examined the user&amp;#8217;s text to determine if any characters where outside the &amp;#8220;Standard Latin Block&amp;#8221; (eg, if any character&amp;#8217;s ordinal is &amp;gt; 127).&lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;li&gt;If so, I disabled the fonts having only &amp;#8220;Latin&amp;#8221; support, and only enabled fonts supporting &amp;#8220;Latin Extended&amp;#8221;&lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;li&gt;For supported fonts, I request the font from Google using the &amp;#8220;subset=latin,latin-ext&amp;#8221;  call, as above.&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;&lt;strong&gt;But that didn&amp;#8217;t quite work&amp;#8230;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&amp;#8230; Because it turns out (I suppose unsurprisingly) that many of the fonts Google has classified as supporting &amp;#8220;Latin Extended&amp;#8221; do not support many of the characters required to display Czech properly (and doubtless many other languages as well)&lt;/p&gt;
&lt;p&gt;Now, I don&amp;#8217;t know who at Google determines how / why a font gets &lt;em&gt;classified as supporting&lt;/em&gt; the &amp;#8220;Latin Extended&amp;#8221; block, what characters must be supported, etc.&lt;/p&gt;
&lt;p&gt;But &amp;#8212; their classification system is quite simply &lt;strong&gt;broken&lt;/strong&gt;. In more ways than this - as you will see.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Designing a &amp;#8220;Smart&amp;#8221; Approach&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I decided that I could do better. I really didn&amp;#8217;t want to offer fonts if they would be unable to display the user&amp;#8217;s language properly. And since Google&amp;#8217;s &amp;#8220;classification&amp;#8221; was not thorough enough, I decided to do it myself.&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;I downloaded the relevant TrueType Font files from Google for the fonts supported in my app.&lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;li&gt;I wrote a small Python program utilizing the &lt;a href="http://sourceforge.net/projects/fonttools/"&gt;TTX/FontTools&lt;/a&gt; package to examine the TrueType files.&lt;br/&gt;&lt;br/&gt;It was relatively simple to search the &amp;#8216;cmap&amp;#8217; table within the TTF File to see if the Font contained a Glyph for a given Unicode ordinal.&lt;br/&gt;&lt;br/&gt;I dumped the list of the supported Glyph Ordinals of the font into a Python &lt;strong&gt;set&lt;/strong&gt; object, let&amp;#8217;s call it &lt;em&gt;fontCharSet&lt;/em&gt;&lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;li&gt;I took the text the user was trying to render, and dumped the Unicode ordinals of the text into another Python &lt;strong&gt;set&lt;/strong&gt; object, let&amp;#8217;s call this &lt;em&gt;userCharSet&lt;/em&gt;&lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;li&gt;Now, determining if a font supported the user&amp;#8217;s language was as simple as calling one line of Python code:&lt;br/&gt;&lt;pre&gt;fontSupported = &lt;em&gt;userCharSet&lt;/em&gt;.issubset(&lt;em&gt;fontCharSet)&lt;br/&gt;&lt;/em&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Wow, that was easy. With just about 100 fonts to check, the process of validating the user&amp;#8217;s text against the supported fonts for my application took less than a millisecond.&lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;li&gt;(See appendix for code example) &lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;Now I had a great way to only show fonts to users &lt;em&gt;if those fonts could properly display their language&lt;/em&gt;. And then I could retrieve those fonts with the extra needed characters, by specifying the &lt;strong&gt;subset&lt;/strong&gt; when calling the WebFonts API.&lt;/p&gt;
&lt;p&gt;I easily extended this include support for Cyrillic and Greek text as well, by separating the user&amp;#8217;s Text into the relevant &lt;a href="http://www.unicode.org/Public/UNIDATA/Blocks.txt"&gt;Unicode blocks&lt;/a&gt; to determine which subsets to request from Google.&lt;/p&gt;
&lt;p&gt;And now, when a user visits my page, only fonts I was certain could display their language were presented as options.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Awesome. Great.  &amp;#8230; Or so I thought.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;It turns out that &amp;#8220;&lt;em&gt;subset classification&lt;/em&gt;&amp;#8221; of fonts that Google offers is not just &lt;strong&gt;&lt;em&gt;for your information&lt;/em&gt;&lt;/strong&gt; &amp;#8212; it is also &lt;em&gt;&lt;strong&gt;limiting&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Take the WebFont &amp;#8220;&lt;strong&gt;PT Sans Narrow&lt;/strong&gt;&amp;#8221; &amp;#8212; a nice sans-serif font with narrow characters, and slightly tall Capital letters. It has good support for Latin, Latin-extended, and Cyrillic.&lt;/p&gt;
&lt;p&gt;Running my &amp;#8220;language checker&amp;#8221; code revealed this font could correctly display all the characters in my Czech user&amp;#8217;s Text, and so this font was duly added to his list of &amp;#8220;Supported Fonts&amp;#8221;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Except it isn&amp;#8217;t supported - not really, not by Google.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If you examine the PT Sans Narrow &lt;a href="http://code.google.com/webfonts/specimen/PT%20Sans%20Narrow"&gt;Font Specimen on Google WebFonts&lt;/a&gt; you will see that &amp;#8220;Latin Extended&amp;#8221; is not listed as one of the supported character sets. Although, in fact, the font supports much of the Latin-Extended set &amp;#8212; enough at least to render my Czech user&amp;#8217;s text.&lt;/p&gt;
&lt;p&gt;And requesting the font with&lt;/p&gt;
&lt;pre&gt;fonts.googleapis.com/css?family=PT+Sans+Narrow&amp;amp;subset=latin,latin-ext&lt;/pre&gt;
&lt;p&gt;Does &lt;strong&gt;not&lt;/strong&gt; return &lt;strong&gt;any&lt;/strong&gt; characters in the Latin-Extended block &lt;strong&gt;at all&lt;/strong&gt;. At all. Not even the characters that &lt;em&gt;do exist&lt;/em&gt;. You just get plain Latin. Sorry.&lt;/p&gt;
&lt;p&gt;And it turns out that there are a &lt;strong&gt;bunch&lt;/strong&gt; of fonts like this on Google WebFonts. Too many to list.&lt;/p&gt;
&lt;p&gt;Fonts that, by examining the actual font file for Glyphs, you find are able to support a given user&amp;#8217;s language needs, but which you &lt;em&gt;cannot retreive from Google with the additional characters needed.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The bottom line is&lt;/strong&gt; - if it doesn&amp;#8217;t say &amp;#8220;Yes this font supports Latin-Extended&amp;#8221; then you can&amp;#8217;t retrieve those characters from Google WebFonts, &lt;em&gt;even if they do exist&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Ugh.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Once again - too smart for my own damn good.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I have filed a bug report with the &lt;a href="http://code.google.com/p/googlefontdirectory/"&gt;Google WebFonts project on Google Code&lt;/a&gt; for some of the fonts I have noted behave in this way. Although I do not suspect it will do much good, looking at the &amp;#8220;Issue tracking&amp;#8221; page for the project. (It seems there is little activity, and virtually no response to any issues reported). And there seems to be no &amp;#8220;Support&amp;#8221; page or link &lt;em&gt;anywhere&lt;/em&gt; on the &lt;a href="http://www.google.com/webfonts"&gt;WebFonts page&lt;/a&gt; or the &lt;a href="https://developers.google.com/webfonts/docs/developer_api"&gt;WebFonts API page&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Sigh. Technology sucks.&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;&lt;em&gt;&lt;strong&gt;EDIT&lt;/strong&gt; - March 15, 12:00 AM GMT&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;To my amazement, by complaining on the &lt;a href="https://groups.google.com/forum/?fromgroups#!topic/googlefontdirectory-discuss/Xqrgy25m2Xc"&gt;Google Font Directory Discussion group&lt;/a&gt; I actually got some feedback from a guy at Google who seems to be in charge of issues like this.&lt;/p&gt;
&lt;p&gt;Basically, this is what I learned from him:&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;If a font is not listed as supporting a script subset on the WebFonts directory (e.g. &amp;#8220;latin-ext&amp;#8221;) then it is &lt;strong&gt;&lt;em&gt;not possible&lt;/em&gt;&lt;/strong&gt; to retrieve those extra characters by using &amp;#8220;subset=latin-ext&amp;#8221;, even if the font in question does indeed contain characters in the Latin-Extended blocks.&lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;li&gt;He cited one of the primary reasons for this limitation is that some fonts support &lt;em&gt;&lt;strong&gt;too many Glyphs&lt;/strong&gt;&lt;/em&gt; in the Latin-Extended block, and thus the resulting file size for the font would be &lt;em&gt;too big. &lt;br/&gt;&lt;br/&gt;&lt;/em&gt;Gee Google, thanks for &lt;em&gt;shafting&lt;/em&gt; people who don&amp;#8217;t use an ASCII Alphabet.&lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;li&gt;He was willing to &amp;#8220;fix&amp;#8221; the Encoding information for a few fonts that I complained about in particular, but again not those whose resulting file size would be &lt;em&gt;too big.&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;&lt;br/&gt;&lt;br/&gt;&lt;em&gt;&lt;strong&gt;Appendix: Python Code Sample: &lt;/strong&gt;&lt;/em&gt; (requires the &lt;a href="http://sourceforge.net/projects/fonttools/"&gt;TTX/fonttools&lt;/a&gt; library)&lt;/p&gt;
&lt;pre&gt;from fontTools import ttLib

fontfile = 'PT_Sans-Narrow-Web-Regular.ttf'
font = ttLib.TTFont(fontfile)
cmaptable = font['cmap'].getcmap(3, 1) # platform id (3,1) = "Windows"
fontCharSet = set(cmaptable.cmap) # set with Unicode ordinals for Glyphs in the font

usertextfile = 'text-sample.txt'
F = open(usertextfile, 'rb')
with F:
	unicodeText = F.read().decode('utf-8')
	# create set of Unicode ordinals in the text
	# (use ord(c) &amp;gt; 32 to skip control characters)
	userCharSet = set([ord(c) for c in unicodeText if ord(c) &amp;gt; 32])

fontSupported = userCharSet.issubset(fontCharSet)&lt;/pre&gt;</description><link>http://blog.post-theory.com/post/19347716849</link><guid>http://blog.post-theory.com/post/19347716849</guid><pubDate>Thu, 15 Mar 2012 19:08:00 -0500</pubDate><category>webfonts</category><category>international support</category><category>python</category><category>fonts</category><category>buggy software</category><category>google webfonts</category><category>when technology fails</category></item><item><title>Thoughts on Internationalization</title><description>&lt;p&gt;I added a bit more support code for international users of my &amp;#8220;Tumblr Pretty Tag Cloud&amp;#8221;. There is still quite some work to do however!&lt;/p&gt;
&lt;p&gt;I never really though about &amp;#8220;internationalization&amp;#8221; when I set off writing the code. Honestly, I gave no second thought to non-English speakers &amp;#8212; and the various scripts (i.e., the different &amp;#8220;alphabets&amp;#8221; we use to write &amp;#8220;letters&amp;#8221; or &amp;#8220;words&amp;#8221; etc)  and the various character encodings (the &amp;#8220;computer representations&amp;#8221; of those scripts) that come with that. I am aware of all these things - but I did not really plan for it, at all.&lt;/p&gt;
&lt;p&gt;In my head, it is so easy to assume &amp;#8220;everyone on the internet uses English&amp;#8221;. Part of this I think has to do with where I live and grew up (e.g., &lt;strong&gt;not&lt;/strong&gt; a major cosmopolitan city, where you find people from different countries and with different languages), and part also because (for the time being, perhaps?) English is the &lt;em&gt;lingua-franca&lt;/em&gt; of programming and the Web &amp;#8212; and I am never really exposed to &amp;#8220;Non-English&amp;#8221; websites.&lt;/p&gt;
&lt;p&gt;And yet now I find that the good majority of people using my tool are &lt;em&gt;non-English-speaking&lt;/em&gt; users. It should not surprise me, I guess - but it still does. Users from Peru, Chile, Brazil, Norway, Czech Republic, Germany, Korea, Japan, Russia - you name it.&lt;/p&gt;
&lt;p&gt;Still, I think it is good, that my first real &amp;#8220;public software release&amp;#8221; has ushered me so quickly into the &lt;em&gt;rest&lt;/em&gt; of the world, and forced me to confront some of the challenges of writing &amp;#8220;internationally aware&amp;#8221; software.&lt;/p&gt;
&lt;p&gt;A few technical points that made all of this &lt;em&gt;much easier&lt;/em&gt; than it could have been:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;I have been using a &lt;a href="http://python.org/"&gt;Python&lt;/a&gt; webstack to develop my server-side code. (because &lt;a href="http://webonastick.com/php.html"&gt;PHP&lt;/a&gt; is so &lt;a href="http://www.codinghorror.com/blog/2008/05/php-sucks-but-it-doesnt-matter.html"&gt;yucky&lt;/a&gt;).&lt;br/&gt;&lt;br/&gt;One of the best things I have found in Python is that it is quite easy to write internationally &amp;#8220;aware&amp;#8221; code. It is simple to maintain all of your strings / text data as Unicode strings &amp;#8212; they act exactly the same as a standard Ascii strings, coerce to a conventional string object as needed (eg, suppose you have a unicode string x = u&amp;#8217;1&amp;#8217; and want to test x == &amp;#8216;1&amp;#8217;), and are easy to encode to various encodings (although the simplest thing &amp;#8212; and the default &amp;#8212;- is to always work with utf-8).&lt;br/&gt;&lt;br/&gt;I didn&amp;#8217;t have to modify a single line of code to &amp;#8220;make it work&amp;#8221; with characters outside the ascii (or Latin) range.&lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;li&gt;It pays to have a good JSON library that encodes your Unicode strings properly for use in Javascript. Don&amp;#8217;t try to cobble one together yourself or use some half-assed implementation someone else threw together in an afternoon.&lt;br/&gt;&lt;br/&gt;The JSON library in the Python Standard Library does a perfect job  &amp;#8212; although it turned out to be &lt;em&gt;quite&lt;/em&gt; slow. So I am using a C-implemented Python library &lt;a href="http://pypi.python.org/pypi/jsonlib"&gt;jsonlib&lt;/a&gt; with excellent results.&lt;br/&gt;&lt;br/&gt;&lt;/li&gt;
&lt;li&gt;It&amp;#8217;s a big help if your Web host (or you!) has your HTTP server configured properly to set HTTP character-encoding headers. If not, you will struggle to remember to set them yourself manually and correctly each time you return data to the client. Configure your server! Don&amp;#8217;t make ugly code.&lt;br/&gt;&lt;br/&gt;My particular webstack runs on a Python-based WSGI server called &lt;a href="http://www.cherrypy.org/"&gt;CherryPy&lt;/a&gt;. It does a spectacular job of properly &amp;amp; automatically interpreting character data in HTTP requests (and returning you nice Unicode string objects), as well as automatically encoding data &amp;amp; setting headers for your HTTP responses. &lt;br/&gt;&lt;br/&gt;Again - not something you should try to cobble together yourself! Someone else has done all this nitty-gritty hard work already. Use their work and benefit from it.&lt;br/&gt;&lt;br/&gt;Keep your code consistent: pick a standard and stick with it. I always work with Unicode strings in my code, and always send output as UTF-8. The HTTP server can handle re-encoding if necessary.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Well, those are just some thoughts.&lt;/p&gt;
&lt;p&gt;Felix&lt;/p&gt;</description><link>http://blog.post-theory.com/post/18997128143</link><guid>http://blog.post-theory.com/post/18997128143</guid><pubDate>Fri, 09 Mar 2012 04:23:00 -0600</pubDate><category>internationalization</category><category>international support</category><category>coding</category><category>python</category></item><item><title>Tumblr "Pretty" Tag Clouds</title><description>&lt;p&gt;I&amp;#8217;m putting up a &lt;strong&gt;beta preview&lt;/strong&gt; of my new &lt;a href="http://post-theory.com/pretty-cloud/maker"&gt;&lt;strong&gt;Pretty Tag Cloud&lt;/strong&gt; maker for Tumblr&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Design your own Pretty Tag Cloud: choose your fonts, colors, etc.&lt;/p&gt;
&lt;p&gt;Then Save it, share a link, embed it on your Tumblr Theme or in a Tumblr Post.&lt;/p&gt;
&lt;p&gt;w00t&amp;#160;!&lt;/p&gt;</description><link>http://blog.post-theory.com/post/18545265828</link><guid>http://blog.post-theory.com/post/18545265828</guid><pubDate>Mon, 05 Mar 2012 21:50:00 -0600</pubDate><category>tag cloud</category><category>tagging</category><category>tags</category><category>tumblr development</category><category>tumblr tools</category><category>post theory</category></item><item><title>Tumblr Themes: Don't Trust a URL is "HTML Safe"</title><description>&lt;p&gt;&lt;strong&gt;Part 3&lt;/strong&gt; in my series on &amp;#8220;&lt;strong&gt;Tumblr Theme Limitations&lt;/strong&gt;&amp;#8221;&lt;/p&gt;
&lt;p&gt;AKA, &lt;em&gt;Why Tumblr&amp;#8217;s Theme Template System is Incredibly Lame, &lt;br/&gt;&lt;/em&gt;and&lt;em&gt; Hacks You Can Use to Get Around Its Limitations &amp;amp; Lameness&lt;br/&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;In my &lt;a href="http://blog.post-theory.com/post/18173369734/tumblr-theme-limitations-when-a-block-doesnt-exist"&gt;previous Article&lt;/a&gt;, I pondered whether or not URL&amp;#8217;s supplied by Tumblr&amp;#8217;s Theme Templater were &lt;em&gt;in general&lt;/em&gt; safe to include directly in JavaScript strings: i.e., that they had at least been properly &lt;strong&gt;Escaped &lt;/strong&gt;for inclusion inside a Double (or single) quoted String.&lt;/p&gt;
&lt;p&gt;I decided that, &lt;em&gt;&lt;strong&gt;No: Tumblr is lame&lt;/strong&gt;. So I should &lt;strong&gt;not assume&lt;/strong&gt; that:&lt;/em&gt;&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;URL&amp;#8217;s have been properly &lt;em&gt;escaped&lt;/em&gt; for inclusion in Strings&lt;em&gt;&lt;br/&gt;&lt;br/&gt;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;URL&amp;#8217;s have been properly &lt;em&gt;URL Encoded&lt;/em&gt; to replace URL-unsafe characters&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;But at least there is the {JS&amp;#8230;} &lt;a href="http://www.tumblr.com/docs/en/custom_themes#variable-transformations"&gt;Variable Transform&lt;/a&gt;, which does seem to function properly &amp;#8212; so far as I can tell. And it&amp;#8217;s useful too &amp;#8212; we&amp;#8217;ll get to that more in this article.&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;&lt;br/&gt;The Question&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;This led me to wonder if &lt;em&gt;in general&lt;/em&gt;, URL&amp;#8217;s supplied by Tumblr&amp;#8217;s Theme Templater were &lt;em&gt;&lt;strong&gt;even safe to include directly in your HTML&lt;/strong&gt;&lt;/em&gt; &amp;#8212; e.g.&lt;/p&gt;
&lt;pre&gt;&amp;lt;a href="{SomeURLVariable}"&amp;gt; ... &lt;/pre&gt;
&lt;h3&gt;&lt;strong&gt;&lt;br/&gt;The Question: Answered&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;The Answer is NO:&lt;/strong&gt; You &lt;strong&gt;&lt;em&gt;cannot&lt;/em&gt;&lt;/strong&gt; assume that &lt;strong&gt;Every&lt;/strong&gt; URL that Tumblr passes you is &lt;strong&gt;Safe &lt;/strong&gt;to include in your HTML.&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;&lt;br/&gt;Case Study: {LinkURL}&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;{LinkURL}&lt;/strong&gt; is the &amp;#8220;Click-through Link&amp;#8221; rendered in Photo Posts. I also discussed this very     same variable &lt;a href="http://blog.post-theory.com/post/18173369734/tumblr-theme-limitations-when-a-block-doesnt-exist"&gt;last time&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Let us suppose that somebody enters a rather naughty &amp;#8220;Click-through&amp;#8221; URL:&lt;/p&gt;
&lt;blockquote&gt;http: //naughty.urls/break&amp;#8221; onclick=&amp;#8221;javascript: alert(&amp;#8216;Tumblr is lame!&amp;#8217;); return false;&lt;/blockquote&gt;
&lt;p&gt;Now, you being the good Theme Developer you are, write your Theme Code like this:&lt;/p&gt;
&lt;pre&gt;&amp;lt;a href="{LinkURL}"&amp;gt;&amp;lt;img .... &amp;gt;&amp;lt;/a&amp;gt;&lt;/pre&gt;
&lt;p&gt;Looks fine, right? &lt;strong&gt;Wrong&lt;/strong&gt;. This is what &lt;em&gt;actually&lt;/em&gt; gets rendered on the page:&lt;/p&gt;
&lt;blockquote&gt;&amp;lt;a href=&amp;#8221;http://naughty.urls/break&amp;#8221; onclick=&amp;#8221;javascript: alert(&amp;#8216;Tumblr is lame&amp;#8217;)&amp;#8221;&amp;gt;&amp;lt;img &amp;#8230;. &amp;gt;&amp;lt;/a&amp;gt;&lt;/blockquote&gt;
&lt;p&gt;Well - you can guess what happens when someone clicks that Image!&lt;/p&gt;
&lt;p&gt;Go &lt;a href="http://broken-theme-1.tumblr.com/"&gt;see for yourself on this page&lt;/a&gt;. Really, go try it. There are two examples. One contains a &amp;#8220;naughty&amp;#8221; URL, and the other a &amp;#8220;nice&amp;#8221; URL which just happens to include a &lt;strong&gt;&amp;#8220;&lt;/strong&gt; character in it.&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;&lt;br/&gt;The (hacky) JavaScript Solution&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Since I&amp;#8217;ve already established that the {JS&amp;#8230;} Variable Transformation seems to function properly,     I&amp;#8217;m going to solve this problem with some hacky JavaScript. Once again.&lt;/p&gt;
&lt;p&gt;For the sake of brevity, let&amp;#8217;s just assume that {LinkURL} exists &amp;#8212; I &lt;a href="http://blog.post-theory.com/post/18173369734/tumblr-theme-limitations-when-a-block-doesnt-exist"&gt;already showed you&lt;/a&gt; how to handle those cases when it does not.&lt;/p&gt;
&lt;p&gt;And here&amp;#8217;s the basic code:&lt;/p&gt;
&lt;pre&gt;{block:Photo}&lt;br/&gt;    &amp;lt;script&amp;gt;&lt;br/&gt;        document.write('&amp;lt;a href="' + encodeURI( {JSLinkURL} ) + '"&amp;gt;');&lt;br/&gt;    &amp;lt;/script&amp;gt;&lt;br/&gt;    &amp;lt;img src="{PhotoURL-500}"&amp;gt;&lt;br/&gt;    &amp;lt;/a&amp;gt;&lt;br/&gt;    ...&lt;br/&gt;{/block:Photo}&lt;br/&gt;&lt;/pre&gt;
&lt;p&gt;Wrapping {JSLinkURL} with the &lt;strong&gt;encodeURI&lt;/strong&gt; JavaScript function makes sure that the link is &lt;em&gt;actually safe&lt;/em&gt; to include inside the href=&amp;#8221;&amp;#8230;&amp;#8221;.&lt;/p&gt;
&lt;p&gt;You can see now, on &lt;a href="http://broken-theme-2.tumblr.com/"&gt;this new page&lt;/a&gt;, the results.  The &amp;#8220;naughty&amp;#8221; URL no longer does anything bad, and the &amp;#8220;nice&amp;#8221; URL works properly.&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;&lt;br/&gt;If {LinkURL} is broken, then what else is Broken?&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Honestly, I don&amp;#8217;t know yet. I haven&amp;#8217;t tried to test every single type of {URL} Variable on Tumblr&amp;#8217;s Theme Templater.&lt;/p&gt;
&lt;p&gt;Here are things I &lt;strike&gt;know&lt;/strike&gt; &lt;em&gt;think&lt;/em&gt; are OK:&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;
&lt;p&gt;In {block:ContentSource} Blocks, the {SourceURL} seems to be OK.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;URLs to pages in your own blog [eg, {Permalink} ] all seem to be OK.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;Things I have observed to be &lt;strong&gt;broken&lt;/strong&gt; in the same way as {LinkURL}:&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;
&lt;p&gt;Links to a User&amp;#8217;s own &amp;#8220;Pages&amp;#8221;:&lt;/p&gt;
&lt;p&gt;Inside the {block:HasPages} and then {block:Pages}, the &lt;strong&gt;{URL}&lt;/strong&gt; variable is     &lt;strong&gt;not&lt;/strong&gt; properly escaped / URL encoded&lt;/p&gt;
&lt;p&gt;What could happen is a user sets up one of their pages with a URL like:&lt;/p&gt;
&lt;blockquote&gt;htp://my-blog.tumblr.com/&amp;#8221;About Me&amp;#8221;&lt;/blockquote&gt;
&lt;p&gt;That will break, if you try to include the {URL} directly in your HTML.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;As I find more bugs, I will update this post to let you know!&lt;/p&gt;</description><link>http://blog.post-theory.com/post/18220496565</link><guid>http://blog.post-theory.com/post/18220496565</guid><pubDate>Fri, 24 Feb 2012 19:19:00 -0600</pubDate><category>exploits</category><category>hacks</category><category>tumblr bugs</category><category>tumblr development</category><category>tumblr exploits</category><category>tumblr is lame</category><category>tumblr themes</category><category>post theory</category></item><item><title>Tumblr Theme Limitations: When a "Block" Doesn't Exist, Part 2</title><description>&lt;p&gt;In &lt;a href="http://blog.post-theory.com/post/18155685811/tumblr-theme-limitations-when-a-block-doesnt-exist"&gt;Part 1&lt;/a&gt;, I discussed an approach to handling Tumblr Theme Variables that do &lt;strong&gt;not&lt;/strong&gt; have corresponding {block:Foobar} Variables to wrap code to only render when the variable {Foobar} exists.&lt;/p&gt;
&lt;p&gt;I used the &lt;strong&gt;{PlayCount}&lt;/strong&gt; variable (rendered in Audio and Video blocks) as my example. In the end, I came up with the following solution:&lt;/p&gt;
&lt;pre&gt;&amp;lt;script&amp;gt;
    if ( "{PlayCount}" ) {
        document.write("&amp;lt;span&amp;gt;played {PlayCount} times!&amp;lt;/span&amp;gt;");
    }
&amp;lt;/script&amp;gt;&lt;/pre&gt;
&lt;p&gt;&amp;#8230; which works fine (in this case), even though it is an ugly solution.&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;&lt;strong&gt;But Sometimes Things are More Complicated&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Now I would like to talk about the &lt;strong&gt;{LinkURL}&lt;/strong&gt; variable, which is rendered inside of Photo posts. This is the so-called &amp;#8220;Click-through URL&amp;#8221; for a Photo.&lt;/p&gt;
&lt;p&gt;Now, Tumblr has the absolute &lt;strong&gt;&lt;em&gt;strangest&lt;/em&gt;&lt;/strong&gt; feature for this variable:  a corresponding &lt;strong&gt;{LinkOpenTag}&lt;/strong&gt; and &lt;strong&gt;{LinkCloseTag}&lt;/strong&gt;, which renders an HTML anchor tag  (&lt;em&gt;&amp;lt;a href=&amp;#8221;&amp;#8230;&amp;#8230; &amp;#8220;&amp;gt;&lt;/em&gt;) for the {LinkURL} &lt;em&gt;only if it exists&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Well, that might be fine for some people. But what if I want to modify that &amp;lt;a&amp;gt; tag? Add a class name to it? A title attribute? Etc.&lt;/p&gt;
&lt;p&gt;Basically - I find {LinkOpenTag} and {LinkCloseTag} &lt;strong&gt;completely bizarre &lt;/strong&gt;and &lt;em&gt;completely out of place&lt;/em&gt; with the rest of the Tumblr Theme Template system.&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;And again - we have the same problem: There is no {block:LinkURL} variable to tell you when {LinkURL} exists.&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;&lt;strong&gt;Trying to Solve the Same Problem the Same Way&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;So, of course I tried to use the same approach as before:&lt;/p&gt;
&lt;pre&gt;&amp;lt;script&amp;gt;&lt;br/&gt;   if ( "{LinkURL}" ) {&lt;br/&gt;      document.write('&amp;lt;a class="foo" href="{LinkURL}"&amp;gt; .. &amp;lt;/a&amp;gt;');&lt;br/&gt;   }&lt;br/&gt;&amp;lt;/script&amp;gt;&lt;/pre&gt;
&lt;p&gt;And yes, this probably works 99% of the time.&lt;/p&gt;
&lt;p&gt;But I don&amp;#8217;t &lt;em&gt;really &lt;/em&gt;trust a URL can be inserted directly into a Javascript chunk in this way. A URL &lt;strong&gt;could&lt;/strong&gt; possibly &lt;strong&gt;break&lt;/strong&gt; the Javascript &lt;strong&gt;String&lt;/strong&gt; in this example, if it has not been &lt;strong&gt;escaped&lt;/strong&gt; properly.&lt;/p&gt;
&lt;p&gt;Does Tumblr escape the {LinkURL} properly? I don&amp;#8217;t know &amp;#8212; but seeing how many other things they manage to mess up, I&amp;#8217;m just going to &lt;em&gt;guess and say No&lt;/em&gt;, just to be on the safe side. Maybe it&amp;#8217;s escaped fine for HTML, but not JavaScript. Who knows.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;br/&gt;So&amp;#8230;Tumblr&amp;#8217;s &lt;a href="http://www.tumblr.com/docs/en/custom_themes#variable-transformations"&gt;Variable Transformations&lt;/a&gt; to the Rescue!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Wait - again you ask? I thought you dismissed that in &lt;a href="http://blog.post-theory.com/post/18155685811/tumblr-theme-limitations-when-a-block-doesnt-exist"&gt;Part 1&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I did dismiss it.&lt;/p&gt;
&lt;p&gt;I showed how &lt;strong&gt;{JSPlayCount}&lt;/strong&gt; does &lt;em&gt;&lt;strong&gt;not&lt;/strong&gt;&lt;/em&gt; do what the Tumblr Documentation says it &lt;em&gt;should&lt;/em&gt; - namely return a Javascript-safe string representation of {PlayCount} &lt;strong&gt;wrapped in quotes.&lt;/strong&gt; [verbatim from the documention]&lt;/p&gt;
&lt;p&gt;Instead it renders &lt;em&gt;nothing, &lt;/em&gt;and not wrapped in quotes. Fine.&lt;em&gt;&lt;br/&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;br/&gt;But it Gets Weirder.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;But I really want to make sure my {LinkURL} is safe to include in my script.&lt;/p&gt;
&lt;p&gt;So I tried playing around with &lt;strong&gt;{JSLinkURL}&lt;/strong&gt;. Now, I figured it would behave like {PlayCount} &amp;#8212; namely that if it didn&amp;#8217;t exist, then {JSLinkURL} should render &lt;em&gt;nothing&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;So I had a stroke of genius:&lt;/p&gt;
&lt;pre&gt;&amp;lt;script&amp;gt;
    if ( &lt;strong&gt;[&lt;/strong&gt; {JSLinkURL} &lt;strong&gt;]&lt;/strong&gt;.length) {
        document.write('.....');
    }
&amp;lt;/script&amp;gt;&lt;/pre&gt;
&lt;p&gt;Notice the &lt;strong&gt;brackets&lt;/strong&gt; create a list. Now, an empty list &lt;strong&gt;[]&lt;/strong&gt; &lt;em&gt;is a valid JavaScript&lt;/em&gt; expression, so if {JSLinkURL} does not render anything at all, this yields:&lt;/p&gt;
&lt;pre&gt;if ( [ ].length ) { .... }&lt;/pre&gt;
&lt;p&gt;Which is valid Javascript, and will return False, if {LinkURL} does not exist.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;br/&gt;Problem Solved &amp;#8212; Right?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Oh, wrong, wrong again.&lt;/p&gt;
&lt;p&gt;I thought it was working.&lt;/p&gt;
&lt;p&gt;And then I came upon some &lt;strong&gt;curious&lt;/strong&gt; posts, which for some reason or other, have &lt;strong&gt;&lt;em&gt;no &lt;/em&gt;&lt;/strong&gt;&lt;em&gt;{LinkURL}&lt;/em&gt;&lt;strong&gt;but&lt;/strong&gt; where &lt;em&gt;{JSLinkURL}&lt;/em&gt; actually &lt;strong&gt;does &lt;/strong&gt;render an &lt;strong&gt;empty JavaScript string &amp;#8220;&amp;#8221; &lt;/strong&gt;!&lt;/p&gt;
&lt;p&gt;But then again, it is Tumblr. &lt;em&gt;Sometimes it works, sometimes it doesn&amp;#8217;t.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;In these weird cases, where there really is no LinkURL, but {JSLinkURL} renders an empty string, you end up with this:&lt;/p&gt;
&lt;pre&gt;if ( [ '' ].length ) { ... }&lt;/pre&gt;
&lt;p&gt;Which unfortunately, returns True in Javascript.   &lt;em&gt;@#$!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;So, revising the code a little:&lt;/p&gt;
&lt;pre&gt;if ( [ {JSLinkUrl} ].length &amp;amp;&amp;amp; [ {JSLinkUrl} ][0] ) {
    ....
}&lt;/pre&gt;
&lt;p&gt;This works in both cases. If {JSLinkUrl} renders nothing, it yields:&lt;/p&gt;
&lt;pre&gt;if ( [].length &amp;amp;&amp;amp; [][0] )  { ... }&lt;/pre&gt;
&lt;p&gt;Which is &lt;strong&gt;fine&lt;/strong&gt; because JavaScript has short-circuit evaluation with the &amp;amp;&amp;amp; operator.&lt;/p&gt;
&lt;p&gt;If {JSLinkURL} renders an empty string, it yields:&lt;/p&gt;
&lt;pre&gt;if ( [ '' ].length &amp;amp;&amp;amp; [ '' ][0] )   { ... }&lt;/pre&gt;
&lt;p&gt;Which is &lt;strong&gt;also fine&lt;/strong&gt;, because although [ &amp;#8221; ].length is &lt;em&gt;True&lt;/em&gt;,  [ &amp;#8221; ][0] is &lt;em&gt;&lt;strong&gt;False&lt;/strong&gt;&lt;/em&gt; in Javascript, since &amp;#8221; evaluates to False.&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;&lt;em&gt;&lt;strong&gt;Putting it all Together:&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;pre&gt;&amp;lt;script&amp;gt;&lt;br/&gt;    if ( [ {JSLinkUrl} ].length &amp;amp;&amp;amp; [ {JSLinkUrl} ][0] ) {&lt;br/&gt;        document.write('&amp;lt;a class="foo" title="bar" href="' + &lt;br/&gt;                        encodeURI( {JSLinkUrl} ) + '"&amp;gt; ... &amp;lt;/a&amp;gt;');&lt;br/&gt;    }&lt;br/&gt;&amp;lt;/script&amp;gt;&lt;/pre&gt;
&lt;p&gt;&lt;br/&gt;&lt;strong&gt;&lt;em&gt;Edit 2/24/2012:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Using what I uncovered in &lt;strong&gt;&lt;a href="http://blog.post-theory.com/post/18220496565/tumblr-themes-dont-trust-a-url-is-html-safe"&gt;Part 3&lt;/a&gt;&lt;/strong&gt;, I now recommend wrapping {JSLinkURL} with &lt;strong&gt;encodeURI &lt;/strong&gt;because this variable is &lt;strong&gt;not&lt;/strong&gt; properly escaped / URL encoded!&lt;strong&gt;&lt;br/&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;br/&gt;This is a &lt;em&gt;fairly robust&lt;/em&gt; way to &lt;strong&gt;emulate &lt;/strong&gt;a {block:LinkURL}, while ensuring that:&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;The JavaScript raises no errors&lt;/li&gt;
&lt;li&gt;The LinkURL you insert is &lt;strong&gt;safe&lt;/strong&gt; to insert directly into the JavaScript code.&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;It&amp;#8217;s ugly. It&amp;#8217;s a hack. But it works.&lt;/p&gt;</description><link>http://blog.post-theory.com/post/18173369734</link><guid>http://blog.post-theory.com/post/18173369734</guid><pubDate>Thu, 23 Feb 2012 22:41:00 -0600</pubDate><category>coding</category><category>hacks</category><category>javascript</category><category>theme development</category><category>tumblr bugs</category><category>tumblr development</category><category>tumblr is lame</category><category>tumblr themes</category><category>post theory</category></item><item><title>Tumblr Theme Limitations: When a "Block" Doesn't Exist, Part 1</title><description>&lt;p&gt;Sometimes it seems like Tumblr &lt;em&gt;actually&lt;/em&gt; had developers in mind when they created their Theme Template system.&lt;/p&gt;
&lt;p&gt;Other times  &amp;#8212;  well, a lot of things are simply a f**ing cludge.&lt;/p&gt;
&lt;p&gt;Let me give you an example I recently encountered, and how I solved it (in an awful, hacky way.)&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;For some theme Variables, Tumblr was nice enough to include a &lt;strong&gt;{block:Foobar}&lt;/strong&gt; variable to let you know whether or not some piece of data &lt;strong&gt;{Foobar}&lt;/strong&gt; exists or not.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;eg, &lt;/strong&gt;The Post Title: &lt;strong&gt;{Title}&lt;/strong&gt; and the corresponding &lt;strong&gt;{block:Title}&lt;/strong&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Anything wrapped with {block:Title} &amp;#8230; {/block:Title} is only rendered IF {Title} exists.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That&amp;#8217;s super nice. I like that.&lt;/p&gt;
&lt;p&gt;And it sure would be nice if &lt;em&gt;&lt;strong&gt;a bunch of over Variables&lt;/strong&gt;&lt;/em&gt; also had those &amp;#8220;if this exists&amp;#8221; wrapper blocks.&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;Here&amp;#8217;s the specific case I&amp;#8217;m talking about. I was working on the HTML to render &lt;strong&gt;Video&lt;/strong&gt; posts. One of the neato variables in the Video block is &lt;strong&gt;{PlayCount}&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;OK, cool. I would like my theme to show how many plays a video got.&lt;/p&gt;
&lt;p&gt;So, I very naively wrote something like this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;lt;span&amp;gt;played {PlayCount} times!&amp;lt;/span&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And no matter how many times I played that damn video, {PlayCount} never rendered anything.&lt;/p&gt;
&lt;p&gt;Well, it turns out that {PlayCount} only exists if a video was uploaded to Tumblr, not if you embed a video from say YouTube.&lt;/p&gt;
&lt;p&gt;OK, fair enough Tumblr - I understand you can&amp;#8217;t count the number of plays of an embedded video.&lt;/p&gt;
&lt;p&gt;But then, you should at least let us &lt;strong&gt;know&lt;/strong&gt; that you &lt;strong&gt;can&amp;#8217;t&lt;/strong&gt; tell us the {PlayCount}, with a nice {block:HasPlayCount} or something. Otherwise my theme / blog looks stupid.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;&lt;br/&gt;Steps Toward a (hacky) Solution:&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;
&lt;p&gt;Let&amp;#8217;s try some Javascript.&lt;/p&gt;
&lt;p&gt;Also, I happen to know that Tumblr is &lt;strong&gt;&lt;em&gt;so cool&lt;/em&gt;&lt;/strong&gt;, that it has &lt;a href="http://www.tumblr.com/docs/en/custom_themes#variable-transformations"&gt;variable transformations&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So I know that I can &amp;#8220;&lt;em&gt;Prefix any theme variable with JS to output a Javascript string (wrapped in quotes)&lt;/em&gt;&amp;#8220;  [straight from the docs]&lt;/p&gt;
&lt;p&gt;Oh, cool. So, if {PlayCount} doesn&amp;#8217;t exist, then {JSPlayCount} &lt;strong&gt;should&lt;/strong&gt; yield an empty Javascript string: &lt;strong&gt;&amp;#8221;&amp;#8221;   Right?&lt;br/&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;lt;script&amp;gt;&lt;br/&gt;     if ({JSPlayCount}) {&lt;br/&gt;          document.write(&amp;#8220;&amp;lt;span&amp;gt;played {PlayCount} times!&amp;lt;/span&amp;gt;&amp;#8221;);&lt;br/&gt;     }&lt;br/&gt;&amp;lt;/script&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;There we go! Perfect!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Wrong.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;It turns out that if a Variable like {PlayCount} doesn&amp;#8217;t exist, then {JSPlayCount} doesn&amp;#8217;t exist either - at all. And no,         it does not get wrapped in quotes. You do not get an empty string. You get nothing.&lt;/p&gt;
&lt;p&gt;So you get a Javascript error with the statement:&lt;/p&gt;
&lt;blockquote&gt;if ()&lt;/blockquote&gt;
&lt;p&gt;&amp;#8230;because you need something inside that if() statement.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;OK, fine. I know {PlayCount} should be a number, so it&amp;#8217;s probably safe NOT to use the JS Variable Transform:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;lt;script&amp;gt;&lt;br/&gt;     if (&amp;#8220;{PlayCount}&amp;#8221;) {&lt;br/&gt;          document.write(&amp;#8220;&amp;lt;span&amp;gt;played {PlayCount} times!&amp;lt;/span&amp;gt;&amp;#8221;);&lt;br/&gt;     }&lt;br/&gt;&amp;lt;/script&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And that works just fine. It&amp;#8217;s ugly, but it works, and does not generate Javascript errors.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;&lt;em&gt;&lt;strong&gt;&lt;br/&gt;But wait, There&amp;#8217;s More!&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;    &amp;#8230; continued in &lt;a href="http://blog.post-theory.com/post/18173369734/tumblr-theme-limitations-when-a-block-doesnt-exist"&gt;Part 2&lt;/a&gt;!&lt;/p&gt;</description><link>http://blog.post-theory.com/post/18155685811</link><guid>http://blog.post-theory.com/post/18155685811</guid><pubDate>Thu, 23 Feb 2012 17:57:00 -0600</pubDate><category>coding</category><category>hacks</category><category>javascript</category><category>theme development</category><category>tumblr bugs</category><category>tumblr development</category><category>tumblr is lame</category><category>tumblr themes</category><category>post theory</category></item><item><title>Undocumented Features are (not)Cool</title><description>&lt;p&gt;So, in writing my theme, I wanted a way to put a &amp;#8220;Reblog&amp;#8221; and &amp;#8220;Like&amp;#8221; link on each post on the &lt;em&gt;main page&lt;/em&gt; of the blog without users having to &amp;#8220;click-through&amp;#8221; to the &amp;#8220;/post&amp;#8221; page, and use Tumblr&amp;#8217;s silly &lt;em&gt;&amp;lt;iframe&amp;gt;&lt;/em&gt; in the upper right corner.&lt;/p&gt;
&lt;p&gt;Well. I investigated the contents of that &lt;em&gt;&amp;lt;iframe&amp;gt;&lt;/em&gt; on the Post page, and found it was pretty simple,      as long as you had a little value called &amp;#8220;&lt;em&gt;rk=xxxxxxxx&lt;/em&gt;&amp;#8221; (or the &amp;#8220;reblog key&amp;#8221;)&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;lt;iframe src=&amp;#8221;http://assets.tumblr.com/iframe.html?10&amp;amp;src=http%3A%2F%2Fblog.post-theory.com%2Fpost%2F18132446503l&amp;amp;amp;pid=18132446503&amp;amp;amp;&lt;em&gt;&lt;strong&gt;rk=xA660hqO&lt;/strong&gt;&lt;/em&gt;&amp;amp;amp;lang=en_US &amp;#8230;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Naturally, this value is not included in the {Posts} blocks by Tumblr&amp;#8217;s theme template engine.&lt;/p&gt;
&lt;p&gt;Easy, I thought: I&amp;#8217;ll just secretly load the &amp;#8220;Post&amp;#8221; page for each post in the background with an AJAX call,      and steal the &amp;#8220;&lt;em&gt;rk=xxxxxxx&lt;/em&gt;&amp;#8221; value from the &lt;em&gt;src attribute&lt;/em&gt; of the &lt;em&gt;&amp;lt;iframe&amp;gt;&lt;/em&gt;&amp;#160;!&lt;/p&gt;
&lt;p&gt;Well, that was working just fine! Super-duper!&lt;/p&gt;
&lt;p&gt;And then I &lt;a href="http://groups.google.com/group/tumblr-themes/browse_thread/thread/cabcfb2539b829a1"&gt;read&lt;/a&gt; that there is an &lt;em&gt;&lt;strong&gt;undocumented&lt;/strong&gt;&lt;/em&gt; Theme operator: &lt;em&gt;&lt;strong&gt;{ReblogURL}&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Seriously?&lt;/strong&gt;&lt;/em&gt; Undocumented features!  Super &lt;em&gt;&lt;strike&gt;cool&lt;/strike&gt;&lt;/em&gt;!       &lt;strong&gt;Lame&lt;/strong&gt;.  C&amp;#8217;mon Tumblr. Really? Features should be documented. How long would it take you to      just fix your &lt;a href="http://www.tumblr.com/docs/en/custom_themes"&gt;documentation&lt;/a&gt;?&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;&lt;strong&gt;{ReblogURL}&lt;/strong&gt; looks something like this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href="http://www.tumblr.com/reblog/18132446503/xA660hqO"&gt;http://www.tumblr.com/reblog/18132446503/xA660hqO&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Where the big integer is the PostID, and those 8 alpha-num characters at the end are the same as that elusive      &amp;#8220;&lt;em&gt;rk=xxxxxxxx&lt;/em&gt;&amp;#8221; &lt;em&gt;&lt;strong&gt;reblog key&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;Oh well, so much for all my cool background AJAX calls :P&lt;/p&gt;</description><link>http://blog.post-theory.com/post/18132446503</link><guid>http://blog.post-theory.com/post/18132446503</guid><pubDate>Thu, 23 Feb 2012 10:06:00 -0600</pubDate><category>theme development</category><category>tumblr development</category><category>tumblr is lame</category><category>post theory</category><category>ReblogURL</category><category>tumblr themes</category></item><item><title>Tumblr Tag Cloud Javascript</title><description>&lt;p&gt;Hello!&lt;/p&gt;
&lt;p&gt;I have decided to go ahead a release my &lt;a href="http://post-theory.com/tumblr-tag-cloud-javascript" title="Tumblr Tag Cloud Script"&gt;Tumblr Tag Cloud Javascript&lt;/a&gt; widget.&lt;/p&gt;
&lt;p&gt;This is just a version 1.0, so you can expect a few bugs and whatnot.&lt;/p&gt;
&lt;p&gt;Feel free to use it on your own Tumblr!&lt;/p&gt;
&lt;p&gt;Thanks,&lt;br/&gt;~ Felix&lt;/p&gt;</description><link>http://blog.post-theory.com/post/18034990547</link><guid>http://blog.post-theory.com/post/18034990547</guid><pubDate>Tue, 21 Feb 2012 17:23:00 -0600</pubDate><category>javascript</category><category>post theory</category><category>tag list</category><category>tags</category><category>tumblr tags</category><category>tumblr themes</category><category>tumblr widgets</category><category>widgets</category><category>tag cloud</category></item><item><title>Coming Soon</title><description>&lt;p&gt;I apologize there&amp;#8217;s actually nothing on this page&amp;#8230; yet.&lt;/p&gt;
&lt;p&gt;But, I have several things which are coming soon (hopefully this week of Feb 20).&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Bumblebee Theme&lt;/em&gt;&lt;/strong&gt;.  Used on this page &amp;amp; my blog.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;&lt;a href="http://post-theory.com/tumblr-tag-cloud-javascript" title="Tumblr Tag Cloud Script"&gt; Tag Cloud JavaScript Widget&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt;     &lt;em&gt;Released 2/21/2012&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I developed my own &amp;#8220;Tag Cloud&amp;#8221; widget, that anyone can insert into their own Tumblr blog.&lt;/p&gt;
&lt;p&gt;I have looked at other Tag Cloud scripts, and realized that for the most part their main failing is the use of too much client-side AJAX for fetching your Posts.&lt;/p&gt;
&lt;p&gt;My Tag Cloud widget is enhanced with server-side &lt;strong&gt;caching&lt;/strong&gt; of your posts, which makes loading tags on a page fast and clean.&lt;/p&gt;
&lt;p&gt;Less load on Tumblr, less load on the client&amp;#8217;s computer.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Blog Backup&lt;/em&gt;&lt;/strong&gt; / &amp;#8220;&lt;em&gt;Download your entire Blog&amp;#8221;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Sort of inspired by Facebook&amp;#8217;s feature that lets you &amp;#8220;Download all your Facebook content&amp;#8221;&lt;/p&gt;
&lt;p&gt;The idea is to provide a way to download all the content you&amp;#8217;ve posted on your blog: text, pictures, etc. The download will include a very simple &amp;#8220;offline&amp;#8221; browser for your posts.&lt;/p&gt;
&lt;p&gt;It will also include a backup list of all the people you follow (say you create a new blog, and you want an easy way to follow some or all of the same people).&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;Hopefully I will be able to finish all this stuff this coming week, and get it up and working for people! After that, I have some more tools planned &amp;amp; already in the works. So stay tuned.&lt;/p&gt;
&lt;p&gt;Felix&lt;/p&gt;</description><link>http://blog.post-theory.com/post/17893760514</link><guid>http://blog.post-theory.com/post/17893760514</guid><pubDate>Sun, 19 Feb 2012 12:33:00 -0600</pubDate><category>updates</category><category>post theory</category></item></channel></rss>
