This describes how to create a gem which can be used with Rails from the Yellow Pencil Wharton theme.
- The Yellow Pencil theme, available in
- Ruby 1.9.2-p290 or compatible
- Rails 3.2.3 or compatible
Let’s create a project folder called
cd into it.
mkdir conversion-project cd conversion-project
Next, create a Rails app which we’ll use to test things out.
rails new dummy
Next, create the plugin gem, which we’ll call
rails plugin new wharton-theme
This will create a directory containing the gem files in the current directory. Let’s add this gem to the test project. We’ll tell the app to look for the gem in a child of its parent directory called
wharton-themeby appending a line to the
echo -e "gem 'wharton-theme', :path => '../wharton-theme'\n" >> dummy/Gemfile
Let’s make sure everything is working by installing the gem.
cd dummy bundle install cd ..
We should now be in the
Let’s assume we have the
assets/WWWv1.0 directory stored in the shell variable
$wwwsrc. Let’s take a quick look at the contents of this directory.
This is fairly straightforward. Let’s first worry about the layout. We’ll copy it into our directory and see how it looks.
cp $wwwsrc/index.html dummy/app/views/layouts/application.html.erb
Let’s see how it looks. We’ll want a resource that we can take a look at.
cd dummy rails generate scaffold items name description:text rake db:migrate rails server
Navigate to http://localhost:3000/items. You should see links and broken images. Notice there is content text on the page. Let’s make sure we show the appropriate content there. There is a line in the layout at
dummy/app/views/layouts/application.html.erb that looks like:
We want to tell Rails that it should put the appropriate content there. We’ll replace it with the following:
<%= yield %>
Which tells Rails to put the results of evaluting the appropriate view at that position. Open a terminal to the parent
conversion-project directory and run this command which adds the
yield statement in the appropriate location.
sed -i"bak" "s#<p>content</p>#<%= yield %>#g" dummy/app/views/layouts/application.html.erb
Refresh your running browser and you should see the text below instead of “content”.
So, we have a working layout (we haven’t gemified this, but we will), and now we should fix the images, scripts, and css. Let’s take care of the css first.
If you take a look at the source, you will notice that there are links to css that look like:
<link href="css/default.css" rel="stylesheet" type="text/css" />
but the URL http://localhost:3000/css/default.css doesn’t exist! We can fix this by copying the stylesheets from
$wwwsrc into the gem into the
mkdir -p wharton-theme/vendor/assets cp -r $wwwsrc/css wharton-theme/vendor/assets/stylesheets
Note that we rename the
css directory to
stylesheets due to convention. While we’re at it, let’s create the
images directories as well. Note that we also rename these directories to match convention.
We’ll edit the
wharton-theme/lib/wharton-theme.rb file, which is typically used to require other gem files. (This is convention.) Enter the following contents:
require 'wharton-theme/version' require 'wharton-theme/engine'
Or use this command:
echo -e "require 'wharton-theme/version'\nrequire'wharton-theme/engine'\n" > wharton-theme/lib/wharton-theme.rb
wharton-theme/lib/wharton-theme/engine.rb file referenced above doesn’t exist yet! Create it with the following contents:
module WhartonTheme class Engine < ::Rails::Engine end end
Or use this command:
echo -e "module WhartonTheme\n class Engine < ::Rails::Engine\nend\nend" > wharton-theme/lib/wharton-theme/engine.rb
This empty class tells the Rails engine that it should look at the gem for asset paths. This is great, because it allows us to modularize our layout’s assets. In Rails, all of the assets are available as children of the
Navigate to http://localhost:3000/assets/default.css, which should now return some results.
Let’s fix our layout to reflect this new path. We’ll replace paths that reference the old
interface directories with absolute references to
We must restart the Rails server in order for it to detect the new asset paths. Issue the command:
Reload your browser and the site should look much better. Still, there are missing images. Notice that inline images are present, but that background-images referenced in stylesheets are not. Let’s fix that. Remember that stylesheet references are relative to the location of the file itself. If we look at
default.css, we’ll see references to images such as
../interface/*. We’ll change these to be absolute references to
sed -i"bak" -e "s#../interface#/assets#g" wharton-theme/vendor/assets/stylesheets/*.css
Refresh your browser. There’s nothing obviously missing now.
Creating a generator
The final thing to do is to package this layout as part of our gem. We’ll do this by creating a generator which we can expose to Rails developers.
Rails exposes a generator for creating generators. We’ll need to be relative to the
dummy application to use it.
cd dummy rails generate generator wharton/layout mkdir -p ../wharton-theme/lib/generators mv lib/generators/wharton ../wharton-theme/lib/generators cd ..
We should be back in the parent directory. We’ll copy the layout we created into the templates director of the generator.
cp dummy/app/views/layouts/application.html.erb wharton-theme/lib/generators/wharton/layout/templates/
Next, we’ll alter the template to prevent evaluating Ruby code.
sed -i"bak" "s#<%#<%%#g" wharton-theme/lib/generators/wharton/layout/templates/application.html.erb
Now, we need to modify the
layout_generator.rb file we generated to copy this file into applications. It should have these contents:
module Wharton class LayoutGenerator < Rails::Generators::Base source_root File.expand_path("../templates", __FILE__) desc "This generator generates layout file with navigation." def generate_layout template "application.html.erb", "app/views/layouts/application.html.erb" end end end
Alternatively, use this command:
echo -e 'module Wharton\nclass LayoutGenerator < Rails::Generators::Base\n source_root File.expand_path("../templates", __FILE__)\n\n desc "This generator generates layout file with navigation."\n def generate_layout\n template "application.html.erb", "app/views/layouts/application.html.erb"\n end\nend\nend\n\n' > wharton-theme/lib/generators/wharton/layout/layout_generator.rb
Let’s test the generator.
cd dummy rails generate wharton:layout
You should get a message that the layout is identical. Now, commit your work to share it.
git add . git commit -m "A meaningful message please" git tag -a "v0.1.0" -m "first version" git push origin master && git push --tags
Let’s assume the remote url is: email@example.com:wharton/wharton-theme.git. One can use this gem by adding the following to their
gem 'wharton-theme', :git => 'firstname.lastname@example.org:wharton/wharton-theme.git', :tag => 'v0.1.0'