Posts Tagged ‘gems’

Release 0.8.2

Sunday, November 30th, 2008

Hey there folks, sorry for the long wait for this release, but it’s here. It’s been a long November for yours truly. I’ve had to find a new job. I’ve had pneumonia. We, at least in America, have celebrated Thanksgiving. And, of course, who can forget RubyConf 2008?

So with that said, what’s in 0.8.2? Honestly, not a whole lot. There are a couple of bug fixes, a button_to_remote (think submit_to_remote in Rails) helper, and deferred routes. More on deferred routes in a moment, as it’s actually a pretty cool feature that only Mack and Merb share. And finally there is bundled gems.

Bundled Gems

What do I mean I say ‘bundled gems’? Well, because of the rather large number of gems that get installed with Mack, and because of some gem version dependency issues, Mack is now bundling it’s third party dependency gems inside itself. For example, mack-facets used to rely on the gems ‘facets’ and ‘english’. Those gems are now bundled inside the mack-facets gem and now longer need to be downloaded and installed by end users. This should make installing Mack super easy. It should also make dealing with having multiple versions of Mack installed on your system easier to deal with and maintain.

Deferred? Routes

So what are deferred routes? Ezra wrote a really great write up back in April. The idea is simple, with newer web servers such as Thin and Ebb, you can tell them to spawn a new thread to handle particular requests, such as long running processes like file uploads. This can really help speed things up as server can process regular requests using an event machine model, which is very fast, but can be really slow and block the server for longer processes. Now those processes can spawn into their own threads and not block the server.

In Mack 0.8.2 you can mark your routes with a deferred? => true option which will trigger this behavior. It’s much more advanced than the similar feature that can be found in Merb, which requires a separate configuration for your deferred actions, and the urls have to be ‘hard coded’. Mack let’s you use all the dynamic power of your routes, like you would want to. It’s just another option on the route itself. For a great tutorial on using deferred routes, check out the following page on www.mackery.com:

http://www.mackery.com/routing/deferred_routes

Upgraded Dependencies

A few gems have been upgraded as part of this release, the big ones include DataMapper to 0.9.7, ActiveRecord to 2.2.2, and Haml to 2.0.4.

Changelog:

  • [#237] Fixed render :rjs throws errors
  • [#236] Upgraded to ActiveRecord 2.2.2
  • [#235] Upgraded to DataMapper 0.9.7
  • [#230] Upgraded to facets 2.4.5
  • [#229] Upgraded to english 0.3.1
  • [#227] Removed WEBrick logging
  • [#226] Bundled gems.
  • [#225] Removed dependency on Thin
  • [#223] Fixed mackery console fails
  • [#148] Added button_to_remote helper method.
  • [#16] Added deferred? routes.
  • gem: active_record 2.2.2
  • gem: data_mapper 0.9.7
  • gem: addressable 2.0.0
  • gem: facets 2.4.5
  • gem: english 0.3.1
  • gem: rspec 1.1.11
  • gem: haml 2.0.4

Ruby Opals

Monday, June 23rd, 2008

At RubyConf a bunch of us sat around a few glasses of beer and had a ‘bitch’ session about the state of Ruby Gems, a system we all consider be rather sub-par. At that session Tracy Flynn, friend and colleague of yours truly, said we should do something about it. He suggested we write RubyOpals. Well, Tracy is putting his money where his mouth is, http://github.com/tflynn/rubyopals/tree/master. I can tell you that I for one, can’t wait for Ruby Opals! I’ve already forked the project and started contributing! As soon as the first version is ready for release, I can tell you that Mack, Cachetastic, Genosaurus, etc… will all be the first available as opals.

I highly encourage all of you out there to add this project to your ‘watch’ list on GitHub. And if you have the time, and want to help write something special, I highly encourage you to fork it and start contributing! Time to get out there and start making the Ruby world a much, much, much better place.

Preview (0.5.5): Adding PDF::Writer Plugin Support Tutorial

Tuesday, May 20th, 2008

Ok, let’s take the new rendering system out for a spin, shall we? Let’s add the PDF::Writer library to our Obligatory Blog Demo application. If you haven’t followed this demo you should do that now.

Let’s start by requiring the gem in our system. Open up your gems.rb file found in config/initializers and let’s add the gem:

require_gems do |gem|
  gem.add "pdf-writer", :version => "1.1.8", :libs => "pdf/writer"
end

Great! We’ve told Mack we want to use the ‘pdf-writer’ gem, version ‘1.1.8′, and we want to automatically require the file ‘pdf/writer’. Now, let’s install the gem:

$ sudo rake gems:install

See how easy this is? We’ve installed the gem, required the libraries, now we’re ready to write our plugin.

$ rake generate:plugin name=render_pdf

That should generate a few files/folders in our vendor/plugins directory. Let’s open up vendor/plugins/render_pdf/lib/render_pdf.rb and let’s start coding.

What we want to do is create a new Mack::Rendering::Engine::Base class so that when we call render(:action) it will have a new engine to render the view file as a PDF.

We’ll examine each section in a minute, but for now, let’s type this into our render_pdf.rb file:

module Mack
  module Rendering
    module Engine
      class Pdf < Mack::Rendering::Engine::Base

        def render(io, binding)
          @_pdf = ::PDF::Writer.new
          self.view_template.instance_variable_set("@_pdf", @_pdf)
          eval(io, binding)
          @_pdf.render
        end

        def extension
          :pdfw
        end

        module ViewHelpers
          def pdf
            @_pdf
          end
        end

      end
    end
  end
end
Mack::Rendering::ViewTemplate.send(:include, Mack::Rendering::Engine::Pdf::ViewHelpers)
Mack::Rendering::Engine::Registry.register(:action, :pdf)

Ok, so on line #4 we extended Mack::Rendering::Engine::Base. This will give us access to a view methods, and will allow us to write to a very simple API. The only method you are absolutely required to implement is the render method. As we can see on line #6, we did just that.

First thing we do in the render method is instantiate a new PDF::Writer class and assign it to an instance variable. We then set that instance variable into the Mack::Rendering::ViewTemplate object we have. We do that because the way the PDF::Writer object works you need to constantly reference the instance of the writer to do your work. Example:

@_pdf.text "Hello World", :font_size => 24, :justification => :center

On line #9 we eval the io and the binding we’ve been given. The io will be contents of the view file we have disk, as a String, and the binding will be that of the Mack::Rendering::ViewTemplate object we’ve been given.

In the extension method we tell the system that are files are going to be found with the extension, pdfw. Another example of this would be the Erubis engine which declares its extension as erb.

The Mack::Rendering::Engine::Pdf::ViewHelpers module we’ve declared on line #17 is there to hide the @_pdf instance variable with a nicer pdf method. On line #27 we include this module into Mack::Rendering::ViewTemplate so it has access to it.

Finally, and most importantly, we need to register the new engine we’ve built with the system. We do that on line #28 with this bit of code:

Mack::Rendering::Engine::Registry.register(:action, :pdf)

That’s saying whenever someone calls render(:action), consider me as an engine to render that. The way the selection of which engine to use is done, is very simple. First come first serve. The engines are in an array, and the first one to have a file with its extension on disk wins. Plain and simple.

Now, let’s see all this in action. Let’s add PDF support for our ’show’ page.

Open up views/posts/show.html.erb and add the following line:

<%= link_to("pdf", posts_show_url(:id => @post, :format => :pdf)) %>

That will give us a link that looks like ‘/posts/:id.pdf’. This will, of course, go to our PostsController and the show action. This method does not need to be altered. That’s right, you heard me. It does not need to change. Mack will handle the appropriate content-type headers for you. Just another great feature in 0.5.5.

Create a file called views/posts/show.pdf.pdfw. I know this might look a little weird, what with ‘pdf.pdfw’, but here’s the reason why. That’s break the file name down into its three parts. ’show’ is the name of the action. ‘pdf’ is the format of the request, think also html, xml, etc… ‘pdfw’ is the engine we want to use. If we hated ourselves we could do this all in erb with a file called show.pdf.erb, but why would we want to do that?

Anyway, let’s dump this nice block of code into our show.pdf.pdfw file:

pdf.select_font "Times-Roman"
pdf.fill_color(Color::RGB::Red)
pdf.text @post.title, :font_size => 24, :justification => :center
pdf.fill_color(Color::RGB::Black)
pdf.text "by #{@post.email}", :font_size => 12, :justification => :center
pdf.with_options(:font_size => 10, :justification => :left) do |p|
  p.text "\n\n"
  p.text @post.body
  p.text "\n\n"
  p.text "Created at: #{@post.created_at}"
  p.text "Updated at: #{@post.updated_at}"
end

Since this is not a tutorial on this particular gem, I’m not going to go into what all that does. Instead, let’s just have a look at it in action.

Fire up your server:

$ rake server

And go to: http://localhost:3000. If you don’t already have a post created, create one. Now click on the show link. You should have a link on your page that says ‘pdf’ click on that link. Voila! You should be seeing a wonderfully formatted PDF right now!

Congrats! You’ve built a plugin and a new rendering engine for Mack. Now, go crazy!

The source for all this can be found at: http://github.com/markbates/mack_blog_demo/tree/master

Release 0.4.2

Wednesday, April 2nd, 2008

Another week, another release, eh? That seems to be the M.O. and today doesn’t seem to be any difference. This week’s release has a few new cool things in it, but overall isn’t the sexiest of releases, but definitely one I would highly recommend downloading.

Initializers

First up, the config/initializers directory. Any .rb files you put in this directory will be loaded up as part of the initialization process

Current Mack initialization load order:

  1. Configuration files.
  2. Logging.
  3. Orm Support, if any.
  4. Mack libraries.
  5. Routes.
  6. Initializers.
  7. Gems.
  8. Plugins.
  9. ‘app’ files.
  10. ‘lib’ files.
  11. Helpers.

In a future release you’ll be able to re-order this list as part of step #1, but that’s a bit of a ways off for right now. Let’s focus on what you can do right now.

Gems

When you create a new Mack app you will find a file called gems.rb in config/initializers. There you can ‘require’ gems into your application.

Example:

require_gems do |gem|
  gem.add :redgreen, :version => "1.2.2", :libs => :redgreen
  gem.add :termios
  gem.add :rubyzip, :source => "http://gems.rubyforge.org"
end

When the application gets loaded up it will call the ‘gem’ method for each of the gems defined, and with specific versions, if defined. If the optional arrary ‘libs’ is present it will ‘require’ each of those files after the ‘gem’ method has been called.

There are also two rake tasks that help with gems:

  • gems:list – This lists all the gems required by the app.
  • gems:install – This will install all the gems required by the app. If a version is specified the task will attempt to install that specific version. If a source is specified then the source will be used to install the gem.

Filters

In previous versions of Mack if you had a controller inherit from another controller and you had filters defined in the parent’s controller they would not get run on the child controller. This has now been fixed.

Example:

class TopController < Mack::Controller::Base
  before_filter :log
  protected
  def log
    # do some logging here...
  end
end
class BottomController < TopController
end

The ‘log’ filter method will now be called on actions in the BottomController class.

Changelog:

  • Added config/initializers directory. All files in this directory will be required at start up time.
  • Gems can now be required simply using the initializers/gems.rb file and the require_gems method.
  • Added gems:list and gems:install rake tasks. The gems:list task will list any gems being required for the application. The gems:install task will install all the gems being required for the application.
  • Filters in controllers can now be inherited from parent controller classes.
  • gem: mack_ruby_core_extensions 0.1.5
  • gem: thing 0.7.1
$ sudo gem install mack

Philosphy of releases

Friday, February 29th, 2008

If you haven’t noticed by now, I tend to release smaller releases more often. I know there isn’t much precedent for that as Mack has only been out a week, and there’s only been three releases, but I can assure you, it’s a sign of things to come.

I feel that at this stage in a code’s life cycle, it benefits from getting out into the wild sooner, rather then later. Sure, I could bulk up features and bug fixes and do big ‘wow’ factor releases, but why should I sit on a cool feature or an important bug fix simply so I can have a bit of ‘wow’? Why not let people start to enjoy those new features, and give me important feedback earlier?

I’m sure as the code tree grows and people start really using Mack, things may slow down a bit. When there are more developers then just myself, things will definitely slow down a pace, but until then, I just don’t see the point in holding back.

When I have something cool and ready to go, I’m going to release it. You don’t have to upgrade your Mack environment if you don’t want to, you can if you want. If you would prefer to ‘bulk’ them up yourself, then that’s entirely up to you. Like I’ve said before, Mack is trying to be as non-opinionated as it can be. That includes how you update your system.

Anyway, I just thought I would share a bit of how things will be handled going forward. I hope that’s fine with you.

Have a good weekend.