Ruby FuzzyHash

I came across an interesting way to use a Hash at http://github.com/joshbuddy/fuzzyhash/tree/master.

I may look into this further for Vapor since this is basically what that RadiantCMS extension needs to do.

I've altered the sample code but it does all the explaining:

>> hash = FuzzyHash.new  
>> hash[/^\d+$/] = 'number'  
>> hash[/.*/] = 'something'  
>> hash['chunky'] = 'bacon'  
>> hash['foo'] = 'vader'

>> hash['foo'] #=> 'vader'  
>> hash['food'] #=> 'something'  
>> hash['123'] #=> 'number'

Rails Metal in RadiantCMS

Radiant edge now supports loading Rails Metal from extensions!

I'm really excited to announce that. I had been working on it before the release of 0.8.0, but hadn't had the time to hammer it out before the release. Admittedly, I push some sloppy commits into the main repo, and I should have rebased them and cleaned them up. This was the first opportunity I'd had to look around at the way Rack middlewares are loaded in Rails, so a lot of my effort was just poking around. Gregg Pollack's screencast on Rack & Metal had some helpful tips in it. Check it out if you want to try out the new features in Radiant.

This will make things like checking a login status (like we're doing with Practice Greenheath and the Header Authorize extension) much faster.

More importantly, Vapor(the extension to allow users to write their own redirect rules which also caches all the rules so its nice and speedy) will be moving to metal. I've created a separate branch for this, but I'm considering backward compatibility so that if you've got an older version of Radiant, it'll still operate the same old way (by catching the requests in the SiteController). I'll need to re-evaluate the code before it goes into the master branch, but it works!

Managing ALL of Your Content

We've been working hard to provide great features to our customers that are using Radiant and we've been pushing a lot of that work out into the community. We've still got plenty more in store for our extension development and of course a lot more to contribute to Radiant.

One of the problems any organization might face is the task of keeping track of your content. Of course, you'd look to a content management system like Radiant, but even beyond your content is the content from others. Many organizations have relationships with others and their content is often linked back and forth. As the content changes, some things may get stale and we're working on a way to keep track of that.

Your content isn't just your content. Your site depends on its environment and you'll need to react to any changes in it.

When you're writing content for your site, you shouldn't just be worried about what you've got. You also need to make sure that your target sites (or sites on which you might comment or to which you might send your visitors) are up and running too. Site Watcher is a great way to keep track of what's happening on your own site and we'll be adding more features there, but there will be more to come for tracking the rest of the world too.

I'll be posting more about this in the future as we get ready to release our upcoming projects.

Pretending to Be Different

It seems to be very common to say in many ways that you are different, but when it comes to showing it, many companies must be too afraid to actually be different.

I've seen a TV commercial for the Audi Q5 which claims that it is unmistakable. From the behavior of the actors in the ad I would guess that it's supposed to be unmistakably different, but when it comes time to show how different it is you are shown that it is... black. The other cars, you see, are beige. Never mind that they look the same in every other way.

This ad just plain confuses the point:

Are you doing this? Is your company claiming to be different but not showing your differences?

What I Learned From a Vacuum

How often does someone want to buy a vacuum? It seems like just one of those things you do and then never do again until 20 years later when your vacuum finally dies.

Dyson makes me want to buy their products. I wonder, when I see their advertisements, if I'm the only one that feels that way. Certainly not, but actually wanting a vacuum is outside the realm of what people usually desire when it comes to material things. A new car, new iPod, new camera, sure. But a vacuum?

Perhaps its the fact that I'm already a satisfied owner and bummed out that I bought one so early that I'm missing out on the new features. They certainly handle their marketing well. They describe so clearly why their product is better; then they follow-through.

A few years ago my wife and I vacuumed our house (during some construction) with a shop vac thinking it would do the best job. We followed up with our Dyson and were astounded at what the supposedly powerful shop vac had missed.

alt textI recently received an email from Dyson about their new airmuscle and it got me thinking about how I need to improve. Dyson shows the process and explains in plain words their complex technology. I'm looking at that for some inspiration. Many clients avoid decision-making because of a lack of understanding. Technology is always increasing its pace in involvement in our lives and businesses, but understanding of it isn't... at least not for all.

Whenever I speak with someone about our work and how we might help, I first try to help them understand. Because even if I win your business, if you don't walk away with a better understanding then you've lost something.

More updates for Radiant comments

I'm slowly working on improving the commenting extension for Radiant.

The simple logic spam blocking has been working fine, and I've just updated it to ensure that the answers are not revealed in the HTML. Originally I just dropped the correct answer into a hidden field, but now the correct answer is hashed so that the value in the form is something like fc7272f83a6dbcfea6a3c81d3eb10e2e rather than the actual text.

Enjoy the more secure simple CAPTCHA system!

I've also added the ability to specify the number of comments per page on the admin side with Radiant::Config['comments.per\_page'] = 100. To any contributors, I am adding some features from the wild, but please write specs for your updates!

I hope to simplify the interface for managing comments as well, but that will come in time.

UPDATE

I've also sanitized the content_html so that you're no longer vulnerable to inserted script elements.

What partnership means

I subscribe to a newsletter from Bright Yellow Jacket where they always seem to have good insight (and you can sign up for it too).

In light of Paul's recent articles (Developer As Typist and Developer as (Fashion) Designer) on what a developer is or is not, I found the latest newsletter from Bright Yellow Jacket to be apropos.

Too often, many businesses may find a designer or developer in order to dole out commands rather than explore what a relationship with that vendor may provide. I thought it would be appropriate to re-broadcast the idea:

Two weekends ago, Sean O’Hair won the Quail Hollow Championship. Paul Tesori also won. Who’s Tesori you may ask? O’Hair’s caddy. This is important. As a golfer, you want someone to carry your clubs. It makes for a more enjoyable day of links. But you need more than that. You need a professional, and better yet, one that knows the game. A professional caddy can provide a second opinion; knowledge of the course; feedback on your shot, club choice and approach that is tailored to your skill set. O’Hair’s caddy carries his clubs, he’s also an ex-PGA player, but most importantly his caddy is his partner.

These are important ideas. I don't say this because I'm in a company that provides partnership like that, I'm in a company that provides partnership like that because these are important ideas.

I really like the way the folks at Bright Yellow Jacket created the analogy. When you want a professional job, you don't just hire someone to drag your clubs around for you.

Who says Perl is dead?

Many in the Ruby world might not be aware of the development in Perl 6 but a good friend pointed out an interesting post about Cross-language library loading on Parrot.

If you're not familiar with it, Parrot is "a virtual machine designed to efficiently compile and execute bytecode for dynamic languages." It's written in C, and the 'rakudo' implementation of Perl 6 runs on Parrot.

Take a gander at the rough-around-the-edges Ruby compiler for Parrot on github.

WolframAlpha Needs Work

There's been a lot of hype around WolframAlpha so I thought I'd test it out today.

Here's what I think so far:

  1. Simple facts might be hard to get
  2. The name is a mouthful
  3. The brand is inconsistent
  4. I'm curious about the revenue

Simple facts might be hard to get

I was away from a computer when I first thought to test it, but I had my iPhone on me, so I quickly went to the new site and tapped "number of chromisomes in a chimp" and hit "Go". Oh well, I thought. I mis-spelled chromosomes (easy to do in a web form on the iPhone), but it should give me a proper spelling to click.

Wolfram|Alpha isn't sure what to do with your input.

Hmm, ok. I tried the proper spelling and full name of the animal: "number of chromosomes in a chimpanzee".

Wolfram|Alpha isn't sure what to do with your input.

Perhaps I'm using it wrong. Google got me the answer pretty quickly even though the answer didn't come from Google (but another site on the internet.) So I tried out what was supposed to be a Google-killer: Cuil (improper spelling to be fair).

No results were found for: number of chromisomes in a chimp

Proper spelling? That got me to a place to look.

According to Wolfram: "We are not a search engine. No searching is involved here". That's fine but a search engine got me my answer. It's 48 by the way.

Forbes magazine had this to say:

...Wolfram Alpha's biggest strength may also be its biggest weakness: The datasets behind its calculations are curated by hand—hundreds of them—and somebody plugged them into the system.

Uhh... really!? I guess that's a necessity for a useful and friendly tool but I was still shocked when I read that. Here's my contribution then:

Dear WolframAlpha,

A chimpanzee has 48 chromosomes.

Sincerely,

Jim

WolframAlpha is a mouthful

It doesn't roll off the tongue as much as it gets stuck coming out. That could be a really good thing if the product is really good. A name that's difficult to pronounce may increase the amount that people tend to discuss it... that gets the name around.

Aside from my search, it produces some great things which could be expected from the makers of Mathmatica. But I fear the advent of startup companies with names like DolphinFrankenfurter. Alright, that doesn't have the difficult "lfr" in the name, but it'll do for a me-too company name.

The WolframAlpha name should be more consistent

The logo seems to say WolframAlpha, but everywhere else that it is written in reads Wolfram|Alpha... What's with the pipe and it's inconsistent usage? Is it WolframAlpha, Wolfram Alpha or Wolfram|Alpha?

I'm curious about the WolframAlpha source of revenue?

Forbes magazine also points out that:

It would be more than foolish to assume Wolfram Research can monetize Wolfram Alpha in the way Google has monetized its search engine through its lucrative paid search business...

It would, wouldn't it. Because that's not the same target market. And making money on ads might mean you need to ensure that a lot more information was readily availabile. Such as the number of chromosomes in a chimp.

Wolfram Research has not said how it intends to monetize its new search engine, but a preview of it offered to Forbes hints at one approach: There's a "Featured Sponsor(s)" module hidden in the code, commented out by the developers. The copy used is dummy text, but suggests that one revenue stream for Wolfram Alpha will be from display ads.

Hmm. I already see ads appearing for featured sponsors, so perhaps that's the route they've chosen. But perhaps a better path would be to charge for it. If it's a great service that is worth money then people will likely pay to use it. It works for Lexis Nexis.

How to write a RadiantCMS extension

If you're looking for the short description that boils down the answer: start. Just start writing an extension and you'll know more after that than you do now.

Radiant is a great system for setting up a website. Many developers who contribute to the core or contribute extensions to the community might forget that there may be plenty of users of Radiant who want to do many things with it, but they just don't know how.

That is part of the reason I wrote the Help Extension. Sure, regular users need help understanding how the system works , but people who provide Radiant to their clients could make the entire community better if they could just get past the point where they begin to understand. "Help" is an apt name for the extension, but there may be a downside in that many Radiant developers may not realize that there's plenty of info in there about how to interact with Radiant through an extension.

I do my best to help new developers. I once was a new developer. Scratch that; I still am a new developer.

Start small

Many of our extensions are small in scope. That's a great way to learn and a great way to pave the path to write something more substantial. You can ask for Radiant help on the email lists. Sometimes the community may come to your aid or sometimes the help doesn't come. That may be because of timing (and everyone is busy with other things when you ask for help) or because no one else particularly cares about what you want to do.

Well how do I get help if nobody cares!? Easy. Ask a technical question. But in order to do that, you need to start.

Start building your extension and when you get an error or arrive at an impasse in your code, you'll have plenty of info to either solve the problem yourself or get help from someone else. If nobody cares about your desire to list widgets on your site, someone may be interested in solving a technical problem with you. Developers are like that.

Throw away your code

One of the things I learned in a Drawing class in college was to be willing to throw something away. So many aspiring artists hold on to every piece of work they've done. They might spend hours upon hours on their work and feel like they have reached a pinnacle when the work is done. But they should always be willing to lose the final piece. You should learn something by doing. You should be able to do it again, even if you do it differently the second (or third, or fourth) time around. The same goes for development when you are learning. The benefit of writing code is that you can put it into source control and all those ideas that you first had and threw away, are safe for you to find again.

If you allow yourself to be willing to throw your code away, you'll be helping yourself learn.

Begin again

Solve the same problem twice and you might discover something you hadn't realized the first time around. While this is not an article about the mechanics of writing extensions for Radiant it is about writing extensions and in order to do that, you must first begin.

After all that, this post isn't really about Radiant, it's about not fearing errors, and about not feeling that editing mere code is a daunting task. I want to encourage any would-be developers to be.

Look for saturnflyer in the #radiantcms IRC channel or on the mailing list. Not every experienced developer may help, but most are happy to help. Just come armed with your info: code, error messages, ideas, etc.

View, Edit and Search your RadiantCMS Database

I came across a handy plugin for Rails applications (version 2.2 or higher) that provides a simple way to view, edit and search the database. Read about it at Neeraj Singh's website.

I thought it would be a useful way to view data in radiant, so I quickly hacked together an extension to view the interface of admin_data.

Originally, the plugin was designed to look into your app/models directory and pull all the classes. But because Radiant loads classes from several locations, it was simpler to just alter this code:

model_dir = File.join(RAILS_ROOT,'app','models')
    Dir.chdir(model_dir) { models = Dir["**/*.rb"] }

to look at the database tables and assume you've followed Rails conventions and load class names according to the table names:

models = ActiveRecord::Base.connection.tables.map{|t| t.singularize.to_s }

The upside of doing that is that it will easily integrate into a system like Radiant.

In a quick test, I found that I also needed to provide a way to alter data in the database without calling validations, so I also provided just that: a button to "Save without Validation!"

At the moment, the extension documentation states that our fork is required and that may remain. The benefit of the original design is that admin_data just looks in the file system for the necessary information, and it preserves any non-standard table naming conventions defined in the models. The downside is that Radiant can't use it like that unless there is some configuration for where to load the models.

Both the extension and the plugin need more tests, but it looks to be a simple way to achieve a separate admin view of data without the need to write all the controllers and views.

I've added it to the extension registry so you can just do a script/extension install admin_data but you'll still need to install the plugin.

How to get what you want

An email from the great Campaign Montior landed in my inbox today and contained a link to a helpful article about getting information on why users have unsubscribed from your email campaign.

This is such a simple concept but it seems that so many seem to be unaware of it. I've recommended this same technique to others in regard to just about anything: if you want something, ask for it.

Many not-for-profit organizations understand this, others seem to miss it. Certainly the way that you ask will have an affect on the answers, but not asking is a great way to not get what you want.

  • Before you leave an interview ask for the job.
  • Ask someone specifically to volunteer for your event.
  • Get a great developer on your open-source project by asking.
  • Need funding for an expansion to your school/university/community center/whatever? Ask for it.

People respond to questions, and asking them with a certain approach will help you get your answer. Take a listen to some great advice for managers on how to delegate tasks (it involves asking for help).

Asking for what you need directly affects your future. By not asking, it means you're just waiting for your future to happen to you.

Radiant Comments and Spam

I've been working with the Radiant Comments extension trying to pull in the various changes from the community and just planning to clean things up in general.

Rather than dealing with an outside service for spam filtering, I'm working on the idea of a simple question to block spam. The comment form asks a simple question that a spambot might not know. It may require more work, but some users of Radiant may find things difficult enough without needing to go to Akismet or Mollom for spam filtering. Yes, I know that's a simple task, but for some just the idea of yet another thing to do gives them pause.

So with this post, here's my test of the spam_answer_tag. It's easy to use: you simply add

What color is a stop sign? < r:spam_answer_tag answer="red" />

I'll certainly be doing more work on the extension to clean things up, but I felt that it needed at least a simple CAPTCHA type of option built-in without all the downsides of generated imagery CAPTCHA.

Let me know what you think!

UPDATE: after reading Adam's comment about the number of questions I realized that you can easily provide your own list of options with Radius tags that are already a part of Radiant. Just use r:random and r:option.