vapor-docs/build/3.0/leaf/basics/index.html

1876 lines
48 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="lang:clipboard.copy" content="Copy to clipboard">
<meta name="lang:clipboard.copied" content="Copied to clipboard">
<meta name="lang:search.language" content="en">
<meta name="lang:search.pipeline.stopwords" content="True">
<meta name="lang:search.pipeline.trimmer" content="True">
<meta name="lang:search.result.none" content="No matching documents">
<meta name="lang:search.result.one" content="1 matching document">
<meta name="lang:search.result.other" content="# matching documents">
<meta name="lang:search.tokenizer" content="[\s\-]+">
<link rel="shortcut icon" href="../../assets/images/favicon.png">
<meta name="generator" content="mkdocs-0.17.3, mkdocs-material-2.7.0">
<title>Basics - Vapor Docs</title>
<link rel="stylesheet" href="../../assets/stylesheets/application.78aab2dc.css">
<link rel="stylesheet" href="../../assets/stylesheets/application-palette.6079476c.css">
<script src="../../assets/javascripts/modernizr.1aa3b519.js"></script>
<link href="https://fonts.gstatic.com" rel="preconnect" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,400i,700|Roboto+Mono">
<style>body,input{font-family:"Roboto","Helvetica Neue",Helvetica,Arial,sans-serif}code,kbd,pre{font-family:"Roboto Mono","Courier New",Courier,monospace}</style>
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
</head>
<body dir="ltr" data-md-color-primary="blue" data-md-color-accent="purple">
<svg class="md-svg">
<defs>
<svg xmlns="http://www.w3.org/2000/svg" width="416" height="448"
viewBox="0 0 416 448" id="github">
<path fill="currentColor" d="M160 304q0 10-3.125 20.5t-10.75 19-18.125
8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19 18.125-8.5
18.125 8.5 10.75 19 3.125 20.5zM320 304q0 10-3.125 20.5t-10.75
19-18.125 8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19
18.125-8.5 18.125 8.5 10.75 19 3.125 20.5zM360
304q0-30-17.25-51t-46.75-21q-10.25 0-48.75 5.25-17.75 2.75-39.25
2.75t-39.25-2.75q-38-5.25-48.75-5.25-29.5 0-46.75 21t-17.25 51q0 22 8
38.375t20.25 25.75 30.5 15 35 7.375 37.25 1.75h42q20.5 0
37.25-1.75t35-7.375 30.5-15 20.25-25.75 8-38.375zM416 260q0 51.75-15.25
82.75-9.5 19.25-26.375 33.25t-35.25 21.5-42.5 11.875-42.875 5.5-41.75
1.125q-19.5 0-35.5-0.75t-36.875-3.125-38.125-7.5-34.25-12.875-30.25-20.25-21.5-28.75q-15.5-30.75-15.5-82.75
0-59.25 34-99-6.75-20.5-6.75-42.5 0-29 12.75-54.5 27 0 47.5 9.875t47.25
30.875q36.75-8.75 77.25-8.75 37 0 70 8 26.25-20.5
46.75-30.25t47.25-9.75q12.75 25.5 12.75 54.5 0 21.75-6.75 42 34 40 34
99.5z" />
</svg>
</defs>
</svg>
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="drawer">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="search">
<label class="md-overlay" data-md-component="overlay" for="drawer"></label>
<a href="#basics" tabindex="1" class="md-skip">
Skip to content
</a>
<header class="md-header" data-md-component="header">
<nav class="md-header-nav md-grid">
<div class="md-flex">
<div class="md-flex__cell md-flex__cell--shrink">
<a href="../.." title="Vapor Docs" class="md-header-nav__button md-logo">
<img src="../../images/droplet-white.svg" width="24" height="24">
</a>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<label class="md-icon md-icon--menu md-header-nav__button" for="drawer"></label>
</div>
<div class="md-flex__cell md-flex__cell--stretch">
<div class="md-flex__ellipsis md-header-nav__title" data-md-component="title">
<span class="md-header-nav__topic">
Vapor Docs
</span>
<span class="md-header-nav__topic">
Basics
</span>
</div>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<label class="md-icon md-icon--search md-header-nav__button" for="search"></label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="query" data-md-state="active">
<label class="md-icon md-search__icon" for="search"></label>
<button type="reset" class="md-icon md-search__icon" data-md-component="reset" tabindex="-1">
&#xE5CD;
</button>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" data-md-scrollfix>
<div class="md-search-result" data-md-component="result">
<div class="md-search-result__meta">
Type to start searching
</div>
<ol class="md-search-result__list"></ol>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<div class="md-header-nav__source">
<a href="http://github.com/vapor/vapor/" title="Go to repository" class="md-source" data-md-source="github">
<div class="md-source__icon">
<svg viewBox="0 0 24 24" width="24" height="24">
<use xlink:href="#github" width="24" height="24"></use>
</svg>
</div>
<div class="md-source__repository">
GitHub
</div>
</a>
</div>
</div>
</div>
</nav>
</header>
<div class="md-container">
<main class="md-main">
<div class="md-main__inner md-grid" data-md-component="container">
<div class="md-sidebar md-sidebar--primary" data-md-component="navigation">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary" data-md-level="0">
<label class="md-nav__title md-nav__title--site" for="drawer">
<span class="md-nav__button md-logo">
<img src="../../images/droplet-white.svg" width="48" height="48">
</span>
Vapor Docs
</label>
<div class="md-nav__source">
<a href="http://github.com/vapor/vapor/" title="Go to repository" class="md-source" data-md-source="github">
<div class="md-source__icon">
<svg viewBox="0 0 24 24" width="24" height="24">
<use xlink:href="#github" width="24" height="24"></use>
</svg>
</div>
<div class="md-source__repository">
GitHub
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../.." title="Overview" class="md-nav__link">
Overview
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-2" type="checkbox" id="nav-2">
<label class="md-nav__link" for="nav-2">
Install
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-2">
Install
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../install/macos/" title="macOS" class="md-nav__link">
macOS
</a>
</li>
<li class="md-nav__item">
<a href="../../install/ubuntu/" title="Ubuntu" class="md-nav__link">
Ubuntu
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-3" type="checkbox" id="nav-3">
<label class="md-nav__link" for="nav-3">
Getting started
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-3">
Getting started
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../getting-started/hello-world/" title="Hello, world" class="md-nav__link">
Hello, world
</a>
</li>
<li class="md-nav__item">
<a href="../../getting-started/toolbox/" title="Toolbox" class="md-nav__link">
Toolbox
</a>
</li>
<li class="md-nav__item">
<a href="../../getting-started/spm/" title="SPM" class="md-nav__link">
SPM
</a>
</li>
<li class="md-nav__item">
<a href="../../getting-started/xcode/" title="Xcode" class="md-nav__link">
Xcode
</a>
</li>
<li class="md-nav__item">
<a href="../../getting-started/structure/" title="Folder Structure" class="md-nav__link">
Folder Structure
</a>
</li>
<li class="md-nav__item">
<a href="../../getting-started/application/" title="Application" class="md-nav__link">
Application
</a>
</li>
<li class="md-nav__item">
<a href="../../getting-started/controllers/" title="Controllers" class="md-nav__link">
Controllers
</a>
</li>
<li class="md-nav__item">
<a href="../../getting-started/routing/" title="Routing" class="md-nav__link">
Routing
</a>
</li>
<li class="md-nav__item">
<a href="../../getting-started/content/" title="Content" class="md-nav__link">
Content
</a>
</li>
<li class="md-nav__item">
<a href="../../getting-started/futures/" title="Futures" class="md-nav__link">
Futures
</a>
</li>
<li class="md-nav__item">
<a href="../../getting-started/services/" title="Services" class="md-nav__link">
Services
</a>
</li>
<li class="md-nav__item">
<a href="../../getting-started/cloud/" title="Deployment" class="md-nav__link">
Deployment
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-4" type="checkbox" id="nav-4">
<label class="md-nav__link" for="nav-4">
Routing
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-4">
Routing
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../routing/getting-started/" title="Getting Started" class="md-nav__link">
Getting Started
</a>
</li>
<li class="md-nav__item">
<a href="../../routing/parameters/" title="Parameters" class="md-nav__link">
Parameters
</a>
</li>
<li class="md-nav__item">
<a href="../../routing/route/" title="Route" class="md-nav__link">
Route
</a>
</li>
<li class="md-nav__item">
<a href="../../routing/router/" title="Router" class="md-nav__link">
Router
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-5" type="checkbox" id="nav-5">
<label class="md-nav__link" for="nav-5">
Fluent
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-5">
Fluent
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../fluent/getting-started/" title="Getting Started" class="md-nav__link">
Getting Started
</a>
</li>
<li class="md-nav__item">
<a href="../../fluent/models/" title="Models" class="md-nav__link">
Models
</a>
</li>
<li class="md-nav__item">
<a href="../../fluent/migrations/" title="Migrations" class="md-nav__link">
Migrations
</a>
</li>
<li class="md-nav__item">
<a href="../../fluent/querying/" title="Querying" class="md-nav__link">
Querying
</a>
</li>
<li class="md-nav__item">
<a href="../../fluent/query-builder/" title="Query Builder" class="md-nav__link">
Query Builder
</a>
</li>
<li class="md-nav__item">
<a href="../../fluent/schema-builder/" title="Schema Builder" class="md-nav__link">
Schema Builder
</a>
</li>
<li class="md-nav__item">
<a href="../../fluent/relations/" title="Relations" class="md-nav__link">
Relations
</a>
</li>
<li class="md-nav__item">
<a href="../../fluent/pivot/" title="Pivot" class="md-nav__link">
Pivot
</a>
</li>
<li class="md-nav__item">
<a href="../../fluent/transaction/" title="Transaction" class="md-nav__link">
Transaction
</a>
</li>
<li class="md-nav__item">
<a href="../../fluent/database/" title="Database" class="md-nav__link">
Database
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-6" type="checkbox" id="nav-6">
<label class="md-nav__link" for="nav-6">
PostgreSQL
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-6">
PostgreSQL
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../postgresql/getting-started/" title="Getting Started" class="md-nav__link">
Getting Started
</a>
</li>
<li class="md-nav__item">
<a href="../../postgresql/fluent/" title="Fluent PostgreSQL" class="md-nav__link">
Fluent PostgreSQL
</a>
</li>
<li class="md-nav__item">
<a href="../../postgresql/core/" title="PostgreSQL Core" class="md-nav__link">
PostgreSQL Core
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-7" type="checkbox" id="nav-7">
<label class="md-nav__link" for="nav-7">
MySQL
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-7">
MySQL
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../mysql/getting-started/" title="Getting Started" class="md-nav__link">
Getting Started
</a>
</li>
<li class="md-nav__item">
<a href="../../mysql/fluent/" title="Fluent MySQL" class="md-nav__link">
Fluent MySQL
</a>
</li>
<li class="md-nav__item">
<a href="../../mysql/core/" title="MySQL Core" class="md-nav__link">
MySQL Core
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-8" type="checkbox" id="nav-8">
<label class="md-nav__link" for="nav-8">
SQLite
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-8">
SQLite
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../sqlite/getting-started/" title="Getting Started" class="md-nav__link">
Getting Started
</a>
</li>
<li class="md-nav__item">
<a href="../../sqlite/fluent/" title="Fluent SQLite" class="md-nav__link">
Fluent SQLite
</a>
</li>
<li class="md-nav__item">
<a href="../../sqlite/core/" title="SQLite Core" class="md-nav__link">
SQLite Core
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-9" type="checkbox" id="nav-9" checked>
<label class="md-nav__link" for="nav-9">
Leaf
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-9">
Leaf
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../getting-started/" title="Getting Started" class="md-nav__link">
Getting Started
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="toc">
<label class="md-nav__link md-nav__link--active" for="toc">
Basics
</label>
<a href="./" title="Basics" class="md-nav__link md-nav__link--active">
Basics
</a>
<nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="#rendering-a-template" title="Rendering a template" class="md-nav__link">
Rendering a template
</a>
<nav class="md-nav">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#async" title="Async" class="md-nav__link">
Async
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#template-syntax" title="Template syntax" class="md-nav__link">
Template syntax
</a>
<nav class="md-nav">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#structure" title="Structure" class="md-nav__link">
Structure
</a>
</li>
<li class="md-nav__item">
<a href="#working-with-context" title="Working with context" class="md-nav__link">
Working with context
</a>
</li>
<li class="md-nav__item">
<a href="#checking-conditions" title="Checking conditions" class="md-nav__link">
Checking conditions
</a>
</li>
<li class="md-nav__item">
<a href="#loops" title="Loops" class="md-nav__link">
Loops
</a>
</li>
<li class="md-nav__item">
<a href="#embedding-templates" title="Embedding templates" class="md-nav__link">
Embedding templates
</a>
</li>
<li class="md-nav__item">
<a href="#other-tags" title="Other tags" class="md-nav__link">
Other tags
</a>
<nav class="md-nav">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#capitalize" title="#capitalize" class="md-nav__link">
#capitalize
</a>
</li>
<li class="md-nav__item">
<a href="#contains" title="#contains" class="md-nav__link">
#contains
</a>
</li>
<li class="md-nav__item">
<a href="#count" title="#count" class="md-nav__link">
#count
</a>
</li>
<li class="md-nav__item">
<a href="#lowercase" title="#lowercase" class="md-nav__link">
#lowercase
</a>
</li>
<li class="md-nav__item">
<a href="#uppercase" title="#uppercase" class="md-nav__link">
#uppercase
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../custom-tags/" title="Custom tags" class="md-nav__link">
Custom tags
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-10" type="checkbox" id="nav-10">
<label class="md-nav__link" for="nav-10">
Redis
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-10">
Redis
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../redis/getting-started/" title="Getting Started" class="md-nav__link">
Getting Started
</a>
</li>
<li class="md-nav__item">
<a href="../../redis/basics/" title="Basics" class="md-nav__link">
Basics
</a>
</li>
<li class="md-nav__item">
<a href="../../redis/custom-commands/" title="Custom commands" class="md-nav__link">
Custom commands
</a>
</li>
<li class="md-nav__item">
<a href="../../redis/pub-sub/" title="Publish and Subscribe" class="md-nav__link">
Publish and Subscribe
</a>
</li>
<li class="md-nav__item">
<a href="../../redis/pipeline/" title="Pipeline" class="md-nav__link">
Pipeline
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-11" type="checkbox" id="nav-11">
<label class="md-nav__link" for="nav-11">
WebSocket
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-11">
WebSocket
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../websocket/websocket/" title="Getting Started" class="md-nav__link">
Getting Started
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-12" type="checkbox" id="nav-12">
<label class="md-nav__link" for="nav-12">
Crypto
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-12">
Crypto
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../crypto/getting-started/" title="Getting Started" class="md-nav__link">
Getting Started
</a>
</li>
<li class="md-nav__item">
<a href="../../crypto/base64/" title="Base64" class="md-nav__link">
Base64
</a>
</li>
<li class="md-nav__item">
<a href="../../crypto/hash/" title="Hashes" class="md-nav__link">
Hashes
</a>
</li>
<li class="md-nav__item">
<a href="../../crypto/mac/" title="Message authentication" class="md-nav__link">
Message authentication
</a>
</li>
<li class="md-nav__item">
<a href="../../crypto/passwords/" title="Password hashing" class="md-nav__link">
Password hashing
</a>
</li>
<li class="md-nav__item">
<a href="../../crypto/random/" title="Random" class="md-nav__link">
Random
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-13" type="checkbox" id="nav-13">
<label class="md-nav__link" for="nav-13">
Testing
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-13">
Testing
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../testing/getting-started/" title="Getting Started" class="md-nav__link">
Getting Started
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-14" type="checkbox" id="nav-14">
<label class="md-nav__link" for="nav-14">
Deploy
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-14">
Deploy
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../deploy/getting-started/" title="Getting Started" class="md-nav__link">
Getting Started
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-15" type="checkbox" id="nav-15">
<label class="md-nav__link" for="nav-15">
Version (3.0-rc)
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-15">
Version (3.0-rc)
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../version/1_5/" title="1.5" class="md-nav__link">
1.5
</a>
</li>
<li class="md-nav__item">
<a href="../../version/2_0/" title="2.0" class="md-nav__link">
2.0
</a>
</li>
<li class="md-nav__item">
<a href="../../version/3_0/" title="3.0-rc" class="md-nav__link">
3.0-rc
</a>
</li>
<li class="md-nav__item">
<a href="../../version/support/" title="Support" class="md-nav__link">
Support
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="toc">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="#rendering-a-template" title="Rendering a template" class="md-nav__link">
Rendering a template
</a>
<nav class="md-nav">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#async" title="Async" class="md-nav__link">
Async
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#template-syntax" title="Template syntax" class="md-nav__link">
Template syntax
</a>
<nav class="md-nav">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#structure" title="Structure" class="md-nav__link">
Structure
</a>
</li>
<li class="md-nav__item">
<a href="#working-with-context" title="Working with context" class="md-nav__link">
Working with context
</a>
</li>
<li class="md-nav__item">
<a href="#checking-conditions" title="Checking conditions" class="md-nav__link">
Checking conditions
</a>
</li>
<li class="md-nav__item">
<a href="#loops" title="Loops" class="md-nav__link">
Loops
</a>
</li>
<li class="md-nav__item">
<a href="#embedding-templates" title="Embedding templates" class="md-nav__link">
Embedding templates
</a>
</li>
<li class="md-nav__item">
<a href="#other-tags" title="Other tags" class="md-nav__link">
Other tags
</a>
<nav class="md-nav">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#capitalize" title="#capitalize" class="md-nav__link">
#capitalize
</a>
</li>
<li class="md-nav__item">
<a href="#contains" title="#contains" class="md-nav__link">
#contains
</a>
</li>
<li class="md-nav__item">
<a href="#count" title="#count" class="md-nav__link">
#count
</a>
</li>
<li class="md-nav__item">
<a href="#lowercase" title="#lowercase" class="md-nav__link">
#lowercase
</a>
</li>
<li class="md-nav__item">
<a href="#uppercase" title="#uppercase" class="md-nav__link">
#uppercase
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content">
<article class="md-content__inner md-typeset">
<a href="https://github.com/vapor/documentation/edit/master/3.0/docs/leaf/basics.md" title="Edit this page" class="md-icon md-content__icon">&#xE3C9;</a>
<h1 id="basics">Basics<a class="headerlink" href="#basics" title="Permanent link">&para;</a></h1>
<p>Welcome to Leaf. Leaf's goal is to be a simple templating language that can make generating views easier. There are plenty of great templating languages, so use what's best for you maybe that's Leaf! The goals of Leaf are:</p>
<ul>
<li>Small set of strictly enforced rules</li>
<li>Consistency</li>
<li>Parser first mentality</li>
<li>Extensibility</li>
<li>Asynchronous and reactive</li>
</ul>
<h2 id="rendering-a-template">Rendering a template<a class="headerlink" href="#rendering-a-template" title="Permanent link">&para;</a></h2>
<p>Once you have Leaf installed, you should create a directory called “Resources” inside your project folder, and inside that create another directory called “Views”. This Resources/Views directory is the default location for Leaf templates, although you can change it if you want.</p>
<p>Firstly, import Leaf to routes.swift</p>
<div class="codehilite"><pre><span></span><span class="kd">import</span> <span class="nc">Leaf</span>
</pre></div>
<p>Then, to render a basic Leaf template from a route, add this code:</p>
<div class="codehilite"><pre><span></span><span class="n">router</span><span class="p">.</span><span class="kr">get</span> <span class="p">{</span> <span class="n">req</span> <span class="p">-&gt;</span> <span class="n">Future</span><span class="p">&lt;</span><span class="n">View</span><span class="p">&gt;</span> <span class="k">in</span>
<span class="kd">let</span> <span class="nv">leaf</span> <span class="p">=</span> <span class="k">try</span> <span class="n">req</span><span class="p">.</span><span class="n">make</span><span class="p">(</span><span class="n">LeafRenderer</span><span class="p">.</span><span class="kc">self</span><span class="p">)</span>
<span class="kd">let</span> <span class="nv">context</span> <span class="p">=</span> <span class="p">[</span><span class="nb">String</span><span class="p">:</span> <span class="nb">String</span><span class="p">]()</span>
<span class="k">return</span> <span class="k">try</span> <span class="n">leaf</span><span class="p">.</span><span class="n">render</span><span class="p">(</span><span class="s">&quot;home&quot;</span><span class="p">,</span> <span class="n">context</span><span class="p">)</span>
<span class="p">}</span>
</pre></div>
<p>That will load home.leaf in the Resources/Views directory and render it. The <code>context</code> dictionary is there to let you provide custom data to render inside the template, but you might find it easier to use codable structs instead because they provide extra type safety. For example:</p>
<div class="codehilite"><pre><span></span><span class="kd">struct</span> <span class="nc">HomePage</span><span class="p">:</span> <span class="n">Codable</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nv">title</span><span class="p">:</span> <span class="nb">String</span>
<span class="kd">var</span> <span class="nv">content</span><span class="p">:</span> <span class="nb">String</span>
<span class="p">}</span>
</pre></div>
<h3 id="async">Async<a class="headerlink" href="#async" title="Permanent link">&para;</a></h3>
<p>Leaf's engine is completely reactive, supporting both streams and futures. One of the only ones of its kind.</p>
<p>When working with Future results, simply pass the <code>Future</code> in your template context.
Streams that carry an encodable type need to be encoded before they're usable within Leaf.</p>
<div class="codehilite"><pre><span></span><span class="kd">struct</span> <span class="nc">Profile</span><span class="p">:</span> <span class="n">Codable</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nv">friends</span><span class="p">:</span> <span class="n">EncodableStream</span>
<span class="kd">var</span> <span class="nv">currentUser</span><span class="p">:</span> <span class="n">Future</span><span class="p">&lt;</span><span class="n">User</span><span class="p">&gt;</span>
<span class="p">}</span>
</pre></div>
<p>In the above context, the <code>currentUser</code> variable in Leaf will behave as being a <code>User</code> type. Leaf will not read the user Future if it's not used during rendering.</p>
<p><code>EncodableStream</code> will behave as an array of LeafData, only with lower memory impact and better performance. It is recommended to use <code>EncodableStream</code> for (large) database queries.</p>
<div class="codehilite"><pre><span></span>Your name is #(currentUser.name).
#for(friend in friends) {
#(friend.name) is a friend of you.
}
</pre></div>
<h2 id="template-syntax">Template syntax<a class="headerlink" href="#template-syntax" title="Permanent link">&para;</a></h2>
<h3 id="structure">Structure<a class="headerlink" href="#structure" title="Permanent link">&para;</a></h3>
<p>Leaf tags are made up of four elements:</p>
<ul>
<li>Token: <code>#</code> is the token</li>
<li>Name: A <code>string</code> that identifies the tag</li>
<li>Parameter List: <code>()</code> May accept 0 or more arguments</li>
<li>Body (optional): <code>{}</code> Must be separated from the parameter list by a space</li>
</ul>
<p>There can be many different usages of these four elements depending on the tag's implementation. Let's look at a few examples of how Leaf's built-in tags might be used:</p>
<ul>
<li><code>#()</code></li>
<li><code>#(variable)</code></li>
<li><code>#embed("template")</code></li>
<li><code>#set("title") { Welcome to Vapor }</code></li>
<li><code>#count(friends)</code></li>
<li><code>#for(friend in friends) { &lt;li&gt;#(friend.name)&lt;/li&gt; }</code></li>
</ul>
<h3 id="working-with-context">Working with context<a class="headerlink" href="#working-with-context" title="Permanent link">&para;</a></h3>
<p>In our Swift example from earlier, we used an empty <code>[String: String]</code> dictionary for context, which passes no custom data to Leaf. To try rendering content, use this code instead:</p>
<div class="codehilite"><pre><span></span><span class="kd">let</span> <span class="nv">context</span> <span class="p">=</span> <span class="p">[</span><span class="s">&quot;title&quot;</span><span class="p">:</span> <span class="s">&quot;Welcome&quot;</span><span class="p">,</span> <span class="s">&quot;message&quot;</span><span class="p">:</span> <span class="s">&quot;Vapor and Leaf work hand in hand&quot;</span><span class="p">]</span>
<span class="k">return</span> <span class="k">try</span> <span class="n">leaf</span><span class="p">.</span><span class="n">make</span><span class="p">(</span><span class="s">&quot;home&quot;</span><span class="p">,</span> <span class="n">context</span><span class="p">)</span>
</pre></div>
<p>That will expose <code>title</code> and <code>message</code> to our Leaf template, which can then be used inside tags. For example:</p>
<div class="codehilite"><pre><span></span>&lt;h1&gt;#(title)&lt;/h1&gt;
&lt;p&gt;#(message)&lt;/p&gt;
</pre></div>
<h3 id="checking-conditions">Checking conditions<a class="headerlink" href="#checking-conditions" title="Permanent link">&para;</a></h3>
<p>Leaf is able to evaluate a range of conditions using its <code>#if</code> tag. For example, if you provide a variable it will check that variable exists in its context:</p>
<div class="codehilite"><pre><span></span>#if(title) {
The title is #(title)
} else {
No title was provided.
}
</pre></div>
<p>You can also write comparisons, for example:</p>
<div class="codehilite"><pre><span></span>#if(title == &quot;Welcome&quot;) {
This is a friendly web page.
} else {
No strangers allowed!
}
</pre></div>
<p>If you want to use another tag as part of your condition, you should omit the <code>#</code> for the inner tag. For example:</p>
<div class="codehilite"><pre><span></span>#if(lowercase(title) == &quot;welcome&quot;) {
This is a friendly web page.
} else {
No strangers allowed!
}
</pre></div>
<h3 id="loops">Loops<a class="headerlink" href="#loops" title="Permanent link">&para;</a></h3>
<p>If you provide an array of items, Leaf can loop over them and let you manipulate each item individually using its <code>#for</code> tag. For example, we could update our Swift code to provide a list of names in a team:</p>
<div class="codehilite"><pre><span></span><span class="kd">let</span> <span class="nv">context</span> <span class="p">=</span> <span class="p">[</span><span class="s">&quot;team&quot;</span><span class="p">:</span> <span class="p">[</span><span class="s">&quot;Malcolm&quot;</span><span class="p">,</span> <span class="s">&quot;Kaylee&quot;</span><span class="p">,</span> <span class="s">&quot;Jayne&quot;</span><span class="p">]]</span>
</pre></div>
<p>We could then loop over them in Leaf like this:</p>
<div class="codehilite"><pre><span></span>#for(name in team) {
&lt;p&gt;#(name) is in the team.&lt;/p&gt;
}
</pre></div>
<p>Leaf provides some extra variables inside a <code>#for</code> loop to give you more information about the loop's progress:</p>
<ul>
<li>The <code>loop.isFirst</code> variable is true when the current iteration is the first one.</li>
<li>The <code>loop.isLast</code> variable is true when it's the last iteration.</li>
<li>The <code>loop.index</code> variable will be set to the number of the current iteration, counting from 0.</li>
</ul>
<h3 id="embedding-templates">Embedding templates<a class="headerlink" href="#embedding-templates" title="Permanent link">&para;</a></h3>
<p>Leafs <code>#embed</code> tag allows you to copy the contents of one template into another. When use this, you should always omit the template file's .leaf extension.</p>
<p>Embedding is useful for copying in a standard piece of content, for example a page footer or advert code:</p>
<div class="codehilite"><pre><span></span>#embed(&quot;footer&quot;)
</pre></div>
<p>This tag is also useful for building one template on top of another. For example, you might have a master.leaf file that includes all the code required to lay out your website  HTML structure, CSS and JavaScript  with some gaps in place that represent where page content varies.</p>
<p>Using this approach, you would construct a child template that fills in its unique content, then embeds the parent template that places the content appropriately.</p>
<p>For example, you might create a child.leaf template like this:</p>
<div class="codehilite"><pre><span></span>#set(&quot;body&quot;) {
&lt;p&gt;Welcome to Vapor!&lt;/p&gt;
}
#embed(&quot;master&quot;)
</pre></div>
<p>That configures one item of context, <code>body</code>, but doesnt display it directly. Instead, it embeds master.leaf, which can render <code>body</code> along with any other context variables passed in from Swift. For example, master.leaf might look like this:</p>
<div class="codehilite"><pre><span></span>&lt;html&gt;
&lt;head&gt;&lt;title&gt;#(title)&lt;/title&gt;&lt;/head&gt;
&lt;body&gt;#get(body)&lt;/body&gt;
&lt;/html&gt;
</pre></div>
<p>When given the context <code>["title": "Hi there!"]</code>, child.leaf will render as follows:</p>
<div class="codehilite"><pre><span></span>&lt;html&gt;
&lt;head&gt;&lt;title&gt;Hi there!&lt;/title&gt;&lt;/head&gt;
&lt;body&gt;&lt;p&gt;Welcome to Vapor!&lt;/p&gt;&lt;/body&gt;
&lt;/html&gt;
</pre></div>
<h3 id="other-tags">Other tags<a class="headerlink" href="#other-tags" title="Permanent link">&para;</a></h3>
<h4 id="capitalize"><code>#capitalize</code><a class="headerlink" href="#capitalize" title="Permanent link">&para;</a></h4>
<p>The <code>#capitalize</code> tag uppercases the first letter of any string. For example, “taylor” will become “Taylor”.</p>
<div class="codehilite"><pre><span></span>#capitalize(name)
</pre></div>
<h4 id="contains"><code>#contains</code><a class="headerlink" href="#contains" title="Permanent link">&para;</a></h4>
<p>The <code>#contains</code> tag accepts an array and a value as its two parameters, and returns true if the array in parameter one contains the value in parameter two. For example, given the array <code>team</code>:</p>
<div class="codehilite"><pre><span></span>#if(contains(team, &quot;Jayne&quot;)) {
You&#39;re all set!
} else {
You need someone to do PR.
}
</pre></div>
<h4 id="count"><code>#count</code><a class="headerlink" href="#count" title="Permanent link">&para;</a></h4>
<p>The <code>#count</code> tag returns the number of items in an array. For example:</p>
<div class="codehilite"><pre><span></span>Your search matched #count(matches) pages.
</pre></div>
<h4 id="lowercase"><code>#lowercase</code><a class="headerlink" href="#lowercase" title="Permanent link">&para;</a></h4>
<p>The <code>#lowercase</code> tag lowercases all letters in a string. For example, “Taylor” will become “taylor”.</p>
<div class="codehilite"><pre><span></span>#lowercase(name)
</pre></div>
<h4 id="uppercase"><code>#uppercase</code><a class="headerlink" href="#uppercase" title="Permanent link">&para;</a></h4>
<p>The <code>#uppercase</code> tag uppercases all letters in a string. For example, “Taylor” will become “TAYLOR”.</p>
<div class="codehilite"><pre><span></span>#uppercase(name)
</pre></div>
</article>
</div>
</div>
</main>
<footer class="md-footer">
<div class="md-footer-nav">
<nav class="md-footer-nav__inner md-grid">
<a href="../getting-started/" title="Getting Started" class="md-flex md-footer-nav__link md-footer-nav__link--prev" rel="prev">
<div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-back md-footer-nav__button"></i>
</div>
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis">
<span class="md-footer-nav__direction">
Previous
</span>
Getting Started
</span>
</div>
</a>
<a href="../custom-tags/" title="Custom tags" class="md-flex md-footer-nav__link md-footer-nav__link--next" rel="next">
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis">
<span class="md-footer-nav__direction">
Next
</span>
Custom tags
</span>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-forward md-footer-nav__button"></i>
</div>
</a>
</nav>
</div>
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-footer-copyright">
<div class="md-footer-copyright__highlight">
Copyright &copy; 2018 Qutheory, LLC
</div>
powered by
<a href="http://www.mkdocs.org">MkDocs</a>
and
<a href="https://squidfunk.github.io/mkdocs-material/">
Material for MkDocs</a>
</div>
<div class="md-footer-social">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<a href="https://twitter.com/@codevapor" class="md-footer-social__link fa fa-twitter"></a>
<a href="http://vapor.team/" class="md-footer-social__link fa fa-slack"></a>
<a href="https://github.com/vapor" class="md-footer-social__link fa fa-github"></a>
</div>
</div>
</div>
</footer>
</div>
<script src="../../assets/javascripts/application.8eb9be28.js"></script>
<script>app.initialize({version:"0.17.3",url:{base:"../.."}})</script>
<script>!function(e,a,t,n,o,c,i){e.GoogleAnalyticsObject=o,e.ga=e.ga||function(){(e.ga.q=e.ga.q||[]).push(arguments)},e.ga.l=1*new Date,c=a.createElement(t),i=a.getElementsByTagName(t)[0],c.async=1,c.src="https://www.google-analytics.com/analytics.js",i.parentNode.insertBefore(c,i)}(window,document,"script",0,"ga"),ga("create","UA-76177358-4","auto"),ga("set","anonymizeIp",!0),ga("send","pageview");var links=document.getElementsByTagName("a");if(Array.prototype.map.call(links,function(e){e.host!=document.location.host&&e.addEventListener("click",function(){var a=e.getAttribute("data-md-action")||"follow";ga("send","event","outbound",a,e.href)})}),document.forms.search){var query=document.forms.search.query;query.addEventListener("blur",function(){if(this.value){var e=document.location.pathname;ga("send","pageview",e+"?q="+this.value)}})}</script>
</body>
</html>