modules.anubis 9.91 KB

   
                                    The Anubis Project. 
   
                                 Making modular web sites.
   
                             Copyright (c) Alain Proute' 2005. 
   
   
   Author: Alain Proute'
   
   Last revision: November 2005.
   
   In  this  file, we  define  the notion  of  'web  module'. A  web  site  may be  easily
   constructed as  a tree of web modules.   This is an autonomous  abstraction layer above
   'web/making_a_web_site.anubis'.   If you  use this  modular system,  you don't  have to
   consider 'making_a_web_site.anubis' nor  'multihost_http_server.anubis', which are used
   transparently here.
   
   
read making_a_web_site.anubis
   
   
   
   
   *** (1) Overview. 
   
   A 'web module'  performs some particular task, and/or provides some  tools to other web
   modules. Web  modules are put  together into a  tree hierarchy. Hence, each  module has
   zero, one or more 'childs'. Each module  also has a set of customization parameters. In
   this file,  we explain how to  use existing modules in  order to make a  web site, very
   simply, just  by assembling modules. If  you want to  create new modules, see  the file
   'library/web/modules/common.anubis'.
   
   
   
   
   *** (2) Parameters and tools. 
   
   Each module  may be customized through  a set of  parameters whose type depends  on the
   particular module.  For example, the  set of parameters  for the module  'babel' (which
   provides tools for handling multilingual texts) is of type 'BabelParameters'. 
   
   Also, each module provides a set of 'tools'  to its childs. Again, the type of this set
   of tools depends on  the particular module.  For example, the set  of tools provided by
   the module 'babel' is of type 'BabelTools'.
   
   Each  module is  presented in  the form  of a  function taking  as arguments  a  set of
   parameters, and  several sets of tools.   For example, the module  'forum' requires the
   tools provided by the modules 'babel' and 'login', hence its type is:
   
                  (ForumParameters,
                   BabelTools,
                   LoginTools)                    -> WebModule
   
   The module  'forum' does not accept childs.  Another example, it that  of 'login' which
   accepts childs. The module 'login' is of type:
   
                  (LoginParameters, 
                   BabelTools, 
                   LoginTools -> List(WebModule)) -> WebModule
   
   The last argument is called (just once) by 'login' at the beginning, so that all childs
   of 'login' receive the login tools.
   
   Notice however,  that a module may  come in several different  'flavors' with different
   types. Hence, the use of a given set of tools may be optional. 
   
   

   *** (3) Constructing a tree of web modules. 

   Below  is an  example  of a  tree containing  the  three modules  'babel', 'login'  and
   'forum'. We saw already the types of 'forum' and 'login' above. The types of babel is:
   
                 (BabelParameters, 
                  BabelTools -> List(WebModule))   -> WebModule
   
   Hence, we can construct the following tree of modules (which is of type 'WebModule'):
   
   babel(my_babel_parameters,
         (BabelTools babel_t) |-> 
           [
             login(my_login_parameters,
                   babel_t,
                   (LoginTools login_t) |-> 
                     [
                       forum(my_forum_parameters,
                             babel_t, 
                             login_t)
                     ]
                  )
           ]
        )

   Have a look  at the files in  'library/web/modules' in order to choose  the modules you
   need for your web site.
   
   
   
   *** (4) Making a modular web site. 

   Now, in order  to make a modular web site,  you just have to provide  a list of 'common
   names' for your site, and a root module.
   
public type WebModule:...             (an opaque type)   
public type ModularWebSite:...        (an opaque type)
   
public define ModularWebSite   
   modular_web_site
     (
       List(String)        common_names, 
       String              site_directory, 
       WebModule           root_module
     ). 
   
   The list of common names is used  by the HTTP/HTTPS server for dispatching the requests
   between the several sites you are starting. For example, it could be:
   
       ["www.our-business.com","www.our-business.local"]
   
   where "www.our-business.com"  is the actual name of  the site (as registred  in the DNS
   servers), and "www.our-business.local"  is for testing your site  locally. For example,
   if the web server is started on the machine whose IP address on your local area network
   is 192.168.0.2, you may  add the following line in your 'hosts'  file (under both Linux
   and Windows):
   
   192.168.0.2    www.our-business.local
   
   so that you can test your site locally using the address 'www.our-business.local'. 

   
   
   
   *** (5) Starting your web sites. 
   
   Now,  you  can start  several  web  sites. You  just  have  to  provide several  global
   informations (common to all your web sites), and a list of modular web sites:
   
public define One
   start_web_sites
     (
       Int32                        ip_address,    // the IP address shared by the web sites
       Int32                        http_port,     // usually: 80
       Int32                        https_port,    // usually: 443
       String                       ssl_certificate_common_name, 
       List(ModularWebSite)         web_sites      // web sites to be started
     ).      
   
   
   
   
   
   *** (6) An example. 
   
   To make a multilingual forum, construct the following source file:
   
   read web/modules.anubis
   read web/modules/babel.anubis
   read web/modules/login.anubis
   read web/modules/forum.anubis
   
   global define One
     start_my_forum
       (
         List(String) args
       ) =
   start_web_sites
     (
       0,       // listen on all interfaces
       80,      // HTTP port
       443,     // HTTPS port
       "www.myforum.com",
       [
         modular_web_site
           (
             [
               "www.myforum.com",
               "www.myforum.local"
             ],
             "/home/georges/myforum",
             babel(default_babel_parameters,
                   (BabelTools babel_t) |-> 
                     [
                       login(default_login_parameters,
                             babel_t,
                             (LoginTools login_t) |-> 
                               [
                                 forum(default_forum_parameters,
                                 babel_t, 
                                 login_t)
                               ]
                             )
                     ]
                  )
           )
       ]
     ).
   
   
   
   --- That's all for the public part ! --------------------------------------------------

   
read common.anubis
read multihost_http_server.anubis   
read mime.anubis   
   
type ModularWebSite:
   mws
     (
       FinalWebModule
     ). 
   
type FinalWebModule:
   fwm
     (
       List(String)          common_names
     ). 
   
public type WebModule:
   web_module
     (
       (List(String)  common_names, 
        String        site_directory) -> FinalWebModule     finalize
     ). 
   
   
   
public define ModularWebSite   
   modular_web_site
     (
       List(String)        common_names, 
       String              site_directory, 
       WebModule           root_module
     ) =
   mws
     (
       common_names, 
       site_directory, 
       if root_module is web_module(finalize)
         then finalize(site_directory)
     ). 
   
   
   
type ModularState:...   
   
define ModularState
   initial_modular_state
     (
       HTTP_Info i
     ). 
   
   
define ModularState
   ticket_expired_modular_state
     (
       ModularState    expired, 
       HTTP_Info        http_info, 
       List(Web_arg)   lwa, 
       Bool            is_https
     ). 
   
define ModularState
   ticket_lost_modular_state
     (
       HTTP_Info        http_info, 
       List(Web_arg)   lwa, 
       Bool            is_https
     ). 
   
   
   
type FinalWebModule:...   
   
define List(Web_Action(ModularState))
   get_web_actions
     (
       FinalWebModule    mwm
     ). 
   
define ModularState -> HTML_Page
   get_compute_page
     (
       FinalWebModule    mwm
     ). 
     
define List(Redirection)
   get_redirections
     (
       FinalWebModule    mwm
     ). 
     

define (String,List(Web_arg)) -> One
   get_before_send_file
     (
       FinalWebModule    mwm
     ). 
     
   
define Web_Site
   to_web_site
     (
       ModularWebSite    mws
     ) =
   if mws is mws(common_names,
                 site_directory, 
                 root_module) then 
   make_web_site_description
     (
       common_names,
       site_directory,
       (One u) |-> unique, 
       initial_modular_state, 
       ticket_expired_modular_state, 
       ticket_lost_modular_state,
       get_web_actions(root_module),
       get_compute_page(root_module), 
       3600, 
       get_redirections(root_module), 
       "UTF-8", 
       [".awp"],
       ["user-agent","host"],
       to_ascii(sha1((random(10000),random(10000),random(10000)))),
       known_mime_types,
       get_before_send_file(root_module)
     ). 
   
   
   
   
   
public define One
   start_web_sites
     (
       Int32                        ip_address,    // the IP address shared by the web sites
       Int32                        http_port,     // usually: 80
       Int32                        https_port,    // usually: 443
       String                       ssl_certificate_common_name, 
       List(ModularWebSite)         modular_web_sites      // web sites to be started
     ) =
   with shutdown_required = var((Bool)false), 
   start_web_sites
     (
       ip_address, 
       http_port, 
       https_port, 
       ssl_certificate_common_name, 
       map(to_web_site,modular_web_sites),
       shutdown_required
     ).