|
| 1 | +## Getting Started in Pharo@cha:gettingstarted-pharoIn this chapter we will explain how to develop a first simple Seaside application: a simple counter. You will follow the entire procedure of creating a Seaside application. This process will highlight some of the features of Seaside such as callbacks and a DSL to emit HTML.We will neither explain the Pharo syntax nor the IDE. We will not explain how to define packages, classes or methods but obviously we will present their definition. If you are new to Pharo, we suggest you to read chapters 3, 4 and 5 of _Pharo by |
| 2 | +Example_ which is a free and online book available from [htp://books.pharo.org](htp://books.pharo.org) and the Pharo mooc available at [http://mooc.pharo.org](http://mooc.pharo.org).### Getting Seaside@pharoOneClickImageIn this book, we use Seaside 3.0.4, included in the _One Click Image_ whichyou can find on the Seaside website at [http://www.seaside.st/download](http://www.seaside.st/download). The_One Click Image_ is a bundle of everything you need to run Seaside. You should see the Seaside development environment open ina single window on your desktop similar to the one presented in Figure *@fig:seasileDesk@*.!!todo revise### Starting the Server @pharoComancheServer!!todo ReviseThe _One Click Image_ image includes a web server called "Comanche" listeningon TCP port 8080. You should check that this server is properly running bypointing your web browser to [http://localhost:8080/](http://localhost:8080/). You should see somethinglike Figure *@fig:seasideServer@*. If you don’t see this page, it is possiblethat port 8080 is already in use by another application on your computer.**Changing the Seaside port number.**If you did not see Figure *@fig:seasideServer@*, you will need to try modifyingthe workspace to restart the Comanche web server on a different port number\(like 8081\). The script *@scr:startServer@* asks the server to stop serving and startserving on port 8081.```language=smalltalk&label=scr:startServer&caption=Stop the server and start a new one. |
| 3 | +WAKom stop. |
| 4 | +WAKom startOn: 8081.```To execute this, you would open a new workspace using _World_ | _Workspace_,enter the text, select it, right-click for the context menu, and select_Do it_.Once you have done this, you can try to view it in your browser making sure youuse the new port number in your URL. Once you have found an available port, makesure you note what port the server is running on. Throughout this book we assumeport 8080 so if you’re using a different port you will have to modify any URLswe give you accordingly.### A First Seaside Component@pharoFirstSeasideComponentNow we are ready to write our first Seaside component. We are going to code asimple counter. To do this we will define a component, add some state to thatcomponent, and then create a couple of methods that define how the component isrendered in the web browser. We will then register it as a Seaside application.#### Defining a Package@pharoDefineCategoryTo start with, we define a new package that will contain the class that definesour component. We will save our class in this package. #### Defining a Component@pharoDefineComponentNow we will define a new component named `WebCounter`. In Seaside, a_component_ refers to any class which inherits from the class `WAComponent`\(either directly or indirectly\).!!note It is only a coincidence that this class has the same name as its package. Normally packages will contain several classes, and the package names and class names are unrelated.To start creating your class, click on the `WebCounter` package you justcreated. The "class creation template" will appear in the source pane of the browser. Edit this template so that it looks asin the script *@scr:pharoClassTemplate@*```language=smalltalk&caption=Pharo class template for the `Web Counter`&label=scr:pharoClassTemplateWAComponent subclass: #WebCounter |
| 5 | + instanceVariableNames: 'count' |
| 6 | + classVariableNames: '' |
| 7 | + package: 'WebCounter'```Notice that lines 3 and 4 contain two consecutive single quote characters, not adouble quote character. We are specifying that the `WebCounter` class is a newsubclass of `WAComponent`. We also specify that this class has one instancevariable named count. The other arguments are empty, so we just pass an emptystring, indicated by two consecutive quote marks. The "package" value shouldalready match the package name. Note that an orange triangle in the top-rightindicates that the code is not compiled yet.Once you are done entering the class definition, right-click anywhere in thatpane to bring up the context menu, and select the menu item _Accept \(s\)_ asshown in Figure *@fig:createdClass@*. Accept in Pharo jargon meanscompile.Once you have accepted, your browser should look similar to the one shown inFigure *@fig:createdClass@*. The browser now shows the class that you havecreated in the class pane. Now we are ready to define some behaviour for ourcomponent.### Defining Basic Methods@pharoDefineCodeNow we are ready to define some methods for our component. We will definemethods that will be executed on an instance of the `WebCounter` class. Wecall them instance methods since they are executed in reaction to a messagesent to an instance of the component.The first method that we will define is the `initialize` method, which will beinvoked when an instance of our component is created by Seaside. Seaside followsnormal Pharo convention, and will create an instance of the component for usby using the message `new`, which will create the new instance and then sendthe message `initialize` to this new instance.```language=smalltalk&label=scr:WebCounterInitialize&caption=WebCounter initialize method.WebCounter >> initialize |
| 8 | + super initialize. |
| 9 | + count := 0```Remember that this definition states that the method `initialize` is aninstance side method since the word `class` does not appear between`WebCounter` and `>>` in the definition.Once you are done typing the method definition, bring up the context menu forthe code pane and select the menu item _accept \(s\)_, as shown in Figure*@fig:compilingMethod@*.At this point Pharo might ask you to enter your full name. This is for thesource code version control system to keep track of the author that wrote thiscode.The method signature will also appear in the method pane as shown in Figure *@fig:compiledMethod@*.Now let’s review what this means. To create a method, we need to define twothings, the name of the method and the code to be executed. The first line givesthe name of the method we are defining. The next line invokes the superclass`initialize` method. The final line sets the value of the count instancevariable to 0.To be ready to define Seaside-specific behaviour, define two more instance methods to change the counter state as inscripts *@scr:increaseMethod@* and *@scr:decreaseMethod@*. You can group them in a protocol 'action'.```language=smalltalk&caption=Increase method.&label=scr:increaseMethodWebCounter >> increase |
| 10 | + count := count + 1``````language=smalltalk&caption=Decrease method.&label=scr:decreaseMethodWebCounter >> decrease |
| 11 | + count := count - 1```### Rendering a Counter@pharoRenderCounterNow we can focus on Seaside specific methods. We will define the method`renderContentOn:` to display the counter as a heading. When Seaside needsto display a component in the web browser, it calls the `renderContentOn:`method of the component, which allows the component to decide how it should berendered.Add a new method category called rendering, and add the method definition inscript *@scr:pharoRenderContentOn@*```language=smalltalk&caption=Example of `renderContentOn:` method&label=scr:pharoRenderContentOnWebCounter>>renderContentOn: html |
| 12 | + html heading: count```We want to display the value of the variable count by using an HTML heading tag.In Seaside, rather than having to write the HTML directly, we simply send themessage `heading:` to the html object that we were given as an argument.As we will see later, when we have completed our application, this method willgive us output as shown in Figure *@fig:simpleCounter@*.#### Registering as a Seaside Application@pharoRegisterSeasideAppWe will now register our component as an application so that we can access itdirectly from the web browser. To register a component as an application, weneed to send the message `register:asApplicationAt:` to `WAAdmin`.```==WAAdmin register: WebCounter asApplicationAt: 'webcounter'==```This expression registers the component `WebCounter` as the application named `webcounter`. The argumentwe add to the `register:asApplicationAt:` message specifies the root componentand the path that will be used to access the component from the web browser. Youcan reach the application under the URL [http://localhost:8080/webcounter](http://localhost:8080/webcounter).Now you can launch the application in your web browser by going to[http://localhost:8080/webcounter/](http://localhost:8080/webcounter/) and you will see your first Seasidecomponent running.!!todo Put the link to section 7.2 in pillarIf you’re already familiar with HTML, you may want to look at the introductionto halos in Section 7.2 to learn a little more about how to investigate what’shappening under the covers.#### Automatically Registering a Component@pharoAutomitacRegisteryIn the future, you may want to automatically register some applications wheneveryour package is loaded into an image. To do this, you simply need to add theregistration expression to the _class_ `initialize` method of the component.A _class_ `initialize` method is automatically invoked when the class isloaded from a file. The script *@scr:classInitialize@* the `initialize` classmethod definition.```language=smalltalk&caption=Automitically register your application with an initialize method.&label=scr:classInitializeWebCounter class >> initialize |
| 13 | + WAAdmin register: self asApplicationAt: 'webcounter'```The word "class" in the `WebCounter class>>` first line indicates that thismust be added as a class method as described below.Because this code is in the `WebCounter` class, we can use the term self inplace of the explicit reference to _WebCounter_ that we used in the previoussection. In Smalltalk we avoid hardcoding class names whenever possible.In the future, we will add configuration parameters to this method, so it isimportant to be familiar with creating it. Remember that this method is executedautomatically only when the class is loaded into memory from some externalfile/source. So if you had not already executed`WAAdmin register: WebCounter asApplicationAt: 'webcounter'` Seaside wouldstill not know about your application. To execute the `initialize` methodmanually, execute `WebCounter initialize` in a workspace; your application willbe registered and you will be able to access it in your web browser.!!note Important Automating the configuration of your Seaside application via class-side `initialize` methods play an important role in building deployable images because of their role when packages are brought into base images, and is a useful technique to bear in mind for future use.The following Figure *@fig:executableComment@* shows a trick Smalltalkersoften use: it adds the expression to be executed as comment in the method. Thisway you just have to put your cursor after the first double quote, click once toselect the expression and execute it using the _Do it \(d\)_ menu item or shortcut.#### Adding Behavior@pharoAddBehaviorNow we can add some actions to our component. We start with a very simplechange; we let the user change the value of the count variable by definingcallbacks attached to links \(also known as anchors\) displayed when the componentis rendered in a web browser, as shown in Figure *@fig:addLink@*. Using callbacksallows us to define some code that will be executed when a link is clicked.We modify the method `WAComponent>>renderContentOn:` as in script*@scr:addCallback@*.```language=smalltalk&caption=Add anchors and callbacks to your counter&label=scr:addCallbackWebCounter >> renderContentOn: html |
| 14 | + html heading: count. |
| 15 | + html anchor |
| 16 | + callback: [ self increase ]; |
| 17 | + with: '++'. |
| 18 | + html space. |
| 19 | + html anchor |
| 20 | + callback: [ self decrease ]; |
| 21 | + with: '--'```!!note Don’t forget that `WAComponent>>renderContentOn:` is on the _instance_ side.Each callback is given a Pharo block: an anonymous method \(strictly speaking, a_lexical closure_\) delimited by \[ and \]. Here we send the message`callback:` \(to the result of the anchor message\) and pass the block as theargument. In other words, we ask Seaside to execute our callback block wheneverthe user clicks on the anchor.Click on the links to see that the counter get increased or decreased as shownin Figure *@fig:callbackResult@*.#### Adding a Class Comment@pharoClassCommentA class comment \(along with method comments\) can help other developersunderstand a class. Do not forget to add a nice comment to your class and save it using your favorite version control system. When you’re studying a framework, class comments are a pretty goodplace to start reading. Classes that don’t have them require a lot moredeveloper effort to figure out so get in the habit of adding these comments toall of your classes.Now you are set to code in Seaside. ### Summary@pharoSummaryYou have now learned how to define a component, register it and modify it. Now you are ready to proceed to Part II to learn all thedetails of using Seaside to build powerful web applications. |
|
0 commit comments