For about two years I have been blogging from Tumblr hosted blog. It’s an awesome service and it’s so easy to publish text, photos, audio, video, etc. However, since most of my articles are code related I decided to give Octopress a try, and I love it!
Octopress is a framework for Jekyll, the blog aware static site generator written in Ruby and powering GitHub pages. Octopress adds some sugar to Jekyll, such as HTML templates, CSS, JavaScripts and configuration.
Hence, let me first summarize what I liked about Jekyll:
Static: Jekyll generates static HTML pages ready to be hosted anywhere. This means, I can easily host my blog at Github Pages or even Dropbox?
Managing posts: It is now much easier to manage my blog posts. I can use the power of my TextMate editor or Bash shell to perform comprehensive operations, such as find/replace, regular expressions, etc, which are not possible with a hosted blog service.
Markdown: It allows me to write blog posts in Markdown. No need to mess up with an awful WYSIWYG HTML editor at Tumblr.
Git: My blog posts are now in a Git version control system. I can store entire history of my blog on Dropbox or Github. I also can write my posts while offline, preview markdown in TextMate, run Blog locally, and commit to Git.
Beautiful code snippets: With a Sass port of Solarized syntax highlighting, Octopress makes it easy to share highlighted code snippets. Moreover, it adds support for codeblock and gist tags (browse through my blog, you will see how great they look!).
So how did I migrate?
Honestly, it took quite a while. Even though, there is a Tumblr to Jekyll script, you will still have to do some manual work. Here are some hints to help you migrate:
Follow instructions at Tumblr to Jekyll to get necessary dependencies.
Download tumblr.rb that supports Markdown conversion. I had to patch the script since Octopress uses .markdown extensions and for some reason several Tumblr blog posts could not be converted to Markdown, so I had to redirect output of html2text to a file.
tumblr.rb
1234567891011121314151617181920
--- source/tumblr.orig.rb 2012-03-24 21:58:08.000000000 +0200+++ source/tumblr.rb 2012-03-26 23:16:25.000000000 +0300@@ -30,7 +30,7 @@ posts = rewrite_urls_and_redirects posts if rewrite_urls
# Second pass for writing post files.
posts.each do |post|
- if format == "md"+ if format == "markdown" post[:content] = html_to_markdown post[:content]
post[:content] = add_syntax_highlights post[:content] if add_highlights
end
@@ -146,7 +146,7 @@ content.gsub!(/<#{tag}/i, "$$" + tag)
content.gsub!(/<\/#{tag}/i, "||" + tag)
end
- content = %x[echo '#{content.gsub("'", "''")}' | html2text]+ content = %x[echo '#{content.gsub("'", "''")}' | html2text 2>> html2md.log] preserve.each do |tag|
content.gsub!("$$" + tag, "<" + tag)
content.gsub!("||" + tag, "</" + tag)
I assume your Octopress blog is working and you are in its root directory. Now, you need to put a modified version of tumblr.rb to the right place and run it:
The script will create Tumblr posts in Markdown format. In order to support old Tumblr URLs, it will also create static pages in post directory with HTML redirects. Let’s move them to the right place in Octopress:
Then, I have gone through all pages and aligned the images. I also ran find/replace to all tumblr_files images, which were fetched from Tumblr during migration.
I had a feeling all these “hash” techniques look a bit “hackish”, do not work properly with browser history and bookmarks, cumbersome to implement and most of the times do not degrade gracefully.
Hence, several weeks ago, I started looking for a new and more elegant solution to implement Ajax powered Search interface with Browser History and Bookmarks support (from my old post):
Consider a Web application with an advanced form. Let’s say you would like to change the form fields (dropdowns, sliders, checkboxes, etc.), click an “Update” button (or even without a click) and get part of the page updated dynamically with Ajax.
As I have heard about HTML5 Push State method already, it did not take long to get into Pjax. Also, I found out that Ryan Bates has several screencasts telling about various techniques, including hash tag, plain Push State and Pjax:
The above screencasts are really great, however after watching them, I wanted to use Pjax also with my Search form and not just the links.
So, in this blog post, I will show you how to use your existing Rails form with Pjax. But, please go through the videos, if you haven’t already, as otherwise the remaining of this post might be difficult to follow.
I assume, you have some kind of form with various fields and components. Make sure it does not have remote tag and uses GET (it’s search, it has to be GET, isnt it?). For example:
The idea is, if the browser does not support Push State it will degrade gracefully and do a full page refresh. If you would keep remote, the URL will not be populated with search params, which would make it impossible to share search query link or bookmark it.
Then, as mentioned in the screencasts, install a Gem rack-pjax. I have used this one, instead of pjax-rails, just because I can control my data-pjax-container and selectively use Pjax.
Then, it took me a bit more time to find out how to Pjaxify my form. Luckily, I found this pull request to pjax-rails, which apparently has not
been accepted. So, I came up with the following code:
The code above will do a PJax request and update the data-pjax-container. Inside the container, you would render your posts (or other Models you may have) matching the search criteria.
If you use pagination, you can simply Pjax the links as follows:
1
($'.pagination a').pjax('[data-pjax-container]')
If you want to do something before or after Pjax request, for example showing a preloader, you can use this code:
1234
($'#articles').bind'start.pjax',-># do something before pjax ($'#articles').bind'end.pjax',-># do something after pjax
And finally, do not forget not to render a layout with Pjax requests. You can do this:
Twitter Bootstrap has a really nice support for modal windows. However, it does not support loading remote content with an Ajax out of the box. If you ever wondered how to do it, read on:
The idea is quite simple. You use the same syntax as described on their site, however in the trigger link, you would use href for a URL to remote content, and data-target for a modal ID.
Now you need the HTML DIV where modal content will be loaded. With remote data, you only need it in one place within your application, for example, in Rails you can put it to a layout file. Of course, this would mean the remote page you are loading has the correct Twitter Bootstrap modal markup (check an example on their site).
1
<divclass="modal fade"id="myModal"></div>
Then, add the actual jQuery spice to your JavaScripts (CoffeeScript syntax):
I was about to write a script to automatically convert Ruby 1.8 hashrocket syntax to Ruby 1.9 in my application and seems like there is a Gem for that, awesome! For the newbies, Ruby 1.8 has the following syntax, when using Hashes:
1
my_hash={:a=>1,:b=>2}
Whereas, Ruby 1.9 is a bit more concise and looks like a JSON style:
1
my_hash={a:1,b:2}
So, just install rip_hashrocket gem and in some seconds it will convert all your hashes to Ruby 1.9 style.
Although, counter cache is documented in the Rails Guides - Associations, I have noticed not many people use this neat feature. Probably for small scaled Rails applications it is not an issue to execute COUNT(*) on all records, however for bigger applications this is definitely a good optimization.
Enabling counter cache will simply make Rails to increment and decrement the counter of associated objects. Whenever you need to execute size on ActiveRecord, Rails will use the cached counter. You can even use a custom column:
Today I got interested how many people visited my Blog since I started last year. Really, I was amazed! About 30K visits with 20K unique visitors. Don’t get me wrong, there are many blogs that generate much higher traffic. However, I write on average about 4 posts per month only, and probably 1-2 of them is useful content.
What I am trying to say is, you do not need to spend considerable amount of time to run a blog. Just write at least 1-2 times a month about anything you think might help others and people will find your content - That’s the power
of Cloud!
Git might be difficult sometimes! Especially the git reset command. Suppose, you have created several commits, then reseted to another state and then realized you need those commits back:
What do you do? Are they lost? The answer is ”No”. You can get the commits back by using git reflog, as long as the Git garbage collection hasn’t run. Reflog is kind of journal, which keeps track of updates to the tip of branches.
Just run git reflog or git log -g, then look for HEAD@{SOME_NUMBER} and apply git reset --hard HEAD@{SOME_NUMBER}
Twitter Bootstrap is a great open source CSS and JavaScript toolkit from Twitter. It provides you an excellent base for typography, forms, buttons, tables, and much more.