From the creator of MVC, now comes... DCI, the new programming paradigm

Thu, 05.07.2012 dci, paradigm

Heck, it’s more than a year that I don’t fill my blog with some content, so here I am with an special entry.

Data, context and interaction, that’s the meaning of the acronym which describes the new programming paradigm proposed by Trygve Reenskaug, the creator of MVC himself (together with James O. Coplien).

So, if I have understood it well, they reckon that Object Oriented Programming is not really about objects, but about classes. Classes are actually that what we define, somehow living on themselves, but not very much flexible in what their different objects can do. When you want a lot of variability in the behaviour of those instances, you need lots of methods, or chains of subclasses, and much coupling in between. Well, (in Ruby there are modules that we can mix in, but) with DCI we are talking about the core capabilities of the language, so in this regard, it is more than a framework. If these ideas get accepted, they should probably be integrated in the language itself (that’d be cool).

Is it really that big an issue? Let’s see what DCI proposes:

  1. The instantiated objects modelling normal application data can play different roles along the execution of the program. Their methods should be compliant with an interface defined by the respective Role that they want to play. So every object able to do certain simple tasks (each one in its own particular way) could play a certain role. This Role therefore extends the capabilities of the object, independently of the class to which it belongs (now that’s polymorphism).
  2. Programmers should then declare algorithmic use cases inside a Context, assigning Objects to play different Roles depending on the scope of actuation.
  3. Finally, there is an Interaction taking place, which is what happens when you actually run the code (in the C language convention, the so called main routine), instantiating, calling some Context routines depending on different inputs, setting parameters which will propagate inside them, and so on.

What I most like about this proposal is that it surreptitiously includes and somehow explicits the concepts of Event-driven programming, in which the Context or use case can be reduced to be just a simple event handler, something I long for.
I can also imagine, that BDD should become a bliss, since stories and scenarios are already included inside the code.
It also allows for unconstrained behaviour of objects in a realistic, extensible and DRY manner.

Summarizing, business logic has finally found its place under the sun. The next big thing (and it is already more than 3 years old, aren’t we outdated!).

Some links:

By the way, I would have called it a more incisive name, like Role, Story, Action, but that’s not my butter anymore.

0 comments

Pagination for non-REST actions with kaminari

Sat, 25.06.2011 pagination, kaminari, params

A few months ago, our not-enough-praised Ryan Bates presented to us an alternative pagination gem, fully Rails 3 Ready TM, called kaminari. It is really simple to use and very powerful as well, but I found a little gotcha that got me crazing around for too long.

Say you have a typical paginated index action in your controller:

1
2
3
4
5
class PostController < ActionController::Base
  def index
    @posts = Post.page(params[:page])
  end
end

Quite fancy and smooth. Alright, say we are in real life, then this would be another controller:

1
2
3
4
5
6
class CommentsController < ActionController::Base
  def index
    @post = Post.find(params[:post_id])
    @comments = post.comments.page(params[:page])
  end
end

A second paginating step, but still quite simple. So let’s write the corresponding view:

1
2
3
4
5
= post.title
= post.body
- for comment in @comments
  = comment.body
= paginate @comments

You can try that out (in case you wonder, that’s not HAML, but Slim, kind of a lighter version of it): this paginate thing is great and it works. But, imagine that today you woke up a little unconventional, you know, sort of against REST conventions, and want to render that view from the PostsController, like this:

1
2
3
4
5
6
class PostsController < ActionController::Base
  def comments
    @post = Post.find(params[:post_id])
    @comments = post.comments.page(params[:page])
  end
end

Not a big deal. You might have your good reasons for it. For instance, ‘comments#index’ could be rendering comments not after post, but after user (or whatever association you could imagine). Well, paginate is not going to work like that, look:

1
No route matches {:controller=>"posts", :action=>"comments", :page=>nil, :post_id=>"1"} (ActionView::Template::Error)

Unless you tweak your declaration a little, of course. That is what drove me nuts (what “no route matches page nil”? ), and I blamed subsequently decent_exposure, cancan and kaminari. But no one was to blame, but myself. Look and get delighted by the simplicity of the solution:

1
2
3
4
5
= post.title
= post.body
- for comment in @comments
  = comment.body
= paginate @comments, :params => {:post_id => post }

It just needed some love, i.e. a params declaration to scope the comments out of their natural environment. Now we are talking…

0 comments

Machinist and database_cleaner

Sat, 09.04.2011 machinist, database_cleaner

I run my cucumber features with the help of the spork server.
I have had some trouble getting my fixtures replacement Machinist to delete old objects in between iterations. In its present state, Machinist has a wonderful syntax, but a hassle: it drives itself nuts trying in order to achieve object caching, and so old objects persist in your test database after a test.

But I got the solution. You’ll need database_cleaner, and the following code at the end of your features/support/env.rb:

1
2
3
4
5
6
7
8
9
DatabaseCleaner.strategy = :truncation

Before do
  DatabaseCleaner.start
end

After do
  DatabaseCleaner.clean
end

It seems to me that the Machinist is going to solve this problem by dropping caching support all along in the near future, so this post might get soon outdated. I hope so, that was a nasty problem, almost invalidating the whole purpose of Machinist.

0 comments

Hideous, obfuscated IDs

Sun, 03.04.2011 obfuscation

When you are developing a public online application where your users have to type in URLs and the like to visit it, you most probably don’t want them know how many users, posts or whatever items there are in your app. But our Rails app is giving all this information away without any discretion. This means that the default behavior regarding to object ids is not very stakeholder friendly and we will have to take care of that ourselves.

In the app that we are currently developing in our startup, we share this perspective: we want to obscure the ids of our objects in front of the outside world, but we still have to allow our users to fetch our resources. None of the solutions that we found (we might have not searched that well, condoned) seemed good enough: either too complicated, too slow, or too insecure, so we had to roll our own.

The requirements are:
- Simple to implement: one or two lines of code in each affected model and controller should be sufficient. We mind more about ease and speed, although beauty would be a plus.
- Recoverable: Given the obfuscated id, we know how to get our original one back!
- Not breakable: if an attacker creates several resources consecutively in time and analyzes the resulting IDs, he should not be able to get the original IDs back. The obfuscated IDs must not be consecutive or follow any recognizable pattern.
- Unobtrusive: the application should not know much about it (not that much in this post on this subject).

This is what I have come up with until now, which seems to be new, for what I know, although built on previous ideas.

First, we need some kind of library to perform the transformation. Actually a very simple one can do. Put this under /extras/hideous.rb:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Hideous
  MAXID = 2147483647  # (2**31 - 1)
  PRIME = #a very big prime number of your choice (like 9 digits big)
  PRIME_INVERSE = #another big integer number so that (PRIME * PRIME_INVERSE) & MAXID == 1
  RNDXOR = #some random big integer number, just not bigger than MAXID

  def self.hide(bare_integer)
    (((bare_integer * PRIME) & MAXID) ^ RNDXOR).to_s(16)
  end

  def self.bare(hide_integer)
    ((hide_integer.to_i(16) ^ RNDXOR) * PRIME_INVERSE) & MAXID
  end
end

How to calculate the proper PRIME and its PRIME_INVERSE? On that there are a couple of answers out there. You can use Scott’s PRIME and INVERSE, but that’s not very secret anymore, so you should go with your own prime number. Where do I get a big one?, you might be asking yourself. Well, you can calculate it yourself, but I suggest you to go faster by grabbing one from the list of the first fifty million primes. Afterwards you need to calculate its inverse (always relative to MAXID, but indeed not a prime number itself). This is a one timer, but none of us wants to do the math (that’s what computers were invented for!). Happily, I already took care of it and offer you a fast solution here for free. Seed your chosen prime into the last line of the following code (I adapted both the modinv function and the egcd function from their respective original Python sources). Simply open an irb session and paste the following in (remember to define your PRIME and MAXID):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# Modular inverse
# Returns x so that ax ≡ 1 (mod m)
def modinv(a, m)
    x, y, g = egcd(a, m)
    if g==1
      return x%m
    else
      return nil
    end
end

# Extended great common divisor
# Returns x, y and gcd(a,b) so that ax + by = gcd(a,b)
def egcd(a, b)
  x, x1, y, y1 = 1, 0, 0, 1
  while b!=0
    q = a/b
    x, x1 = x1, x-q*x1
    y, y1 = y1, y-q*y1
    a, b  =  b, a-q*b
  end
  return x, y, a
end

prime_inverse = modinv(PRIME,MAXID+1)

you surely get what you are looking for. Proof that it went well doing:

1
2
(PRIME * PRIME_INVERSE) & MAXID == 1
=> true

And what’s the point of all this, actually? What are we getting here? Well, let’s go back to our hide function. We could decompose it into three steps:

1
2
3
4
5
def self.hide(bare_integer)
  knuth_hash = bare_integer * PRIME & MAXID
  unleashable_hash = knuth_hash ^ RNDXOR
  shorter_hash = unleashable_hash.to_s(16)
end

The first one, bare_integer * PRIME & MAXID, is called the Knuth’s integer hash. It has the very important advantage that it shouldn’t produce collisions (i.e. two different inputs would never give the same output). But it also has a downside: if you compare several consecutively generated obfuscated numbers, you can extract a pattern and therefore break the illusion created by the hash. To avoid that, I have devised a second step in the algorithm (this is my real contribution here, all the rest being blows and whistles), knuth_hash ^ RNDXOR, which should make its result virtually impossible to unleash. Hidden, obfuscated, befuddled. It is actually a very easy concept, just make a bit XOR comparison of the number with another invented one. The beauty of it is that you just have to repeat it to get the original number back:

1
2
hashed_integer = original_integer ^ RNDXOR
original_integer  =  hashed_integer ^ RNDXOR

Besides, it is a very fast calculation which introduces almost no delay in the chain. The third step is an optional one. If you employ the suggested algorithm and appropriate big numbers, you should be getting 10 digit long ids back, which might be quite a length. In case you want to shorten them, you can make them be displayed in base 16, which will make them 8 digit long (or even base 32, making them 6 digit long, it is up to you).

So, all requirements are met: recoverability, unobtrusiveness and unbreakability (well, some very very brute force attack could unveil our original ids, but none of us mortals has to worry about that, since being a victim of such attacks would mean that we have become big numbers).

Modify your /config/application.rb. so that the hideous.rb file gets loaded by Rails at server startup:

1
config.autoload_paths += %W(#{config.root}/extras)

Now we are ready to start using our Hideous class to obscure our ids, like so (that goes for the last requirement, easiness):

1
2
hidden_id = Hideous.hide(plain_id)
plain_id = Hideous.bare(hidden_id)

Yes, we could have utilized it in some other way. But that’s another discussion, and there are different alternatives about how to integrate such an obfuscating library into our Rails app.

Update
You might be wondering about what a possibly good looking RNDXOR is. As the name itself expresses, any random integer not bigger than MAXID is alright, since we will be using it for a simple XOR bit operation. But, if you want to be really really random by not choosing the number by yourself, I have a small suggestion for you. In your irb:

1
2
require 'active_support/secure_random'
ActiveSupport::SecureRandom.hex(4).to_i(16) & MAXID

That way you avoid introducing any bias in the randomness of your RNDXOR.

1 comment

Slug that slash

Thu, 17.03.2011 rails 3, url, slug

I was doubting, whether to title this post Slash that slug, but let’s leave it like it is…

Anyways, the known way to embellish your URL in Rails is the definition of to_param in your model. Most of the solutions offered out there, including the Rails Guides, propose joining the id with the name of the model with a score, like this: /posts/478-a-post-title/. But I don’t really like that. I rather separate concerns. The id should always be the same, while the name should be modifiable. If editing a model’s name changes your URL, you can always redirect the old one to the new one (or the other way round) with permalinks, a task where that constant id will help enormously. So I prefer this URL: /posts/478/a-post-title/. But how to accomplish it easily?

There are just two things to do. The first is to define it in your model, as said:

1
2
3
4
5
6
7
def to_param
  "#{id}/#{slug}"
end

def slug
  title #or whatever, here you can make use of a plugin like 'friendly_id'
end

The second step is to inform your routing system. Rails 3 turns out to offer a very simple way to do it. If you checked the above link, you might already have a clue:

1
resources :posts, :constraints => { :id => /[0-9]+\/.+/ }

or, if you aren’t defining a resource:

1
match 'posts/:id' => 'posts#show', :constraints => { :id => /[0-9]+\/.+/ }

Here we are defining a constraint on the id through a regular expression. Beware that this id is the one that the routing system understands as directly coming from the model as our to_param defines it, and not the real id of the post object as in the database. As this regex is defined, we are supposing that the model’s id is an integer number, and the slug is a normal string.

You can even simplify the route’s definition, if you please:

1
2
3
resources :posts, :id => /[0-9]+\/.+/
# or
match 'posts/:id' => 'posts#show', :id => /[0-9]+\/.+/

An added benefit is that you won’t have to clutter your routing calls, only a clean link_to is needed:

1
link_to @post.title, @post

This is a simple method to get modern and friendly URLs for your models in Rails 3. Less code, more beauty. Nice?

1 comment

The case of 'case/when' vs 'if/include'

Mon, 17.01.2011 rails 3, splat, include

I am not a native English speaker (and probably not a native developer either), so I had to search for splat, as I found this word the other day. It turned out to be the name of that funny operator which looks like an asterisk and is written pressing the asterisk key of your keyboard. But don’t get confound, it is not an asterisk, it is a splat, like so: *

As a result, I ended up reviewing my knowledge of that somehow ignored Ruby operator. Usually, most of us know from doing

1
2
3
4
def some_method(important_parameter, *args)
  do_something_with(important_parameter)
  super(args)
end

Kind of a Mary Poppins bag, where anything can pop in and out. On this respect, I found this very detailed post about the possibilities of the splat, which motivates mine now. Go through it and perhaps improve your understanding of this array operator, and afterward go back to the section 4.Case/When. The code in example is actually been taken from production code in current Rails 3.0.3:

1
2
3
4
5
6
7
8
9
10
def find(*args)
   ...
   case args.first
   when :first, :last, :all
      send(args.first)
   else
      find_with_ids(*args)
   end
   ...
end

That code called my attention: a case statement with a single when. I immediately thought about an obvious alternative:

1
2
3
4
5
6
7
8
9
def find(*args)
   ...
  if [:first, :last, :all].include? args.first
    send(args.first)
  else
    find_with_ids(*args)
  end
   ...
end

Both sets of code will give the same result. The Rails version allows having more alternatives if we wanted (like following different paths for :first, :last and :all ), but for now let us follow YAGNI and ask ourselves: if both do the same thing, which one of them is going to be faster? Let’s refactor and make use of that one!

So, I made my homework, and wrote the following file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class BM
  def self.a
    [1,2,3]
  end

  # rails benchmarker 'BM.casewhen'
  def self.casewhen
    9999.times do
      case 4
      when *a
        b=1
      else
        b=2
      end
    end
  end
  
  # rails benchmarker 'BM.ifinclude'
  def self.ifinclude
    9999.times do
      if a.include? 4
        b=1
      else
        b=2
      end
    end
  end
end

The evaluation will result as false since 4 is not in the array and Ruby will follow the else branch. This to ensure the worst case, so that the array is always gone through. I will measure the difference in running time for a standard Ruby 1.9.2 installation on a Debian Squeeze.

To make it fast and simple, I put this file into some rails project at app/model/bm.rb and run both methods manually 7 times each (which I suppose enough to avoid random delays due to other processes in my system), with the following results:

  • rails benchmarker ‘BM.casewhen’
    => real time: 14489 13849 14862 16344 16667 15016 15047
    => Mean: 15182, Standard Deviation:996.73

  • rails benchmarker ‘BM.ifinclude’
    => real time: 14266 13886 12886 14044 13973 14484 12896
    => Mean: 13776.42857, Standard Deviation:636.4741

As you can see, the second method is taking about a 10% less time to execute. I have to say that it doesn’t surprise me, a case statement should intuitively take more time to evaluate than an if statement, but you can run the test with other configurations (JRuby, Windows, you name it). If you do so, please comment here on your results.

And we all love our servers spending less time doing finds, isn’t it? I know that you’re thinking: “these three lines don’t make the world”, but I bet that ‘find’ is in the top ten of executed sentences in our applications. So why not get this little boost for free?

I am on my way of making it into the next Rails version.

Update 1:
With the help of rafmagana I realized that my code was incomplete. He had a much more clear code which I squeezed for newer, discouraging results (real time offered):

  • first with when: 0.923457
  • first with include?: 1.201857
  • last with when: 0.926521
  • last with include?: 1.301077
  • all with when: 0.945277
  • all with include?: 1.354739
  • find_with_ids with when: 3.035178
  • find_with_ids with include?: 1.816336

As we can see, :first, :last and :all prefer when (25-30% faster) whereas find_with_ids prefers include? (40% faster). How logical is that?
I mean, find_with_ids has (should have) to go through each item in the list and see whether it is there or not before the final diversion into the else. So it has more work to do and does it faster?
I hope I have a lesson learned: check every possibility, even if it seems unlogical, you never know…

Update 2:
The next time I want to do something on performance, remind to see again this incredible video from Aaron Paterson at the RubyConf 2010. I already downloaded a copy for my own future reference.

0 comments

Star Rating for Rails 3 and jQuery

Sun, 28.11.2010 rating, rails 3, jquery, ajax

You might be starting a project (or upgrading an older one) on our shiny newly branded Rails 3, and in that process, you might as well be looking for a solution to the problem of offering a trendy Star Rating system in your app. Googling for “Rails rating” tells you to go with the ajaxful-rating plugin, to which I won’t offer you the link, since that won’t work (for now) with Rails 3.

There are Other Solutions TM out there, but some won’t work if you have more than one Star Rating Form in a single page (although much of this post was inspired by it). But there are good news: you needn’t reinvent the wheel. You are probably using jQuery anyways, so why not just use one of its plugins? jQuery Star Rating Plugin is the way to go. And why? Because it is great, and I am telling you here how to make use of it! (but be careful, I use it only in a prototype of an app that we are building, no production stories yet).

So, you installed the jquery-rails plugin (at least version 0.2.5 if downloading from github). You also downloaded the files from the jQuery Star Rating Plugin and put them into your public/javascripts folder, along with its (only!) two images under public/images and its stylesheet under public/stylesheets/jquery.rating.css . What’s next? Obviously, you need a set of models, controller and views. I went with the good ol’ acts_as_rateable plugin, also available as a gem, but you might not need so much power (it polymorphically allows to rate different models). Let’s say you want to rate comments on a post.

1
2
3
4
class Comment
  belongs_to :post
  acts_as_rateable
end

And under app/views/posts/show.html.erb you have something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<% for comment in @post.comments %>
  <h4><%= comment.title %></h4>
  <p><%= comment.body %></p>
  <p>by <%= comment.author %> on <%= comment.date %></p>
  <p>
    Rating: <%= comment.average_rating %>
    <%= form_for(Ratings.new) do |f| %>
      <% 1.upto(5) do |value| %>
        <%= star_button f, comment, value, (value==5) %>
      <% end %>
      <%= hidden_field_tag("comment_id", comment.id) %>
    <% end %>
  </p>
<% end %>

That’s a simple example of how comments would look like (you may extract everything inside the for into a partial, but that’s another story). Notice a couple of things:

  • There is no way to change your rating once you cast it. For what I know, acts_as_rateable doesn’t let you do it either, but I did not investigate much on that yet.
  • We are offering 5 stars, you might want other solutions for your upto(5) (at line 8).
  • There are two helper methods on that code:
    1. average_rating (at line 6) comes with acts_as rateable and gives us, well, eh…, yes, the average rating of the given comment.
    2. star_button (at line 9) I wrote:

      1
      2
      3
      
        def star_button(f, comment, value, checked)
          radio_button_tag("rating[#{comment.id}]", value, checked, :class => 'star')
        end
      

      This key method is self explaining, and builds the markup that our jQuery Star Rating Plugin understands. I would only point out that you could make the checked radiobutton/star appear a value different than my chosen 5, for instance referring to the last rating score given by the current_user or to the mean of users (average_rating) or something else. I chose it quite neutral.
      Put it inside app/helpers/posts_helper.rb , and that will provide the following code:

      1
      2
      3
      4
      5
      
      <input class="star" id="rating_15_1" name="rating[15]" type="radio" value="1" />
      <input class="star" id="rating_15_2" name="rating[15]" type="radio" value="2" />
      <input class="star" id="rating_15_3" name="rating[15]" type="radio" value="3" />
      <input class="star" id="rating_15_4" name="rating[15]" type="radio" value="4" />
      <input checked="checked" class="star" id="rating_15_5" name="rating[15]" type="radio" value="5" />
      

      where 15 is the comment’s id. Respect the class star for the plugin to work.


You can already let it run and see how it looks like. Not that bad for that little work. And the best news is: we are almost finished. Get this at app/controllers/ratings_controller.rb :

1
2
3
4
5
6
7
8
9
10
11
class RatingsController < ApplicationController
  def create
    @comment = Comment.find_by_id(params[:comment_id])
    if @comment.rate_it(params[:rating][@comment.id.to_s], current_user.id)
      respond_to do |format|
        format.html { redirect_to post_path(@comment.post) :notice => "Your rating has been saved" }
        format.js
      end
    end
  end
end

The method rate_it (at line 4) also comes with acts_as_rateable , and wants a value (coming from the POST params) and a user rating the comment.
Notice that we are trying to allow nice degradation when JS is not activated. That’s why we provide format.html (at line 6). You can try this as a pure HTML form (add a submit button on your form!, like this: <%= f.submit :rate %>).
But for AJAX to work, we need a last thing. The one that motivates this post, since the jQuery Star Rating Plugin doesn’t provide a way to save your rating.
Put the following under public/javascripts/jquery.rating.save.js :

1
2
3
4
5
6
7
8
9
10
$(document).ready(function() {
  // Hides the submit button
  $('.new_rating').children('input[type=submit]').addClass('hide');

  // Submits the form (saves data) after user makes a change.
  $('.star').click(function(){
        form = $(this).parent().parent();
        form[0].submit();
    });
});

Provided that you have a CSS class in your stylesheets called hide saying display:none , your submit button will disappear. And when you click on that rating star, it will automatically fetch its parent form and submit it. You can even have as many simultaneous forms in your page as you like.

Let me know if you get some issues. Happy rating!

14 comments

Accept OpenID comments without reCAPTCHA on Enki

Sat, 30.10.2010 enki, comments, recaptcha

If you are running (or planning to do it) your Rails blog on Enki (as I do), you might want to add reCAPTCHA to avoid that some of your commenters spam your home place.

But we need to take this configuration one step further. If a visitor of yours identifies him/herself with OpenID, which is already a little hassle for him/her (you will make him pay an extra visit to his/her OpenID provider to ask for his/her credentials), you don’t want to make it even more complicated by forcing him to fill the reCAPTCHA field as well. So, how do we deactivate the spam captcha in this case?

Go to your comments_controller.rb and, at what should be the line 54 (check this out), you’ll see:

1
    if session[:pending_comment].nil? && @comment.save

Now, put this there instead:

1
2
3
4
5
6
7
    if session[:pending_comment].nil? && (
        verify_recaptcha(
            :model => @comment,
            :message => "Please write the words in the image in the spam captcha"
        ) || (
            @comment.requires_openid_authentication? && @comment.openid_error.empty?) 
        ) && @comment.save

and you are done. Of course, you might want to replace that error message by a more suitable one.

That was an easy one to improve, right?

2 comments

Branching development workflow model with git-flow

Thu, 28.10.2010 git, git-flow, workflow, branching, document

When developing agile, there are some tools which help the advised programmer. One of them is git-flow. This sh script was created by Vincent Driessen (nvie) after the development model described on his very instructive post on git branching. He even released (with a CC-BY-SA license) a beautiful PDF graphic showing the whole work flow.

If you follow along the comments on his blog entry, many people were concerned that he did not depict support branches, a fairly common pattern (albeit not so much in web development). Xiong Changnian went as far as making an expanded SVG version of nvie’s graphic, which I subsequently decided to retouch and improve on stylishness, and share it with you. So here it is in all its A4 magnificence:

Branching development workflow
(Click on the image to get the SVG version)

I also changed the name of the branches to make them more Railish. So, print it, share it, or correct it, either personally or dropping me a comment.

0 comments

Formatting comments with lesstile

Thu, 21.10.2010 lesstile, comments, help

Apart from the usage of some normal HTML tags (like strong, em, and so on), the comments in this blog can be formatted using lesstile.
Here is a short explanation about the usage of this gem:

Links

If you want to create some links, typing "Search in Google":http://www.google.com/ produces: Search in Google.

Code

If you want to format some code, open and close it with three dashes. Write the following:

---here is some formatted code---

to get

1
  here is some formatted code

Blank spaces before the dashes do not affect the result, but breaklines can introduce unexpected blank lines.

Ruby code

You can be also more precise and define which language you are using. For the moment HTML and Ruby are supported. Just write the name of the language after the dashes, like this:

  --- ruby
  def hello_world
    puts “hello world!”
  end
  ---

and you’ll get:

1
2
3
  def hello_world
    puts "hello world!"
  end  

it doesn’t matter whether you capitalize the word ruby or not.

HTML code

Finally, after writing:

  --- HTML
  <strong>Look, HTML code</strong>
  ---

you’ll get


  <strong>Look, HTML code</strong>  

as expected. And that’s it! Make your comments, ladies and gentlemen.

0 comments

Hello world

Thu, 21.10.2010 msm

Hi!

This is my first post on my first blog on my first website ever.

I have been in Internet continuously since 1993, but as the say goes, the shoemaker’s children go barefoot.

Now the time has come, and here I am. For the good. There is more coming. Just wait!

0 comments