Turning a Widget into a Gem

The Scrivito SDK lets you turn any widget into a reusable gem. There are several advantages of a widget gem compared to a widget implementation directly in the application.

  1. You can more easily reuse code in different applications and organize that code so that it can be maintained easier.
  2. You can separate concerns regarding the development of the widget from the development of your application. Maybe you even want a different team to work on your widgets.
  3. You have an easier time to update a widget across multiple applications, which is very important to save valuable time when updating a third party library used in your widget code or when you have fixed a bug in your widget logic.
  4. It allows you to publish your widgets, use widgets maintained by other developers and rely on a usually more robust code base instead of reinventing the wheel. As the community gets bigger and the selection of widgets becomes richer, you can benefit from a wide range of widgets and ready-to-use code, accelerating the development of your application.
  5. You learn and practice a very important aspect of structuring your Ruby application. Developing your own gems also opens a door to the very active open source Ruby community.

The only disadvantage of turning your widgets into gems is probably the cost of learning how to do it, and a bit more complexity regarding the maintenance of your applications. So let's get started and outsource a simple text widget to a gem.

Prerequisites

You should at least have created one widget directly in your application. No matter how simple or complex this widget is, but since you've implemented it yourself, you know what it consists of and where all the parts belong that make up a fully functional widget inside a Ruby on Rails application based on the Scrivito SDK.

In case you haven't already done so, please have a look at the guide on how to create your first widget. Once you're finished, you could use that new widget and turn it into a gem.

Creating a new widget gem

We start by choosing a name for our widget. In this guide, we will name it “scrivito_text_widget”. We would like to see widgets named consistently, so that published widget gems can be easily identified. If you plan to publish your gem, please make sure that its name starts with “scrivito_”. If you publish your gem on RubyGems, you also need to find a unique gem name, so make sure to search for the name before you start.

Having decided on a name, you can create the main gem structure:

rails plugin new scrivito_text_widget --mountable --skip-test-unit --skip-active-record

As you can see, the widget gem is actually nothing else than a Ruby on Rails engine. If you want, you can look up further details in the Ruby on Rails guides for engines. We are using the engine mechanism to put all the required files in their proper place, the place they would also occupy in your application. Once the gem is included in the Gemfile of your application, the widget files appear to be part of it.

Next, we will configure the gem and insert the widget files.

Gem configuration and widget logic

You now have a working gem, which needs to be configured. We also need to put the widget files in their proper location.

First, we adapt the gem metadata and edit the scrivito_text_widget.gemspec file. Fill in all the TODO statements, and add the Scrivito SDK as a dependency of your gem.

s.add_dependency 'scrivito'

There are also a couple of files we actually don't require in this guide but that might be needed by your specific gem. For example, the “assets”, “mailers”, “helpers”, “controllers”, “config” or “bin” folders will not be used here, but might contain logic of your own gem. So it's up to you to delete them or leave them where they are.

Next, we will add our widget files. The text widget is very simple, so we only need the basics.

Copy
# app/models/text_widget.rb
class TextWidget < Widget
  attribute :content, :html
end

Scrivito will automatically find your widget model if it is located in the app/models directory of your application and if its name ends with “Widget.” If, for some reason, this is not the case, please refer to the Scrivito model library API for making your widget model available.

We provide two views, one for rendering the widget on pages, and one for displaying its thumbnail in the widget selection dialog:

Copy
<!-- app/views/text_widget/show.html.erb -->
<%= scrivito_tag :div, widget, :content %>
Copy
<!-- app/views/text_widget/thumbnail.html.erb -->
<%= scrivito_thumbnail 'Text', :text do %>
  Creates a simple widget with content.
<% end %>

It is important to remember that your gem should include everything needed to actually use your widget.

Package and use the gem

That's it. You created a gem that holds your widget and are almost ready to fire up your application including the new and shiny text widget. Before your application can access the gem, it needs to be packaged and published on RubyGems.

To install your gem on your local machine, for testing it in an application, run this simple rake task:

bundle exec rake install

Now open your application and add the new gem to your Gemfile and run bundle.

gem 'scrivito_text_widget'

If you now start your application, you should be able to insert the new widget somewhere on a page that includes a widgetlist attribute.

Final thoughts

You've successfully created your first widget gem. Very good job! There are still a couple of things you can do to improve your widget and help others to create better applications.

  • You could add a few Test Unit or rspec tests to your gem. Start small and test your models, for example.
  • Take a closer look at your *.gemspec file and fill it out to mention the great authors or your own homepage. If you want to make the gem open source, we recommend uploading the source code to Github and give your gem a nice description in the README.rdoc file. You should also update your license to whatever you think is appropriate.
  • Create richer widgets including controllers, specific assets, and custom routes that can be mounted into the application.
  • You can create entire components and third party integrations such as a keyword density meter, a webpage speed analyzer, your own image manipulation tool, and much more.
  • ...

If you have any questions, want some help, or need feedback on your gems, just contact us or leave a comment. We're excited to see what you all come up with.

Publish the gem

Publishing your gem on RubyGems makes it visible to every developer all around the globe. So before publishing it, please consider:

  • Will it be of interest to other developers?
  • Is there another gem for the same purpose? If there is, why not use the other one?
  • What about the code quality level required for publishing on RubyGems? In case of doubt, don't hesitate to contact the Scrivito team.

If you are happy with the result and would like every Scrivito application in the world to use your new widget, feel free to publish the gem on RubyGems:

bundle exec rake release

This uploads the gem to rubygems.org and makes it available to everyone by just mentioning it in their Gemfile. Congratulations, and welcome to the Scrivito community!