ruby Rack application for hosting your bookmarks or maintaining a link blog
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


Host your bookmarks or maintain a link blog.

  • post from command-line, bookmarklet, or web interface
  • fetches url titles and generates thumbnails from page
  • jGrowls embedded versions of Imageshack, Imgur, Vimeo and YouTube urls
  • converts Twitter status urls to their full text and adds user thumbnail
  • normalizes and strips junk from urls using postrank-uri
  • generates Atom and RSS feeds
  • generates podcast RSS feed and m3u file for all audio urls
  • generates json and jsonp feeds for client-side inclusion in other sites
  • search, all output formats can be filtered by search criteria
  • uses HTML5 audio for mp3 and ogg urls
  • looks good on iPhone
  • PubSubHubbub notification
  • plugin interface
  • rack interface
  • Gravatar support
  • generates import scripts from delicious api exports
  • optionally store thumbnails in S3
  • experimental support for posting by email via POP

See for example.


Phusion Passenger

DESTINATION_DIRECTORY is the web directory to install the murlsh site to.

gem install murlsh
rake config[root_url,<site root url>]
change anything else you want in config.yaml
rake init


S3 is used for thumbnail storage because Heroku cannot write local files.

gem install heroku
heroku keys:add

gem install murlsh
mkdir murlsh_deploy <or any other name>
cd murlsh_deploy
murlsh .
git init
heroku create --stack cedar <choose a name>

rake app:gemfile
bundle install

rake heroku:config
rake config[s3_bucket,<your S3 bucket name>]
rake config[s3_id,<your S3 id>]
rake config[s3_secret,<your S3 secret>]
change anything else you want in config.yaml

rake user:add

git add .
git commit
git push heroku master

heroku addons:add shared-database
heroku run rake db:migrate


Create a fork on Github and clone it.

rake config[root_url,http://localhost:9292/]
rake db:migrate
rake user:add

Browse to http://localhost:9292/


If you are using the gem and it gets updated to a new version you should run
the murlsh command again from your web directory to update plugins, javascript
and css. It will prompt before overwriting anything in case you have made



rake post_bookmarklet

This will produce a bookmarklet link customized with your murlsh’s URL
and your password. Create a link in your bookmarks toolbar with the
output; the resulting bookmarklet will let you post to your murlsh
from whatever page you’re currently viewing.

If you select text on the page before hitting the bookmarklet, your
selection will be used as the title; otherwise, the page’s title will
be used.

Shell script

rake post_sh

will produce a customized shell script that will take command-line
arguments for URL, etc, and post to your murlsh using curl.


Recent urls

  • http://your_root/atom.atom
  • http://your_root/rss.rss
  • http://your_root/podcast.rss (urls with audio/mpeg content type)
  • http://your_root/m3u.m3u (urls with audio content types)
  • http://your_root/json.json
  • http://your_root/json.json?callback=x (jsonp)


Thumbnail images are generated from added urls using plumnailer. They are
scaled down to ‘thumbnail_max_side’ in config.yaml and stored locally.

Thumbnails can also be manually specified by passing their url as the
‘thumbnail’ parameter when adding a url. They are also scaled and stored

The plugin add_pre_40_thumbnail_shortcuts.rb can be used to specify
short names for frequently used thumbnail urls that can be passed in instead.


Classes in the plugins directory can be used to change behavior at certain
points. Each class that extends Murlsh::Plugin and sets an instance variable
called @hook will be called for that hook. Each plugin has a run() method that
accepts arguments and returns something. These methods will be called in the
order of their class names sorted lexically. Some hooks pass the output of their
run() method to the next plugin for that hook so that the data can be passed
through a chain of methods that each do something to it.

A lot of the standard behavior is implemented as plugins. See the plugins
directory for examples.

Plugin hooks

Hook Description run() arguments Returns
add_pre called before a new url is saved url, config hash undefined
add_post called after a new url is saved url, config hash undefined
avatar called to get an avatar url from an email md5 sum avatar url, url, config hash avatar url
store_asset store an asset somewhere where it can be loaded by url name, data, config hash asset url if successfully stored
url_display_add called to display additional information after urls markup builder, url, config hash undefined
url_display_pre called to modify a url on-the-fly before display, does not change database url, rack request, config hash undefined


Murlsh can notify PubSubHubbub hubs
when a new url is added by adding them to config.yaml. The pubsubhubbub_hubs
key is a list of hashes in the following format:

- publish_url:

publish_url is where the notifications get sent
subscribe_url is what gets put in the feed as link rel=“hub”

This will make updates to your feed show up in Google Reader instantly.

Questions and comments: