7. Architecture

Building a UI with widgets does not only consist of adding elements one after another; there must be a minimal structure that lets them relate to each other. So a widget can use resources of another (get the text entered by the user, know if it is validated, know the selected option...). For that we will learn the minimal concepts with the goal of creating scalable and reusable interfaces.

We are going to explore the order and steps a UI must follow to be created.

1. Imports

At the start we must import the widget and wid-edit packages.

;; Imports
(require 'widget)

(eval-when-compile
  (require 'wid-edit))

Actually the widget package is empty, it is kept for backward compatibility. Internally it imports the wid-edit package, which is the one that contains all the functionality. Hence the eval-when-compile condition that lets the wid-edit package be compiled before being used.

If you use other packages, this is the right place to import them.

2. Variables

When you create a widget, it is added to the current buffer but its reference is lost. To be able to access it, we must create a variable that contains it. For example:

(defvar input-email)

Later, when we create the widget, we will assign it to this variable.

(setq input-email (widget-create 'editable-field
                 :size 30
                 :format "Email: %v"))

We will never create the variable and the widget in the same step since widgets are created where the cursor is. We must have control over where they are created.

3. Functions

All the logic that the buttons, text fields, validations, utilities, etc. will use.

You should have a function dedicated exclusively to redrawing the widgets depending on the state of the application or the variables.

4. Layout

The functions that create the widgets and add them to the buffer. In other words, the user interface.

I recommend creating a function called main-layout with the main widgets and other minor functions to update parts of the interface. For example: header-layout, first-step-layout, contact-layout, modal-layout, etc.

A main layout, or main-layout, must follow the following scheme:

;; Optional, if it is going to be called from a button
(interactive)
;; Switch to a new buffer
(switch-to-buffer "Buffer name")
;; Clear the buffer of local variables and overlays
(kill-all-local-variables)
(let ((inhibit-read-only t))
    (erase-buffer))
(remove-overlays)

;; The widgets will go here
(widget-insert "Title \n\n")
(setq input-field-1 (widget-create 'editable-field
                     :size 5
                     :tag "Number 1"
                     :help-echo "Type a number"
                     :valid-regexp "^[0-9]+$"
                     :error "Invalid number"
                     :notify #'input-show-error
                     :format "%v"))
;; The widgets end here

;; Set the keymap for the widgets
(use-local-map widget-keymap)
;; Configure all the widgets for user interaction, for example, show them with the right appearance, allow navigation between them with the keyboard and respond to mouse events
(widget-setup)
;; Optional, give focus to the first widget
(widget-forward 1)

5. Initialization

We call the main-layout function, or whatever you have called it, so it runs and shows the user interface.

(main-layout)

Summary

A good way to create a UI is to keep the following structure:

;; Imports

;; Variables
(defvar state)
(defvar input-email)

;; Functions
(defun init ())
(defun update ())

;; Layouts
(defun main-layout ())
(defun login-layout ())

;; Initialization
(init)

If you look at all the previous examples, you will find this same structure. And later we will keep using it to create more complex interfaces.

Practice and keep your code tidy.

In the following lessons we are going to focus on organizing and reusing the widgets.

Building SPAs with Django and HTML Over the Wire: Learn to build real-time single page applications with Python

Building SPAs with Django and HTML Over the Wire: Learn to build real-time single page applications with Python

The HTML over WebSockets approach simplifies single-page application (SPA) development and lets you bypass learning a JavaScript rendering framework such as React, Vue, or Angular, moving the logic to Python. This web application development book provides you with all the Django tools you need to simplify your developments with real-time results.

Buy the book

Help me keep writing

Every coffee gives me a push toward the next article.

Comments

There are no comments yet.