B4J Library [B4X] MiniHTML4

Version 4.05
GitHub: https://github.com/pyhoon/MiniHTML4

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

Overview​

MiniHTML4 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

Last edited:
In short, V4 removed many redundant methods, thanks to the new feature of B4J v10.7, optional parameters.
 
I am experimenting with MiniHTML4. I downloaded Library and selected in B4J Pages IDE
I am having some trouble with the just creating a simple html page. I had no problem with earlier versions - but I guess I don't know what all the defaults are.
Could you post one or more examples of using version 4 please.
 
I am experimenting with MiniHTML4. I downloaded Library and selected in B4J Pages IDE
I am having some trouble with the just creating a simple html page. I had no problem with earlier versions - but I guess I don't know what all the defaults are.
Could you post one or more examples of using version 4 please.
Hi William,
Thanks for testing MiniHTML4.

This version is not backward compatible to previous version.

You need to follow the Migration Guide posted in post #2.

To create a simple html page, follow these steps:
  1. Add MiniHTML (v4) and MiniJS to a new project.
  2. Create a Code Module and name it MH.
  3. Inside MH.bas, after the line Sub Process_Globals, type "help" to activate the code snippet for "MiniHTML Helper".
  4. Ignore the highlighted placeholders, just press Enter.
  5. In Main, create a sub call BuildPage.
  6. Copy the example code from README.md Quick Start section into BuildPage.
  7. Call BuildPage sub from Appstart.
  8. Find index.html inside Objects folder.
B4X:
Sub BuildPage
    ' Build a simple HTML page
    Dim html1 As MiniHtml = MH.Html
    Dim head1 As MiniHtml = MH.Head.up(html1)
    MH.Title.up(head1).text("Hello")
    Dim body1 As MiniHtml = MH.Body.up(html1)
    Dim div1 As MiniHtml = MH.Div.up(body1)
    div1.cls("container")
    div1.text("Hello World!")
    File.WriteString(File.DirApp, "index.html", html1.build)
End Sub
 
I had no problem with earlier versions - but I guess I don't know what all the defaults are.
Basically V4 is very similar to V3.
I thought V4 is a cleaner version by using the default parameters. Especially it is used in the Helper module (MH.bas)

My first results are very promising. I use your build method on the map I create html from the conversion algorithm results.
I never tested but as far as I concern, the FromMap (or FromJson) to MiniHtml to build html is still remaining the same.
 
Last edited:
You're right, for this I only needed MiniHTML (any version).
The helper and MiniJS modules are not needed for this.

It works quite well, but had to revise WiLXLayouts to expose two more methods.
I also discovered that I was wrong when I thought that the Main view was not needed in the generic txt file.
I have to do a little more work on WiLXLayouts.
I will include this translation to HTML as an example when I post my revisions - in a day or two.

Your MiniHTML library is a beautiful thing.

webScreenShot.png


This is the generic layout text:
B4X:
    Dim textLayout As String = $"
'________________________________________
name=*    type=Main
width=1000
height=1000
baseColor=0xFFFFDDDD
title="Test from Layout to HTML using MiniHTML"

'________________________________________
name=Pane5    type=Panel
eventName=Pane5
enabled=true    visible=true

width=700    fromLeft=350
height=120    fromTop=250
    
baseColor=White

borderWidth=3    borderColor=Blue    borderRadius=3

'________________________________________
name=Label5    type=Label
parent=Pane5    eventName=Label5
enabled=true    visible=true
    
width=*    fromLeft=10    fromRight=10
height=*    fromTop=10    fromBottom=10
    
baseColor=Blue
    
textContent="Popular Test\nThe Quick Brown Fox Jumped Over The Lazy Dog"
fontColor=Blue    fontSize=20
vAlign=CENTER    hAlign=CENTER    wordWrap=false
    "$

Here is the section of code related to the translation:
B4X:
    Dim convert As WiLConverter
    convert.initialize(False)
    
    'This section and its helper subs will expand quite a bit for all the attributes, inline style, and content stuff
    Dim viewMap As Map = convert.parseVariant(variantList)
    Dim mainMap As Map = viewMap.Remove("*")

    'Translate the properties of the view maps to HTML terms
    Dim translatedMaps As Map = CreateMap()
    For Each viewName As String In viewMap.Keys
        Dim propMap As Map = addLowerCase(viewMap.Get(viewName))

        'translateView is the sub that does item by item conversion - I omitted it here (it is pretty boring)
        translatedMaps.Put(viewName, translateView (propMap, viewMap, mainMap))   
    Next
    
    'It isn't hard to build the generic view tree - it is a utility method of WiLConverter
    Dim viewTree As Map = convert.mapToTree(translatedMaps)

    'We do need to convert the htmtag property of the root and its children (recursively)
    Dim lst As List = emptyList
    For Each vwname As String In viewTree.Keys
        Dim viewMap As Map = viewTree.Get(vwname)
        lst.Add(convertToNew(viewMap))
    Next
    
    'add the html - head - body containers and body contents to a miniHTM map - using the HM helper code module works too
    Dim children As List = emptyList

    Dim headElements As List = emptyList
    headElements.Add(CreateMap("title": mainMap.Get("title").as(String).replace(QUOTE,"")))
    children.Add(CreateMap("head": CreateMap("children": headElements)))

    Dim bodyElements As List = emptyList
    bodyElements.Add(lst.Get(0))
    Dim color As String = mainMap.Get("basecolor")
    If color<> "" Then
        If color.StartsWith("0x") Then color = "#" & color.SubString(4).toLowerCase
        Dim colstr As String = $"background-color: ${color};"$
        children.Add(CreateMap("body": CreateMap("style": colstr, "children": bodyElements)))
    Else   
        children.Add(CreateMap("body": CreateMap("children": bodyElements)))
    End If
    
    Dim htmlMap As Map = CreateMap("html": CreateMap("lang": "en", "children": children))
    
    'use MiniHTML to do the heavy lifting
    Dim mht As MiniHtml
    mht.initialize("")
    File.WriteString(File.DirApp, "test.htm", mht.fromMap(htmlMap).build)

And this is the HTML String

B4X:
#if html
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Test from Layout to HTML using MiniHTML</title>
  </head>
  <body style="background-color: #ffdddd">
    <div id="Pane5" class="panel" style="position: absolute; left: 350px; top: 250px; width: 700px; height: 120px; background-color: White; border: 3px solid Blue; border-radius: 10px">
      <p id="Label5" class="label" style="position: relative; left: 10px; top: 10px; width: 680px; height: 100px; color: Blue; font-size: 20pt; font-family: Arial; text-align: center">Popular Test<BR>The Quick Brown Fox Jumped Over The Lazy Dog</p></div>
  </body>
</html>
#end if
 

What's New​

v4.05 (Latest)​

Rendering fixes​

  • MiniHtml.build now wraps the closing tag of a uniline element onto its own line when its last child is a tag that renders on its own line. For example, &lt;div&gt;&lt;div&gt;...&lt;/div&gt;&lt;/div&gt; no longer ends with &lt;/div&gt;&lt;/div&gt;; text-only and inline content keep the closing tag inline.
  • convertToMiniHtml no longer trims text node values, so leading and trailing spaces survive when parsed HTML is rebuilt. input/option value attributes are still trimmed.
  • Parsed text nodes are flattened into their parent as inline text, so &lt;th&gt;Name&lt;/th&gt;, &lt;td&gt;1&lt;/td&gt; and similar tags no longer put the text on its own indented line.
  • Added an optional escaped parameter to text(value, wrap, escaped) and replace(value, escaped), plus the EscapeHtml(value) helper. Text is escaped by default; pass escaped = False for raw markup. Internal comment, script and parser paths opt out so they are not double-encoded. esc(value, wrap) remains as shorthand.
  • Library version bumped to 4.05 (manifest.txt and module version labels); 4.04 was a version-only bump.

v4.02​

Core rendering and parent attachment​

  • MiniHtml.build no longer forces a child indent to level 1 when its parent has Indentation = False; indentation now follows the explicit build depth and each node's own indentation setting.
  • MiniHtml.addTo(parentTag) now safely returns the current tag without attaching it when parentTag is uninitialized. For an initialized parent it delegates to addChild and returns the child, preserving the fluent up/addTo pattern.

B4J project and library metadata​

  • Updated B4J asset setup from App.staticfiles.Folder to App.AssetsFolder to match the current EndsMeet API.
  • Renamed the exported custom class template from Main View Class to View Class (Main); the class remains MainView.
  • Updated the project and module IDE metadata to B4J 10.7 and rebuilt release/MiniHTML.b4xlib with manifest version 4.02.

Examples and templates​

  • Corrected CDN/SRI examples to use the fluent .src(...) and .href(...) methods; documented the Bootstrap CSS integrity hash alongside the JS and HTMX hashes.
  • Updated the version labels in the source templates and generated snippets to 4.02.
 
Back
Top