A clean, simple and well-structured framework for writing HTML pages in Java.
API documentation is available here.
Goals:
- Use minimal resources when creating and writing pages.
- Involve minimal boilerplate and screen-wastage for the user.
- Be applicable both for static and procedurally-generated pages.
Hypertext is available in Kenzie's repository.
<repository>
<id>kenzie</id>
<name>Kenzie's Repository</name>
<url>https://repo.kenzie.mx/releases</url>
</repository>
Common
<dependency>
<groupId>mx.kenzie</groupId>
<artifactId>hypertext-common</artifactId>
<version>1.1.0</version>
</dependency>
Bootstrap 4 helper elements
<dependency>
<groupId>mx.kenzie</groupId>
<artifactId>hypertext-bootstrap</artifactId>
<version>1.1.0</version>
</dependency>
Markdown parser element (commonmark)
<dependency>
<groupId>mx.kenzie</groupId>
<artifactId>hypertext-markdown</artifactId>
<version>1.1.0</version>
</dependency>
Pages can be written through the PageWriter
resource, which deals with exceptions, charsets and output automatically.
Pages can also be written manually through the element write
method, but this requires more effort on the part of the user.
try (final PageWriter writer = new PageWriter(file)) { // auto-handles streams
writer.write(page);
}
To assemble a page, HTMElement
s (HyperText Markup Elements) must be assembled using a hybrid constructor/builder process.
Each element references an individual HTML <tag></tag>
pair (or single <tag />
) and contains its metadata and children.
These can be assembled manually using new HTMElement("tagname")
but, for simplicity, Hypertext contains an entire set of pre-defined HTML tag elements according to the HTML5 schema.
These can be used with a static import (for simplicity.)
import static mx.kenzie.hypertext.element.StandardElements.*;
With this import, the tags may then be used by name.
new Page(
DOCTYPE_HTML,
HTML.child(
HEAD.child(
TITLE.write("Page Title"),
META.set("name", "description").set("content", "My description.")
),
BODY.child(
DIV.child(
P.write("goodbye! :)")
)
)
)
);
Tags can be modified using their builder methods. If the tag is finalised
(as the standard set are) this will create a modifiable clone that can be altered.
This is done to save memory where possible by reusing element objects unless they need to be different.
The .child(element, element, ...)
method adds multiple elements as children.
BODY.child( // <body>
DIV.child( // <div>
P.write("goodbye! :)"), // <p></p>
P.write("goodbye! :)") // <p></p>
) // </div>
) // </body>
The .set(key, value)
method sets a meta tag in the header to the given value.
META.set("name", "description").set("content", "My description.")
// <meta name="description" content="My description." />
The .classes(class, class, ...)
method adds (multiple) classes to the element.
DIV.classes("col", "col-md-8", "col-lg-12")
// <div class="col col-md-8 col-lg-12"></div>
Some individual element types may have additional modifier methods.
Hypertext supports constructing basic CSS selectors and rules.
These can either be written into a STYLE
element in the head, or into a stylesheet using another PageWriter
. Since Rules are writable elements, they can be written as well as normal HTML.
The simplest way to write CSS rules is using the constructor.
HEAD.child( // <head>
STYLE.child( // <style>
new Rule("p").rule("color", "red"),
new Rule("div").rule("border-bottom", "2px solid black")
) // </style>
) // </head>
p {
color: red;
}
div {
border-bottom: 2px solid black;
}
This also supports using the HTMElement
s directly to select tags.
STYLE.child(
new Rule(DIV).rule("background", "red")
)
However, more advanced selector-building methods are also available.
The multi-element selector:
STYLE.child(
Rule.all(UL, P, DIV, BR)
)
ul, p, div, br {
}
Complex attribute selectors:
STYLE.child(
Rule.of(DIV, ATTRIBUTE_EQUALS.of("name", "hello"))
)
div[name=hello] {
}
Many more types are available, with examples in the documentation.
Existing HTML files can be unwrapped into HTMElements. This allows navigating, editing and reconstructing the page.
try (final Page page = SourceUnwrapper.forHTML(source)) {
// page is available here
}