what

Layouts

Wrap pages in shared HTML structure. Define it once, apply it everywhere.

Creating a Layout

A layout is an HTML file in your components/ directory. It uses <slot/> to mark where page content is injected.

components/main-layout.html
<what>
props = "title"
defaults.title = "My Site"
</what>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>#title#</title>
  <link rel="stylesheet" href="/static/what.css">
</head>
<body>
  <nav>
    <a href="/">Home</a>
    <a href="/about">About</a>
  </nav>

  <main>
    <slot/>
  </main>

  <footer>
    <p>&copy; 2025 My Site</p>
  </footer>
</body>
</html>

The <slot/> tag is replaced with the full content of the page that uses this layout.

Using a Layout

Assign a layout to a page in its <what> block:

site/about.html
<what>
layout: "components/main-layout.html"
title: "About Us"
</what>

<h1>About Us</h1>
<p>We build things with HTML.</p>

The page content replaces the <slot/> in the layout. Props declared in the layout's <what> block (like title) receive values from the page's <what> block.

Layout Inheritance

Instead of setting a layout on every page, define it once in an application.what file. Every page in that directory (and its subdirectories) inherits the layout automatically.

site/application.what
layout = "components/main-layout.html"

With this in place, every page under site/ uses main-layout.html without declaring it individually.

Subdirectories can override the parent layout:

site/admin/application.what
layout = "components/admin-layout.html"

Now all pages in site/admin/ use the admin layout, while the rest of the site keeps the main layout.

Disabling a Layout

Some pages need to render without any wrapping layout — API-like endpoints, standalone landing pages, or widget embeds. Use layout: none:

site/widget.html
<what>
layout: none
</what>

<div class="widget">
  <p>This renders without any layout.</p>
</div>

This overrides any inherited layout from application.what.

Passing Data to Layouts

Layouts declare props in their <what> block. Pages pass values through their own <what> block:

components/page-layout.html
<what>
props = "title, page, section"
defaults.title = "Docs"
defaults.section = ""
</what>
<!DOCTYPE html>
<html>
<head>
  <title>#title# - Docs</title>
</head>
<body>
  <if section>
    <span class="badge">#section#</span>
  </if>
  <slot/>
</body>
</html>
site/docs/templates.html
<what>
title: "Variables & Filters"
page: templates
section: Templates
</what>

<h1>Variables & Filters</h1>
<p>Content goes here...</p>

The layout receives title, page, and section as props from the page. Props with defaults are optional.

Nested Layouts

Layout inheritance follows the directory tree. Each application.what applies to its directory and all children, unless overridden deeper in the tree.

site/
  application.what          <!-- layout = "components/main-layout.html" -->
  index.html                <!-- uses main-layout -->
  about.html                <!-- uses main-layout -->
  blog/
    application.what        <!-- layout = "components/blog-layout.html" -->
    index.html              <!-- uses blog-layout -->
    post.html               <!-- uses blog-layout -->
  admin/
    application.what        <!-- layout = "components/admin-layout.html" -->
    dashboard.html          <!-- uses admin-layout -->
    settings.html           <!-- uses admin-layout -->

The chain resolves from the page's directory upward. The first layout found wins. A page-level layout: directive always takes priority over application.what.

Tip: Layouts are regular component files. They can use conditionals, loops, variables, and even other components. The only special part is <slot/>.

Complete Example

Here's a typical project setup with a shared layout:

components/site-layout.html
<what>
props = "title"
defaults.title = "What"
</what>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>#title#</title>
  <link rel="stylesheet" href="/static/what.css">
</head>
<body>
  <header class="flex items-center justify-between p-4">
    <a href="/">My App</a>
    <nav class="flex gap-4">
      <if user.authenticated>
        <span>#user.full_name#</span>
        <form method="post" action="/w-auth/logout">
          <input type="hidden" name="_csrf" value="#_csrf#">
          <button type="submit">Log out</button>
        </form>
      </if>
      <else/>
        <a href="/login">Log in</a>
      </else>
    </nav>
  </header>

  <main class="p-6">
    <slot/>
  </main>

  <footer class="p-4 text-center text-sm text-muted">
    <p>Built with What</p>
  </footer>
</body>
</html>
site/application.what
layout = "components/site-layout.html"
site/index.html
<what>
title: "Home"
</what>

<h1>Welcome</h1>
<p>This page is wrapped in site-layout automatically.</p>