Seaside

                                             Build
                                                    ing
      ...
This is not...
This is not...


        A Seaside
         Tutorial
What we‘ll look at
What we‘ll look at

Quick, what is Seaside?
What we‘ll look at

Quick, what is Seaside?
Parallels between Fat client development in
VAST and Seaside Web development
What we‘ll look at

Quick, what is Seaside?
Parallels between Fat client development in
VAST and Seaside Web development
T...
Quick, what is
  Seaside?
Quick, what is
  Seaside?

                A very short
        introduction to the
                Seaside Web
     Appli...
Overview

Open Source
Started by Avi Bryant in 2001
Currently maintained by Lukas Renggli,
Adrian Lienhardt and others
In ...
In Production

DabbleDB (by Avi        Reserve Travel (Hotel
Bryant‘s company)       Booking engine)

CMSBox              ...
Seaside is different

Components vs. html-pages
You never see http requests or responses
(unless you want to)
No templatin...
Pure Smalltalk

Components defined in Smalltalk
Control Flow in Smalltalk
   No XML configuration, no state machine
   Plain...
Components

Subclasses of WAComponent
Hold state
render themselves: #renderContentOn:
Can have subcomponents (#children)
R...
Rendering a Component
WAStoreCartView>>renderContentOn: html
   cart hasItems ifFalse: [^ self].
   html div
      id: 'ca...
Rendering a Component
                                     html is the canvas
                                     we‘re p...
Rendering a Component
WAStoreCartView>>renderContentOn: html
   cart hasItems ifFalse: [^ self].
   html div
      id: 'ca...
Rendering a Component
                              rendering can include
                                 application log...
Rendering a Component
WAStoreCartView>>renderContentOn: html
   cart hasItems ifFalse: [^ self].
   html div
      id: 'ca...
Rendering a Component
                   a DIV tag for
WAStoreCartView>>renderContentOn: html
                   applying ...
Rendering a Component
WAStoreCartView>>renderContentOn: html
   cart hasItems ifFalse: [^ self].
   html div
      id: 'ca...
Rendering a Component
         this is a brush to
WAStoreCartView>>renderContentOn: html
        paint on the canvas
   ca...
Rendering a Component
WAStoreCartView>>renderContentOn: html
   cart hasItems ifFalse: [^ self].
   html div
      id: 'ca...
Rendering a Component
WAStoreCartView>>renderContentOn: html
   cart hasItems ifFalse: [^ self].
           with: is alway...
Rendering a Component
WAStoreCartView>>renderContentOn: html
   cart hasItems ifFalse: [^ self].
   html div
      id: 'ca...
Rendering a Component
WAStoreCartView>>renderContentOn: html
   cart hasItems ifFalse: [^ self].
   html div
      id: 'ca...
Rendering a Component
WAStoreCartView>>renderContentOn: html
   cart hasItems ifFalse: [^ self].
   html div
      id: 'ca...
Rendering a Component
WAStoreCartView>>renderContentOn: html
   cart hasItems ifFalse: [^ self].
   html div
      id: 'ca...
Rendering a Component
WAStoreCartView>>renderContentOn: html
   cart hasItems ifFalse: [^ self].
   html div
      id: 'ca...
Rendering and Callbacks
WAStoreCartView>>renderRowForCount: aNumber of: anItem
on: html
   | countString |
   countString ...
Rendering and Callbacks
WAStoreCartView>>renderRowForCount: aNumber of: anItem
on: html
   | countString |
   countString ...
Rendering and Callbacks
WAStoreCartView>>renderRowForCount: aNumber of: anItem
on: html
   | countString |
   countString ...
Rendering and Callbacks
WAStoreCartView>>renderRowForCount: aNumber of: anItem
on: html
   | countString |
   countString ...
Rendering and Callbacks
WAStoreCartView>>renderRowForCount: aNumber of: anItem
on: html
   | countString |
   countString ...
Rendering and Callbacks
                   f!
                 o
WAStoreCartView>>renderRowForCount: aNumber of: anItem


...
Rendering Result - the page
Rendering Result - the page
                           this is the
                         subcomponent
                 ...
Rendering Result - the page
Rendering Result - html
<!DOCTYPE html PUBLIC quot;-//W3C//DTD XHTML 1.0 Strict...>
<html xmlns=...>
...
<div id=quot;cart...
CSS for the Design

Components generate valid XHTML only
CSS files for Designing the XHTML output
   separation between cod...
Seaside development
 for VA Smalltalkers
Seaside development
   for VA Smalltalkers
       lels
  aral
P
        een
   etw
b
      side
 Sea           ent
       ...
Components vs.
    Visual Parts
Both can be composed to complex
components with subcomponents
Controls are event driven
Ca...
Composed Components
                 vs. Subparts
                                                                     Com...
Composed Components
                 vs. Subparts                                                                         ...
Event-to-Action
             connections

abtBuildInternals
...
refreshButton
    abtWhenPrimitive: #clicked
    perform: ...
Action and Value
             Callbacks
renderContentOn: html
  ...
  html submitButton
    callback: [self applicationMod...
Differences
Feedback cycle:
 Fat client: instant feedback
 Web: On Submit (AJAX / Scriptaculous for
 immediate feedback)
S...
Control Flow
Tasks


Subclasses of WATask
Control flow
single method #go
Can call Tasks and Components
Call and Answer

Components and Tasks can #call: and
#answer:
Caller gets replaced by callee / delegate
Control is delegat...
Call and Answer (2)

        Component 1
handleSomeCallbackWith: param
 ...
                                              ...
Call and Answer (2)
                                             Component 2 gets
                                      re...
Call and Answer (2)
                                                    Component 2 gets
                                 ...
A typical Fat Client
  in VA Smalltalk
A typical Fat Client
  in VA Smalltalk
                      typically your
 Workflow Controller
                       fra...
A typical Fat Client
        in VA Smalltalk
                               typically your
          Workflow Controller
  ...
A typical Fat Client
        in VA Smalltalk
                                 typically your
          Workflow Controller
...
A typical Fat Client
        in VA Smalltalk
                                       typically your
          Workflow Contr...
A typical Seaside
  Application
A typical Seaside
  Application
                     call:
   WATask           answer:
A typical Seaside
        Application
                           call:
            WATask        answer:

                ...
A typical Seaside
        Application
                             call:
            WATask          answer:

            ...
A typical Seaside
        Application
                                   call:
            WATask                answer:

...
ga
               tin          ion
            ri           at
          W          lic          ga
                   p
 ...
Seaside and
Rich Internet Applications
Ajax

Most popular RIA technology
Combination of
   Server Side-Application Code
   JavaScript in the Browser
   XML HTTP ...
JavaScript Libraries

Numerous available
Most Popular (and one of the most mature /
complete)
    Prototype
    Script.acu...
Seaside and Scriptaculous

Seaside wrappers Prototype / Scriptaculous
Developer writes Smalltalk code
JavaScript ‚rendered...
Demo
From Fat Client to
Seaside Application

            What you have to
                  look at
            and change in a...
From Fat Client to
 Seaside Application
Persistency

               What you have to
                     look at
        ...
From Fat Client to
 Seaside Application
Persistency
Back-end access
                   What you have to
                  ...
From Fat Client to
 Seaside Application
Persistency
Back-end access
                   What you have to
                  ...
From Fat Client to
 Seaside Application
Persistency
Back-end access
                   What you have to
                  ...
Comparing the two
  architectures
                                                                       Database
        ...
Changing the
          Architecture
Easier when layers are clearly structured
MVC Pattern
Business logic should be fully r...
Persistency
                            on a Fat Client
                                                                  ...
Persistency
                                 on a Web Server
                                                             ...
Persistency
   on a Web Server
Connection Pooling
Parallel Transactions
Isolation on Image Level
Multithreading
All suppor...
Accessing Backend
     Systems
CICS, Host-programs etc.
Requests may not block the server
Multithreading
Last Resort: Repl...
Another Interaction
      model
HTML is different than a local GUI
Server Round-Trip vs. instant Event
handling
 Validatio...
Possible Solutions
JavaScript-based
                                Ajax-calls for server-side
Validation in the
         ...
Other Topics
  Access Control

Many fat client apps use DB
password of current user
User management and access
control nee...
Other Topics
      Performance
Server Smalltalk and Seaside can
handle several hundred requests per
second on a normal PC
...
Other Topics
      Production
Logging
Error reporting
Health checks
Performance measurement and
reporting


              ...
Other Topics
        Availability
Scheduled Downtimes for
Maintenance Tasks
 DB Reorganization
 Installing Fixpacks
 New r...
Deployment scenario
Seaside       Seaside         Seaside        Seaside
 Image         Image           Image          Ima...
How to start
a conversion project?
Build a prototype (3-4 developers)
Choose a few dialogs of your app
 Some easier ones t...
Advantages of
a conversion project?
Reuse existing Smalltalk Know-How
Reuse existing business code
Adopt corporate Design ...
Questions?


       Contact details:
       objektfabrik Joachim Tuchel
       Fliederweg 1
       71640 Ludwigsburg,
    ...
u
              o
            y
         k
       n            !
     a            g
   h           in
T            n
    ...
Building Seaside Applications in VA Smalltalk
Upcoming SlideShare
Loading in...5
×

Building Seaside Applications in VA Smalltalk

3,451

Published on

Short intro to Seaside Web Programming in Smalltalk.
Thoughts and experiences on turning existing Smalltalk applications into a Web Application Server using Seaside. Seaside makes Web programming very much like writing a modal fat/rich client application.
This presentation was given at the VA Smalltalk Forum Europe 2008.
For more information visit http://www.objektfabrik.de

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
3,451
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
0
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide


























































































































































































  • Transcript of "Building Seaside Applications in VA Smalltalk"

    1. 1. Seaside Build ing Web App licat VA S ions i n mall talk Vers ion 8 © Joachim Tuchel, www.objektfabrik.de
    2. 2. This is not...
    3. 3. This is not... A Seaside Tutorial
    4. 4. What we‘ll look at
    5. 5. What we‘ll look at Quick, what is Seaside?
    6. 6. What we‘ll look at Quick, what is Seaside? Parallels between Fat client development in VAST and Seaside Web development
    7. 7. What we‘ll look at Quick, what is Seaside? Parallels between Fat client development in VAST and Seaside Web development Turning a fat client into a Seaside Web application
    8. 8. Quick, what is Seaside?
    9. 9. Quick, what is Seaside? A very short introduction to the Seaside Web Application Framework
    10. 10. Overview Open Source Started by Avi Bryant in 2001 Currently maintained by Lukas Renggli, Adrian Lienhardt and others In productive use since 2002 Available for Squeak,VisualWorks, Gemstone, Dolphin and soon VA Smalltalk
    11. 11. In Production DabbleDB (by Avi Reserve Travel (Hotel Bryant‘s company) Booking engine) CMSBox Run Basic www.cmsbox.ch auctomatic.com Seaside.st (Homepage whooka.com (outdoor of Seaside) sports) In-house applications many more...
    12. 12. Seaside is different Components vs. html-pages You never see http requests or responses (unless you want to) No templating or mixing code and design (like jsp‘s) Share as much as possible Components hold application state
    13. 13. Pure Smalltalk Components defined in Smalltalk Control Flow in Smalltalk No XML configuration, no state machine Plain Smalltalk code Debugging in Smalltalk ! You can read all code and learn from it
    14. 14. Components Subclasses of WAComponent Hold state render themselves: #renderContentOn: Can have subcomponents (#children) Reusable (same page and other pages) Pages are composed of components
    15. 15. Rendering a Component WAStoreCartView>>renderContentOn: html cart hasItems ifFalse: [^ self]. html div id: 'cart'; with: [ html small: [ html strong: 'Your cart:' ]. html table: [ cart countsAndItems do: [:assoc | self renderRowForCount: assoc key of: assoc value on: html ]. html tableRow: [ html space]. html tableRow: [ html tableData: ''. html tableData: ''. html tableData: [ html strong: cart totalPrice printStringAsCents ] ] ] ]
    16. 16. Rendering a Component html is the canvas we‘re painting on WAStoreCartView>>renderContentOn: html cart hasItems ifFalse: [^ self]. html div id: 'cart'; with: [ html small: [ html strong: 'Your cart:' ]. html table: [ cart countsAndItems do: [:assoc | self renderRowForCount: assoc key of: assoc value on: html ]. html tableRow: [ html space]. html tableRow: [ html tableData: ''. html tableData: ''. html tableData: [ html strong: cart totalPrice printStringAsCents ] ] ] ]
    17. 17. Rendering a Component WAStoreCartView>>renderContentOn: html cart hasItems ifFalse: [^ self]. html div id: 'cart'; with: [ html small: [ html strong: 'Your cart:' ]. html table: [ cart countsAndItems do: [:assoc | self renderRowForCount: assoc key of: assoc value on: html ]. html tableRow: [ html space]. html tableRow: [ html tableData: ''. html tableData: ''. html tableData: [ html strong: cart totalPrice printStringAsCents ] ] ] ]
    18. 18. Rendering a Component rendering can include application logic WAStoreCartView>>renderContentOn: html cart hasItems ifFalse: [^ self]. html div id: 'cart'; with: [ html small: [ html strong: 'Your cart:' ]. html table: [ cart countsAndItems do: [:assoc | self renderRowForCount: assoc key of: assoc value on: html ]. html tableRow: [ html space]. html tableRow: [ html tableData: ''. html tableData: ''. html tableData: [ html strong: cart totalPrice printStringAsCents ] ] ] ]
    19. 19. Rendering a Component WAStoreCartView>>renderContentOn: html cart hasItems ifFalse: [^ self]. html div id: 'cart'; with: [ html small: [ html strong: 'Your cart:' ]. html table: [ cart countsAndItems do: [:assoc | self renderRowForCount: assoc key of: assoc value on: html ]. html tableRow: [ html space]. html tableRow: [ html tableData: ''. html tableData: ''. html tableData: [ html strong: cart totalPrice printStringAsCents ] ] ] ]
    20. 20. Rendering a Component a DIV tag for WAStoreCartView>>renderContentOn: html applying CSS cart hasItems ifFalse: [^ self]. formatting html div id: 'cart'; with: [ html small: [ html strong: 'Your cart:' ]. html table: [ cart countsAndItems do: [:assoc | self renderRowForCount: assoc key of: assoc value on: html ]. html tableRow: [ html space]. html tableRow: [ html tableData: ''. html tableData: ''. html tableData: [ html strong: cart totalPrice printStringAsCents ] ] ] ]
    21. 21. Rendering a Component WAStoreCartView>>renderContentOn: html cart hasItems ifFalse: [^ self]. html div id: 'cart'; with: [ html small: [ html strong: 'Your cart:' ]. html table: [ cart countsAndItems do: [:assoc | self renderRowForCount: assoc key of: assoc value on: html ]. html tableRow: [ html space]. html tableRow: [ html tableData: ''. html tableData: ''. html tableData: [ html strong: cart totalPrice printStringAsCents ] ] ] ]
    22. 22. Rendering a Component this is a brush to WAStoreCartView>>renderContentOn: html paint on the canvas cart hasItems ifFalse: [^ self]. html div id: 'cart'; with: [ html small: [ html strong: 'Your cart:' ]. html table: [ cart countsAndItems do: [:assoc | self renderRowForCount: assoc key of: assoc value on: html ]. html tableRow: [ html space]. html tableRow: [ html tableData: ''. html tableData: ''. html tableData: [ html strong: cart totalPrice printStringAsCents ] ] ] ]
    23. 23. Rendering a Component WAStoreCartView>>renderContentOn: html cart hasItems ifFalse: [^ self]. html div id: 'cart'; with: [ html small: [ html strong: 'Your cart:' ]. html table: [ cart countsAndItems do: [:assoc | self renderRowForCount: assoc key of: assoc value on: html ]. html tableRow: [ html space]. html tableRow: [ html tableData: ''. html tableData: ''. html tableData: [ html strong: cart totalPrice printStringAsCents ] ] ] ]
    24. 24. Rendering a Component WAStoreCartView>>renderContentOn: html cart hasItems ifFalse: [^ self]. with: is always the html div call on a brush last id: and writes xhtml 'cart'; with: [ html small: [ html strong: 'Your cart:' ]. html table: [ cart countsAndItems do: [:assoc | self renderRowForCount: assoc key of: assoc value on: html ]. html tableRow: [ html space]. html tableRow: [ html tableData: ''. html tableData: ''. html tableData: [ html strong: cart totalPrice printStringAsCents ] ] ] ]
    25. 25. Rendering a Component WAStoreCartView>>renderContentOn: html cart hasItems ifFalse: [^ self]. html div id: 'cart'; with: [ html small: [ html strong: 'Your cart:' ]. html table: [ cart countsAndItems do: [:assoc | self renderRowForCount: assoc key of: assoc value on: html ]. html tableRow: [ html space]. html tableRow: [ html tableData: ''. html tableData: ''. html tableData: [ html strong: cart totalPrice printStringAsCents ] ] ] ]
    26. 26. Rendering a Component WAStoreCartView>>renderContentOn: html cart hasItems ifFalse: [^ self]. html div id: 'cart'; blocks for nesting with: [ certain brushes/tags html small: [ html strong: 'Your cart:' ]. html table: [ cart countsAndItems do: [:assoc | self renderRowForCount: assoc key of: assoc value on: html ]. html tableRow: [ html space]. html tableRow: [ html tableData: ''. html tableData: ''. html tableData: [ html strong: cart totalPrice printStringAsCents ] ] ] ]
    27. 27. Rendering a Component WAStoreCartView>>renderContentOn: html cart hasItems ifFalse: [^ self]. html div id: 'cart'; with: [ html small: [ html strong: 'Your cart:' ]. html table: [ cart countsAndItems do: [:assoc | self renderRowForCount: assoc key of: assoc value on: html ]. html tableRow: [ html space]. html tableRow: [ html tableData: ''. html tableData: ''. html tableData: [ html strong: cart totalPrice printStringAsCents ] ] ] ]
    28. 28. Rendering a Component WAStoreCartView>>renderContentOn: html cart hasItems ifFalse: [^ self]. html div id: 'cart'; with: [ cart is an inst var html small: [ html strong: 'Your cart:' ]. of the component html table: [ cart countsAndItems do: [:assoc | self renderRowForCount: assoc key of: assoc value on: html ]. html tableRow: [ html space]. html tableRow: [ html tableData: ''. html tableData: ''. html tableData: [ html strong: cart totalPrice printStringAsCents ] ] ] ]
    29. 29. Rendering a Component WAStoreCartView>>renderContentOn: html cart hasItems ifFalse: [^ self]. html div id: 'cart'; with: [ html small: [ html strong: 'Your cart:' ]. html table: [ cart countsAndItems do: [:assoc | self renderRowForCount: assoc key of: assoc value on: html ]. html tableRow: [ html space]. html tableRow: [ html tableData: ''. html tableData: ''. html tableData: [ html strong: cart totalPrice printStringAsCents ] ] ] ]
    30. 30. Rendering and Callbacks WAStoreCartView>>renderRowForCount: aNumber of: anItem on: html | countString | countString := (aNumber = 1) ifTrue: [''] ifFalse: ['(', aNumber displayString, ') ']. html tableRow: [ html tableData: [ html anchor callback: [ cart remove: anItem ]; with: '-']. html tableData: countString, anItem title. html tableData: (aNumber * anItem price) printStringAsCents ]
    31. 31. Rendering and Callbacks WAStoreCartView>>renderRowForCount: aNumber of: anItem on: html | countString | countString := (aNumber = 1) ifTrue: [''] the anchor brush ifFalse: ['(', aNumber displayString, ') ']. html tableRow: [ a link draws html tableData: [ html anchor callback: [ cart remove: anItem ]; with: '-']. html tableData: countString, anItem title. html tableData: (aNumber * anItem price) printStringAsCents ]
    32. 32. Rendering and Callbacks WAStoreCartView>>renderRowForCount: aNumber of: anItem on: html | countString | countString := (aNumber = 1) ifTrue: [''] ifFalse: ['(', aNumber displayString, ') ']. html tableRow: [ html tableData: [ html anchor callback: [ cart remove: anItem ]; with: '-']. html tableData: countString, anItem title. html tableData: (aNumber * anItem price) printStringAsCents ]
    33. 33. Rendering and Callbacks WAStoreCartView>>renderRowForCount: aNumber of: anItem on: html | countString | countString := (aNumber = 1) this block will be ifTrue: [''] evaluated when user ifFalse: ['(', aNumber displayString,the link ']. clicks ') html tableRow: [ html tableData: [ html anchor callback: [ cart remove: anItem ]; with: '-']. html tableData: countString, anItem title. html tableData: (aNumber * anItem price) printStringAsCents ]
    34. 34. Rendering and Callbacks WAStoreCartView>>renderRowForCount: aNumber of: anItem on: html | countString | countString := (aNumber = 1) ifTrue: [''] ifFalse: ['(', aNumber displayString, ') ']. html tableRow: [ html tableData: [ html anchor callback: [ cart remove: anItem ]; with: '-']. html tableData: countString, anItem title. html tableData: (aNumber * anItem price) printStringAsCents ]
    35. 35. Rendering and Callbacks f! o WAStoreCartView>>renderRowForCount: aNumber of: anItem g tS on: html ns | countString | ie countString := (aNumber = 1) su ifTrue: [''] r ifFalse: ['(', aNumber displayString, ') ']. aq html tableRow: [ html tableData: [ Pe html anchor callback: [ cart remove: anItem ]; with: '-']. oR html tableData: countString, anItem title. NP html tableData: (aNumber * anItem price) printStringAsCents ] T T H
    36. 36. Rendering Result - the page
    37. 37. Rendering Result - the page this is the subcomponent we just rendered
    38. 38. Rendering Result - the page
    39. 39. Rendering Result - html <!DOCTYPE html PUBLIC quot;-//W3C//DTD XHTML 1.0 Strict...> <html xmlns=...> ... <div id=quot;cartquot;> <small><strong>Your cart:</strong><small> <table> <tr> <td><a href=quot;http://localhost:...quot;>-</a></ td><td>California Roll</td><td>$2.50</td></tr> <tr> <td><a href=quot;http://localhost:...quot;>-</a></ td><td>Akagai</td><td>$3.00</td></tr> <tr>&nbsp;</tr> <tr> <td></td><td></td><td><strong>$5.50</strong></ td></tr> </table> </div>
    40. 40. CSS for the Design Components generate valid XHTML only CSS files for Designing the XHTML output separation between code and design code is written by developer, css is written by web designer Served from within Image or from external web sever
    41. 41. Seaside development for VA Smalltalkers
    42. 42. Seaside development for VA Smalltalkers lels aral P een etw b side Sea ent lopm eve d and ient Cl Rich ent opm alk vel de allt A Sm in V
    43. 43. Components vs. Visual Parts Both can be composed to complex components with subcomponents Controls are event driven Callbacks to perform Smalltalk methods
    44. 44. Composed Components vs. Subparts Component renderContentOn: renderContentOn: html Your personal todomatic Page ... html render: mySubComponent1. html render: mySubComponent2. ... Save Logoff Subcomonent Subcomponent renderContentOn: renderContentOn: Checkbox Array: Option 1 ! Option 3 ! Option 5 Your rating: ! Option 2 Option 4 Multi-select: Full List My Items Item 1 none avarage: Item 2 Item 3 Item 4 Favourite: City, State, Postal - Select One - City Postal State Code:
    45. 45. Composed Components vs. Subparts don‘t call renderContentOn: of child components! Seaside calls it! Component renderContentOn: renderContentOn: html Your personal todomatic Page ... html render: mySubComponent1. html render: mySubComponent2. ... Save Logoff Subcomonent Subcomponent renderContentOn: renderContentOn: Checkbox Array: Option 1 ! Option 3 ! Option 5 Your rating: ! Option 2 Option 4 Multi-select: Full List My Items Item 1 none avarage: Item 2 Item 3 Item 4 Favourite: City, State, Postal - Select One - City Postal State Code:
    46. 46. Event-to-Action connections abtBuildInternals ... refreshButton abtWhenPrimitive: #clicked perform: ( conn22 := AbtEventToActionConnection new source: refreshButton; eventName: #clicked; actionProvider: applicationModel variableFeatureName: #refreshTrafficMessages featureSelector: #IS_refreshTrafficMessages).
    47. 47. Action and Value Callbacks renderContentOn: html ... html submitButton callback: [self applicationModel refreshTrafficMessages]; with: ‘Refresh‘. ... html label: ‘Please enter a name:‘. html textInput callback: [:txt| self name: txt]; value: self name. “or in short form“ html textInput on: #name of: self.
    48. 48. Differences Feedback cycle: Fat client: instant feedback Web: On Submit (AJAX / Scriptaculous for immediate feedback) Seaside has no GUI painter out of the box projects going on useful in HTML/CSS ?
    49. 49. Control Flow
    50. 50. Tasks Subclasses of WATask Control flow single method #go Can call Tasks and Components
    51. 51. Call and Answer Components and Tasks can #call: and #answer: Caller gets replaced by callee / delegate Control is delegated to callee #answer:returns a result to caller and returns control to caller
    52. 52. Call and Answer (2) Component 1 handleSomeCallbackWith: param ... Component 2 result := self call: ((Component2 new) renderContentOn: html someInstVar: param; html form: [ yourself). html text: someInstVar result ifTrue: [self saveData] printString. ifFalse: [self discardAll]. html submitButton callback: [self answer: true] text: ‚Okay, save this‘].
    53. 53. Call and Answer (2) Component 2 gets rendered in place of Component Component 1 1 and takes control of request/ response processing handleSomeCallbackWith: param ... Component 2 result := self call: ((Component2 new) renderContentOn: html someInstVar: param; html form: [ yourself). html text: someInstVar result ifTrue: [self saveData] printString. ifFalse: [self discardAll]. html submitButton callback: [self answer: true] text: ‚Okay, save this‘].
    54. 54. Call and Answer (2) Component 2 gets rendered in place of Component Component 1 1 and takes control of request/ response processing handleSomeCallbackWith: param ... Component 2 result := self call: ((Component2 new) renderContentOn: html someInstVar: param; html form: [ yourself). html text: someInstVar result ifTrue: [self saveData] printString. ifFalse: [self discardAll]. html submitButton callback: [self answer: true] text: ‚Okay, save this‘]. Component 1 gets back control as soon as Comp.2 was submitted and can use the answer to continue
    55. 55. A typical Fat Client in VA Smalltalk
    56. 56. A typical Fat Client in VA Smalltalk typically your Workflow Controller framework
    57. 57. A typical Fat Client in VA Smalltalk typically your Workflow Controller framework View Controller(s) typically a visual part / Composition Editor
    58. 58. A typical Fat Client in VA Smalltalk typically your Workflow Controller framework View View Controller(s) Controller(s) typically a visual part / Composition Editor
    59. 59. A typical Fat Client in VA Smalltalk typically your Workflow Controller framework View View ... Controller(s) Controller(s) typically a visual part / Composition Editor
    60. 60. A typical Seaside Application
    61. 61. A typical Seaside Application call: WATask answer:
    62. 62. A typical Seaside Application call: WATask answer: rendering Component request handling call/answer rendered by Web browser
    63. 63. A typical Seaside Application call: WATask answer: rendering Component Component request handling call/answer rendered by Web browser
    64. 64. A typical Seaside Application call: WATask answer: rendering ... Component Component request handling call/answer rendered by Web browser
    65. 65. ga tin ion ri at W lic ga p Ap itin ide like wr as Se ion h cat uc li m pp ry ve IA is GU al od M
    66. 66. Seaside and Rich Internet Applications
    67. 67. Ajax Most popular RIA technology Combination of Server Side-Application Code JavaScript in the Browser XML HTTP Request as transport protocol for portions of a page
    68. 68. JavaScript Libraries Numerous available Most Popular (and one of the most mature / complete) Prototype Script.aculo.us Full access to CSS styles, DOM objects XmlHttpRequest Browser-neutral
    69. 69. Seaside and Scriptaculous Seaside wrappers Prototype / Scriptaculous Developer writes Smalltalk code JavaScript ‚rendered‘ in Smalltalk JavaScript is embedded in HTML Page html updater id: ‚myelement‘ callback: [:html| self renderNewStuffOn: html].
    70. 70. Demo
    71. 71. From Fat Client to Seaside Application What you have to look at and change in an existing application
    72. 72. From Fat Client to Seaside Application Persistency What you have to look at and change in an existing application
    73. 73. From Fat Client to Seaside Application Persistency Back-end access What you have to look at and change in an existing application
    74. 74. From Fat Client to Seaside Application Persistency Back-end access What you have to look at GUI Interaction and change in an existing application
    75. 75. From Fat Client to Seaside Application Persistency Back-end access What you have to look at GUI Interaction and change in an existing application Miscellaneous
    76. 76. Comparing the two architectures Database Database fat client Persistency Persistency server Persistency Business logic Business logic Persistency Business logic Presentation Presentation Business logic Presentation Presentation browser Presentation Presentation Presentation 34
    77. 77. Changing the Architecture Easier when layers are clearly structured MVC Pattern Business logic should be fully reusable Persistency Persistency Business logic Business logic Transition Controller Presentation Presentation Presentation View 35
    78. 78. Persistency on a Fat Client 1 or only a few ID lastname firstname 1 Henderson Joe active transactions 2 Levinson Mark 3 McLachlan Sarah per client Database Each client holds its own copy 1 Concurrency & Joe 1 Henderson Joe Isolation on Henderson 1 Joe Client 1 Database level Henderson Client 1 Client 1 36
    79. 79. Persistency on a Web Server Many active transactions ID lastname firstname 1 Henderson Joe 2 Levinson Mark 3 McLachlan Sarah Server holds 1 copy per session Database Concurrency in 1 Image or DB 1 1 Joe Joe Joe Henderson Henderson Henderson Isolation on Web Server Server / Session todomatic.com todomatic.com todomatic.com level Details of Joe Henderson Details of Joe Henderson Details of Joe Henderson 37
    80. 80. Persistency on a Web Server Connection Pooling Parallel Transactions Isolation on Image Level Multithreading All supported by current Frameworks 38
    81. 81. Accessing Backend Systems CICS, Host-programs etc. Requests may not block the server Multithreading Last Resort: Replace existing library with TCP/IP based communications 39
    82. 82. Another Interaction model HTML is different than a local GUI Server Round-Trip vs. instant Event handling Validation Error Reporting HTML knows no Datatypes, only text 40
    83. 83. Possible Solutions JavaScript-based Ajax-calls for server-side Validation in the validation Browser Faster Slower, many requests Server-side validation validation only necessary implemented on the server Type info needs to be Type info only on the sent to the browser server 41
    84. 84. Other Topics Access Control Many fat client apps use DB password of current user User management and access control needs to be implemented 42
    85. 85. Other Topics Performance Server Smalltalk and Seaside can handle several hundred requests per second on a normal PC Overall performance depends on application code more than SST/ Seaside 43
    86. 86. Other Topics Production Logging Error reporting Health checks Performance measurement and reporting 44
    87. 87. Other Topics Availability Scheduled Downtimes for Maintenance Tasks DB Reorganization Installing Fixpacks New releases Database Migrations Most important for Internet Apps 45
    88. 88. Deployment scenario Seaside Seaside Seaside Seaside Image Image Image Image Sticky Sessions Static Files HTTP Server with Load Balancing Images (e.g. Apache with mod_proxy_balancer or mod_rewrite) CSS Media... 46
    89. 89. How to start a conversion project? Build a prototype (3-4 developers) Choose a few dialogs of your app Some easier ones to start with ca. 2 complex ones to see if possible Address architectural risks ~2 months to make a decision
    90. 90. Advantages of a conversion project? Reuse existing Smalltalk Know-How Reuse existing business code Adopt corporate Design Standards seamless visual integration Keep the Pace of Smalltalk Make Teams‘ strengths visible
    91. 91. Questions? Contact details: objektfabrik Joachim Tuchel Fliederweg 1 71640 Ludwigsburg, Germany email: jtuchel@objektfabrik.de http://www.objektfabrik.de
    92. 92. u o y k n ! a g h in T n te ! s e li id r s o a f e S y jo n E

    ×