Method Libraries

Method library is a library of static resources (like JS, CSS and image files for some JS library) stored in plain methods. Note that everything is on class side and library is accessible image wide, not site by site.

Main advantage of method library is that static resources are not stored separately in files but are stored in methods in your image and specially, they can be versioned with Smalltalk versioning tools, which does not handle versioning of separated files. Another advantage is much easier installation - no need to care with separate files, one image is enough.

Library which originally came in hierarchy of directories can also be imported in method library.

Method libraries must be subclasses of class WebMethodLibrary.

Import or upgrade library

  • You can import or upgrade the library directly from internet:
WebMethodLibImporter default
   baseUrl: '/jquery-mobile';
   library: 'JQueryMobileLibrary';  "class name, lib class will be created if not yet exist"
   exclude: #('/demos');            "optional, exclude directories like demos etc."
   package: 'Aida-Libraries';       "optional, useful for new libraries, under Undeclared by default"
   import: 'http://code.jquery.com/mobile/1.1.1/jquery.mobile-1.1.1.zip' "also file:// or ftp://"
  • Put above script in library's class comment to ease its upgrade. Don't forget to save the script after any change.
  • To import from local file use file://, like 'file://~/jquery-1.8.2.zip' to import from home directory

On-demand loading of libraries

Libraries have the additional class side  #ensure methods which allows on-demand loading the library when needed. By example, to load jQuery for using UI Autocomplete field:

WebAutocopleteField>>initialize
    super initialize.
    JQueryLibrary ensureUI.

Ensure methods ensure that a library will be initialized properly by putting proper lines in page header. When you import a new library, you should write an appropriate class side #ensure method. See other libraries for examples. For jQuery there are two: #ensure, and #ensureUI. Let we see the later:

JQueryLibrary class>>ensureUI
    "ensure jQuery UI resources in page header"
    | page |
    self ensure. "base jQuery is always needed"
    page := self context page.
    self ensure: '/js/jquery-ui-1.8.21.custom.min.js' onPage: page.  "update those Urls after each library update!"
    self ensure: '/css/ui/jquery-ui-1.8.21.custom.css' onPage: page.

And how the page headers look like:

<head>
   ...
  <script  src="/jquery/js/jquery-1.7.2.min.js" language="JavaScript" type="text/javascript">script>
  <script  src="/jquery/js/jquery-ui-1.8.21.custom.min.js" language="JavaScript" type="text/javascript">script>
  <link rel="stylesheet" type="text/css" media="screen" href="/screen.css" >
  <link rel="stylesheet" type="text/css" media="print" href="/print.css" >
  <script  src="/scripts.js" language="JavaScript" type="text/javascript">script>
 head>

Note that resources from your style class are always put at the end in the header. This allows you to override both JS and CSS to your per-site specific needs, by providing js* and css* methods put in your own WebStyle subclass.

Resources from style class are always on the same Urls: /screen.css, /print.css, possibly /mobile.css, and /scripts.js.

Implementation

  • Resources are stored in class methods under 'resources' category
  • urlToMethodMap is created, as dictionary of resources relative Url a key, method and content type as value. for example:
urlToMethodMap
    "Url relative to base Url  as key, method and content type in value. Subclasess shall override
     this method according to example here"
    MapCache ifNotNil: [^MapCache].
    ^MapCache := Dictionary new
        at: '/jquery.mobile-1.1.1.css' put: #(jQueryMobile111Css  'text/css');
        at: '/jquery.mobile-1.1.1.js' put: #(jQueryMobile111Js  'application/javascript');
        yourself
  • both resource methods and urlToMethodMap are created automatically while importing/upgrading the library
  • WebMethodLibrary as superclass of all libraries is put as possible route in WebRouter (see #addMethodLibrariesRoute)
  • #resourceFor: aRequest class side in WebMethodLibrary then searches all subclasses for a resource on requests Url. If found, the library containing the resource is returned
  • #aidaPresenterFor: returns self in composing phase
  • #streamHtmlTo:for:on: then call the appropriate method gets its content type from a url-method map and sream resul directly to the response.