No description
Find a file
2025-12-22 00:29:52 +01:00
examples Complete rewrite of extended example 2025-12-22 00:26:33 +01:00
app-o-matic.css Various minor improvements to basic framework: script, style and README 2025-12-22 00:20:20 +01:00
app-o-matic.js Various minor improvements to basic framework: script, style and README 2025-12-22 00:20:20 +01:00
README.md Fixed typos in README 2025-12-22 00:29:52 +01:00

App-O-Matic

Instant Web App Framework

Features

  • Open Source
  • Light weight: no dependencies
  • Multilingual
  • Responsive design: tabbed view on laptop, thumb friendly menu on mobile devices
  • Support for dark mode
  • Easy sharing page/view by email, Mastodon, Element or url
  • Support for back end through API calls
  • JWT Authentication in conjunction with account API / identity server

Getting started: Just Add Content!

The basic idea is that you put some HTML documents in a folder, add the app-o-matic script and stylesheet to their <head> sections, and add a json configuration file to set up a menu, title etc.

  1. Get ingredients: Download app-o-matic
  2. Write a menu: Define the main hierarchy of tabbed pages
  3. Cook up a number of HTML pages and add the app-o-matic sauce by including stylesheet and javascript
  4. Add extra's to taste: better visuals, a back-end server,
  5. Serve

A number of examples are provided in the examples folder:

  1. Basic: A simple example app with 2 views
    • Text
    • Draw an image
  2. Extended:
    • add a multilingual interface
    • local storage
    • visualisation libraries
    • sharing mechanism
  3. Backend: add API calls to a database for authentication
  4. Services: integrate into the mobile OS environment

1. Install

Download a zip file from src.giplt.nl/harmen/app-o-matic and extract in a folder, or use git

git clone https://src.giplt.nl/harmen/app-o-matic.git

An App-O-Matic Progressive Web App has the following basic folder structure:

├─── app-o-matic
│    ├─── app-o-matic.css    Stylesheet
│    └─── app-o-matic.js     Magic sauce
├─── languages               Language files
│    └─── en.json
├─── libraries               Extra libraries for visuals, calculations, back end calls, service workers et cetera
│    └─── *.min.js
├─── pages                   Repository of the HTML pages you want to combine in a Web App
│    ├─── help.html          Page which is made available in the options menu
│    └─── *.html
├─── images                  Various images for the user interface
│    ├─── app-o-matic.ico    Favicon which will show in a browsers' tab
│    └─── *.svg              SVG icons for the User Interface
├─── config.json             Configuration file telling App-O-Matic how to combine the HTML pages in a menu structure
├─── index.html              Landing page
└─── manifest.json           Another configuration file telling a PWA packager how to make your web pages into a native smartphone app

2. Menu

The config.json document in the root of your app is used to setup your app. It defines the title, available languages, default language, a menu structure and some very basic theming. Together with the content in the folder pages this generates the appearance and interaction of a simple web app which can be accessed in a browser of packaged and installed as a native smartphone app.

Example config.json

{
	"title": "MyApp",
	"languages": "en",
	"defaultLanguage": "en",
	"menu": [
		{
			"filename": "write.html",
			"tabname": "write",
			"icon": "typewriter"
		}
		,{
			"filename": "draw.html",
			"tabname": "draw",
			"icon": "pen-swirl"
		}
	],
	"theme": {
		"light": {
			"background": "#100040",
			"color": "#ffffff"
		},
		"dark": {
			"background": "#100040",
			"color": "#bfbfbf"
		}
	}
}

3. Pages

App-o-matic pages are simnple HTML pages linking to the App-o-matic stylesheet and javascript, and placed in the folder pages.

Example page.html

<!DOCTYPE html>
<html lang="en">
	<head>
		<!-- PWA framework -->
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" />
		<link rel="stylesheet" href="PATH/TO/app-o-matic.css">
		<script type="text/javascript" src="PATH/TO/app-o-matic.js" defer></script>
		<link rel="icon" type="image/x-icon" href="images/app-o-matic.ico">
	</head>
	<body>
		Page content
	</body>
</html>

4. Extra's

Images

Icons and other images can be put in the folder images.

Icons are black and white SVG images as these can be easily adapted to another color scheme. e.g. dark mode or some theme color.

A favicon which displays in a browser tab and additional images can be put in this folder as well

Text layout flag

By default the entire window surface is available for content, so that maps and other graphics can take advantage of the available pixels on bigger displays. However, when a class named text-layout is added to the body element of a page, it will be rendered in a single column of limited width on bigger screens to improve the readablility of text content.

<body class="text-layout">
	This text will be rendered with a limited line width on bigger screens.
</body>

Setup function

If a setup function is defined in a page it is called first after loading the page.

Example setup function

<body>
	<div id="foo">
		bar
	</div>
	<script>
		function setup() {
			document.getElementById('foo').innerHTML = 'baz';
		}
	</script>
</body>

Options menu

Page specific options can be added to the context or hamburger menu top left by adding a <div id="options"> element to the page body.

Example options menu

<body>
	<div id="foo">
		bar
	</div>
	<div id="options">
		<button onclick="changeText();"></button>
	</div>
	<script>
		function changeText() {
			document.getElementById('foo').innerHTML = 'baz';
		}
	</script>
</body>

Adding languages

For a multilingual web app, language files can be added to the language folder. These have a two letter (ISO 639) language code filename, e.g. en.json.

The language json files are lookup dictionaries with "id": "message" pairs.

In stead of text in the apps' pages one can add span elements with a data-i18n attribute holding the message id.

Language content in attributes can be translated by entering the message id as its value, with 'data-i18n-' as a prefix. More specifically this works for the attributes title, value and placeholder.

Example multilanguage text content

<span data-i18n="msg-id"></span>
<input title="data-i18n-msg-id"/>

When the config.json defines multiple languages app-o-matic will add a langugage selection option in the options menu and fill the language <span> elements with the corresponding messages from the language file of the active language.

Example config.json options for multiple languages

"languages": "en,nl",
"defaultLanguage": "en",

If multiple language are available as set in config.json a language selector is added to the options menu.

Additional libraries

Libraries for additional functionality like rendering maps, graphs, tables or formula's, doing calculations or back end calls etc can be placed in the libraries folder.

Preferably these are light weight addons which can be added as a self contained js file to improve usability also on low resource devices and avoid dependency on external CDN's.

Some personal favorites:

  • sorttable makes all your tables sortable.
  • dygraphs is a fast, flexible open source JavaScript charting library.

LocalStorage

Data can be stored on the device or in the browser using the localStorage object. This mechanism is used to store JWT authentication keys but can also be used to store other content, preferences etc that should persist between sessions.

To avoid conflicts between various apps the path part of the webapps' url is added as a prefix to the variable. App wide variable names should be prefixed with the path variable, e.g.

localStorage.setItem(path + 'myVar');
localStorage.getItem(path + 'myVar', myData);

Data which is specific to a page in the app can be stored by adding the page's filename, e.g.

localStorage.setItem(path + filename + 'myVar');
localStorage.getItem(path + filename + 'myVar', myData);

A page specific JSON object named view' is stored and retrieved by default. This can be used to store data or rendering settings that will allow a user to pick up interaction from the same state where the last session was left, e.g. lon/lat/zoom for a map

Sharing mechanism

The page's url and an encoded view object can be shared through a link that is generated in the share menu. Sending this link to someone else lets them pick up the work where you left it. If the view object is available from both localStorage and a share link the latter takes precedence.

Integration with API backend

JWT

Service workers

Background behaviour: what should the app do when the user focuses on another app?

  • timers for regular updates from a server
  • pause calculations or stay on a job

Notification: How to interact with the systems notification infrastructure

  • sounds
  • messages
  • in icon
  • on home screen
  • on sleep screen

Updates

5. Serve

The webapp can be simply deployed by uploading the files to a web server. It can now be viewed in a browser in any device. In order to distribute as a native app a few more steps are needed to package for various platforms.

Packaging

PWA Builder