Welcome to Webtalk, a framework for building web applications using Logtalk with SWI-Prolog as the backend. Templating features are provided by the simple_template SWI-Prolog pack.
-
SWI-Prolog >= 7.7.1
-
Logtalk >= 3.12.0
-
simple-template >= 1.2.0
All configurations, set using config_property/2
or daemon_option/2
, are currently in config.lgt
and can be adjusted using environment variables. daemon_option/2
is only to be used to store options related to running the server as a unix daemon. Environment variables are expected to be prefixed by the atom set using app_prefix/1
in config.lgt
. The default prefix is WEBTALK_
. The environment variables that are currently supported are detailed below.
All of these options are passed to the templating system to be made available in template files.
-
WEBTALK_SERVER_PORT
- configuresserver_port
, which is the port used when the application run usinghttp_server/2
instead ofhttp_daemon/1
. Default is5000
. -
WEBTALK_SITE_NAME
- configuressite_name
, which is the name of the site displayed in the navigation bar when using the default theme. Default isWebtalk
. -
WEBTALK_JQUERY_VERSION
- configuresjquery_version
, which is the version of the jQuery library used in the default theme. Default is3.2.1
. -
WEBTALK_JQUERY_VALIDATE_VERSION
- configuresjquery_validate_version
, which is the version of the jQuery validate library used in the default theme. Default is1.17.0
. -
WEBTALK_POPPER_VERSION
- configurespopper_version
, which is the version of the Popper.js library used in the default theme. Default is1.11.0
. -
WEBTALK_BOOTSTRAP_VERSION
- configuresbootstrap_version
, which is the version of the Bootstrap responsive framework that the default theme is based on. Default is4.0.0-beta
.
The details of all these options, except for daemonize
and daemon_https_only
can be found on the http_daemon/0 documention page on the SWI-Prolog website.
-
WEBTALK_DAEMONIZE
- configuresdaemonize
, which is a boolean value that inicates if the application is to be run usinghttp_daemon/1
instead ofhttp_server/2
. Default isfalse
. -
WEBTALK_DAEMON_HTTPS_ONLY
- configureshttps_only
, which, if set to true, forces all HTTP requests to be redirected to HTTPS. Default isfalse
. -
WEBTALK_DAEMON_PORT
- configuresdaemon_port
, which is--port
on the documentation page. If unset, the package default is used. -
WEBTALK_DAEMON_IP
- configuresdaemon_ip
, which is--ip
on the documentation page. If unset, the package default is used. -
WEBTALK_DAEMON_DEBUG
- configuresdaemon_debug
, which is--debug
on the documentation page. If unset, the package default is used. -
WEBTALK_DAEMON_SYSLOG
- configuresdaemon_syslog
, which is--syslog
on the documentation page. If unset, the package default is used. -
WEBTALK_DAEMON_USER
- configuresdaemon_user
, which is--user
on the documentation page. If unset, the package default is used. -
WEBTALK_DAEMON_GROUP
- configuresdaemon_group
, which is--group
on the documentation page. If unset, the package default is used. -
WEBTALK_DAEMON_PIDFILE
- configuresdaemon_pidfile
, which is--pidfile
on the documentation page. Default is/var/run/webtalk
. -
WEBTALK_DAEMON_OUTPUT
- configuresdaemon_output
, which is--ouput
on the documentation page. Default is/var/log/webtalk.log
. -
WEBTALK_DAEMON_FORK
- configuresdaemon_fork
, which is--fork
on the documentation page. If unset, the package default is used. -
WEBTALK_DAEMON_HTTP
- configuresdaemon_http
, which is--http
on the documentation page. If unset, the package default is used. -
WEBTALK_DAEMON_HTTPS
- configuresdaemon_https
, which is--https
on the documentation page. If unset, the package default is used. -
WEBTALK_DAEMON_CERTFILE
- configuresdaemon_certfile
, which is--certfile
on the documentation page. If unset, the package default is used. -
WEBTALK_DAEMON_KEYFILE
- configuresdaemon_keyfile
, which is--keyfile
on the documentation page. If unset, the package default is used. -
WEBTALK_DAEMON_PWFILE
- configuresdaemon_pwfile
, which is--pwfile
on the documentation page. If unset, the package default is used. -
WEBTALK_DAEMON_PASSWORD
- configuresdaemon_password
, which is--password
on the documentation page. If unset, the package default is used. -
WEBTALK_DAEMON_CIPHERLIST
- configuresdaemon_cipherlist
, which is--cipherlist
on the documentation page. If unset, the package default is used. -
WEBTALK_DAEMON_INTERACTIVE
- configuresdaemon_interactive
, which is--interactive
on the documentation page. If unset, the package default is used. -
WEBTALK_DAEMON_GTRACE
- configuresdaemon_gtrace
, which is--gtrace
on the documentation page. If unset, the package default is used. -
WEBTALK_DAEMON_SIGHUP
- configuresdaemon_sighup
, which is--sighup
on the documentation page. If unset, the package default is used. -
WEBTALK_DAEMON_WORKERS
- configuresdaemon_workers
, which is--workers
on the documentation page. If unset, the package default is used.
The following commands are to be issued in the base directory:
$ swilgt -s app.lgt
Environment variables may precede the command.
$ WEBTALK_DAEMONIZE=true sudo -E bash -c 'swilgt -s app.lgt'
For an example on how to run Webtalk as a systemd service, see the service template file of the webtalk-ops repository.
Webtalk supports customisation via pluggable themes and extensions. The best practice when developing a custom application is to avoid hacking the core at all costs and perform customizations via themes and extensions placed in the app/theme
and app/extension
directories respectively.
Custom pages can be added to an application by way of custom blueprints. As a best practice, each custom blueprint should be placed in its own subdirectory of the app/blueprint
directory, and should contain a .lgt file with the same name as the directory. For example, to create a blueprint that defines all the first level pages in your website's content structure, you could create a blueprint called first_level
at app/blueprint/first_level/first_level.lgt
.
To have such a blueprint overwrite core's main
blueprint, one would just have to reassign the HTTP handlers for the endpoints in main
to the first_level
class. For example:
:- http_handler(root(.),
[Request]>>(first_level::index(Request)), [id("first_level.index")])
Each custom theme must be placed in its own subdirectory of the app/theme
directory. The name of the subdirectory must correspond to the name of the theme and must contain, at least, a JSON theme info file, theme.json
, and a Logtalk theme file, theme_{{theme_name}}.lgt
. In addition to these, the theme directory must also contain a static
subdirectory, that is used for serving static files such as CSS, JS and image files, and a template
subdirectory that contains the HTML templates for the views that are rendered for the user. The directory tree below shows the structure of the default base
theme that is bundled with Webtalk.
base
├── static
│ ├── css
│ │ ├── simple-sidebar.css
│ │ └── style.css
│ └── js
│ ├── install.js
│ └── script.js
├── template
│ ├── auth
│ │ └── login.html
│ ├── base.html
│ ├── config
│ │ ├── appearance.html
│ │ ├── extensions.html
│ │ ├── index.html
│ │ └── vendor.html
│ ├── install
│ │ └── index.html
│ └── main
│ └── index.html
├── theme_base.lgt
└── theme.json
The expected values for the JSON info file are:
name
- The name of the theme, which must match the name of the theme directory.title
- The title of the theme that is displayed in configuration pages.description
- A brief description of the theme that is displayed in configuration pages.version
- The version number of the theme.
The theme_{{theme_name}}.lgt
file is expected to contain an object called theme_{{theme_name}}
, which extends the theme
prototype provided by the core library. This object must define, at least, the install/0
and uninstall/0
predicates that handle setting up and tearing down theme data on installing and uninstalling the theme respectively. The example below is the theme object of the default base
theme.
:- object(theme_base,
extends(theme)).
install :-
{assertz(user:file_search_path(static, core(theme/base)))}.
uninstall :-
{retractall(user:file_search_path(static, core(theme/base)))}.
:- end_object.
Each custom extension must be placed in its own subdirectory of the app/extension
directory. The name of the subdirectory must correspond to the name of the extension and must contain, at least, a JSON extension info file, extension.json
, and a Logtalk extension file, ext_{{extension_name}}.lgt
. The directory tree below shows the structure of the menu
extension that is bundled with Webtalk.
menu
├── extension.json
└── ext_menu.lgt
The expected values for the JSON info file are:
name
- The name of the extension, which must match the name of the theme directory.title
- The title of the extension that is displayed in configuration pages.description
- A brief description of the extension that is displayed in configuration pages.version
- The version number of the extension.
The ext_{{extension_name}}.lgt
file is expected to contain an object called ext_{{extension_name}}
, which extends the extension
prototype provided by the core library. This object must define, at least, the install/0
and uninstall/0
predicates that handle setting up and tearing down extension data on installing and uninstalling the extension respectively. The example below is a snippet from the extension object of the core menu
extension.
:- object(ext_menu,
extends(extension)).
...
install :-
::register_menu(main),
::register_menu(user),
templating::assert_data_hook(ext_menu, inject_menus).
uninstall :-
true.
...
:- end_object.
Webtalk supports dynamic menus via the core menu
extension, the functions of which are accessed via the ext_menu
object.
-
To register a new menu, the
register_menu/1
predicate can be used. Two menus,main
anduser
, are registered by default. -
Any menu created in this way can also be removed using the
deregister_menu/1
predicate. -
To add an item to a registered menu, the
add_menu_item/5
predicate can be used. The signature of this predicate isadd_menu_item(Menu, Title, Path, Weight, Description)
. The weight is an integer that affects the ascending sort order of the menu items. -
Menu items may be removed using the
remove_menu_item/2
predicate, the signature of which isremove_menu_item(Menu, Title)
. -
All registered menus are made available to all template files via the
menus
dictionary. For example, to access the items of themain
menu in a template file, one may use themenus.main.items
list.
Copyright (c) 2017 - 2018 Sando George.
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.