Hobo Recipe Ideas

Posted over 7 years back at The Hobo Blog

I’m thinking more and more that a great way to document Hobo is with a collection of “Hobo Recipes”. So I’ve created a wiki page where we can capture ideas for recipes. There’s only two there at the moment but I’m sure it will grow fast.

Hobo Recipe Ideas

Posted over 7 years back at The Hobo Blog

I’m thinking more and more that a great way to document Hobo is with a collection of “Hobo Recipes”. So I’ve created a wiki page where we can capture ideas for recipes. There’s only two there at the moment but I’m sure it will grow fast.

Episode 27: Cross Site Scripting

Posted over 7 years back at Railscasts

Another common security issue is cross site scripting. In this episode you will see why it is so important to escape any HTML a user may submit.

Focussing on documentation

Posted over 7 years back at The Hobo Blog

The forums are getting really busy, which is a great sign that Hobo is starting to gain some mind-share. It’s so busy that it’s getting harder for me to keep up. If you look at a few posts, it quickly becomes clear that the main issue is lack of documentation. There’s an obvious conclusion here - writing docs is a better way for me to help you all than answering lots of individual questions.

Up until now I’ve had a kind of “no unanswered questions” attitude to the forum, but I don’t think it’s sensible to carry on like that. I’ve set aside a chunk of time each day to keep the Hobo community ticking along, and for now I’m going to try and focus a bit more on documentation and a bit less on the forums.

I’ll still follow the forums closely of course, and reply to the more challenging questions and bug reports, so you’ll still see lots of posts from me. Those of you that have dived into the source and learnt Hobo the hard way – it would be great if you could help out in the forums with some of the more basic questions.

Focussing on documentation

Posted over 7 years back at The Hobo Blog

The forums are getting really busy, which is a great sign that Hobo is starting to gain some mind-share. It’s so busy that it’s getting harder for me to keep up. If you look at a few posts, it quickly becomes clear that the main issue is lack of documentation. There’s an obvious conclusion here - writing docs is a better way for me to help you all than answering lots of individual questions.

Up until now I’ve had a kind of “no unanswered questions” attitude to the forum, but I don’t think it’s sensible to carry on like that. I’ve set aside a chunk of time each day to keep the Hobo community ticking along, and for now I’m going to try and focus a bit more on documentation and a bit less on the forums.

I’ll still follow the forums closely of course, and reply to the more challenging questions and bug reports, so you’ll still see lots of posts from me. Those of you that have dived into the source and learnt Hobo the hard way – it would be great if you could help out in the forums with some of the more basic questions.

CSS: CSS Browser Selector

Posted over 7 years back at Revolution On Rails


Each browser has its quirks. Having a clear way of organizing the work arounds
for those quirks is a challenge. Using CSS selectors is not a new idea, but I thought it might be helpful to others to give an example of the technique and how we've been able to successfully deploy it for revolutionhealth.com.



First, for IE (the browser that usually requires a hack), we can rely on conditional comments. This is good because it means we don't need to depend on Javascript. For other browsers we'll have to rely on a document.write solution. For Safari, Opera, and Firefox, we rely on the script from http://rafael.adm.br/css_browser_selector/ and for IE, conditional comments.


Here's what we include at the top of our document. (The browser_detect_start partial.)



<!--[if lt IE 7.]>
<div class='ie ie6'>
<![endif]-->
<!--[if IE 7]>
<div class='ie ie7'>
<![endif]-->
<script type="text/javascript">//<![CDATA[
var d = browserCSSDetection();
if( d.browser != "ie" ){ document.write( "<div class='" + d.browser + " " + d.os + "'>" ); }
//]]></script>

And here's what we do for the end of the document. (The browser_detect_end partial.)

<!--[if IE ]>
</div>
<![endif]-->
<script type="text/javascript">//<![CDATA[
var d = browserCSSDetection();
if( d.browser != "ie" ){ document.write( "</div>" ); }
//]]></script>


The browser detection in Javascript. This could be enhanced further, but for us this allowed us to get the site working relatively easy in Konqueror. As well it enabled us to fix our menu's so that they float over flash in Linux using this techinque.



function browserCSSDetection()
{
// see: http://rafael.adm.br/css_browser_selector/
var ua = navigator.userAgent.toLowerCase();
var is = function(t){ return ua.indexOf(t) != -1; };
var b = (!(/opera|webtv/i.test(ua))&&/msie (\d)/.test(ua)) ?
('ie ie'+RegExp.$1) :
is('gecko/') ? 'gecko' :
is('opera/9') ? 'opera opera9' :
/opera (\d)/.test(ua) ? 'opera opera'+RegExp.$1 :
is('konqueror')?'konqueror' :
is('applewebkit/') ? 'webkit safari':
is('mozilla/')?'gecko':'';
// see: http://www.mozilla.org/docs/web-developer/sniffer/browser_type.html
var os = (is('x11')||is('linux'))?' linux':is('mac')?' mac':is('win')?' win':'';
var css = {browser:b,os:os};
return css;
}


Finally, to make all this fit nicely into a layout:

<head>
<%= javascript_include_tag 'browser_detect' %>
</head>
<body>
<%= render :partial => "browser_detect_start" %>
<%= @content_for_layout %>
<%= render :partial => "browser_detect_end" %>
</body>


Update:
Here's a simple example of what this enables. The advantage of this over a conditionally included file is it keeps everything about the login box isolated to one place. You don't need to worry about openning up a separate file to make your IE fixes. We do use iefix specific CSS for our site, but only for very large features like menus



#login {
padding:0px;
}
.ie6 #login {
padding: 2px;
}

CSS: CSS Browser Selector

Posted over 7 years back at Revolution On Rails


Each browser has its quirks. Having a clear way of organizing the work arounds
for those quirks is a challenge. Using CSS selectors is not a new idea, but I thought it might be helpful to others to give an example of the technique and how we've been able to successfully deploy it for revolutionhealth.com.



First, for IE (the browser that usually requires a hack), we can rely on conditional comments. This is good because it means we don't need to depend on Javascript. For other browsers we'll have to rely on a document.write solution. For Safari, Opera, and Firefox, we rely on the script from http://rafael.adm.br/css_browser_selector/ and for IE, conditional comments.


Here's what we include at the top of our document. (The browser_detect_start partial.)



<!--[if lt IE 7.]>
<div class='ie ie6'>
<![endif]-->
<!--[if IE 7]>
<div class='ie ie7'>
<![endif]-->
<script type="text/javascript">//<![CDATA[
var d = browserCSSDetection();
if( d.browser != "ie" ){ document.write( "<div class='" + d.browser + " " + d.os + "'>" ); }
//]]></script>

And here's what we do for the end of the document. (The browser_detect_end partial.)

<!--[if IE ]>
</div>
<![endif]-->
<script type="text/javascript">//<![CDATA[
var d = browserCSSDetection();
if( d.browser != "ie" ){ document.write( "</div>" ); }
//]]></script>


The browser detection in Javascript. This could be enhanced further, but for us this allowed us to get the site working relatively easy in Konqueror. As well it enabled us to fix our menu's so that they float over flash in Linux using this techinque.



function browserCSSDetection()
{
// see: http://rafael.adm.br/css_browser_selector/
var ua = navigator.userAgent.toLowerCase();
var is = function(t){ return ua.indexOf(t) != -1; };
var b = (!(/opera|webtv/i.test(ua))&&/msie (\d)/.test(ua)) ?
('ie ie'+RegExp.$1) :
is('gecko/') ? 'gecko' :
is('opera/9') ? 'opera opera9' :
/opera (\d)/.test(ua) ? 'opera opera'+RegExp.$1 :
is('konqueror')?'konqueror' :
is('applewebkit/') ? 'webkit safari':
is('mozilla/')?'gecko':'';
// see: http://www.mozilla.org/docs/web-developer/sniffer/browser_type.html
var os = (is('x11')||is('linux'))?' linux':is('mac')?' mac':is('win')?' win':'';
var css = {browser:b,os:os};
return css;
}


Finally, to make all this fit nicely into a layout:

<head>
<%= javascript_include_tag 'browser_detect' %>
</head>
<body>
<%= render :partial => "browser_detect_start" %>
<%= @content_for_layout %>
<%= render :partial => "browser_detect_end" %>
</body>


Update:
Here's a simple example of what this enables. The advantage of this over a conditionally included file is it keeps everything about the login box isolated to one place. You don't need to worry about openning up a separate file to make your IE fixes. We do use iefix specific CSS for our site, but only for very large features like menus



#login {
padding:0px;
}
.ie6 #login {
padding: 2px;
}

Plugems - Why views in plugems?

Posted over 7 years back at Revolution On Rails


When we started to develop Plugems we had multiple applications that all shared a similar look and feel. One concept that emerged recently for me was that layouts can act like objects. In our suite of applications, we have a base layout that each application can derive from to satisfy it's unique set of presentation requirements. For example our UI plugem has the following:



ui/views/layouts/default.rhtml

Using a little magic from fora.pragprog we can extend our default layout writing the following:

<% inside_layout 'default' do -%>
<%= @content_for_layout %>
<% end -%>



As well as with layouts, there are also smaller blocks of UI that make up a page that can be shared. I've always thought of these as widgets, which in many cases can be defined as a set of partials and helpers. An application may place a widget on a view, feeding it the data needed to bring it to life. This is different from components because there is no controller logic. Really the presentation side of a widget can be expressed by a set of partials, Javascript, CSS and a healthy dose of ruby [e.g. helpers]. In this way partials are the basic building block on which many UI components can be built. By themselves they are incomplete, but within the context of an application they are alive...




Plugems enables you to share common UI widgets across multiple applications. Common assets (css, js, images) can live in a plugem, but be shared across applications at deployment time. I hope to post more in depth on this topic in near future.

Plugems - Why views in plugems?

Posted over 7 years back at Revolution On Rails


When we started to develop Plugems we had multiple applications that all shared a similar look and feel. One concept that emerged recently for me was that layouts can act like objects. In our suite of applications, we have a base layout that each application can derive from to satisfy it's unique set of presentation requirements. For example our UI plugem has the following:



ui/views/layouts/default.rhtml

Using a little magic from fora.pragprog we can extend our default layout writing the following:

<% inside_layout 'default' do -%>
<%= @content_for_layout %>
<% end -%>



As well as with layouts, there are also smaller blocks of UI that make up a page that can be shared. I've always thought of these as widgets, which in many cases can be defined as a set of partials and helpers. An application may place a widget on a view, feeding it the data needed to bring it to life. This is different from components because there is no controller logic. Really the presentation side of a widget can be expressed by a set of partials, Javascript, CSS and a healthy dose of ruby [e.g. helpers]. In this way partials are the basic building block on which many UI components can be built. By themselves they are incomplete, but within the context of an application they are alive...




Plugems enables you to share common UI widgets across multiple applications. Common assets (css, js, images) can live in a plugem, but be shared across applications at deployment time. I hope to post more in depth on this topic in near future.

Episode 26: Hackers Love Mass Assignment

Posted over 7 years back at Railscasts

Your site may be at risk! When using mass assignment, you are giving the user complete control over that model and its associations. See how a hacker might use this vulnerability and learn how to stop it in this episode.

Plugems, Welcome!

Posted over 7 years back at Rails Engines News

Revolution on Rails have finally released their solution to shared dependencies between Rails applications, which they have called Plugems (see what they’ve done there?). In their announcement they discuss some of the differences between plugins, “engines” (ahem!) and Plugems, and I think they’ve raised some interesting points.

Continue Reading…

Breaking change, and the ups and downs of FileMerge

Posted over 7 years back at The Hobo Blog

I forgot to mention – there’s a small breaking change in 0.5.3, object_table@skip_fields has been renamed to just skip (that’s the skip_fields attribute of <object_table> using a syntax that just popped into my head). The reason being that you can now use that attribute to skip both fields and associations.

I blame FileMerge - it neglected to remind me about the change. If you’re a Mac user and you’ve not discovered FileMerge (I didn’t know about it for a good while), you’re missing out. Once you’ve installed Xcode you’ll find it in /Developer/Applications/Utilities. It’s a diff/merge tool for both files and whole directory trees and, in a very Mac-like way, it just works. It’s got the most readable display of any such tool I’ve used.

You can also launch it from the command line, where it goes by the name (somewhat strangely) of opendiff.

So I just do something like

opendiff rel_0.5.2 rel_0.5.3

And document all the changes I see in the changelog.

So why was I not reminded of that breaking change? Well, one of the “just work” features of FileMerge is that it automatically ignores .svn directories – very nice. A quick look in preferences shows that there’s a pre-configured list of filename patterns the tool will ignore. And alas, in that list is “tags” (I believe that’s a ctags thing). Sometimes “just works” just doesn’t :-(.

I’ve removed ‘tags’ from that list now of course, but I’ve probably missed changes within Hobo’s tags directory in several chapters of the changelog. I should go back and fix that I guess. Hmm… :-)

And finally, absolutely free of charge, here’s a groovy FileMerge link for you :-)

Breaking change, and the ups and downs of FileMerge

Posted over 7 years back at The Hobo Blog

I forgot to mention – there’s a small breaking change in 0.5.3, object_table@skip_fields has been renamed to just skip (that’s the skip_fields attribute of <object_table> using a syntax that just popped into my head). The reason being that you can now use that attribute to skip both fields and associations.

I blame FileMerge - it neglected to remind me about the change. If you’re a Mac user and you’ve not discovered FileMerge (I didn’t know about it for a good while), you’re missing out. Once you’ve installed Xcode you’ll find it in /Developer/Applications/Utilities. It’s a diff/merge tool for both files and whole directory trees and, in a very Mac-like way, it just works. It’s got the most readable display of any such tool I’ve used.

You can also launch it from the command line, where it goes by the name (somewhat strangely) of opendiff.

So I just do something like

opendiff rel_0.5.2 rel_0.5.3

And document all the changes I see in the changelog.

So why was I not reminded of that breaking change? Well, one of the “just work” features of FileMerge is that it automatically ignores .svn directories – very nice. A quick look in preferences shows that there’s a pre-configured list of filename patterns the tool will ignore. And alas, in that list is “tags” (I believe that’s a ctags thing). Sometimes “just works” just doesn’t :-(.

I’ve removed ‘tags’ from that list now of course, but I’ve probably missed changes within Hobo’s tags directory in several chapters of the changelog. I should go back and fix that I guess. Hmm… :-)

And finally, absolutely free of charge, here’s a groovy FileMerge link for you :-)

Hobo 0.5.3 - dev mode gets a big speed boost

Posted over 7 years back at The Hobo Blog

A quick release this time – not too many changes. The reason is, I wanted to quickly get a couple of important changes to you.

The first is a fix to a trivial but annoying bug that sneaked into 0.5.2. The <show> tag was playing up so that certain “magic-updates” after in-place-edits were not working, and worse, belongs_to and has_many associations were not displayed at all by <show>. People were hitting this as soon as they tried the screencast for themselves. Not good.

The second thing is more fun. Development mode just got a whole lot faster. Like Rails, in development mode DRYML reloads every taglib on every request. Because of dependencies, we even reload taglibs that haven’t changed. Avoiding these reloads is actually pretty hard, but we’ve at least made the reload much faster by caching the generated ERB source.

This improvement was implemented by James – the new guy at HoboTech, so many thanks to James.

There’s a couple of smaller changes too, including stuff that you kind folk have reported in the forums. Check the changelog for details.

* Change Log * hobo-0.5.3.gem

Hobo 0.5.3 - dev mode gets a big speed boost

Posted over 7 years back at The Hobo Blog

A quick release this time – not too many changes. The reason is, I wanted to quickly get a couple of important changes to you.

The first is a fix to a trivial but annoying bug that sneaked into 0.5.2. The <show> tag was playing up so that certain “magic-updates” after in-place-edits were not working, and worse, belongs_to and has_many associations were not displayed at all by <show>. People were hitting this as soon as they tried the screencast for themselves. Not good.

The second thing is more fun. Development mode just got a whole lot faster. Like Rails, in development mode DRYML reloads every taglib on every request. Because of dependencies, we even reload taglibs that haven’t changed. Avoiding these reloads is actually pretty hard, but we’ve at least made the reload much faster by caching the generated ERB source.

This improvement was implemented by James – the new guy at HoboTech, so many thanks to James.

There’s a couple of smaller changes too, including stuff that you kind folk have reported in the forums. Check the changelog for details.

* Change Log * hobo-0.5.3.gem