Backup Blogsome Posts

I didn’t realize this until the other day, but it’s possible to back up every post you’ve ever made using an offline client, such as the excellent ecto. I use the Mac version of this great program, and to back up every post I’ve ever made is as simple as:

  • Find out how many posts you have made.
  • Tell ecto to download this many recent posts.
  • Press the Refresh button.

The first one is easy: when you first log into your Blogsome blog, you’ll see on the dashboard a panel like:

Blog Stats There are currently 393 posts and 284 comments, contained within 19 categories.

Getting this info to your offline composer might be difficult - each one has different settings. In ecto, choose the Account in the main window (Entries & Drafts), and then go to the ecto→Preferences… menu (keyboard shortcut: Cmd-, ). In the window that appears, choose the Recent Entries tab.

I use the following settings: Store copies of published entries locally, uncheck Retrieve titles and summaries only, and insert the desired number of entries to retrieve. Then, click Save, and press Refresh in the main view. It might take some time if you have a lot of entries, but it’s nice to know you have a backup.

Oh, and if you do regular backups, you can set the value to a reasonable value, like 10 or 20, and make sure you do it every now and then before you’ve posted that many new posts. If you make any edits to old posts, they’ll only get picked up in a large backup like this one, though.

•

If you are using another client, the instructions will be similar, but you may have to search around for a while before you find where to change the number of entries to retrieve. Good luck: happy backup.

Spooky iTunes Coincidences

I just listen to random music most of the time. But every now and then a weird series of tracks come up. The normal thing is that tracks that we currently have in the car CD player play. But this one tops everything. The Eagles, New Kid In Town comes on, and I switch over to iTunes Rater to rate it, as I like that song. Then I notice this: The title of the previous song was “Johnny Come Lately”, words that are part of the chorus of “New Kid In Town”. Almost as spooky as the bit in Metal Gear Solid 2 where stuff starts going bunkum, and the voice says:

You’ve been playing this video game for too long. Turn the console off now.

This occurred at around 4am, so I was totally freaked. It was right, I had been playing the game for too long. Although this was actually part of the plot (trying to make Raiden(?) believe he is not real), I was convinced.

The Night Is A Blackbird • [Augie March][2] • [Strange Bird][3]

[2]: http://www.google.com/search?q=%22Augie March%22 [3]: http://www.google.com/search?q=%22Strange Bird%22

Functions Rewrite

I’ve got a bit of JavaScript in my site: Quicktags, Comment Preview, Catchpa and Gravatars, just to name a few of the recent additions. I’ve also got some pretty hairy Smarty Code thrown in there too. Some of it would be better off to be replaced by JavaScript. The two main examples of this are the Time Since code (eg: 22 hours, 34 minutes after the fact), and the _Human Time _code (Posted late at night). I’ve actually rewritten pretty much all of this code, and packaged it all up into one JavaScript, so I can just let other people include one line of code, with some others setting up what features they want, rather than having to wade through the code and find where to add bits. At the moment, most of it is quite functional, but would still require the use of a whole bunch of inline scripting. I’m working to replace this with functions that automatically run after the page has loaded (or, perhaps even better, when the main page has loaded, but before it displays?). So, for instance, you would just have the following code in your main page, inside the <head> section: <script type="text/javascript" src="http://schinckel.net/images/blogsome.jpg"><script> And, then in the templates, include a block of text that looks like: <div class="options" style="display:none;"> gravatar preview quicktags </div> You can have different features on different templates: the one above would make sense on a comments page, but not on others, for example. There will be robust error checking as to validity of particular features and their applicability on a particular page, but only including features you actually plan to use will make the page load faster. This ultimately should make the page load faster than with all of the inline code, and calls to several external javascripts. I think browsers will cache the blogsome.jpg file (it’s really a .js file, but don’t tell anyone), so the initial load time will be reduced on successive page loads. It will also mean I can add or improve features, and fix bugs. The tricky part is turning out to be catering for different layouts: the gravatar part was easy: the only code a user needs to put into their blog is the simple {capture name=reader}{comment_author_email}{/capture} <div class="gravatar">{$smarty.capture.reader|encode:"hex"}</div> Where they want the gravatar to appear, and it will work. Setting up for the Catchpa, which is pretty simple, turned out to be a little sticky. It all depends on how people’s templates are set up: what the structure of their form looks like. It might be easier to have them insert some HTML code, and then look for that. It makes it a little more work for the user, but more reliable.

Enlarge Text Area.

Last update for tonight: <a class='button' onclick='javascript:document.getElementById("the_id").rows+=10;'> Make Text Box Bigger </a> And similar for Make Text Boxes Smaller. It’s working on my comment box as we speak. Try it out. (Thanks to Dunstan).

Posted... (human time display)

Following on from the previous post, I’ve also shamelessly poached another idea from Dunstan: human-readable timestamps. Just pop this into your post.html file, where you want the ’time’ to appear.

    {capture name=hour}{the_time d="G"}{/capture}
    {assign var=hour value=$smarty.capture.hour}
    Posted
    {if $hour eq "00" or $hour eq "01" or $hour eq "02"}
        in the wee hours,
    {elseif $hour eq "03" or $hour eq "04" or $hour eq "05" or $hour eq "06"}
        terribly early in the morning,
    {elseif $hour eq "07" or $hour eq "08" or $hour eq "09"}
        early in the morning,
    {elseif $hour eq "10"}
        mid-morning,
    {elseif $hour eq "11"}
        late morning,
    {elseif $hour eq "12" or $hour eq "13"}
        mid-morning,
    {elseif $hour eq "14"}
        early afternoon,
    {elseif $hour eq "15" or $hour eq "16"}
        mid-afternoon,
    {elseif $hour eq "17"}
        late afternoon,
    {elseif $hour eq "18" or $hour eq "19"}
        early evening,
    {elseif $hour eq "20" or $hour eq "21"}
        evening,
    {elseif $hour eq "22"}
        late evening,
    {elseif $hour eq "23"}
        late at night,
    {/if}

Time Since (...after the fact).

I had noticed lots of blogs had a nice little Posted x hours, y minutes after the fact tag attached to Comments. I thought this was pretty cool, and had a very short attempt at this some time ago. Then, over on Binary Bonsai, Michael mentioned how the plugin was broken, and how it needs fixing. Well, I didn’t fix the PHP version, but I did write a pure Smarty version!

    {* 
    
    "Time Since" Smarty Code 
    
    Author: Matt Schinckel <matt@schinckel.net>
        http://schinckel.net
    
    Based on a WordPress Plugin "Time Since" 
        http://binarybonsai.com/wordpress/timesince
    
    Notes: Insert this whole text where you want the
    text to appear.  If keen, you could move the first
    pair of lines to a place outside of the comment loop,
    but still inside the post.  This might save some
    precious server seconds.
    
    The accuracy of the 'time since' decreases over time:
    there aren't 30.4 days in every month, for instance.
    
    *}
    
    {capture name=post_time}{the_time d="U"}{/capture}
    {assign var=post_time value=$smarty.capture.post_time}
    
    {capture name=comment_time}{comment_date d='U'}{/capture}
    {assign var=comment_time value=$smarty.capture.comment_time}
    
    
    {assign var=since value=$comment_time-$post_time}
    
    
    {if $since < 3600}
        {assign var=name1 value="minute"}{assign var=sec1 value=60}
        {assign var=name2 value="second"}{assign var=sec2 value=1}
    {elseif $since < 86400}
        {assign var=name1 value="hour"}{assign var=sec1 value=3600}
        {assign var=name2 value="minute"}{assign var=sec2 value=60}
    {elseif $since < 604800}
        {assign var=name1 value="day"}{assign var=sec1 value=86400}
        {assign var=name2 value="hour"}{assign var=sec2 value=3600}
    {elseif $since < 2626560}
        {assign var=name1 value="week"}{assign var=sec1 value=604800}
        {assign var=name2 value="day"}{assign var=sec2 value=86400}
    {elseif $since < 31536000}
        {assign var=name1 value="month"}{assign var=sec1 value=2626560}
        {assign var=name2 value="week"}{assign var=sec2 value=604800}
    {else}
        {assign var=name1 value="year"}{assign var=sec1 value=31536000}
        {assign var=name2 value="month"}{assign var=sec2 value=2626560}
    {/if}
    {math equation='floor(a/b)' a=$since b=$sec1 assign=count1}
    {math equation='floor((a-floor(a/b)*b)/c) a=$since b=$sec1 c=$sec2 assign=count2}
    Posted {$count1} {$name1}{if $count1 != 1}s{/if},
           {$count2} {$name2}{if $count2 != 1}s{/if} after the fact.

Another Gravatar Implementation

I recalled at some stage there was a Smarty Modifier called escape. I think it was when I was looking for one called rot13. Anyways, you can use this and the JavaScript function unescape() to obfuscate the email address. You’ll need this code early in your template: I stick it at the start just after <html>

1
2
3
    <script type="text/javascript" 
        src="http://schinckel.net/images/md5.jpg">
    </script>

This fragment will insert the Gravatar Image:

    {capture name=reader}{comment_author_email}{/capture}
    <script type="text/javascript">
    document.write('<div class="right">');
    document.write('<img src="http://www.gravatar.com/avatar.php?gravatar_id='); 
    document.write(hex_md5(unescape("{$smarty.capture.reader|escape:"hex"}"))); 
    document.write('&size=40" alt="" />');
    document.write('</div>');
    </script>

This seems to more reliably display the Gravatars, so I’d suggest you use it instead. Either that, or Gravatar just fixed up their servers…

Show/Hide JavaScript Code

There’s a little one-liner I’ve just learned for showing or hiding the contents of a particular <div> tag. (May also work for other types of tag). The stuff you want to show or hide needs to have an id attribute. I use it to hide some stuff if there are no Comments or Trackbacks, since I’ve seperated them, and this was the best way to hide the title.

1
2
3
    <div id="the_id">
        Text/Data To Hide Goes Gere
    </div>

Then, you can use this code to hide it (in an {if} block, for instance):

1
2
3
    <script type="text/javascript">
        document.getElementById("the_id").style.display = "none";
    </script>

And this to show it:

1
2
3
    <script type="text/Javascript">
        document.getElementById("the_id").style.display = "block";
    </script>

I haven’t tried, but it’s also probably possible to have show/hide links:

1
2
3
4
5
6
7
8
9
    <div id="the_id">
        Text/Data to Hide Goes Here.
    </div>
    <a onclick="javascript:document.getElementById('the_id').style.display = 'none'">
        Hide Text
    </a>
    <a onclick="javascript:document.getElementById('the_id').style.display = 'block'">
        Show Text
    </a>

Of course, if you want to hide text in-place (without rearranging the flow of the remainder of the text), you’ll need:

1
2
3
4
5
6
7
8
9
    <div id="the_id">
        Text/Data to Hide Goes Here.
    </div>
    <a onclick="javascript:document.getElementById('the_id').style.visibility = 'hidden'">
        Hide Text
    </a>
    <a onclick="javascript:document.getElementById('the_id').style.visibility = 'visible'">
        Show Text
    </a>

Script to XHTML

I wrote my own script to convert the selection (or whole front document) in Script Editor to XHTML. It uses the same CSS tags as Jonathon’s program, but does not add the style data in, unless a property is set. I’ve also got the Source Code for his program, so it will be interesting to see similarities.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
    (*
    Script to XHTML v1.0
    ©2005 Matthew Schinckel
    http://schinckel.net/
    
    Converts selection (or whole document) into XHTML code.
    
    Insert the StyleSheet into your CSS if you want.  Else set externalCSS to false.
    
    Put it in your Scripts Menu, and it will work a treat for you.  
    Even copies the data to the clipboard.
    
    Bugs/Issues:
    
    • Script Editor reports the start of comments [--] as being black, not grey.
    • Doesn't handle references.
    • Operators and values are treated all as values.
    
    *)
    
    property StyleSheet : "
    .AppleScript { background-color:#ffffff; border: solid black 1px; padding:0.5em 1em 1em 1em; text-align:left; font-family: Verdana,Sans-Serif; overflow:auto; font-size:0.9em; white-space:pre; line-height:1.2em; margin-bottom:9px;}
    .as_new_text  { font-family:Courier; color: purple; }
    .as_operators  { color: black; }
    .as_language  { font-weight: bold; color: blue; }
    .as_application  { color: blue; }
    .as_comments, .as_comment  { font-style:italic; color: gray; }
    .as_values  { color: black; }
    .as_variables ,.as_variable { color: green; }
    .as_references  { color: purple; }
    "
    property externalCSS : true
    
    -- The HTML code either side of the block.
    property htmlStart : "<pre class='AppleScript'>" & return
    property htmlEnd : return & "</pre>" & return
    
    property tagStart : "<span class='"
    property tagMiddle : "'>"
    property tagEnd : "</span>"
    
    -- Apparently, this one is different to 'return'
    property enter : "
    "
    -- For testing, set this to 2, for use via Script Menu, set to 1.
    property win : 1
    
    if externalCSS is not true then set htmlStart to htmlStart & "<style>" & return & StyleSheet & return & "</style>" & return
    
    tell application "Script Editor"
    	set theData to contents of selection of document of window win
    	if (theData is "") then
    		-- No selection, let's do the whole document.
    		set textList to attribute run of contents of document of window win
    		set fontList to font of attribute run of contents of document of window win
    		set colorList to color of attribute run of contents of document of window win
    	else
    		set textList to attribute run of contents of selection of document of window win
    		set fontList to font of attribute run of contents of selection of document of window win
    		set colorList to color of attribute run of contents of selection of document of window win
    	end if
    end tell
    
    set html to ""
    
    repeat with i from 1 to the count of textList
    	set theClass to whichClass(item i of fontList, item i of colorList)
    	set theText to my HTMLify(item i of textList)
    	set html to html & tagStart & theClass & tagMiddle & theText & tagEnd
    end repeat
    
    set the clipboard to htmlStart & html & htmlEnd
    beep
    
    -- Utility Functions
    
    on whichClass(theFont, theColor)
    	-- Set the class according to the font or colour.
    	if theFont is "Verdana-Bold" then return "as_language"
    	if theColor is {16384, 32768, 0} then return "as_variables"
    	if theColor is {19660, 19960, 19960} then return "as_comments"
    	if theColor is {0, 0, 65535} then return "as_application"
    	if theColor is {32768, 0, 32768} then return "as_new_text"
    	return "as_values"
    end whichClass
    
    on replace(theText, find, replace)
    	-- Nice replace function
    	set OldDelims to AppleScript's text item delimiters
    	set AppleScript's text item delimiters to find
    	set newText to text items of theText
    	set AppleScript's text item delimiters to replace
    	set theResult to newText as text
    	set AppleScript's text item delimiters to OldDelims
    	return theResult
    end replace
    
    on HTMLify(someText)
    	-- This might need some more entries.
    	-- Perhaps a better way of doing it...?
    	set someText to replace(someText, "&", "&amp;")
    	set someText to replace(someText, "\"", "&quot;")
    	set someText to replace(someText, "<", "&lt;")
    	set someText to replace(someText, ">", "&gt;")
    	--set someText to replace(someText, tab, "&nbsp;&nbsp;&nbsp;&nbsp;")
    	--set someText to replace(someText, enter, "<br />" & enter)
    	--set someText to replace(someText, return, "<br />" & return)
    	return someText
    end HTMLify

I will not tickle you!

Got this one from Boing Boing: