B4J Library [Web] MiniHtml

Yet the potential or use cases of this library may be unknown as you can literally write plain HTML and save it as a file.

GitHub: https://github.com/pyhoon/MiniHtml-B4X

Sample:
B4X:
Sub AppStart (Args() As String)
    GenerateHtml
    StartMessageLoop
End Sub

Sub GenerateHtml
    Dim html As MiniHtml
    html.Initialize
    'html.Flat = True
    html.Text("#macro( header )")
    html.DocType
    html.Language("en")
    html.Comment(" velocity.vm ")
    html.Head
    html.Meta(html.Attrs(Array("http-equiv", "content"), Array("content-type", "text/html; charset=utf-8")))
    html.Meta(html.Attrs(Array("name", "content"), Array("viewport", "width=device-width, initial-scale=1")))
    html.Text("$csrf")
    html.Meta(html.Attrs(Array("name", "content"), Array("description", "")))
    html.Meta(html.Attrs(Array("name", "content"), Array("author", "")))
    html.Title("$APP_TITLE")
    html.Headx
    html.Body
    html.H1("Hello, World!")
    html.Img("/img/hello.png")
    html.Bodyx
    html.Htmlx
    Dim content As String = html.ToString
    Log(content)
    File.WriteString(File.DirApp, "velocity.vm", content)
End Sub

Output:
HTML:
#macro( header )
<!DOCTYPE html>
<html lang="en">
<!-- velocity.vm -->
<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    $csrf
    <meta name="description" content="" />
    <meta name="author" content="" />
    <title>$APP_TITLE</title>
</head>
<body>
    <h1>Hello, World!</h1>
    <img src="/img/hello.png" />
</body>
</html>
 

Attachments

  • MiniHtml.b4xlib
    1.7 KB · Views: 52
  • MiniHtmlExample.zip
    985 bytes · Views: 59
Last edited:

aeric

Expert
Licensed User
Longtime User
I'll start by saying that I'm not an expert in HTML (never loved it), perhaps you could put something as optional, without having to explicitly write the command (but being able to do it, anyway).
Maybe these:
It is still in early stage. Any suggestion is welcome.

If you look in the class, there are many similar subs.
e.g Body, BodyA, BodyB, Body0 and Bodyx (note that the ending is not denoting blood type 😅 )
without the postfix, this is the most common or default sub to use. "A" denotes it expect attributes as parameter, "B" denotes without attributes, "0" may means no attributes and no new line, "x" for closing tag.

HeadX, BodyX, HtmlX

Why not:
HeadEnd, BodyEnd, HtmlEnd

(the editor will help you to write them and they would be more readable, although even I understand what they are for 😄)
I am lazy (to type longer words). You can add these subs if you like.

This could be confusing. Can you add one that one can just pass "name":"viewport" key value pairs, and or just a map variable.
There is another way.

Instead of writing:
B4X:
html.Meta(html.Attrs(Array("name", "content"), Array("viewport", "width=device-width, initial-scale=1")))
We can also write it as: (just slightly more characters)
B4X:
html.Meta(Array(CreateMap("name": "viewport"), CreateMap("content": "width=device-width, initial-scale=1")))

edit:

Or just add this sub

B4X:
Public Sub Meta_ViewPort
    Meta(Array(KV("name", "viewport"), KV("content", "width=device-width, initial-scale=1.0")))
End Sub

and call it as:
B4X:
html.Meta_ViewPort
 
Last edited:

Mashiane

Expert
Licensed User
Longtime User
Rather think of working around separation of concerns as your base, e.g. a head class, a body class etc. Unless of course "you are lazy"... :D:D:D:D (no harm meant)

I just think the more easier you make this to use the better.

html.Meta(Array(CreateMap("name": "viewport"), CreateMap("content": "width=device-width, initial-scale=1")))
to

B4X:
html.Meta1(CreateMap("name":"viewport", "content":"width-device, initial-scale=1"))

Becoming

B4X:
<meta "name"="viewport" "content"="width-device, initial-scale=1"/>

or whatever...

My 2 cents...
 

PaulMeuris

Active Member
Licensed User
Reminds me of the HTML class in PHP i wrote long time ago...
So you have to write 30 lines of B4X code to produce 17 lines of HTML...
Maybe the pure HTML code is the better way to go...
 

aeric

Expert
Licensed User
Longtime User
Rather think of working around separation of concerns as your base, e.g. a head class, a body class etc. Unless of course "you are lazy"... :D:D:D:D (no harm meant)

I just think the more easier you make this to use the better.


to

B4X:
html.Meta1(CreateMap("name":"viewport", "content":"width-device, initial-scale=1"))

Becoming

B4X:
<meta "name"="viewport" "content"="width-device, initial-scale=1"/>

or whatever...

My 2 cents...
I tried but H11 will be confusing.
 

aeric

Expert
Licensed User
Longtime User
Reminds me of the HTML class in PHP i wrote long time ago...
So you have to write 30 lines of B4X code to produce 17 lines of HTML...
Maybe the pure HTML code is the better way to go...
It will be less and less code. Hopefully.
There are reasons behind and defeat the raw HTML.

Reason 1: I can change the attributes and overide the values since it is List and Maps using B4X code.
 

alwaysbusy

Expert
Licensed User
Longtime User
Reminds me of the HTML class in PHP i wrote long time ago...
So you have to write 30 lines of B4X code to produce 17 lines of HTML...
Maybe the pure HTML code is the better way to go...
I'm also not (yet) convinced of the advantages. Seems you still have to be aware of how HTML (tags, attributes, styles, classes, data) works to use it. It even introduces multiple forms for each tag if I read it correctly (Body, BodyA, BodyB, Body0 and Bodyx). I use the magic of B4J's Smart Strings and IMHO I even find it more readable (the DOM tree is more visible for example), especially when things get more complex.
 

aeric

Expert
Licensed User
Longtime User
I'm also not (yet) convinced of the advantages. Seems you still have to be aware of how HTML (tags, attributes, styles, classes, data) works to use it. It even introduces multiple forms for each tag if I read it correctly (Body, BodyA, BodyB, Body0 and Bodyx). I use the magic of B4J's Smart Strings and IMHO I even find it more readable (the DOM tree is more visible for example), especially when things get more complex.
I plan to use it for simple solutions. Not really a full blown framework. It is similar concept to my MiniORM library. Maybe the benefit will appear when I apply it to some of my future projects.
 

Mashiane

Expert
Licensed User
Longtime User
e.g Body, BodyA, BodyB, Body0 and Bodyx (note that the ending is not denoting blood type 😅 )
without the postfix, this is the most common or default sub to use. "A" denotes it expect attributes as parameter, "B" denotes without attributes, "0" may means no attributes and no new line, "x" for closing tag.
I know its early days, but please comment the public subs and or even use <code></code> so that one can just copy the code and paste on the IDE. It's always easy to look at a sub name and know what it does. Now, one has to study the whole sub to know what it does. :D:D:D, besides your sub names are rather encryptic, ;)

I understand the need to be set on using Lists for almost everything, as indicated in the class. In any HTML element, remember, the attributes names are unique, the most basic ones being id, style (JSON like) and class across all elements where necessary.

I just think using lists for what a map variable can do quickly is much more sensible (in the case of your attributes build up process), you transverse once instead of twice, In this case, 1st being the list, then being the map inside the list. Is the extra code really necessary? Why not just use a map variable, once and thus have 1 loop instead of 2 loops for building your attributes.

I'm sorry I'm really trying to understand that part, perhaps I'm still missing something.
 

aeric

Expert
Licensed User
Longtime User
I know its early days, but please comment the public subs and or even use <code></code> so that one can just copy the code and paste on the IDE. It's always easy to look at a sub name and know what it does. Now, one has to study the whole sub to know what it does. :D:D:D, besides your sub names are rather encryptic, ;)

I understand the need to be set on using Lists for almost everything, as indicated in the class. In any HTML element, remember, the attributes names are unique, the most basic ones being id, style (JSON like) and class across all elements where necessary.

I just think using lists for what a map variable can do quickly is much more sensible (in the case of your attributes build up process), you transverse once instead of twice, In this case, 1st being the list, then being the map inside the list. Is the extra code really necessary? Why not just use a map variable, once and thus have 1 loop instead of 2 loops for building your attributes.

I'm sorry I'm really trying to understand that part, perhaps I'm still missing something.
First I didn't expect this library attract attention. It just a work in a few hours. Don't expect the best ideas.

I have some basic knowledge in Html. I basically know what I am doing.

I have tried make use of json and xml to represent the html elements but failed. I tried with xml2map library but it doesn't provide what I need. j2html also look complex to wrap.

Regarding usage of list. I tried with b4xorderedmap but in this version I am using list of map. It is to preserve the order.
 

Mashiane

Expert
Licensed User
Longtime User
First I didn't expect this library attract attention. It just a work in a few hours. Don't expect the best ideas.

I have some basic knowledge in Html. I basically know what I am doing.

I have tried make use of json and xml to represent the html elements but failed. I tried with xml2map library but it doesn't provide what I need. j2html also look complex to wrap.

Regarding usage of list. I tried with b4xorderedmap but in this version I am using list of map. It is to preserve the order.
Thanks for the green lights. I want to use this on something. My mind is just trying to reconcile itself to your coding style and more specifically ease of use and an easier learning curve. Let me wait for a stable version and play around then.
 

aeric

Expert
Licensed User
Longtime User
Thanks for the green lights. I want to use this on something. My mind is just trying to reconcile itself to your coding style and more specifically ease of use and an easier learning curve. Let me wait for a stable version and play around then.
This is more like a proof of concept. If anyone interested can fork it and improve it. Maybe I will use it together with velocity and EndsMeet.
 

peacemaker

Expert
Licensed User
Longtime User
Maybe is it good to extend it further with, say, macro-objects ?
B4X:
Dim f as HtmlForm
f.Initialize
f.AddLabel(....)
f.AddButton(....)

Dim b1 as HtmlButton
b1.Initialize
b1.Text = "Save"
Html.AddView(b1)
Html.AddView(f)
 

aeric

Expert
Licensed User
Longtime User
Maybe is it good to extend it further with, say, macro-objects ?
B4X:
Dim f as HtmlForm
f.Initialize
f.AddLabel(....)
f.AddButton(....)

Dim b1 as HtmlButton
b1.Initialize
b1.Text = "Save"
Html.AddView(b1)
Html.AddView(f)
You almost read my mind.
I had another version of class call CodeGenerator. The Sub name starting with Addxxxx
It was use to build something similar to this library but that time I was trying to build with Vue.JS.

1706192613431.png
 
Top