docs.vapor.codes Open in urlscan Pro
18.238.243.61  Public Scan

Submitted URL: http://docs.vapor.codes/4.0/leaf/getting-started
Effective URL: https://docs.vapor.codes/leaf/getting-started/
Submission: On February 02 via api from US — Scanned from ES

Form analysis 2 forms found in the DOM

<form class="md-header__option" data-md-component="palette">
  <input class="md-option" data-md-color-media="(prefers-color-scheme: light)" data-md-color-scheme="default" data-md-color-primary="black" data-md-color-accent="blue" aria-label="Switch to dark mode" type="radio" name="__palette" id="__palette_0">
  <label class="md-header__button md-icon" title="Switch to dark mode" for="__palette_1">
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
      <path
        d="M12 18c-.89 0-1.74-.2-2.5-.55C11.56 16.5 13 14.42 13 12c0-2.42-1.44-4.5-3.5-5.45C10.26 6.2 11.11 6 12 6a6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12 20 8.69Z">
      </path>
    </svg>
  </label>
  <input class="md-option" data-md-color-media="(prefers-color-scheme: dark)" data-md-color-scheme="slate" data-md-color-primary="black" data-md-color-accent="blue" aria-label="Switch to light mode" type="radio" name="__palette" id="__palette_1">
  <label class="md-header__button md-icon" title="Switch to light mode" for="__palette_0" hidden="">
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
      <path d="M12 8a4 4 0 0 0-4 4 4 4 0 0 0 4 4 4 4 0 0 0 4-4 4 4 0 0 0-4-4m0 10a6 6 0 0 1-6-6 6 6 0 0 1 6-6 6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12 20 8.69Z"></path>
    </svg>
  </label>
</form>

Name: search

<form class="md-search__form" name="search">
  <input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required="">
  <label class="md-search__icon md-icon" for="__search">
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
      <path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5Z"></path>
    </svg>
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
      <path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12Z"></path>
    </svg>
  </label>
  <nav class="md-search__options" aria-label="Search">
    <button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1">
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
        <path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41Z"></path>
      </svg>
    </button>
  </nav>
  <div class="md-search__suggest" data-md-component="search-suggest"></div>
</form>

Text Content

Skip to content

Vapor Docs
Getting Started

 * English
 * 简体中文
 * Nederlands
 * Français
 * German
 * Italiano
 * Español
 * Polski
 * 한국어
 * 日本語

Type to start searching
Vapor GitHub
 * 4.92.1
 * 23.6k
 * 1.5k

Vapor Docs
Vapor GitHub
 * 4.92.1
 * 23.6k
 * 1.5k

 * Welcome
 * Install
   Install
    * macOS
    * Linux

 * Getting Started
   Getting Started
    * Hello, world
    * Folder Structure
    * SwiftPM
    * Xcode

 * Basics
   Basics
    * Routing
    * Controllers
    * Content
    * Client
    * Validation
    * Async
    * Logging
    * Environment
    * Errors

 * Fluent
   Fluent
    * Overview
    * Model
    * Relations
    * Migrations
    * Query
    * Transactions
    * Schema
    * Advanced

 * Leaf
   Leaf
    * Getting Started Getting Started
      Table of contents
       * Package
       * Configure
       * Folder Structure
       * Rendering a View
   
    * Overview
    * Custom Tags

 * Redis
   Redis
    * Overview
    * Sessions

 * Advanced
   Advanced
    * Middleware
    * Testing
    * Server
    * Files
    * Commands
    * Queues
    * WebSockets
    * Sessions
    * Services
    * Request
    * APNS

 * Security
   Security
    * Authentication
    * Crypto
    * Passwords
    * JWT

 * Deploy
   Deploy
    * DigitalOcean
    * Fly
    * Heroku
    * Supervisor
    * Systemd
    * Nginx
    * Docker

 * Contributing
   Contributing
    * Contributing Guide

 * Version (4.0)
   Version (4.0)
    * Legacy Docs
    * Upgrading

 * Release Notes

Table of contents
 * Package
 * Configure
 * Folder Structure
 * Rendering a View

Your new development career awaits. Check out the latest listings. ads via
Carbon


LEAF¶

Leaf is a powerful templating language with Swift-inspired syntax. You can use
it to generate dynamic HTML pages for a front-end website or generate rich
emails to send from an API.


PACKAGE¶

The first step to using Leaf is adding it as a dependency to your project in
your SPM package manifest file.

// swift-tools-version:5.2
import PackageDescription

let package = Package(
    name: "MyApp",
    platforms: [
       .macOS(.v10_15)
    ],
    dependencies: [
        /// Any other dependencies ...
        .package(url: "https://github.com/vapor/leaf.git", from: "4.0.0"),
    ],
    targets: [
        .target(name: "App", dependencies: [
            .product(name: "Leaf", package: "leaf"),
            // Any other dependencies
        ]),
        // Other targets
    ]
)



CONFIGURE¶

Once you have added the package to your project, you can configure Vapor to use
it. This is usually done in configure.swift.

import Leaf

app.views.use(.leaf)


This tells Vapor to use the LeafRenderer when you call req.view in your code.

Note

Leaf has an internal cache for rendering pages. When the Application's
environment is set to .development, this cache is disabled, so that changes to
templates take effect immediately. In .production and all other environments,
the cache is enabled by default; any changes made to templates will not take
effect until the application is restarted.

Warning

For Leaf to be able to find the templates when running from Xcode, you must set
the custom working directory for you Xcode workspace.


FOLDER STRUCTURE¶

Once you have configured Leaf, you will need to ensure you have a Views folder
to store your .leaf files in. By default, Leaf expects the views folder to be a
./Resources/Views relative to your project's root.

You will also likely want to enable Vapor's FileMiddleware to serve files from
your /Public folder if you plan on serving Javascript and CSS files for
instance.

VaporApp
├── Package.swift
├── Resources
│   ├── Views
│   │   └── hello.leaf
├── Public
│   ├── images (images resources)
│   ├── styles (css resources)
└── Sources
    └── ...



RENDERING A VIEW¶

Now that Leaf is configured, let's render your first template. Inside of the
Resources/Views folder, create a new file called hello.leaf with the following
contents:

Hello, #(name)!


Tip

If you're using VSCode as your code editor, we recommend installing the Leaf
extension to enable syntax highlighting: Leaf HTML.

Then, register a route (usually done in routes.swift or a controller) to render
the view.

app.get("hello") { req -> EventLoopFuture<View> in
    return req.view.render("hello", ["name": "Leaf"])
}

// or

app.get("hello") { req async throws -> View in
    return try await req.view.render("hello", ["name": "Leaf"])
}


This uses the generic view property on Request instead of calling Leaf directly.
This allows you to switch to a different renderer in your tests.

Open your browser and visit /hello. You should see Hello, Leaf!. Congratulations
on rendering your first Leaf view!

Vapor Documentation © 2023 by Vapor is licensed under CC BY-NC-SA 4.0
Made with Material for MkDocs