Guise™ Mummy static site generator library and CLI application.
Guise Mummy takes a set of source files of various types and generates a static site, analogous to Jekyll or Hugo. Guise Mummy is extremely fast and cross-platform, as it is based upon the Java Version Machine (JVM). It is standards-based and designed in a way to be flexible and extensible.
Here are a few of its features, which illustrate how Guise Mummy simply does what you would expect it to do, and does it right.
- An emphasis on “convention over configuration", with inspiration from Apache Maven. Put your source files in
src/site
, and your site will be generated intarget/site
with no need for configuraiton—unless you want to. - A normalized view of your site. No more deciding whether to link to
foo/bar/index.html
or tofoo/bar/
; Guise Mummy will normalize all your links tofoo/bar/
(unless you configure otherwise). - Example-based navigation regeneration. Why create complicated expression-language logic (unless you want to) just to create a navigation menu in your template? Just provide an example menu in the template and Guise Mummy will regenerate the menu for each page, using the correct page names and menu styles, just by looking at your example.
- Fast: your site is generated in parallel using multiple processor cores. (Upcoming feature.)
- Semantic: change a page property just by updating an HTML or Markdown header in the page source itself. Guise Mummy uses a simple but extensive semantic-based metadata framework, the Uniform Resource Framework (URF), throughout.
- Complete link relativization. Just put a link you want in the template; Guise Mummy will update the link to still point to the same resource wherever the template is used in your hierarchy.
- An option to generate clean URLs with no file extensions, such as
products/mousetrap
instead ofproducts/mousetrap.html
. (Upcoming feature.) Nevertheless file type such astext/html
will be maintained, whether for local serving via the CLI or for deploying to a remote hosting service. - Automated deployment. (Upcoming feature.) With a simple CLI command you can upload your entire site to a hosting service, such as Amazon S3. Such deployment will transfer appropriate per-page metadata such as Internet media type, even if clean URL generation was chosen.
The initial release of Guise Mummy is completely functional, although the options it supports is not yet complete. Nevertheless it is fully capable of generating a full site with basic capabilities. Its current limitations include:
- Source files must be XHTML5 (XML files using the HTML5 vocabulary, not necessarily following any legacy XHTML) using the
.xhtml
extension. Markdown and plain HTML5 coming soon. - Configuration files are not yet implemented.
- No expression language or interpolation is yet included.
Guise Mummy is available in the Maven Central Repository as io.guise:guise-mummy. For building the entire Guise ecosystem see the documentation for the parent Guise Mummy project.
Guise Mummy may be used programmatically, but is most easily used by consumers via the Command-Line Interface (CLI). The following is a very quick overview of the basic CLI commands. Use guise help
for more details and options.
guise clean
: Deletes everything in thesite/target
directory, relative to the current directory.guise mummify
: Uses the source files insrc/site
directory and generates a static site in thetarget/site
directory.guise serve
: Starts an HTTP server listening on port4040
and opens the default browser to test the generated site.
Source files currently must be XHTML5 using the .xhtml
extension. A sample source file may be found in the Hello World Demo.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Hello, World!</title>
</head>
<body>
<p>Hello, World!</p>
</body>
</html>
- Any directory or file starting with
.
(a “dotfile”) is not included in the generated static site, although it may be used to influence site generation. For example a.template.xhtml
template file will be used as a template (see below), but that template file itself will not appear in the generated site. - Any directory or file starting with an underscore
_
is considered a “veiled” resource; it will be included in the generated static site, but will not appear in any generated navigation menu. For example an_assets
directory (containing perhaps_assets/css/…
and_assets/js/…
) will still appear in the static site with its contents, but if a template contained a menu for regeneration, the generated menu would not include any sort of “assets” menu item.
If you place a template file named .template.xhtml
in any directory, the outline and style of that template will be used to generate each artifact in that directory and directories below it, placing the artifact's title, metadata, and content inside the template. Guise Mummy oriented features are indicated by elements and attributes in the https://guise.io/name/mummy/
XHTML namespace.
Here's an example of a template that uses the Guise Skeleton CSS framework (for example only; not yet included in the Guise distribution) for styling and Font Awesome for icons; and indicates that the menu should be regenerated automatically using the mummy:regenerate
attribute. The stylesheet link will be retargeted as appropriate if the template is applied to an artifact in a subdirectory. The navigation menu will be regenerated for each artifact, based upon the other content artifacts and directories (that are not veiled; see above) at each level.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:mummy="https://guise.io/name/mummy/">
<head>
<meta charset="UTF-8" />
<title>Example Template</title>
<link href="_assets/css/guise-skeleton.min.css" rel="stylesheet" />
<link href="_assets/css/fontawesome-all.min.css" rel="stylesheet" />
</head>
<body class="guise-skeleton">
<header>
<nav class="bar box">
<a class="concise" href="./">Acme Company</a>
<input class="toggle" type="checkbox" id="nav-toggle" role="button" />
<ul class="menu" mummy:regenerate="regenerate">
<li class="active"><a class="disabled" href="">Foo</a></li>
<li><a href="about.xhtml">About</a></li>
</ul>
<label for="nav-toggle" class="toggle concise"><span class="fas fa-bars"></span></label>
</nav>
</header>
<main>
<!-- artifact content will be placed here -->
</main>
</body>
</html>
There is no need for an expression language to mark certain menu items as "active" or "disabled" (although an expression language will be provided in the future for complex tasks). Guise Mummy determines the style for the current active menu item based upon the template menu item with a link to ""
(indicate the artifact “self”). Other menu items will be given styles based upon the first non-self menu item in the template.
The following are the mail entities in the Guise Mummy domain model
- Guise Mummy (class
io.guise.mummy.GuiseMummy
) : The central class responsible for orchestrating static site generation, referred to as “mummification”. - Artifact (interface
io.guise.mummy.Artifact
) : Represents a file or directory generated in the static site. Note: Not all artifacts will have a true representation in the source tree. Some artifacts may be created from a separate list of blog entries, and “phantom” artifacts don't exist in source form at all. The latter includeindex.html
files generated in order to create content for directories. Nevertheless, artifacts expose a hypothetical source file during processing, so that links will be correctly processed if any source files link to them in the source tree. Each artifact has a description, a set of properties and values that describe it, using the Uniform Resource Framework (URF). - Mummifier (interface
io.guise.mummy.Mummifier
) : The strategy for generating an artifact in the target tree. New strategies can be registered, normally based on source file type. For example, in the future a LaTeX mummifier might be associated with the.tex
source extension. Guise Mummy would automatically delegate to this mummifier to generate static HTML files whenever*.tex
file were encountered.
“Mummification”, or generation of a static site, occurs in several phases:
- Validate : The configuration and parameters are validated.
- Plan
: Guise Mummy discovers resources in the source tree, and plans mummification by i) choosing the correct mummifier, ii) determining a description for the artifact, and iii) creating an artifact to become part of the mummification plan. Note that each mummifier controls the process of planning its contents, allowing for custom mummification based upon artifact type. Thus a special calendar directory might have a calendar mummifier that generates a calendar page based upon iCalendar files within that directory, rather than creating HTML pages for the child
*.ics
files. - Mummify : Guise Mummy initiates site mummification of the planned site based upon the plan, using the selected mummifiers to generate the artifacts.
The mummification phase can be divided into subphases for generation of a typical HTML file. Pages are generated by instances of io.guise.mummy.PageMummifier
. The io.guise.mummy.AbstractPageMummifier
is typically the base implementation for all page mummifiers. XHTML source files are generated using io.guise.mummy.XhtmlPageMummifier
.
- Load : The source file of whatever type is loaded (or created/generated) and normalized as an in-memory XHTML DOM tree (regardless of course format) for further processing.
- Apply Template
: If any
.template.*
file is present in the given directory or any parent directory, the template is applied to the file. This includes i) loading the template as if it were a source artifact, using the appropriate mummifier ii) relocating its links for its new location, iii) substituting the artifact title into the template, iv) substituting the artifact metadata into the template, and v) extracting the main content from the artifact and inserting it into the template. The template can be a standard.template.xhtml
file for example; its<main>
or<body>
content will be used as a target for the<main>
or<body>
content of the artifact. Support for custom content and insertion points will be included in a future release. - Process : The normalized XHTML DOM tree is evaluated and transformed appropriately. This includes regenerating sections such as navigation menus, evaluating expressions (upcoming feature), and intepolating properties (upcoming feature).
- Relocate
: The artifact's links are converted to reflect its new location in the generated site. This includes moving links to their new location, as well as changing the links based upon their target artifacts. For example a source link to
example.tex
would be converted toexample.html
, if a LaTeX mummifier were installed that actually converted the referencedexample.tex
to HTML in the target tree. - Cleanse : All Guise Mummy related content (such as attributes or metadata used to direct mummification) is removed from the processed XHTML tree
- Save : An HTML file is generated from the resulting in-memory XHTML DOM representation.
Note that some mummifiers do not follow all these subphases. For example an io.guise.mummy.OpaqueFileMummifier
will simply copy the source file unaltered for unrecognized source files. Currently this includes images, CSS, and JavaScript files. (As Guise Mummy grows in sophistication, however, even some of these artifacts may have specialized mummifiers which perform some manipulation if so configured.)
- Normalized artifact processing model. Artifacts are typically normalized to an XHTML5 DOM in-memory representation, regardless of original format. This provides for standardized processing and extensibility. For example template application and menu regeneration doesn't need to know if the content originated as an XHTML file or a Markdown file.
- Each artifact can expose "referent" path names for link normalization. For example by default a directory will expose both a path to
foo/
and a path tofoo/index.xhtml
(based upon the whichever so-called “content artifact” is present to be used for default content). This way any link tofoo/index.xhtml
can be normalized tofoo/
for concise, semantic links.
- Java's
java.net.URI
relativation algorithm does not support “backtracking”; that is, determining relative links to parent or sibling hierarchies. For example it can't relativize a link fromexample/foo/page1.html
toexample/bar/page2.html
, which would require a backtracking../bar/page2.html
reference. See JDK-6226081 and How to construct a relative path in Java from two absolute paths (or URLs)? The solution is not trivial, but GlobalMentor implemented a general URI relativization algorithm for use in Guise Mummy, tracked by JAVA-102. - Java's
java.net.URI
class furthermore follows RFC 2396 instead of the updated RFC 3986. One downside is that its handling of relative URIs conflicts with that of modern browsers and HTML5. For example if a link appears infoo/bar.html
referencing""
(the empty string), the referent resource should be thefoo/bar.html
resource itself. Java, however, resolves the target link to thefoo/
parent resource, as discussed on Stack Overflow. Guise Mummy works around this limitation as well.
Issues tracked by JIRA.