Skip to main content

Mobomo webinars-now on demand! | learn more.

If you’ve taken a look at Mustache, the “stupid in a good way” templating engine, you might know that there are also Javascript Mustache renderers such as Mustache.js. Today we’ve released a small library called mustache_json that allows you to compile your Mustache view objects into JSON, allowing them to be interpreted by Javascript Mustache rendering engines.

What this means for your project is that you will finally have a identical client-side and server-side rendering interface, opening wide the opportunities for pushing more of the rendering work onto the client-side, a boon for many real-time and heavy-interaction applications.

To install mustache_json, just get the gem from Gemcutter:

gem install mustache_json

To use it, simply require 'mustache_json' and all of your Mustache objects will automatically be given a #to_json method. For instance:

require 'mustache_json'  class Person < Mustache   def initialize(first_name, last_name)     context[:first_name], context[:last_name] = first_name, last_name   end      def initials     "#{context[:first_name][0..0]}.#{context[:last_name][0..0]}."   end      def listing     "#{context[:last_name]}, #{context[:first_name]}"   end end  bob = Person.new('Bob', 'Bobson') bob.to_json

This will render into a JSON object that looks like this:

{"last_name":"Bobson","initials":"B.B.","listing":"Bobson, Bob","first_name":"Bob"}

Mustache JSON gives you access to all of the public instance methods you declare in your Mustache as well as any context you have set. It is essentially a fully compiled version of the Mustache view, providing everything another renderer needs to create the actual markup. The JSON back-end for this library is swappable, meaning you can use the JSON gem, JSON pure, ActiveSupport, or Yajl by default (and any other class with an encode method if you’ve got a different library).

Documentation is available on RDoc.info and the source is available on GitHub. Stay tuned for posts in the future about utilizing this library to actually perform identical rendering in Ruby and Javascript.

Categories
Author

One of my earliest gems was Mash, a useful tool for creating mocking objects as a Hash. One of the most common problems people had with Mash was a simple one: it conflicted with another class of the same name in extlib! To address this problem as well as give the project some room to grow, Mash is now part of a new toolkit called Hashie. Hashie is available now via Gemcutter and the source, as always, is available on GitHub. To install:

gem install hashie

Hello, Hashie

Hashie is, right now, simply the former Mash code along with a new extended Hash called a Dash. A Dash is a “discrete hash” that has pre-defined properties. It can be used as a dead-simple data object when even something like DataMapper is too heavy, but a Struct is too light (Dash gives you the ability to set per-property defaults as well as initialize from an attributes Hash). For example:

class Person < Hashie::Dash   property :name   property :email   property :occupation, :default => 'Rubyist' end  p = Person.new p.name # => nil p.occupation # => 'Rubyist' p.email = 'abc@def.com' p.email # => 'abc@def.com' p['awesome'] # => NoMethodError  p = Person.new(:name => "Awesome Guy") p.name # => "Awesome Guy" p.occupation # => "Rubyist"

The other advantage Hashie has over Mash is that it’s built from the ground up to avoid conflicts. Instead of adding stringify_keys methods to the Hash class, it’s instead added to a Hashie::Hash subclass. You can, however, get Hashie’s few Hash extensions in the Hash class by including the HashExtensions:

Hash.send :include, Hashie::HashExtensions

Hopefully the move will make it easier for everyone to use it in their projects without fear of running into conflicts, and hopefully you’ll also find the Dash useful. Over time the functionality of Hashie may grow to encompass additional simple and useful extensions of Hash. So install Hashie, your friendly neighborhood Hash toolkit, today!

Categories
Author

Twitter’s Streaming API is one of the most exciting developments in the Twitter API in some time. It gives you the ability to create a long-standing connection to Twitter that receives “push” updates when new tweets matching certain criteria arrive, obviating the need to constantly poll for updates. TweetStream is a Ruby library to access the new API.

Installation

Installation of TweetStream is simple, it’s available as a gem on GitHub and Gemcutter.org. To install it from GitHub:

gem sources -a http://gems.github.com gem install intridea-tweetstream

To install it from Gemcutter:

gem sources -a http://gemcutter.org gem install tweetstream

Usage

TweetStream creates a long-standing HTTP connection to Twitter, so unlike other Twitter libraries you don’t simply run it once and deal with the results. Instead, you provide a block that will be yielded to with each new status that arrives. The most basic example is:

require 'rubygems' require 'tweetstream'  TweetStream::Client.new('user','pass').sample do |status|   puts "[#{status.user.screen_name}] #{status.text}" end

This will provide you with a small sample snapshot of all of the updates being posted to Twitter at this moment and print them to the screen. There are also methods available to track single-word keywords as well as the updates of a specified list of user ids (integers, not screen names). You can do that like so:

# Track the terms 'keyword1' and 'keyword2' TweetStream::Client.new('user','pass').track('keyword1', 'keyword2') do |status|   puts "[#{status.user.screen_name}] #{status.text}" end  # Track users with IDs 123 and 456 TweetStream::Client.new('user','pass').follow(123, 456) do |status|   puts "[#{status.user.screen_name}] #{status.text}" end

Handling Deletion/Limit Notices (Updated in 0.1.4)

Sometimes the Streaming API will send messages other than statuses.
Specifically, it does so when a status is deleted or rate limitations
have caused some tweets not to appear in the stream. To handle these, you can use the on_delete and on_limit methods. Example:

TweetStream::Client.new('user','pass').on_delete{ |status_id, user_id|   Tweet.delete(status_id) }.on_limit { |skip_count|   # do something }.track('intridea') do |status|   # do something with the status like normal end

Daemonization

One of the most useful features of TweetStream is its built-in daemonization functionality. This allows you to create scripts that run in the background of your machine rather than taking up an active process. To create a daemon script, you simply use TweetStream::Daemon instead of TweetStream::Client. Here’s an example:

require 'rubygems' require 'tweetstream'  # The third argument is an optional process name. TweetStream::Daemon.new('user','pass','tracker').track('keyword1','keyword2') do |status|   # Do something like dump the status to ActiveRecord   # or anything else you want. end

If you were to place the above code in a file called tracker.rb you could then run ruby tracker.rb to see a list of daemonization commands such as start, stop, or run.

TweetStream is a simple wrapper on the Streaming API, but with built-in daemonization provides powerfully flexible means of accessing the Twitter Streaming API using familiar Ruby tools. More complete code documentation is available at rdoc.info.

Update: I overlooked the deletion and rate limit notices when I wrote the initial version of the gem. As of version 0.1.4 these are handled properly.

Categories
Author
TwitterAuth

The public beta of Twitter OAuth support has been released and I’m excited to introduce a new library that I’ve been working on called TwitterAuth. TwitterAuth is a Rails plugin that provides a full external authentication stack for Rails applications utilizing Twitter. Think of it as “Twitter Connect” for Rails, letting you create an application that may be logged into using only Twitter credentials.

TwitterAuth supports both OAuth and HTTP Basic (though OAuth is certainly the recommended strategy) giving you maximum flexibility for building the application. Without further ado, let’s get into the installation and usage of TwitterAuth!

Installation

TwitterAuth is available as a GemPlugin, so the preferred way to install it is simply to add it as a dependency in your config/environment.rb:

config.gem 'twitter-auth', :lib => 'twitter_auth'

You can also choose to install it as a traditional Rails plugin:

script/plugin install git://github.com/mbleigh/twitter-auth.git

Once you’ve installed it, you’re ready to create a new application using TwitterAuth!

The Low-Down

TwitterAuth uses Rails 2.3 Engine support to completely encapsulate the login process within itself. All you need to do is run a generator to make all of the support files necessary in your application. Run it with the --basic option if you want to use HTTP Basic, otherwise it will default to OAuth.

script/generate twitter_auth

This generates a User class, a migration, and twitter_auth.yml. You will need to edit twitter_auth.yml to match the settings of your application, such as providing the OAuth client token and secret.

Once you’ve migrated, that’s it! You are up and running with Twitter authentication; just point users at /login to start the process (login and registration are handled in a single step). For more detailed usage information including how to access the Twitter API through TwitterAuth, take a look at the README file.

The source for TwitterAuth is available on GitHub. I have also created a Lighthouse Project for the reporting of any bugs you may come across. There is also a basic homepage that will be listing who’s using TwitterAuth.

If you’re pretty familiar with Rails authentication systems (particularly Restful Authentication), this is probably all you need to know to get started. Go forth and make awesome apps! If not, I’ve written a quick run-through of the whole process to make it easy for anyone to get started with Twitter apps.

A Quick Run-Through

I think the best way to show what TwitterAuth is capable of is just to show how quickly you can build a simple Twitter application with it. To that end, let’s build a simple way to look at your friends’ timeline in an old-school text-based way (note, this is a totally useless application but works well for a quick demo). First we need to generate the app:

rails texty-twitter

Next we want to install TwitterAuth on the application, so we’ll add this to our config/environment.rb:

config.gem 'twitter-auth', :lib => 'twitter_auth'

Once we have hooked TwitterAuth into the application, we will want to run the generator to build the support files we need:

script/generate twitter_auth --oauth

Before I start on application logic I always lay out a basic HTML layout. Here it is for this application (in app/views/layouts/master.html.erb):

<html>   <head>     <style type='text/css'>       ul.tweets {         list-style: none;         margin: 0;         padding: 0;       }        ul.tweets li {         font-family: monospace;         font-size: 14px;         padding: 4px 8px;       }        ul.tweets li a {         color: #fa0;         font-weight: bold;         text-decoration: none;       }     </style>   </head>   <body>     <%= yield %>   </body> </html>

The next step is to edit config/twitter_auth.yml to reflect our OAuth client key and secret (to register your application log in to Twitter and visit http://twitter.com/oauth_clients). Other than the client key and secret, the defaults are fine for our purposes. We’ve now set up a basic TwitterAuth application; that’s really all there is to it. So now let’s make it a working Twitter application. First let’s generate a controller:

script/generate controller timeline

This will just be a one-action controller that will render out the main timeline for the logged in user in an text-based manner. Here’s the contents of the controller:

class TimelineController < ApplicationController   # this requires us to log in through Twitter before accessing any actions here   before_filter :login_required    def index       @tweets = current_user.twitter.get('/statuses/friends_timeline')   end end

In this action, current_user is the logged in user, and the twitter method provides a simple wrapper around the Twitter REST API that will automatically parse JSON API requests into Ruby hashes for you to use in your application. So current_user.twitter.get('/statuses/friends_timeline') will grab the latest statuses from your friends’ timeline (the main timeline you see when you’re logged in to Twitter) as an array of hashes. Now let’s display the tweets by creating app/views/timeline/index.html.erb:

<ul class='tweets'>   <% for tweet in @tweets %>     <li><%= link_to tweet['user']['screen_name'] + ':', 'http://twitter.com/' + tweet['user']['screen_name'], :target => '_blank' %> <%= tweet['text'] %></li>   <% end %> </ul>

This simply goes through each of the tweets we pulled down and adds a list item with a link to the author of the tweet and the content of the tweet. The structure of the hashes are identical to their description in the Return Elements section of the Twitter API wiki.

Finally, we need to add some routing to tie everything together. Make the config/routes.rb look like this:

ActionController::Routing::Routes.draw do |map|   map.root :controller => 'stream', :action => 'index' end

And we’re done! Fire up your server with script/server and go to http://localhost:3000/. If everything is working properly, it should redirect you to Twitter with a screen like this:

Once you click through and hit allow, it should then take you back and display your tweet stream in an old-school text interface, something like this:

It’s a simple and useless application, but in about 10-15 minutes you’ve created a fully-functioning Rails application that accesses the Twitter API and stores user information. Not bad!

See You At RailsConf!

RailsConf 2009

TwitterAuth is a big part of what I will be talking about at RailsConf in my session ‘Twitter on Rails’. if you’re interested in the plugin and attending RailsConf in May I hope you’ll stop by; I’ll be building an entire Twitter application from scratch during the 45 minute presentation. Also, feel free to follow me on Twitter if you’re so inclined.

Categories
Author

Today came the announcement that all of the major search engines are going to support a ‘canonical’ URL hint that will allow site owners to specify a single URL for content that may be replicated across many URLs (such as for categories etc.).

To make use of this in Rails applications, I’ve written a plugin that allows you to easily specify canonical URLs for your content. To install it as a gem, just add this to your environment.rb:

config.gem 'mbleigh-canonical-url', :source => 'http://gems.github.com', :lib => 'canonical_url'

Using it is extremely simple; just add this to the <head> section of your layout:

<%= canonical_link_tag %>

And in your controllers, any time you want to specify a canonical URL you can do so like this:

class BlogController < ApplicationController   def show     @post = find_post # assume this is a standard blog post type record     canonical_url blog_post_path(post.year, post.month, post.day, post.slug)   end end

Now any time the show action is run, no matter how the routing came to be there, a single canonical URL will be shown in the header. If no canonical URL is specified in the controller (or through the canonical_link_tag helper directly) the helper will not output anything, making it completely harmless to add to any application.

The source for the plugin is available on GitHub. So go forth and canonize your applications!

Categories
Author

Last night after watching the Lost premiere I had a question to which I was having a hard time finding the answer. The show had just ended and I wanted to know (tiny spoiler alert) who the woman Benjamin Linus was talking to at the end of the episode was. Google was no help (the episode had finished mere minutes before) so I turned to Twitter for some real-time searching.

By searching for lost old woman I was able to find plenty of other people asking the same question I had, but no one was giving the answer. I suspected that a reply to one of the tweets in question would have the answer so a few more minutes of manually searching for replies to the search result tweets finally yielded my answer. It also showed me how useful Twitter Search could be with a built-in way to find replies to the tweets. Rather than request the feature and wait until Twitter decides to implement it, I got my hands dirty with Greasemonkey and rolled my own.

Twitter Search Plus

This userscript (which requires the Greasemonkey Firefox Extension or equivalent userscript support in another browser) will automatically add a “Find Replies” link to the actions on Twitter search results and go out, find, and insert the replies to the user in question inline, just like the Show Conversation view. Here’s a screenshot of it in action:

This makes it really convenient to discover if a tweet you found while searching sparked any conversation. While I used it for entertainment, you could easily also find out who replied to a negative post about your brand, or if anyone else has already answered a question you were about to answer.

Installation and Limitations

You can install the script by following this link and see the source right here as a GitHub Gist. The script has also been posted to UserScripts.org.

Because there is no way to sort Twitter searches from oldest to newest, you will only see the 15 most recent replies to the user posted after the tweet in question. If the tweet is old or the user is extremely popular you might not get the replies you’re looking for. I’m open to suggestions as to how to make this work better.

Happy Twittering!

Categories
Author

There will be no killer words in this application: Behold the mighty Fu-fu! And there was much rejoicing… But first, a little history on Fu-fu: The Profanity Filter for Rails.

A Little History

Recently, I needed a simple (profanity/cuss/swear/bad word) filter for a Rails app, so I hit up Google for the answer as this seemed like a problem that should have been solved by an expert. Sadly, this was not the case.

Over the next day or so I was able to get a simple prototype up and running in our application and that’s the way it stayed for the next couple weeks. Then I realized that this was reason I wasn’t able to find a profanity filter plugin on Google.

Upon closer inspection it seems that people are building their own filters and leaving it at that. Almost being guilty of this, I decided that it was time to give back to the community and get a profanity filter plugin out in the wild.

I was able to publish the first version of the Profanity Filter during the Community Code Drive at RailsConf 2008. Hacking in the same room as DHH, David Chelimsky, Chad Fowler, Rich Kilmer, Marcel Molina Jr., and the entire Intridea team is a great motivator.

During RailsConf we decided that the plugin needed a real name; “Profanity Filter” wasn’t cutting it. Someone suggested fu-fu pronounced ‘eff-you-foo’. That was promptly shortened to ‘foo-foo’. How can you not love something named Fu-fu that deals with profanity and abuses plugin idioms at the same time?

Continue Rejoicing (Examples!)

The interface for Fu-fu is clean and straight forward. For example. lets say that ‘frak’ is a common curse word.

class Post < ActiveRecord::Base   profanity_filter :title, :body end  post = Post.create(:title => 'Fraking title', :body => 'What a bunch of frak')  post.title          #=> '@#$% title' post.title_original #=> 'Fraking title'  post.body           #=> 'What a bunch of @#$%' post.body_original  #=> 'What a bunch of frak'

 

By default the filter will replace common curses with the standard curse notation of ‘@#$%’. Fu-fu is also has the ability to do dictionary replacements:

class Post < ActiveRecord::Base   profanity_filter :title, :body, :method => 'dictionary' end  post = Post.create(:title => 'Fraking title', :body => 'What a bunch of frak')  post.title          #=> 'fr*k*ng title' post.body           #=> 'What a bunch of fr*k'

 

Fu-fu comes with a default dictionary file that replaces all vowels with asterisks (*).

You can also add an exclamation point to the end of the filter call (profanity_filter!) and have the method save the filtered text to the database (although this is not recommended for most applications).

You can also call Fu-fu directly:

ProfanityFilter::Base.clean('frak')               #=> '@#$%' ProfanityFilter::Base.clean('frak', 'dictionary') #=> 'fr*k

 

Todos and Fixes

But alas, there is still danger in Caerbannog. As with all things, there is room for improvement.

* better filter regex, doesn't currently catch things like 'f-r-a-k' * needs support for multiple dictionaries and configuration * needs support for different levels of filtering (prude, normal, weak, etc)

 

Installation

To install the Fu-fu: The Profanity Filter on Edge Rails or Rails 2.1 and greater:

script/plugin install git://github.com/adambair/fu-fu.git

 

On earlier versions of Rails:

git clone git://github.com/adambair/fu-fu.git vendor/plugins/fu-fu

 

Resources

Bug tracking is available through the Fu-fu Lighthouse project. Also, feel free to contribute. I’ll be happy to accept patches and push requests for reasonable fixes and additions as long as they come with test coverage.

The source code is available on GitHub.

For general discussion about the plugin, please use the forums and wall of Fu-Fu’s Acts As Community Profile

Thanks to the Intridea team for their time, contributions, and suggestions. I’ve had a great time building Fu-fu and I hope someone may find it useful.

Categories
Author

Josh Owens and Dave Naffis were the 7th and 8th leading contributors, respectively, in the October '07 Rails Hackfest. The Rails Hackfest recognizes developers who, by submitting patches, documentation, tests, and/or tickets, are actively involved in improving Ruby on Rails. Kudos to Josh and Dave for their accomplishment! Intridea is proud to give back to the Rails community, as well as other open source projects.

Categories
Author
Subscribe to Open Source