jose.costa

Dumb script to reassemble HTML + SSI pages

Posted by jose.costa
on January 31, 2009

While working on our website(WyeWorks website), we wanted to serve some dynamic content but it just didn't justify having some "big" dynamic technology behind to achieve this. Also as programmers, we like our code (even our static website content) to be nicely separated so we can keep things in order, better maintenance, blah blah blah. Seriously, we really like those things :)

So that's when we came across the Apache Server Side Includes (Apache SSI) (a much more interesting topic than the addressed here). So, then we divided our static pages to separate the header, menu, content, footer, and we placed a bunch of page includes.

One drawback: checking the content and styles as a whole is now a little bit difficult if you don't have your Apache SSI capable on handy to reassemble all back together. So this tiny dumb script library (plus some bunch of code not shown here) did that for us.

require 'fileutils'

module SSI

  def self.generate(source, dest)
    file = File.new(source)
    lines = file.readlines
    file.close
    lines.each do |line|
      if line =~ //
        path_to_included_file = $2
        unless path_to_included_file[0..0] == "/"
          path_to_included_file = File.join(File.dirname(source),path_to_included_file)
        end
        partial = File.new(path_to_included_file)
        lines_to_include = partial.readlines
        partial.close
        line.gsub!(//, lines_to_include.join(""))
      end
    end
    if File.directory?(dest)
      dest = File.join(dest, File.basename(source))
    end
    file = File.new(dest, "w")
    lines.each do |line|
      file.write(line)
    end
    file.close
  end
    
end

It behaves pretty much like any standard copy command, adding the replacement of the included files for their real content. Note there is no error checking whatsoever.

SSI.generate(source_file, dest_file_or_directory)

Hopefully it will save a minute or two to someone somewhere.

| |
sebastian.martinez

Setting up Passenger in Linux

Posted by sebastian.martinez
on January 28, 2009

Clearly one of the problems with Rails as a major platform right now is it’s hosting situation. Currently a good solution is to proxy HTTP requests from Apache or Nginx to a cluster of mongrels, which is tricky to set up and somewhat tedious. I wanted to easily have our rails applications deployed (in our development environment), and have them running without having to manually start each server. Messing around I found Passenger(Passenger), a module for Apache that hosts Rails applications. Note this was tested in Ubuntu, but it's very similar for other Linux distributions.

To install the module simply run:

$ sudo gem install passenger

Then, you need to do

$ passenger-install-apache2-module

and just follow the instructions. The installer is very easy to follow, and in my case it detected some software not installed, so i had to run

$ sudo apt-get install apache2-prefork-dev

Once the installation was successfully completed, it asked to add the following lines to the apache configuration file, /etc/apache2/apache2.conf

"LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/passenger-2.0.2/ext/apache2/mod_passenger.so
PassengerRoot /usr/lib/ruby/gems/1.8/gems/passenger-2.0.2
PassengerRuby /usr/bin/ruby1.8"

At this point, Passenger is properly configured, and the only thing left is to configure our applications to work with Apache. So, let's do it: make your 'httpd.conf' file to look like this:

NameVirtualHost localhost:80

      ServerName app1.local
      DocumentRoot /app1_path/public



      ServerName app2.local
      DocumentRoot /app2_path/public

...and so on for more applications.

Also, modify the '/etc/hosts' file to have your applications go to localhost. It should look similar to this:

127.0.0.1       localhost app1.local app2.local

There are some considerations to make here. First and most important, the rails environment. Passenger sets it to production as default, but if you want it to be some other, just need to add the following line into the configuration file:

RailsEnv environment

Now if you just type into your browser app1.local you should see your application alive! Without the images and style? Yes, simply to solve.

Delete the following file and restart apache.

$ rm -f /your_app_path/public/.htaccess

Bingo!

That was all the strictly necessary to have your application deployed with Passenger...but we have some tricks to share ;)

Suppose you want your Ruby on Rails application to be accessible from the URL http://localhost/app. To do this, make a symlink from your Ruby on Rails application's public folder to a directory in the document root. For example:

Type

$ ln -s /your_app_path/public /var/www/app1

in a terminal.

Next, add a RailsBaseURI option to the virtual host configuration:



    ServerName app1.local
    DocumentRoot /app1_path/public
    RailsBaseURI /app1                # This line has been added.

Now, according to Passenger's documentation, this should be it, but I've found some problems with Rails 2.2.2. Going to http://localhost/app1 now may give you a HTTP 404 error. To solve this, you need to add this line to environment.rb of your application:

config.action_controller.relative_url_root = "/app1"

Another sweet thing is restarting a Rails app hosted by Passenger - simply touch a file called tmp/restart.txt within the Rails application root:

$ touch tmp/restart.txt

And that's it. Enjoy this beauty. Note that this configuration is intended to be for development environment only. Passenger provides other parameters for production, which we will tackle in the near future, and public our opinions. So, don't forget to keep visiting us. Seeya in the next post!

| |
sebastian.martinez

Twenty Reasons I Love Ruby

Posted by sebastian.martinez
on January 23, 2009

Inspired by Hal Fulton's article Thirty-seven Reasons I Love Ruby(Thirty-seven Reasons I Love Ruby), i'd like to share my top twenty reasons I love Ruby.

  1. {color:#993300}It's object-oriented. What does that mean? Well, for every ten programmers, there are twelve opinions as to what OOP is. I will leave it your judgment. But for the record, Ruby does offer encapsulation of data and methods within objects and allows inheritance from one class to another; and it allows polymorphism of objects. Unlike some languages (like C++ for instance) Ruby was designed from the beginning to be object-oriented.
  2. {color:#993300}It's a pure OOP language. Am I being redundant? I don't think so. By this I mean that everything, including primitive data types such as strings and integers, is represented as an object. There is no need for wrapper classes such as Java has. And in addition, even constants are treated as objects, so that a method may be invoked with, for example, a numeric constant as a receiver.
  3. {color:#993300}It's a dynamic language. For people only familiar with more static languages such as C++ and Java, this is a significant conceptual leap. It means that methods and variables may be added and redefined at runtime. It obviates the need for such features as C's conditional compilation (#ifdef), and makes possible a sophisticated reflection API. This in turn allows programs to become more "self-aware" -- enabling runtime type information, detection of missing methods, hooks for detecting added methods, and so on.
  4. {color:#993300}It's an interpreted language. This is a complex issue, and deserves several comments. It can be argued that performance issues make this a negative rather than a positive. To this concern, I reply saying that a rapid development cycle is a great benefit, and it is encouraged by the interpreted nature of Ruby.
  5. {color:#993300}It understands regular expressions. For years, this was considered the domain of UNIX weenies wielding clumsy tools such as grep and sed, or doing fancy search-and-replace operations in vi. Perl helped change that, and now Ruby is helping, too. More people than ever recognize the incredible power in the super-advanced string and text manipulation techniques.
  6. {color:#993300}It's multi-platform. It runs on Linux and other UNIX variants, the various Windows platforms, BeOS, and even MS-DOS.
  7. {color:#993300}It's derivative. Is this a good thing? Outside of the literary world, yes, it is. Isaac Newton said, "If I have seen farther than others, it is because I stood on the shoulders of giants." Ruby certainly has stood on the shoulders of giants. It borrows features from Smalltalk, CLU, Lisp, C, C++, Perl, Kornshell, and others. The principles I see at work are: 1. Don't reinvent the wheel. 2. Don't fix what isn't broken. 3. Finally, and especially: Leverage people's existing knowledge. You understand files and pipes in UNIX? Fine, you can use that knowledge. You spent two years learning all the printf specifiers? Don't worry, you can still use printf. You know Perl's regex handling? Good, then you've walked a way in Ruby path too.
  8. {color:#993300}It has a smart garbage collector. Routines like malloc and free are only last night's bad dream. You don't even have to call destructors. Enough said.
  9. {color:#993300}It's a scripting language. Don't make the mistake of thinking it isn't powerful because of this. It's not a toy. It's a full-fledged language that happens to make it easy to do traditional scripting operations like running external programs, examining system resources, using pipes, capturing output, and so on.
  10. {color:#993300}It's open-source. You want to look at the source code? Go ahead. Want to suggest a patch? Go ahead. You want to connect with a knowledgeable and helpful user community, including the language creator himself? You can. Welcome on board.
  11. {color:#993300}It has an advanced Array class. Arrays are dynamic; you don't have to declare their size at compile-time as in, say, Pascal. You don't have to allocate memory for them as in C, C++, or Java. They're objects, so you don't have to keep up with their length; it's virtually impossible to "walk off the end" of an array as you might in C. Want to process them by index? By element? Process them backwards? Print them? There are methods for all these. Want to use an array as a set, a stack, or a queue? There are methods for these operations, too. Want to use an array as a lookup table? That's a trick question; you don't have to, since we have hashes for that.
  12. {color:#993300}It's extensible. You can write external libraries in Ruby or in C. In addition, you can modify the existing classes and objects at will, on the fly.
  13. {color:#993300}It uses punctuation and capitalization creatively. A method returning a Boolean result (though Ruby doesn't call it that) is typically ended with a question mark, and the more destructive, data-modifying methods are named with an exclamation point. Simple, informative, and intuitive. All constants, including class names, start with capital letters. All object attributes start with an @ sign. Again, simple.
  14. {color:#993300}It pays attention to detail. Synonyms and aliases abound. You can't remember whether to say size or length for a string or an array? Either one works. For ranges, is it begin and end, or first and last? Take your pick. You spell it indices, and your evil twin spells it indexes? They both work.
  15. {color:#993300}It has a debugger. In a perfect world, we wouldn't need debuggers. This is not a perfect world.
  16. {color:#993300}It is concise. There are no superfluous keywords such as Pascal's begin, then after if, do after while. Variables need not be declared, as they do not have types. Return types need not be specified for methods. The return keyword is not needed; a method will return the last evaluated expression. On the other hand... it is not so cryptic as C.
  17. {color:#993300}It is expression-oriented. You can easily say things like x = if a < 0.
  18. {color:#993300}It has powerful string handling. If you want to search, substitute, justify, format, trim, delimit, interpose, or tokenize, you can probably use one of the built-in methods. If not, you can build on them to produce what you need.
  19. {color:#993300}It has few exceptions to its rules. The syntax and semantics of Ruby are more self-consistent than most languages. Every language has oddities, and every rule has exceptions; but Ruby has fewer than you might expect.
  20. {color:#993300}It is laced with syntax sugar. (To paraphrase Mary Poppins: A spoonful of syntax sugar helps the semantic medicine go down.) If you want to iterate over an array x by saying for a in x, for example, you can.
| |
jose.costa

Gravatars in Mephisto (article's title included)

Posted by jose.costa
on January 23, 2009

Goal: I just want to see the gravatars not only for comments but in the article's title also.

I have no prior knowledge of Mephisto (this is my second day with it) nor Liquid. So, here is how i did it ... may be far from perfect but it seems to pull it off:

Comments, easy:

There is already a method gravatar that receives a hash with the comment properties and does the trick. So, placing the following line in the right spot of the appropriate liquid file (for me that's the _article.liquid file) should be enough:

Articles are a little more tricky

Since there is no support in for gravatars for article's author i've coded a simple initializer to add a new method for this purpose and keep the original code as clean as possible. This initializer adds the method gravatar_for_article to the UrlFilters module.

module UrlFilters
 
   def gravatar_for_article(article, size=80, default=nil)
     article = Article.find article["id"]
     gravatar({'author_email' => article.user.email,
                     'author' => article.user.login},size,default)
   end
   
 end

The code above creates a new hash from some of the article's properties to mock the comment structure and passes it to the original gravatar method. Now, place the following line inside the article's header and voilá.

Style it and you're done.

| |
jose.costa

WyeWorks Blog Opening!

Posted by jose.costa
on January 22, 2009

Just after launching our website, we are proud to announce the opening of our blog!

Here you’ll found articles, hopefully useful, from the WyeWorks development team, and of course comments of our critics which are indeed welcomed :)

Enjoy!

| |