How to create embeddable widgets with Rails
Sometime you have to allow embeddable widgets or badges with your application. Just like Youtube allows you to embed videos or many social networking sites allow embedding badges or buttons with some dynamic information on them.
Let’s say we are developing a project which allows you to maintain a database of dinosaurs. You can create profiles for various dinosaurs with their name, description and other details. Now, it will be cool if you allowed your users to embed their favourite dinosaur on their blog. They could just add a small script like this in their blog where ever they want the widget to appear:
We will show how to build just such a widget into your Rails project.
Firstly, let’s start a fresh rails project. It should have Dinosaurs with some profile data, images and whatever else you fancy:
$ rails new dino_app $ cd dino_app $ rake db:create $ rails server $ rails generate scaffold dianosaur name:string genus:string description:text period:string $ rake db:migrate
/dianosaurs in your browser and ddd a few of your favourite dianos.
Next, we will create a embed script so that users can embed any one dinosaur data on their site. There are two ways of implementing it. One is by injecting your HTML content directly into the site and the other is to use an iframe. You can use either one based on what suits your needs. We describe both techniques below:
Load html content inline
# File: app/controller/dianosaurs_controller.rb def show @dianosaur = Dianosaur.find(params[:id]) end
- File: show.js.erb
- File: _embed.html.erb
- This file contains whatever CSS, JS and HTML you want embedded
- remember that there is no layout since you are embedding on a third party
- site and the CSS needs to be written carefully
<%= dianosaur.name %>
<%= dianosaur.genus %>
The CSS needs to be written in such a way that the target site’s CSS does not interfere with it and changes the look. Common techniques for that are to heavily use !important tag or to write style for each and every element, since you cannot leave anything to be influenced by parent’s style (in this case, you don’t want the stylesheet to cascade).
Now you can embed the diano widget on a different site using the following script:
Here are some tips for more advanced uses:
- If you want to include jQuery in the third-party page. You can add this to the top of
- Separate CSS and JS in a separate file instead of inlining them. Add the following at the top of
Insert an iframe on the target site, which can load the contents automatically
- File: routes.rb
resources :dianosaurs do
- File: dianosours_controller.rb
@dianosaur = Dianosaur.find(params[:id])
- File: widget.html.erb
<%= @dianosaur.name >
<= @dianosaur.genus %>
There are certain advantage of using an iframe:
Also, here are some disadvantages:
- Width and height of the iframe has to be fixed. It cannot auto adjust based on the content in iframe.
- To load the contents of the widget, browser should make atleast two requests to the application. One request to load show.js.erb with iframe tag and another request to load iframe content from the URL specified in the src atribute of the iframe.