Skip to content

Writing my first app

Hannes Hirzel edited this page May 2, 2014 · 62 revisions

Note: This page applies to version 0.12, 0.12.1, 0.12.2, 0.12.3 but not to 0.12.4.

Let's make a Hello World program in Amber.

The instructions are divided into two parts

  1. Setup of directories and index.html file
  2. Writing the Amber Smalltalk code

In the second part it is also shown how a Smalltalk method is called from JavaScript in the index.html file.

###Setup of directories and index.html file

First, you need a place for your new project. Create the following directory structure to store the project files:

projects/vendor/amber/
projects/hello
projects/hello/st
projects/hello/js

The projects/vendor/amber directory contains amber as obtained using git or unzipping the zip from github (other subdirectories of vendor can hold other common libraries used by projects).

To make things a little easier, add a symbolic link to the vendor directory from within the hello project:

$ ln -s projects/vendor projects/hello/vendor

To get started, add a new index.html file to the folder projects/hello and choose prefix that all your packages will have. This prefix is better known as a namespace.

One way to choose namespace is reverse an email or website URL belonging to your organization, e.g. johndoe@gmail.com becomes com_gmail_johndoe or company.com becomes com_company, and append the name of the project. This hello example project uses the namespace com_example_hello. Do not use periods in namespaces as it confuses require.js used in the loader.

Namespaces beginning with amber are reserved for internal use of amber.

Your index.html can be really basic. The most important thing it does is include amber.js, require.js, configure namespace-to-path mapping and run require. Here is a basic index.html you can use:

    <!DOCTYPE html>
    <html>
      <head>
        <title>My First Amber Project</title>
        <script src="vendor/amber/support/amber.js"></script>
        <script src="vendor/amber/support/requirejs/require.min.js"></script>
        <script type="text/javascript">
          require.config({ paths: {
            'com_example_hello': 'js', // mapping for compiled .js files
            'com_example_hello/_source': 'st' // mapping for smalltalk source files
          }});
          require(['amber/devel'], function (smalltalk) {
            // up to 0.12.2
            smalltalk.defaultAmdNamespace = "com_example_hello"; //used for all new packages in IDE
            smalltalk.initialize();
            // since 0.12.3
            smalltalk.initialize({
              "transport.defaultAmdNamespace": "com_example_hello"  //used for all new packages in IDE
            });
          });
        </script>
      </head>
      <body>
        <article>
          <h1>My First Amber Project</h1>
          <button onclick="require('amber_vm/smalltalk').Browser._open()">class browser</button>
          <button id="sayHello">say hello</button>
        </article>
      </body>
    </html>

Change directories to be inside the hello project: cd hello

Now start up amber with vendor/amber/bin/amber serve and navigate to http://localhost:4000/hello/index.html

The terminal should say: Starting file server on http://127.0.0.1:4000

If this doesn’t work, try re-reading Getting-started to see if you can get a basic amber server going.

###Writing the Amber Smalltalk code

Let’s get to writing some Amber Smalltalk code:

  1. Click the button to open the class browser.
  2. Take a look at the class browser’s code source section. It should contain a class manifest that looks something like this:
    screen shot 2013-12-08 at 1 49 07 am
  3. Change the name of the class to Hello and its package to HelloApp. It should now look like this:
    screen shot 2013-12-08 at 1 49 31 am
  4. Click Save. This creates new class according to the manifest. The Hello class will look like this:
Object subclass: #Hello
  instanceVariableNames: ''
  package: 'HelloApp'
  1. Now navigate to your new class in its new package. It should look like this:
    screen shot 2013-12-08 at 1 59 59 am
  2. Click Commit to commit the packages present in the class browser to disk. That button looks like this:
    screen shot 2013-12-08 at 2 00 08 am

You just created a new class and saved your work. On your file system, check out your `hello/js` and `hello/st` folders. Your new class is now saved in both JavaScript and Smalltalk. If it isn't, something is set up wrong; go back to Getting-started to figure it out. 6. Refresh your browser page and reopen the class browser. Oh no, your new class is gone! To load your new class automatically, you have to add it in `index.html`. Make your `require` call look like this: ```javascript require(['amber/devel', 'com_example_hello/HelloApp'], function (smalltalk) { // up to 0.12.2 smalltalk.defaultAmdNamespace = "com_example_hello"; //used for all new packages in IDE smalltalk.initialize(); // since 0.12.3 smalltalk.initialize({ "transport.defaultAmdNamespace": "com_example_hello" //used for all new packages in IDE }); }); ``` 7. Save and refresh again. Now your class Hello is loaded and shows up in the class browser. 8. Let’s make this class do something. Create a new _message_ in the class browser by navigating to the Hello class, then click on **not yet classified**, which should look like this:
![screen shot 2013-12-08 at 2 11 08 am](https://f.cloud.github.com/assets/325/1699930/f7748916-5fd7-11e3-9fba-bff44678a205.png)
You see the message template in code source section. Try filling in a simple message , like this for example: ```smalltalk begin "Makes me say hello."

| sentence button | sentence := 'Hello world!'. button := '#sayHello' asJQuery. button click: [button after: '

' , sentence , '

'].
9. Your message isn't too helpful if it doesn't get called, which is what’s happening due to the Hello class needing to be manually instantiated and its `#begin` instance method called. Save it, commit the package, then edit `index.html ` again. You can write JavaScript code that sends a message to Smalltalk:
```javascript
require(['amber/devel', 'com_example_hello/HelloApp'], function (smalltalk) {
  // ---- up to 0.12.2
  smalltalk.defaultAmdNamespace = "com_example_hello"; //used for all new packages in IDE
  smalltalk.initialize();
  // ---- since 0.12.3
  smalltalk.initialize({
    "transport.defaultAmdNamespace": "com_example_hello"  //used for all new packages in IDE
  });
  // ----

  $(function() {
    smalltalk.Hello._new()._begin();
  });
});

From there, you can create new Smalltalk classes and messages to build up your app. Enjoy!

Clone this wiki locally