Faire un site web avec Gambas

modifier

Note : vous devriez avoir déjà fait les tutoriels précédents avant de suivre celui-ci !

Note : Le tutoriel ci-après est destiné à vous montrer comment ça fonctionne. Il n'est pas destiné à être pris comme modèle. Tout à la fin de cette page, vous trouverez un lien sur un site fonctionnel.

Tutoriel

modifier

Démarrez l'environnement de développement et créez un nouveau projet de type "Application Web CGI" ! Appelez votre projet "webdemo" par exemple !

Ajoutez un module comme suit :

  • Sur la gauche, dans le volet du projet, faites un clic-droit sur Sources et
  • Cliquez sur Nouveau, Module
  • Nommez-le GlobalRequestHandler !

Définissez ce module comme module de démarrage :

  • Sur la gauche, dans le volet du projet, faites un clic-droit sur GlobalRequestHandler puis
  • Classe de démarrage

Supprimez les autres modules, classes et autres composants !

Ajoutez le composant Web de Gambas qui va vous permettre de réagir aux divers sollicitations des utilisateurs du site :

  • Cliquez sur le menu Projet !
  • Cliquez sur Propriétés !
  • Activez l'onglet Composants !
  • Le composant gb.web doit être activé !

En suite, comme pour les autres tutoriels, vous allez copier le code ci-dessous :

' Gambas module file

' pour tester / ces informations devraient être créées
'  et lues dans une base de données.
Public Const constStrAdminEMail As String = "admin"
Public Const constStrAdminPWD As String = "secret"

Public Const constSPathDelim As String = "/"
Public Const constSRqstLastErr As String = "lastrequesterror"
Public Const constSRqstController As String = "controller"
Public Const constSRqstControllerDefault As String = ""
Public Const constSRqstControllerAccount As String = "account"
Public Const constSRqstAction As String = "action"
Public Const constSRqstActionNone As String = ""
Public Const constSRqstActionSignIn As String = "signin"
Public Const constSRqstActionCreate As String = "create"
Public Const constSRqstActionLogin As String = "login"
Public Const constSRqstActionLogout As String = "logout"
Public Const constSRqstActionShowState As String = "showstate"
Public Const constSRqstActionCheckCredentials As String = "checkcredentials"
Public Const constSUserEMail As String = "email"
Public Const constSUserPassword As String = "pwd"
Public Const constSUserAccountIsCreated As String = "accountcreated"
Public Const constSUserAccountIsCreatedTrueValue As String = "true"
Public Const constSUserLogged As String = "logged"
Public Const constSUserLoggedTrueValue As String = "true"


' la procédure Main() est appelée à l'arrivée de chaque requête.
'  C'est un contrôleur qui gère les inputs de l'extérieur ...
Public Sub Main()

  ManageIncomingRequest()

End


Private Sub ManageIncomingRequest()

  ' Arrivée d'une requête ...
  ' =====================
  '
  Select Case Request.Method
    Case "POST"
      ManageIncomingInformations()
      Response.Redirect(Application.Root)
    Case "GET"
      BuildResponse()
    Case ""
      BuildResponse()
    Case Else
      Session[constSRqstLastErr] = "The HTML Request Method " & Request.Method & " is not supported!"
      Response.Redirect(Application.Root)
  End Select

End


Private Sub ManageIncomingInformations()

  Session[constSRqstLastErr] = ""
  ' - l'utisateur nous envoie des informations à traiter ...
  ' - on retient le controleur et l'action voulue ...
  If Request.Post.Exist(constSRqstController) Then
    Session[constSRqstController] = Request[constSRqstController]
  Else
    Session[constSRqstController] = constSRqstControllerDefault
  Endif
  If Request.Post.Exist(constSRqstAction) Then
    Session[constSRqstAction] = Request[constSRqstAction]
  Else
    Session[constSRqstAction] = constSRqstControllerDefault
  Endif
  '
  ' - traitement des informations spécifiques à chaque formulaire ...
  Select Case Request[constSRqstController]
    Case constSRqstControllerDefault
      If Not Request[constSRqstAction] = constSRqstActionNone Then
        Session[constSRqstLastErr] = "Unrecognized action for the default controller!"
      Endif
    Case constSRqstControllerAccount
      ManageIncomingInformationsAccount()
    Case Else
      Session[constSRqstLastErr] &= "Unrecognized controller : " & Request[constSRqstController]
      Session[constSRqstLastErr] &= "! Operation not supported!"
  End Select

End


Private Sub ManageIncomingInformationsAccount()

  Select Case Request[constSRqstAction]
    Case constSRqstActionCreate
      ManageIncomingInformationsAccountCreate()
    Case constSRqstActionSignIn
      ' For now, nothing to manage here ...
    Case constSRqstActionLogin
      ' For now, nothing to manage here ...
    Case constSRqstActionCheckCredentials
      ManageIncomingInformationsAccountCheckCredentials()
    Case constSRqstActionLogout
      ManageIncomingInformationsAccountLogout()
    Case constSRqstActionShowState
      ' For now, nothing to manage here ...
    Case Else
      Session[constSRqstLastErr] &= "Unrecognized action in the account controller! ("
      Session[constSRqstLastErr] &= Request[constSRqstAction] & ")"
  End Select

End


Private Sub ManageIncomingInformationsAccountCreate()

  If Request.Post.Exist(constSUserEMail) Then
    Session[constSUserEMail] = Request[constSUserEMail]
  Else
    Session[constSRqstLastErr] &= "The User E-Mail is missing! "
  Endif
  If Not Request.Post.Exist(constSUserPassword) Then
    Session[constSRqstLastErr] &= "The User Password is missing! "
  Endif
  If Request[constSUserEMail] = constStrAdminEMail And
      Request[constSUserPassword] = constStrAdminPWD And
      (Not (Session[constSUserAccountIsCreated] = constSUserAccountIsCreatedTrueValue)) Then
    Session[constSUserPassword] = "" ' Le mot de passe n'est pas géré dans les cookies ...
    Session[constSUserLogged] = constSUserLoggedTrueValue
    Session[constSUserAccountIsCreated] = constSUserAccountIsCreatedTrueValue
    Session.Save
  Else
    If Session[constSUserLogged] Then
      Session[constSUserLogged] = ""
    Endif
    Session[constSRqstLastErr] &= "A problem occured in the login process! "
  Endif
  ' set the future redirection ..
  If Session[constSRqstLastErr] Then
    Session[constSRqstAction] = constSRqstActionNone
    Session[constSRqstController] = constSRqstControllerDefault
  Else
    Session[constSRqstController] = constSRqstControllerAccount
    Session[constSRqstAction] = constSRqstActionShowState
  Endif

End


Private Sub ManageIncomingInformationsAccountCheckCredentials()

  If Request.Post.Exist(constSUserEMail) Then
    Session[constSUserEMail] = Request[constSUserEMail]
  Else
    Session[constSRqstLastErr] &= "The User E-Mail is missing! "
  Endif
  If Not Request.Post.Exist(constSUserPassword) Then
    Session[constSRqstLastErr] &= "The User Password is missing! "
  Endif
  If Request[constSUserEMail] = constStrAdminEMail And
      Request[constSUserPassword] = constStrAdminPWD And
      Session[constSUserAccountIsCreated] = constSUserAccountIsCreatedTrueValue Then
    Session[constSUserPassword] = "" ' Le mot de passe n'est pas géré dans les cookies ...
    Session[constSUserLogged] = constSUserLoggedTrueValue
    Session.Save
  Else
    If Session[constSUserLogged] Then
      Session[constSUserLogged] = ""
    Endif
    Session[constSRqstLastErr] &= "A problem occured in the login process! "
  Endif
  ' set the future redirection ..
  If Session[constSRqstLastErr] Then
    Session[constSRqstController] = constSRqstControllerDefault
    Session[constSRqstAction] = constSRqstActionNone
  Else
    Session[constSRqstController] = constSRqstControllerAccount
    Session[constSRqstAction] = constSRqstActionShowState
  Endif

End


Private Sub ManageIncomingInformationsAccountLogout()

  If Session[constSUserLogged] Then
    Session[constSUserLogged] = ""
  Endif
  Session.Save()
  Session[constSRqstController] = constSRqstControllerDefault
  Session[constSRqstAction] = constSRqstActionNone

End

Private Sub BuildResponse()

  Response.Begin
  BuildSharedStart()
  If Session[constSRqstLastErr] Then BuildErrorMsg()
  Select Case Session[constSRqstController]
    Case constSRqstControllerAccount
      BuildResponseAccount()
    Case Else
      BuildResponseDefault()
  End Select
  BuildSharedEnd()
  Response.End

End


Private Sub BuildSharedStart()

  Print "<html>"
  Print "<head>"
  Print " <title>" & Application.Name & "</title>"
  Print "</head>"
  Print "<body>"

End


Private Sub BuildErrorMsg()

  Print " <div name=\"errormessage\">"
  Print Session[constSRqstLastErr]
  Print " </div>"

End


Private Sub BuildResponseAccount()

  Select Case Session[constSRqstAction]
    Case constSRqstActionLogin
      BuildResponseAccountLogin()
    Case constSRqstActionSignIn
      BuildResponseAccountSignIn()
    Case constSRqstActionShowState
      BuildResponseAccountShowState()
    Case Else
      BuildResponseDefault()
  End Select

End


Private Sub BuildResponseDefault()

  Print "<h1>Welcome</h1>"
  If Session[constSUserLogged] = constSUserLoggedTrueValue Then
    ' admin
    Print "<p>You are logged as " & Session[constSUserEMail] & " with privileges!</p>"

  Else
    ' guest
    Print "<p>This is the default page for guests ...</p>"
    If Session[constSUserAccountIsCreated] = constSUserAccountIsCreatedTrueValue Then
      PrintHtmlCodeForButton(constSRqstControllerAccount, constSRqstActionLogin, "Login")
    Else
      PrintHtmlCodeForButton(constSRqstControllerAccount, constSRqstActionSignIn, "SignIn")
    Endif

  Endif
  PrintHtmlCodeForButton(constSRqstControllerAccount, constSRqstActionShowState, "Show account state")

End


Private Sub BuildResponseAccountLogin()

  Print "<h1>Login</h1>"
  Print "<form method=\"POST\">"
  Print "  E-Mail<br>"
  Print "  <input type=\"text\" name=\"" & constSUserEMail & "\" value=\"" & Session[constSUserEMail] & "\"><br>"
  Print "  Password<br>"
  Print "  <input type=\"password\" name=\"" & constSUserPassword & "\"><br>"
  Print "  <input type=\"hidden\" name=\"" & constSRqstController & "\" value=\"" & constSRqstControllerAccount & "\">"
  Print "  <input type=\"hidden\" name=\"" & constSRqstAction & "\" value=\"" & constSRqstActionCheckCredentials & "\">"
  Print "  <input type=\"submit\" value=\"LogIn\">"
  Print "</form action>"
  PrintHtmlCodeForButton("account", "signin", "SignIn Page")
  PrintHtmlCodeForButton("", "", "Back to the Welcome Page!")

End


Private Sub BuildResponseAccountSignIn()

  Print "<h1>SignIn</h1>"
  Print "<form method=\"POST\">"
  Print "  E-Mail<br>"
  Print "  <input type=\"text\" name=\"" & constSUserEMail & "\"><br>"
  Print "  Password<br>"
  Print "  <input type=\"password\" name=\"" & constSUserPassword & "\"><br>"
  Print "  <input type=\"hidden\" name=\"" & constSRqstController & "\" value=\"" & constSRqstControllerAccount & "\">"
  Print "  <input type=\"hidden\" name=\"" & constSRqstAction & "\" value=\"" & constSRqstActionCreate & "\">"
  Print "  <input type=\"submit\" value=\"SignIn\">"
  Print "</form action>"
  PrintHtmlCodeForButton("account", "login", "Login Page")
  PrintHtmlCodeForButton("", "", "Back to the Welcome Page!")

End


Private Sub BuildResponseAccountShowState()

  Print "<h1>Account State</h1>"
  If Session[constSUserAccountIsCreated] = constSUserAccountIsCreatedTrueValue Then
    If Session[constSUserLogged] = constSUserLoggedTrueValue Then
      Print "<p>Your E-Mail is " & Session["email"] & ". You're in!</p>"
      Print "<form method=\"POST\">"
      Print "  <input type=\"hidden\" name=\"" & constSRqstController & "\" value=\"" & constSRqstControllerAccount & "\">"
      Print "  <input type=\"hidden\" name=\"" & constSRqstAction & "\" value=\"" & constSRqstActionLogout & "\">"
      Print "  <input type=\"submit\" value=\"LogOut\">"
      Print "</form action>"
    Else
      Print "<p>Your E-Mail is " & Session["email"] & ". You're currently logout ... </p>"
      PrintHtmlCodeForButton("account", "login", "Login Page")
    Endif
  Else
    Print "<p>You're a Guest! </p>"
    PrintHtmlCodeForButton("account", "signin", "Create Account!")
  Endif
  PrintHtmlCodeForButton("", "", "Go to the Welcome Page!")

End


Private Sub BuildSharedEnd()

  Print "</body>"
  Print "</html>"

End


' utilitaires ...
Private Sub PrintHtmlCodeForButton(ControllerName As String, ActionName As String, ButtonCaption As String)

  Print "<form method=\"POST\">"
  Print "  <input type=\"hidden\" name=\"" & constSRqstController & "\" value=\"" & ControllerName & "\">"
  Print "  <input type=\"hidden\" name=\"" & constSRqstAction & "\" value=\"" & ActionName & "\">"
  Print "  <input type=\"submit\" value=\"" & ButtonCaption & "\">"
  Print "</form>"

End

C'est un exemple volontairement simplifié qui n'est pas destiné à être mis en production.

À chaque fois que l'utilisateur veut quelque-chose, c'est à dire à chaque fois qu'il clique ou qu'il fait F5 dans son navigateur, il y a une requête HTTP qui arrive côté serveur. Cette requête peut être de type GET ou de type POST ou autres.

Dans le code ci-dessus, on trouve le type et on réagit en fonction du type. Si c'est GET, c'est une demande d'afficher une page. Si c'est POST, c'est une nouvelle information que l'on doit traiter.

Dans tous les cas, on va devoir renvoyer une réponse c'est à dire une page avec le contenu demandé ou le résultat du traitement !

Le chemin affiché dans le navigateur a aussi son importance. Nous pouvons l'utiliser pour savoir quelle est la partie du site concernée et quelle action est demandée. Une autre manière de faire consiste à enregistrer les choix de l'utilisateur avec l'objet Session ou dans une base de données.

Nous n'en n'avons pas fini en ce qui concerne l'exemple web. Un autre tutoriel concernera le déploiement de votre application Web CGI.

Lien(s)

modifier

En cas d'intérêt, voici un premier lien qui vous permettra de trouver le code du gambas-farm-server : https://gitlab.com/gambas/gambas

Allez sous

  • app
  • src
  • gambas-farm-server
  • .src
  • MMain.module

C'est une Web Application avec un module unique MMain. Il semble que le projet utilise de nombreux composants :

  • gb.db
  • gb.db.mysql
  • gb.db.sqlite3
  • gb.image
  • gb.image.io
  • gb.net
  • gb.net.smtp
  • gb.settings
  • gb.util.web
  • gb.web

Voici un second lien sur le projet GambasForge : code source ici.

GambasForge est un site fonctionnel réalisé avec la version 2 de Gambas. Pour rappel, nous en sommes à la version 3.