Dynamic placeholder images in Paperclip
Tonight I was integrating Thoughtbot’s Paperclip plugin as I have done many times before. Only this time I realized what a pain it really is to deal with missing images. Paperclip does a pretty good job at this by looking for a “default_url” which you can set in your model. This is good, until you’re more than a few models in. Then I found this solution. Now we’re getting somewhere. But I still thought, why can’t this be completely dynamic? Well it can, and pretty easily I might add.
First go get mdarby’s placeholder on the github. This gem makes use of placehold.it‘s super easy api for creating, you guessed it, placeholder images. It’s actually quite useful.
Next we have to monkey patch paperclip. Create an initializer file called paperclip.rb and drop in the following.
def url(style_name = default_style, use_timestamp = @use_timestamp)
url = original_filename.nil? ? get_placeholder(style_name) : interpolate(@url, style_name)
use_timestamp && updated_at ? [url, updated_at].compact.join(url.include?("?") ? "&" : "?") : url
end
def get_placeholder(style_name)
Placeholder.new(styles[style_name].geometry, :text => "Placeholder").url
end
end
Basically we’re just overriding this method to generate a placehold.it url when the attachment is not present. One downside to this method is that it overrides is globally. You will no longer be able to set the “default_url” in your model. But hey that’s the whole point of this anyway right? Right. I plan to fork paperclip and try to get this in as an actual option, but we’ll see how long that takes. Anyway, enjoy!
Tabbed Interface – A new rails plugin
It’s not like we really need a new rails plugin, but this one I really saw the need for. Tabbed interfaces can really improve how your website looks and flows. Here’s a great article from smashingmagazine about how, when and why to use tabbed interfaces. Here’s a quick rundown of the plugin. Let me know what you think!
TabbedInterface
Build a tabbed interface very easily. Requires Prototype.
see a working example at http://tab-interface.heroku.com
Install
./script/plugin install git://github.com/jondruse/tabbed_interface.git
Move the ajax-loader.gif from the resources folder to your public images folder, or go make one at http://www.ajaxload.info/. Whatever you do, just make sure you call it ajax-loader.gif.
An example css file is also included in the resources folder.
Example
In this simple example we setup a TabbedInterface with two tabs.
# You don't have to include these. They are the defaults, but this is how you would change them.
<% box.content_wrapper = "tabbed_content" %>
<% box.navigation_wrapper = "tabbed_navigation" %>
<% box.tab_tag = :li %>
<% box.tabs_tag = :ul %>
# Let's add some tabs!
# All you need is a title and a url. Also accepts two options hashes that get passed directly to the link_to_remote
call.
<% box.tab("Test One", test_one_path, {:method => :post}, {:class => "different-class"}) %>
<% box.tab("Test Two", test_two_path) %>
<% box.content = capture do %>
# Put your default content here (probably the content for the the first tab, but doesn't have to be)
Default text
<% end %>
<% end %>
The tabbed_content helper yields an object that has two main methods.
#tab
This method will setup a new tab header. Just pass the title and the url to call and update the main content area.
#content
The only requirement is that you use capture (as shown above). This sets the default content for the interface. Then when you click on a different tab, the content will be updated. You can put anything in here, but it will probably be a partial, being that the links use link_to_remote to update the main content area. There are no limitations on how any tabs you can have, or how many interfaces you can have on a page.
Enjoy!
Pesky form error markup in Rails
Have you ever spent hours coding up the most awesome form you’ve ever seen only to have Rails break it with it’s error markup? I have, and it really sucks. So today I set out on a mission to solve this ever annoying problem. Here’s how I did it.
Step 1. Find the source.
If you’ve ever gone looking through Rails source, you know this wasn’t a very easy thing to do. But after some digging I found what was causing me so much grief.
@@field_error_proc = Proc.new{ |html_tag, instance| "<div class=\"fieldWithErrors\">#{html_tag}</div>" }
Step 2. Figure out what you want.
I found that the problem was that it was using a div to wrap the incorrect fields. This didn’t work for me. I needed a span so it wouldn’t break the layout. So what do you need? Maybe a div works, but you want to use a different class name? Whatever it is, figure it out. Firebug may be of some help to you.
Step 3. Patch Rails.
I love how easy this step is. Put a file in RAILS_ROOT/config/initializers called rails_ext.rb. You can really name this file whatever you want, but that’s what mine is called.
Next add these lines.
class Base
@@field_error_proc = Proc.new{ |html_tag, instance| "<span class=\"fieldWithErrors\">#{html_tag}</span>" }
cattr_accessor :field_error_proc
end
end
Now restart your server and enjoy.
Closing Thoughts.
Now I know what you’re thinking. Why don’t I just edit the css? Well here it is. My markup is a big deal. If I want a span I should have a span. I guess it really comes down to preference. Take it or leave it.
Leveraging the power of inheritance in Rails.
Here’s a neat trick. It’s pretty simple but really helpful.
Problem: You’re always setting up the same stuff in every controller. Layouts, helper methods and so on.
Solution: Set up your own controller to inherit from.
Throw this into a new file in the controllers folder called base_controller.rb.
layout "base"
helper :my_cool_helper
end
Now take any controller and change the first line like below. Now anything in BaseController you get for free. So in the example below, PostsController’s layout will be “base” and will have the MyCoolHelper included also.
def list
end
end
Wow, that was easy. Now it’s much easier to make (and change) default behaviors in your app. Hope this helps you, it sure helped me.