B4J Library [B4X] MiniHTML3

Version 3.06
MiniHTML library for B4X — a fluent HTML builder for B4J/B4A/B4i.

GitHub: https://github.com/pyhoon/MiniHTML3

Overview​

MiniHTML3 lets you construct HTML documents programmatically in B4X using an object-oriented, chaining API. Instead of concatenating strings, you build a tree of MiniHtml tag objects, then call build to render the final HTML string.
 

Attachments

  • MiniHTML.b4xlib
    21.8 KB · Views: 2
Last edited:

aeric

Expert
Licensed User
Longtime User

Features​

  • Fluent API — Method chaining for concise, readable code
  • Automatic tag mode — Self-closing (<br>, <img>), uniline (<span>text</span>), multiline (<div> text</div>), meta (<!DOCTYPE>, <meta>), or no-tag (raw text)
  • Class & style management — addClass, removeClass, addStyle, removeStyle with auto-sync to class/style attributes
  • Attribute helpers — attr, attr2 (map), attr3 (boolean), plus convenience methods: lang, required, disabled, checked, selected, hidden, readonly
  • HTML parsing — Parse existing HTML strings into MiniHtml objects (Parse, ConvertFromBytes, ConvertToMiniHtml)
  • CDN helpers — cdn, cdn2, cdn3 for adding <script> and <link> tags with integrity/crossorigin support
  • Comments — comment (indented), comment2 (inline)
  • Text wrapping — text, text2 (overwrite), textWrap (indented)
  • Output options — build (no indent), build2 (custom indent), buildImpl (custom indent + attribute alignment)
  • Flat/minified output — Set Flat = True to suppress line breaks
  • Indentation control — Customize indent string (default: " "), control indent per-node
  • Format attributes — FormatAttributes = True aligns attributes across lines
  • Child traversal — ChildByName, ChildById, ChildByIndex with deep search
 

aeric

Expert
Licensed User
Longtime User

Quick Start​

(Using MiniHTML Helper module)
B4X:
' Build a simple HTML page
Dim doc As MiniHtml
doc.Initialize("doctype")
doc.Append(GeneratePage)
Return doc.ToString

Sub GeneratePage As String
    Dim html1 As MiniHtml = MH.Html
    Dim head1 As MiniHtml = MH.Head.up(html1)
    Dim title1 As MiniHtml = MH.Title.up(head1)
    title1.text("Hello")
    Dim body1 As MiniHtml = MH.Body.up(html1)
    Dim div1 As MiniHtml = MH.Div.up(body1)
    div1.cls("container").text("Hello World!")
    Return html1.build
End Sub

To create a MiniHTML helper module:
  1. Add a new Code Module and name it MH.
  2. Put cursor after the line Sub Process_Globals.
  3. Start typing "minihelper".
  4. Press Enter.
  5. The code will be added to the module.
1781886830093.png
 
Last edited:

aeric

Expert
Licensed User
Longtime User

API Reference​

MH.bas — Tag Factories​

MethodTag
Html<html lang="en">
Head<head>
Body<body>
Title<title>
Div<div>
Span<span>
P<p>
Anchor<a>
Button<button>
Input<input>
Label<label>
Form<form>
Table<table>
Tr<tr>
Td<td>
Th<th>
Thead<thead>
Tbody<tbody>
Ul<ul>
Li<li>
SelectTag<select>
Option<option>
Textarea<textarea>
Img<img>
Meta<meta>
Link<link>
Script<script>
Style<style>
Strong<strong>
Br<br>
Nav<nav>
Icon<i>
Svg<svg>
Path<path>
Footer<footer>
Caption<caption>
H1, H2, H3, H5, H6Heading tags

MiniHtml — Key Methods​

Construction:
  • Initialize(Name) — Create a tag with auto-detected mode
  • build — Render to string (no indent, no CRLF on first line)
  • build2(indent) — Render with custom indent
  • buildImpl(indent, AlignAttributes) — Full control
Adding children:
  • add(ChildTag) — Add child, returns child
  • up(ParentTag) — Add to parent, returns self (alias for addTo)
  • addTo(ParentTag) — Add to parent, returns self
  • text(value) — Add inner text
  • text2(value) — Clear children and set inner text
  • textWrap(value) — Add indented inner text
  • script(value) — Add <script>value</script> child
  • linebreak — Add a non-indented line break
  • comment(value) — Add <!-- value --> with indent
  • comment2(value, newline) — Add inline comment
Attributes:
  • attr(key, value) — Set attribute
  • attr2(map) — Set multiple attributes from map
  • attr3(key) — Set boolean attribute (no value)
Classes & Styles:
  • cls(value) or addClass(value) — Add class(es)
  • removeClass(value) — Remove class
  • sty(value) or addStyle(value) — Add style(s) (semicolon-separated)
  • removeStyle(key) — Remove style
Boolean attributes:
  • required, disabled, checked, selected, hidden, readonly
CDN helpers:
  • cdn(format, url) — Add <script src="..."> or <link href="...">
  • cdn2(format, url, integrity, crossorigin) — With SRI
  • cdn3(format, url, keyvals) — With extra attributes
Traversal:
  • ChildByName(value) — Deep search by tag name
  • ChildById(value) — Deep search by id attribute
  • ChildByIndex(index) — Get child by position
Parsing & JSON:
  • Parse(HtmlText) — Parse HTML string into MiniHtml
  • FromJson(JsonStr) — Parse JSON string into MiniHtml tree (shorthand format)
  • FromMap(m As Map) — Parse pre-parsed Map into MiniHtml (shorthand format)
  • ToMap — Serialize MiniHtml tree to a Map in shorthand format
  • ToJson — Serialize MiniHtml tree to a JSON string
  • ConvertFromBytes(Buffer()) — Parse from byte array
  • ConvertToBytes — Serialize to byte array
  • ConvertToMiniHtml(HtmlNode) — Convert parser node to MiniHtml
Configuration:
  • Flat — Suppress line breaks (minified output)
  • Indentation — Enable/disable per-node indent
  • LineFeed — Enable/disable CRLF
  • IndentString — Indentation string (default: " ")
  • FormatAttributes — Align multi-line attributes
  • Mode — uniline, multiline, meta, self, notext
  • SpecialTags — Tags excluded from default indentation

MiniHtmlParser — HTML Parser​

The parser (credits to Erel) converts HTML strings into a tree of HtmlNode objects.

Types:
  • HtmlNode(Name, Children, Attributes, Closed, Parent)
  • HtmlAttribute(Key, Value)
Key methods:
  • Parse(HtmlText) — Returns root HtmlNode
  • FindNode(Root, TagName, Attribute) — Recursive node search
  • FindDirectNodes(Root, TagName, Attribute) — Direct children search
  • IsNodeMatches(Node, TagName, Attribute) — Match test
  • GetTextFromNode(Node, ChildIndex) — Extract text
  • GetAttributeValue(Node, Key, Default) — Get attribute value
  • UnescapeEntities(XmlInput) — Unescape HTML entities
  • PrintNode(node) — Debug output
  • CreateHtmlAttribute(Key, Value) — Create attribute
 

aeric

Expert
Licensed User
Longtime User

JSON to MiniHtml​

Build HTML from JSON using the shorthand format.

Format​

JSON:
{"tagname": {"property": "value", ...}}

The outer key is the tag name, and its value is a map of properties. A string value is treated as inner text.

Properties​

KeyTypeDescription
classstringCSS class(es)
stylestringCSS style(s)
textstringInner text
idstringid attribute
attrsmapAdditional attributes
childrenarrayNested elements (same format)
modestringuniline, multiline, meta, self
flatboolSuppress line breaks
indentationboolEnable indentation
formatattributesboolAlign multi-line attributes
requiredboolBoolean attribute
disabledboolBoolean attribute
checkedboolBoolean attribute
selectedboolBoolean attribute
hiddenboolBoolean attribute
readonlyboolBoolean attribute
(any other)*Treated as attribute

Examples​

B4X:
Dim m As MiniHtml
m.Initialize("")
Dim root As MiniHtml = m.FromJson($"
{
  "div": {
    "class": "container",
    "style": "margin: auto",
    "attrs": {"data-id": "123"},
    "children": [
      {"h1": {"text": "Title"}},
      {"p": {"class": "lead", "text": "Paragraph text"}},
      {"button": {
        "class": "btn btn-primary",
        "disabled": true,
        "text": "Submit"
      }}
    ]
  }
}
"$)
Return root.build

Array root for multiple fragments:
JSON:
[{"div": {"class": "alert", "text": "Message"}}, {"script": {"text": "console.log('ok')"}}]

String shorthand for text-only tags:
JSON:
{"span": "hello world"}

Pre-parsed Map:
B4X:
Dim map1 As Map = CreateMap("div": CreateMap("class": "foo", "text": "bar"))
Dim root As MiniHtml = m.FromMap(map1)

Round-trip (ToMap / ToJson)​

Serialize a MiniHtml tree back to Map or JSON:
B4X:
Dim m As MiniHtml
m.Initialize("")
Dim root As MiniHtml = m.FromJson(${"div": {"class": "container", "text": "Hello"}}$)

' To Map
Dim map1 As Map = root.ToMap

' To JSON string
Dim json As String = root.ToJson

Text-only shorthand is preserved:
B4X:
Dim el As MiniHtml
el.Initialize("span")
el.text("Hello")
Log(el.ToJson) ' {"span":"Hello"}

Mixed content (text + tags) uses a children array with strings for text:
B4X:
' Produces: {"children": ["Hello ", {"strong": {"text": "world"}}, "!"]}

Boolean attributes round-trip as true:
B4X:
Dim el As MiniHtml
el.Initialize("button")
el.required
el.text("Submit")
Log(el.ToJson) ' {"button": {"text": "Submit", "required": true}}
 

aeric

Expert
Licensed User
Longtime User

Helper.bas — Higher-Level UI Helpers​


Static-code module providing tag factories, Bootstrap 5 UI components, form helpers, HTMX helpers, and custom components for the MiniHTML library.

Tag Factories​

MethodTagNotes
CreateTag(Name)anyGeneric tag factory
Html<html>With lang="en"
Head<head>
Body<body>
Title<title>
Div<div>
Span<span>
P<p>
Anchor<a>
Button<button>
Strong<strong>
Br<br>
Nav<nav>
Form<form>
H1, H2, H3, H5, H6<h1>–<h6>
Script<script>
Style<style>
Meta<meta>
Link<link>
Icon<i>
Img<img>
Svg<svg>
Path<path>
Input<input>
Label<label>
Caption<caption>
Footer<footer>
Table<table>
Thead<thead>
Tbody<tbody>
Tr<tr>
Td<td>
Th<th>
Ul<ul>
Li<li>
SelectTag<select>
Option<option>
Textarea<textarea>

Custom Components​

MethodReturnsDescription
CreateAlertInfo(Message, Status)AlertInfoCreate alert data object
CreateToastInfo(Entity, Action, Message, Status)ToastInfoCreate toast data object
Alert(info)StringRenders <div class="alert alert-{status}">{message}</div>
Toast(id, table, info)StringHTMX out-of‑band swap container + MiniJs event dispatch
NavLinkItem(text, href, icon_cls, icon_title)MiniHtml<li class="nav-item"> with anchor + icon
AnchorIcon(cls, hx_get, title_text, icon_class)MiniHtmlAnchor with hx-get for modal trigger + icon
ButtonCloseMiniHtml<button type="button" class="btn-close" data-bs-dismiss="modal">
ButtonAdd(text, cls, hx_get, hx_target, hx_trigger, data_bs_target, data_bs_toggle)MiniHtmlButton with icon + HTMX modal attributes
ButtonSubmit(text, cls)MiniHtml<button type="submit">
ButtonCancel(text, cls)MiniHtml<button type="button" data-bs-dismiss="modal">
ButtonSearch(text, cls, hx_post, hx_target)MiniHtmlSearch button with HTMX attrs
InputSearch(cls, id, name)MiniHtml<input type="text"> search field
TextLabel(text, cls, forId)MiniHtml<label for="...">
FormGroupMiniHtml<div class="form-group">
InputGroupMiniHtml<div class="input-group mb-3">
HiddenInput(id, name, value)MiniHtml<input type="hidden">
RequiredLabel(text, forId)MiniHtmlLabel with red asterisk
RequiredTextInput(id, name, value)MiniHtmlRequired text input
RequiredDropdown(id, name)MiniHtmlRequired <select class="form-select">
ContainerModalMiniHtmlBootstrap 5 modal container (fade, centered)
ContainerModalWithButton(TitleText, ParagraphText, ButtonText)MiniHtmlModal with header, body, footer + dismiss button
ContainerToastMiniHtmlFixed-position toast container (bottom‑right)

Conversion Helpers​

MethodReturnsDescription
ConvertFromBytes(Buffer())MiniHtmlParse UTF‑8 byte array into MiniHtml tree
ConvertToMiniHtml(Root)Byte()Serialize MiniHtml tree to UTF‑8 byte array

Bootstrap Layout Helpers​

MethodReturnsDescription
ContainerMiniHtml<div class="container">
ContainerFluidMiniHtml<div class="container-fluid">
RowMiniHtml<div class="row">
Col(cols)MiniHtml<div class="col-{cols}">

Form Input Helpers​

All form helpers apply form-control class and guard empty-string parameters.
MethodReturnsDescription
InputText(id, name, value, placeholder)MiniHtml<input type="text">
InputEmail(id, name, value, placeholder)MiniHtml<input type="email">
InputPassword(id, name, placeholder)MiniHtml<input type="password">
InputNumber(id, name, value, MinValue, MaxValue, StepValue)MiniHtml<input type="number">
InputDate(id, name, value)MiniHtml<input type="date">
InputFile(id, name, accept, multiple)MiniHtml<input type="file">
TextareaInput(id, name, value, rows, placeholder)MiniHtml<textarea class="form-control">
CheckboxInput(id, name, value, text, checked)MiniHtmlform-check div with label
RadioInput(name, id, value, text, checked)MiniHtmlform-check div with label
SelectInput(id, name, options, selectedValue, prompt, required)MiniHtml<select class="form-select"> with <option> children
SelectInput expects options as a List of Map items with keys "value" and "text".

Bootstrap UI Components​

MethodReturnsDescription
CardMiniHtml<div class="card">
CardHeaderMiniHtml<div class="card-header">
CardBodyMiniHtml<div class="card-body">
CardFooterMiniHtml<div class="card-footer">
CardTitleMiniHtml<h5 class="card-title">
CardTextMiniHtml<p class="card-text">
Badge(text, cls)MiniHtml<span class="badge {cls}">{text}</span>
ListGroupMiniHtml<ul class="list-group">
ListGroupItem(text, cls)MiniHtml<li class="list-group-item {cls}">{text}</li>
ListGroupButton(text, cls, active)MiniHtml<button class="list-group-item list-group-item-action {cls}[ active]">
ProgressBar(now, MinValue, MaxValue, cls, showLabel)MiniHtmlProgress bar with ARIA attrs
Spinner(cls, text)MiniHtml<div class="spinner-border {cls}"> + sr‑only text
SpinnerGrow(cls, text)MiniHtml<div class="spinner-grow {cls}"> + sr‑only text
AlertDismissible(message, status)MiniHtmlDismissible Bootstrap alert with close button

HTMX Helpers​

MethodReturnsDescription
HxGet(href, target, swap, trigger)MiniHtmlAnchor with hx-get, hx-target, hx-swap, hx-trigger
HxPost(href, target, swap)MiniHtmlButton with hx-post, hx-target, hx-swap

Navigation Helpers​

MethodReturnsDescription
Navbar(brand, expand, cls)MiniHtml<nav class="navbar navbar-expand-{expand} {cls}"> with brand
NavItem(text, href, active)MiniHtml<li class="nav-item"><a class="nav-link[ active]" href="...">

Utility Helpers​

MethodReturnsDescription
CssLink(href)MiniHtml<link rel="stylesheet" href="...">
JsScript(src)MiniHtml<script src="...">
ImgResponsive(src, alt, cls)MiniHtml<img class="img-fluid {cls}" src="..." alt="...">
PageHeading(text, tag)MiniHtmlGeneric heading tag with inner text
ButtonIcon(text, iconCls, btnCls)MiniHtmlButton with icon + text
AnchorButton(text, href, cls)MiniHtmlAnchor styled as button (class="btn {cls}")

Types​

B4X:
Type AlertInfo (Message As String, Status As String)
Type ToastInfo (Entity As String, Action As String, Message As String, Status As String)
 

aeric

Expert
Licensed User
Longtime User

Cache.bas — Page & Component Caching​

Static-code module for caching MiniHtml objects in a Map context. Supports round‑tripping through byte arrays so cached MiniHtml trees can be cloned without re-building.

Methods​

MethodReturnsDescription
ExistInCache(ctx, Key)BooleanCheck if Key exists in the cache map
WriteToCache(ctx, Key, Value)-Store Value in the cache map
ReadFromCache(ctx, Key)ObjectRead from cache; returns MiniHtml if stored as MiniHtml or byte array, otherwise raw Object
ConvertFromBytes(Buffer())MiniHtmlParse UTF‑8 byte array into a MiniHtml tree
ConvertToBytesByte()Serialize an empty MiniHtml to UTF‑8 byte array

Example​

MC is Cache code module
ProductsView.bas:
Public Sub Show As String
    Dim CacheName As String = "Products Page"
    ' Check and write
    If MC.ExistInCache(App.ctx, CacheName) = False Then
        MC.WriteToCache(App.ctx, CacheName, ProductsPage)
    End If
    ' Read back (auto-detects MiniHtml vs byte[])
    Dim page1 As MiniHtml = MC.ReadFromCache(App.ctx, CacheName)
    Dim doc As MiniHtml
    doc.Initialize("doctype")
    doc.Append(page1.build)
    Return doc.ToString
End Sub

Notes​

  • ReadFromCache transparently handles both raw MiniHtml objects and byte arrays ([B type), calling ConvertFromBytes on the latter.
  • ConvertToBytes serializes an empty tag — useful when you want to clone a MiniHtml tree by storing and re-reading it as bytes.
 

aeric

Expert
Licensed User
Longtime User
Version 3.03

What's New​

  1. Code Snippets updated
    • Model Class
    • View Class
    • Handler Class
    • CurrentDateTime Sub (new) - to be added to Main
  2. Clean up source project
  3. Cache.md, Helper.md added
 

aeric

Expert
Licensed User
Longtime User
Version 3.06

What's New​

  1. Code Snippets updated
    • Cache module
      • ClearFromCache
      • ClearAllFromCache
    • Helper module
  2. added add2
  3. added down
  4. added selectedIf
  5. added defer
  6. added integrity
  7. added crossorigin
  8. added PrependToMap (private)
  9. updated cdn now returns as child for chaining
  10. updated cdn2 now returns as child for chaining (deprecated)
  11. updated cdn3 now returns as child for chaining (deprecated)
 
Top