Creating a static site using pure Java. Objectos 0.5.1 released

Welcome to Objectos Weekly issue #018.
I have released Objectos 0.5.1! Most of the work done on this release was internal. In other words, it contains just a few of user-facing changes. I expect the next few releases to follow suit.
In any case, I will show what's new in Objectos 0.5.1.
Let's begin.
Before we begin
I use Objectos in production. This very page was generated using Objectos HTML (and a few other Objectos libraries).
Having said that, please know that Objectos is alpha software. In particular:
-
it is far from being stable: deviate slightly from the shown use-case and it will probably fail;
-
API might change substantially between minor/patch releases; and
-
documentation is a work in progress.
Creating a static site using pure Java
The following were introduced to Objectos HTML in version 0.5.1:
-
the
HtmlSink
class; -
the
HtmlSink::toDirectory(HtmTemplate, Path)
method; -
the
pathName
instruction of theHtmlTemplate
class; and -
the
pathTo
instruction of theHtmlTemplate
class.
They are all related. Let's look at an example to see how they work together.
Our template
Suppose the following Objectos HTML template:
public class MyTemplate extends HtmlTemplate { String pathName; @Override protected final void definition() { pathName(pathName); doctype(); html( head( title("Objectos HTML example") ), body( p( a(pathTo("/index.html"), t("Home")) ), dl( dt("Path name:"), dd(pathName) ) ) ); }}
Notice the pathName
instruction at the top of the definition
method:
@Overrideprotected final void definition() { pathName(pathName); ...}
It represents the path of generated HTML file.
The pathTo
instruction was used inside the anchor in the template's body
:
a(pathTo("/index.html"), t("Home"))
It is a link that takes you back to the site's home.
The pathTo
instruction generates a href
attribute.
But it uses the pathName
information to generate a relative link.
Generating our static site
We will use the HtmlSink
class to generate our static site to a pre-defined directory.
The following code does that:
var tmpdir = System.getProperty("java.io.tmpdir");var target = Path.of(tmpdir, "objectos-html-example");var pathNames = List.of( "/index.html", "/blog/index.html", "/blog/2023/03/17/objectos-html-is-cool.html");var htmlSink = new HtmlSink();var template = new MyTemplate();for (var pathName : pathNames) { template.pathName = pathName; htmlSink.toDirectory(template, target);}
We start by defining our target directory:
var tmpdir = System.getProperty("java.io.tmpdir");var target = Path.of(tmpdir, "objectos-html-example");
I am running Linux, so I expect the target directory to be /tmp/objectos-html-example
Next, we define the structure of our static site:
var pathNames = List.of( "/index.html", "/blog/index.html", "/blog/2023/03/17/objectos-html-is-cool.html");
Note that the pathnames must start with the '/' slash character. Our hypothetical site contains three files. In a real site the structure could come e.g. from your AsciiDoc or Markdown files.
Next, we generate our site using HtmlSink
and our MyTemplate
class from before:
var htmlSink = new HtmlSink();var template = new MyTemplate();for (var pathName : pathNames) { template.pathName = pathName; htmlSink.toDirectory(template, target);}
So, for each pathName
defined, we set the pathName
instance variable of our template.
Then, we invoke the HtmlSink::toDirectory
method.
Please note that it throws an IOException
.
Running our example
After running our example, here's the structure generated:
$ find /tmp/objectos-html-example -type f
/tmp/objectos-html-example/blog/2023/03/17/objectos-html-is-cool.html
/tmp/objectos-html-example/blog/index.html
/tmp/objectos-html-example/index.html
So the HtmlSink
class used the pathName
to generate the directory hierarchy automatically.
Let's look at generate HTML of our home page:
<!doctype >
<html>
<head>
<title>Objectos HTML example</title>
</head>
<body>
<p><a ="index.html">Home</a></p>
<dl><dt>Path name:</dt><dd>/index.html</dd></dl></body>
</html>
Notice the href
in the anchor: it is not absolute.
The reason becomes clearer in the blog index page:
<!doctype >
<html>
<head>
<title>Objectos HTML example</title>
</head>
<body>
<p><a ="../index.html">Home</a></p>
<dl><dt>Path name:</dt><dd>/blog/index.html</dd></dl></body>
</html>
Remember we used the pathTo
instruction in the anchor (instead of a href
).
The pathTo
instruction uses the template's pathName
value to generate a relative link.
For completeness, let's look at the generated HTML of the blog article:
<!doctype >
<html>
<head>
<title>Objectos HTML example</title>
</head>
<body>
<p><a ="../../../../index.html">Home</a></p>
<dl><dt>Path name:</dt><dd>/blog/2023/03/17/objectos-html-is-cool.html</dd></dl></body>
</html>
So, during development, there's no need for a web server. In other words, you can point your browser to:
file:///tmp/html-sink-example/blog/index.html
And links should work fine.
Objectos Code: allow annotations in field declarations
I continue to work on the Objectos Code documentation.
While documenting field declarations I realized that Objectos Code did not allow for fields to be annotated. So I implemented that. And also wrote the documentation for it.
So the following Objectos Code:
import objectos.code.ClassTypeName;import objectos.code.JavaTemplate;public class FieldAnnotations extends JavaTemplate { static final ClassTypeName ANNO_A = ClassTypeName.of("com.example.annotations", "AnnotationA"); static final ClassTypeName ANNO_B = ClassTypeName.of("com.example.annotations", "AnnotationB"); static final ClassTypeName ANNO_C = ClassTypeName.of("com.example.annotations", "AnnotationC"); @Override protected final void definition() { autoImports(); classDeclaration( name("FieldAnnotations"), field( annotation(ANNO_A), annotation(ANNO_B), annotation(ANNO_C), PUBLIC, INT, name("multiple") ) ); }}
Generates the following Java code:
import com.example.annotations.AnnotationA;import com.example.annotations.AnnotationB;import com.example.annotations.AnnotationC;class FieldAnnotations { @AnnotationA @AnnotationB @AnnotationC public int multiple;}
Until the next issue of Objectos Weekly
So that's it for today. I hope you enjoyed reading.
The source code of all of the examples are in this GitHub repository.
Please send me an e-mail if you have comments, questions or corrections regarding this post.