-
-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Description
Layouts are an interesting problem because:
- They are necessary for markdown files to be pages.
- They aren't necessary for HMX pages, but can still be useful.
Our current approach to layouts has the following downsides:
- HMX pages do not have full control over their output HTML.
- Which means special syntax is required to put parts of an HMX page into parts of the parent layout.
- A page cannot set the
<html>element (or any attributes on it). - A page cannot set the
doctype(less important these days but conceptually it speaks to the underlying issue here). - A page cannot omit head/body tags. (again, not important, but speaks to the problem).
- HMX is not a true superset of HTML because you cannot paste arbitrary HTML into an HMX file and have it work.
One of the goals of HMX was to provide a light and familiar syntax that is mostly just HTML, with a couple of exceptions in capital-Component tags and JSX expressions. Layouts as they currently are add this third concept with special rules for what you can and cannot due.
Component approach to layouts
I'd like to propose an alternative to layouts as we currently have them. What if layouts were just components like any other? In a page you import a component and use it. With the basic primitive of slots you have the power to define what slots the layout component needs and name them whatever you want.
This approach has the following upsides:
- You can use React, Vue, etc. components as layouts!
- No special head/body handling within the compiler. The HMX compiler doesn't need to know about head and body tags at all. The markdown to HMX compiler does, of course, but it can compile to component usage. (see next section). This means that HMX pages have full control over the HTML they produce. They can use layouts or not.
- No need for a special layouts folder. Layouts are just components, they can go in the components folder (having a special folder is not a bad thing for organization, but it's not a requirement here because there's nothing special about layouts).
- Alternative patterns to layouts are possible. Instead of creating a layout you can just have special components that you use for inserting tags into the head.
Markdown pages compiled to layout usage
You could see markdown being transformed to HMX that looks a little like below. This is the same way an HMX page that uses layouts could be authored.
post.md
<script astro>
import Layout from '../layouts/blog.hmx';
</script>
<Layout>
<Fragment slot="head">
<title>My Blog Post</title>
<link rel="stylesheet" href="/styles/blog.css">
</Fragment>
<div slot="content">... blog post content here</div>
<Layout>layouts/blog.hmx
<!doctype html>
<html class="home-page">
<head>
<meta charset="utf-8">
<slot name="head"></slot>
</head>
<body>
<header>
<h1>Matthew's blog</h1>
</header>
<slot name="content"></slot>
</body>HMX pages that don't use layouts
An HMX page could be written like this, to solve the problem of things like common head elements without the wrapper layout component. This is just intended to demonstrate that layouts are optional and the same problem they solve can be done other ways (this is typically how I do things with 11ty personally):
pages/news.hmx
<script astro>
import CommonMeta from '../components/meta.hmx';
import CommonStyles from '../components/styles.hmx';
import SiteHeader from '../components/site-header.hmx';
</script>
<!doctype html>
<html lang="en">
<head>
<CommonMeta />
<title>My page<title>
<CommonStyles />
<link rel="stylesheet" href="/styles/news.css">
</head>
<body>
<SiteHeader />
<h2>Our News</h2>
...
</body>