Layouts

Define shared page shells with yield placeholders and extend them from any page or nested layout.

How layouts work

A layout is a .tulip file in the layouts/ directory that defines the outer structure of a page. It uses @yield to mark where child content is injected. Pages extend a layout with @extends and fill the yield slots with @section blocks.

Defining a layout

Create a file in layouts/ with yield placeholders:

<!-- layouts/main.tulip -->
<!DOCTYPE html>
<html>
<head>
    <title>{{ site.name }}</title>
</head>
<body>
    <header>
        <h1>{{ site.name }}</h1>
    </header>
    <main>
        @yield('content')
    </main>
    <footer>
        @yield('footer')
    </footer>
</body>
</html>

Extending a layout

In a page file, declare which layout to extend and provide the section content:

@extends('layouts/main')

@section('content')
    <h1>Welcome</h1>
    <p>This is the home page.</p>
@endsection

The @extends directive must be the first line in the file. The path is relative to the project root, without the .tulip extension.

Multiple sections

A layout can define multiple @yield slots, and a page can fill any combination of them:

@extends('layouts/main')

@section('content')
    <article>Page content here.</article>
@endsection

@section('footer')
    <p>Custom footer for this page.</p>
@endsection

If a page does not provide a section for a given @yield, that slot renders as empty.

Nested layouts

Layouts can extend other layouts, creating a chain. For example, a blog layout that extends the main layout:

<!-- layouts/blog.tulip -->
@extends('layouts/main')

@section('content')
    <div class="blog-container">
        <aside>Blog sidebar</aside>
        <div class="blog-content">
            @yield('post')
        </div>
    </div>
@endsection

A blog post page then extends the blog layout:

@extends('layouts/blog')

@section('post')
    <h1>My Blog Post</h1>
    <p>Post content here.</p>
@endsection

The chain resolves from the innermost page outward: post fills @yield('post') in the blog layout, which fills @yield('content') in the main layout.

Layout file location

All layout files must be in the layouts/ directory at the root of your tulip project:

my-site/
  layouts/
    main.tulip       # @extends('layouts/main')
    blog.tulip       # @extends('layouts/blog')
    docs.tulip       # @extends('layouts/docs')