Jtalk on Rails: editing Javascript in my browser

If you don’t know JTalk yet, you’re missing something. It’s an awesome piece of work: a Smalltalk to Javascript compiler and a Smalltalk editor running in Javascript, IN YOUR BROWSERGo check it out, now!

Now that you’ve played a bit with JTalk, let’s get started.

If you’re like me, you’re a bit annoyed by WebDAV, the proposed solution to save changes to disk. And if you’re like me, you would like to use Jtalk with Rails, and because you’re a lazy ass like me, you use WEBrick instead of Apache for your development.

Let’s hack something up to replace WebDAV!

Create a Rails application

rails new jtalkonrails
cd jtalkonrails
bundle install
rm public/index.html
rails generate controller home index
printf "Jtalkonrails::Application.routes.draw do\n  root :to => \"home#index\"\nend\n" > config/routes.rb

(I should really make a script out of all my rails initialization commands, one of these days…)

Add Jtalk to your application

cd public/
wget http://github.com/NicolasPetton/jtalk/tarball/master --no-check-certificate
tar zxvf master
cp -R NicolasPetton-jtalk-20cd63e/st .
cp -R NicolasPetton-jtalk-20cd63e/js .
cp -R NicolasPetton-jtalk-20cd63e/css .
cp -R NicolasPetton-jtalk-20cd63e/ide .
rm -rf NicolasPetton-jtalk-20cd63e

JTalk stores source code in three forms: Smalltalk code, Javascript code and smaller Javascript code (“*.deploy.js”).

Jtalk hello world: the Counter example

now, edit app/views/layouts/application.html.erb so that it looks like this:

<!DOCTYPE html>
<html>
<head>
  <title>Jtalk On Rails</title>
  <%= stylesheet_link_tag :all %>
  <%= javascript_include_tag :defaults %>
  <%= csrf_meta_tag %>
  <script src="js/jtalk.js" type="text/javascript"></script>
  <script type="text/javascript"> loadJtalk()</script>
</head>
<body>
<button onclick="smalltalk.Browser._open()">Class browser</button>

<div id="counters"></div>

<script type="text/javascript">
  jQuery(document).ready(function() {'#counters'._asJQuery()._append_(smalltalk.Counter._new())});
</script>
<%= yield %>

</body>
</html>

Here, we included a button to open the code browser, and added a Counter in a div. Oh, I forgot to tell you: Jtalk works seamlessly with JQuery 🙂
Now, go check it out, and you will seee the counter and be able to increase and decrease the value displayed (yes, that’s a counter).

Editing the code

Click on the “Class browser” button to start the IDE. Select the “Examples” category, the “Counter” class, the “actions” method category, and the “increase method”. You will see in the text box below the source code of the increase method:

increase
count := count + 1.
header contents: [:html | html with: count asString]

Edit that method to increase by steps of 2 instead of 1, and hit “Save”. Now, the counter on your page will increase by steps of 2.
Unfortunately, on the next page refresh, you will lose these changes. That’s why the “Commit category” button is there.
It will take the updated files (here, Examples.st, Examples.js and Examples.deploy.js) and make a PUT request to their original URL.

A PUT, you said? Well, I can work something out with a PUT.

Saving the code

Let’s create a new controller, called Uploader:

rails generate controller uploader jtalk

And edit config/routes.rb as follows:

Jtalkonrails::Application.routes.draw do
  root :to => "home#index"
  if Rails.env == 'development'
    put 'st/:id' => 'uploader#jtalk'
    put 'js/:id' => 'uploader#jtalk'
    put 'js/:id.:deploy' => 'uploader#jtalk'
  end
end

Now the PUT requests are redirected to our controller, but only in the development environment. You do not want to make your JS editable from the browser in a production app. DO NOT WANT!

The only thing left is the controller itself:

class UploaderController < ApplicationController

  def jtalk
    path = Rails.root.join('public')
    if(params[:format] == "js")
      path = path.join("js")
    elsif(params[:format] == "st")
      path = path.join("st")
    end

    if(params[:deploy])
      path = path.join(params[:id]+".deploy."+params[:format])
    else
      path = path.join(params[:id]+"."+params[:format])
    end

    File.open(path, "w") do |f|
      f.write(request.body.read())
    end

    head 200
  end

end

Here, we build the file path from the parameters. I use request.body.read() to get the file content because Rails seems to truncate the beginning of the file.

Profit

Now, go back to the web page, click on “Commit category”, and refresh the page. Your changes were saved! You can enjoy editing your frontend directly from the webpage itself, in the code browser, and more importantly, write your whole frontend in Smalltalk! It’s still missing the workflow “edit-try-debug-edit-continue”, but it already feels just like a “normal” Smalltalk environment. It feels like home 🙂

Post Scriptum

If you want to add a new category, it’s easy: create a file Mycategory.js and put it in public/js, with this content:

smalltalk.addClass('Myclass', smalltalk.Object, [], 'Mycategory');

and change your initialization from loadJtalk() to loadJtalk(new Array(“Mycategory.js”)). The new category will now appear in the code browser, and clicking on “Commit category” will create the deployment file and Smalltalk source file.

Advertisements

2 thoughts on “Jtalk on Rails: editing Javascript in my browser

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s