Dep: update
주로 PHAN
This commit is contained in:
+39
@@ -0,0 +1,39 @@
|
||||
+++
|
||||
title = "Introduction"
|
||||
[menu.main]
|
||||
parent = "getting-started"
|
||||
weight = 1
|
||||
+++
|
||||
|
||||
[](https://twitter.com/reinink)
|
||||
[](https://github.com/thephpleague/plates)
|
||||
[](https://github.com/thephpleague/plates/releases)
|
||||
[](https://github.com/thephpleague/plates/blob/master/LICENSE)
|
||||
{{<html>}}<br/>{{</html>}}
|
||||
[](https://github.com/thephpleague/plates/actions?query=workflow%3APHP+branch%3Av3)
|
||||
[](https://scrutinizer-ci.com/g/thephpleague/plates/code-structure)
|
||||
[](https://scrutinizer-ci.com/g/thephpleague/plates)
|
||||
[](https://packagist.org/packages/league/plates)
|
||||
|
||||
## About
|
||||
|
||||
Plates is a native PHP template system that's fast, easy to use and easy to extend. It's inspired by the excellent [Twig](http://twig.sensiolabs.org/) template engine and strives to bring modern template language functionality to native PHP templates. Plates is designed for developers who prefer to use native PHP templates over compiled template languages, such as Twig or Smarty.
|
||||
|
||||
## Highlights
|
||||
|
||||
- Native PHP templates, no new [syntax]({{< relref "templates/syntax.md" >}}) to learn
|
||||
- Plates is a template system, not a template language
|
||||
- Plates encourages the use of existing PHP functions
|
||||
- Increase code reuse with template [layouts]({{< relref "templates/layouts.md" >}}) and [inheritance]({{< relref "templates/inheritance.md" >}})
|
||||
- Template [folders]({{< relref "engine/folders.md" >}}) for grouping templates into namespaces
|
||||
- [Data]({{< relref "templates/data.md#preassigned-and-shared-data" >}}) sharing across templates
|
||||
- Preassign [data]({{< relref "templates/data#preassigned-and-shared-data" >}}) to specific templates
|
||||
- Built-in [escaping]({{< relref "templates/escaping.md" >}}) helpers
|
||||
- Easy to extend using [functions]({{< relref "engine/functions.md" >}}) and [extensions]({{< relref "engine/extensions.md" >}})
|
||||
- Framework-agnostic, will work with any project
|
||||
- Decoupled design makes templates easy to test
|
||||
- Composer ready and PSR-2 compliant
|
||||
|
||||
## Questions?
|
||||
|
||||
Plates is maintained by [RJ Garcia](https://twitter.com/ragboyjr) and originally created by [Jonathan Reinink](https://twitter.com/reinink). Submit issues to [Github](https://github.com/thephpleague/plates/issues).
|
||||
@@ -0,0 +1,6 @@
|
||||
+++
|
||||
title = "The Engine"
|
||||
[menu.main]
|
||||
identifier = "engine"
|
||||
weight = 2
|
||||
+++
|
||||
@@ -0,0 +1,119 @@
|
||||
+++
|
||||
title = "Extensions"
|
||||
linkTitle = "Engine Extensions"
|
||||
[menu.main]
|
||||
parent = "engine"
|
||||
weight = 5
|
||||
+++
|
||||
|
||||
Creating extensions couldn't be easier, and can really make Plates sing for your specific project. Start by creating a class that implements `\League\Plates\Extension\ExtensionInterface`. Next, register your template [functions]({{< relref "engine/functions.md" >}}) within a `register()` method.
|
||||
|
||||
## Simple extensions example
|
||||
|
||||
~~~ php
|
||||
use League\Plates\Engine;
|
||||
use League\Plates\Extension\ExtensionInterface;
|
||||
|
||||
class ChangeCase implements ExtensionInterface
|
||||
{
|
||||
public function register(Engine $engine)
|
||||
{
|
||||
$engine->registerFunction('uppercase', [$this, 'uppercaseString']);
|
||||
$engine->registerFunction('lowercase', [$this, 'lowercaseString']);
|
||||
}
|
||||
|
||||
public function uppercaseString($var)
|
||||
{
|
||||
return strtoupper($var);
|
||||
}
|
||||
|
||||
public function lowercaseString($var)
|
||||
{
|
||||
return strtolower($var);
|
||||
}
|
||||
}
|
||||
~~~
|
||||
|
||||
To use this extension in your template, simply call your new functions:
|
||||
|
||||
~~~ php
|
||||
<p>Hello, <?=$this->e($this->uppercase($name))?></p>
|
||||
~~~
|
||||
|
||||
They can also be used in a [batch]({{< relref "templates/functions.md#batch-function-calls" >}}) compatible function:
|
||||
|
||||
~~~ php
|
||||
<h1>Hello <?=$this->e($name, 'uppercase')</h1>
|
||||
~~~
|
||||
|
||||
## Single method extensions
|
||||
|
||||
Alternatively, you may choose to expose the entire extension object to the template using a single function. This can make your templates more legible and also reduce the chance of conflicts with other extensions.
|
||||
|
||||
~~~ php
|
||||
use League\Plates\Engine;
|
||||
use League\Plates\Extension\ExtensionInterface;
|
||||
|
||||
class ChangeCase implements ExtensionInterface
|
||||
{
|
||||
public function register(Engine $engine)
|
||||
{
|
||||
$engine->registerFunction('case', [$this, 'getObject']);
|
||||
}
|
||||
|
||||
public function getObject()
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function upper($var)
|
||||
{
|
||||
return strtoupper($var);
|
||||
}
|
||||
|
||||
public function lower($var)
|
||||
{
|
||||
return strtolower($var);
|
||||
}
|
||||
}
|
||||
~~~
|
||||
|
||||
To use this extension in your template, first call the primary function, then the secondary functions:
|
||||
|
||||
~~~ php
|
||||
<p>Hello, <?=$this->e($this->case()->upper($name))?></p>
|
||||
~~~
|
||||
|
||||
## Loading extensions
|
||||
|
||||
To enable an extension, load it into the [engine]({{< relref "engine/overview.md" >}}) object using the `loadExtension()` method.
|
||||
|
||||
~~~ php
|
||||
$engine->loadExtension(new ChangeCase());
|
||||
~~~
|
||||
|
||||
## Accessing the engine and template
|
||||
|
||||
It may be desirable to access the `engine` or `template` objects from within your extension. Plates makes both of these objects available to you. The engine is automatically passed to the `register()` method, and the template is assigned as a parameter on each function call.
|
||||
|
||||
~~~ php
|
||||
use League\Plates\Engine;
|
||||
use League\Plates\Extension\ExtensionInterface;
|
||||
|
||||
class MyExtension implements ExtensionInterface
|
||||
{
|
||||
protected $engine;
|
||||
public $template; // must be public
|
||||
|
||||
public function register(Engine $engine)
|
||||
{
|
||||
$this->engine = $engine;
|
||||
|
||||
// Access template data:
|
||||
$data = $this->template->data();
|
||||
|
||||
// Register functions
|
||||
// ...
|
||||
}
|
||||
}
|
||||
~~~
|
||||
@@ -0,0 +1,35 @@
|
||||
+++
|
||||
title = "File Extensions"
|
||||
linkTitle = "Engine File Extensions"
|
||||
[menu.main]
|
||||
parent = "engine"
|
||||
weight = 2
|
||||
+++
|
||||
|
||||
Plates does not enforce a specific template file extension. By default it assumes `.php`. This file extension is automatically appended to your template names when rendered. You are welcome to change the default extension using one of the following methods.
|
||||
|
||||
## Constructor method
|
||||
|
||||
~~~ php
|
||||
// Create new engine and set the default file extension to ".tpl"
|
||||
$template = new League\Plates\Engine('/path/to/templates', 'tpl');
|
||||
~~~
|
||||
|
||||
## Setter method
|
||||
|
||||
~~~ php
|
||||
// Sets the default file extension to ".tpl" after engine instantiation
|
||||
$template->setFileExtension('tpl');
|
||||
~~~
|
||||
|
||||
## Manually assign
|
||||
|
||||
If you prefer to manually set the file extension, simply set the default file extension to `null`.
|
||||
|
||||
~~~ php
|
||||
// Disable automatic file extensions
|
||||
$template->setFileExtension(null);
|
||||
|
||||
// Render template
|
||||
echo $templates->render('home.php');
|
||||
~~~
|
||||
@@ -0,0 +1,49 @@
|
||||
+++
|
||||
title = "Folders"
|
||||
linkTitle = "Engine Folders"
|
||||
[menu.main]
|
||||
parent = "engine"
|
||||
weight = 3
|
||||
+++
|
||||
|
||||
Folders make it really easy to organize and access your templates. Folders allow you to group your templates under different namespaces, each of which having their own file system path.
|
||||
|
||||
## Creating folders
|
||||
|
||||
To create folders, use the `addFolder()` method:
|
||||
|
||||
~~~ php
|
||||
// Create new Plates instance
|
||||
$templates = new League\Plates\Engine();
|
||||
|
||||
// Add folders
|
||||
$templates->addFolder('admin', '/path/to/admin/templates');
|
||||
$templates->addFolder('emails', '/path/to/email/templates');
|
||||
~~~
|
||||
|
||||
## Using folders
|
||||
|
||||
To use the folders you created within your project simply append the folder name with two colons before the template name. For example, to render a welcome email:
|
||||
|
||||
~~~ php
|
||||
$email = $templates->render('emails::welcome');
|
||||
~~~
|
||||
|
||||
This works with template functions as well, such as layouts or nested templates. For example:
|
||||
|
||||
~~~ php
|
||||
<?php $this->layout('shared::template') ?>
|
||||
~~~
|
||||
|
||||
## Folder fallbacks
|
||||
|
||||
When enabled, if a folder template is missing, Plates will automatically fallback and look for a template with the **same** name in the default folder. This can be helpful when using folders to manage themes. To enable fallbacks, simply pass `true` as the third parameter in the `addFolders()` method.
|
||||
|
||||
~~~ php
|
||||
// Create new Plates engine
|
||||
$templates = new \League\Plates\Engine('/path/to/default/theme');
|
||||
|
||||
// Add themes
|
||||
$templates->addFolder('theme1', '/path/to/theme/1', true);
|
||||
$templates->addFolder('theme2', '/path/to/theme/2', true);
|
||||
~~~
|
||||
@@ -0,0 +1,33 @@
|
||||
+++
|
||||
title = "Functions"
|
||||
linkTitle = "Engine Functions"
|
||||
[menu.main]
|
||||
parent = "engine"
|
||||
weight = 4
|
||||
+++
|
||||
|
||||
While [extensions]({{< relref "engine/extensions.md" >}}) are awesome for adding additional reusable functionality to Plates, sometimes it's easier to just create a one-off function for a specific use case. Plates makes this easy to do.
|
||||
|
||||
## Registering functions
|
||||
|
||||
~~~ php
|
||||
// Create new Plates engine
|
||||
$templates = new \League\Plates\Engine('/path/to/templates');
|
||||
|
||||
// Register a one-off function
|
||||
$templates->registerFunction('uppercase', function ($string) {
|
||||
return strtoupper($string);
|
||||
});
|
||||
~~~
|
||||
|
||||
To use this function in a template, simply call it like any other function:
|
||||
|
||||
~~~ php
|
||||
<h1>Hello <?=$this->e($this->uppercase($name))</h1>
|
||||
~~~
|
||||
|
||||
It can also be used in a [batch]({{< relref "templates/functions#batch-function-calls">}}) compatible function:
|
||||
|
||||
~~~ php
|
||||
<h1>Hello <?=$this->e($name, 'uppercase')</h1>
|
||||
~~~
|
||||
@@ -0,0 +1,56 @@
|
||||
+++
|
||||
title = "Overview"
|
||||
linkTitle = "Engine Overview"
|
||||
aliases = ["/engine"]
|
||||
[menu.main]
|
||||
parent = "engine"
|
||||
weight = 1
|
||||
+++
|
||||
|
||||
Plates uses a central object called the `Engine`, which is used to store the environment configuration, functions and extensions. It helps decouple your templates from the file system and other dependencies. For example, if you want to change the folder where your templates are stored, you can do so by simply changing the path in one location.
|
||||
|
||||
## Basic usage
|
||||
|
||||
~~~ php
|
||||
// Create new Plates engine
|
||||
$templates = new League\Plates\Engine('/path/to/templates');
|
||||
|
||||
// Add any additional folders
|
||||
$templates->addFolder('emails', '/path/to/emails');
|
||||
|
||||
// Load any additional extensions
|
||||
$templates->loadExtension(new League\Plates\Extension\Asset('/path/to/public'));
|
||||
|
||||
// Create a new template
|
||||
$template = $templates->make('emails::welcome');
|
||||
~~~
|
||||
|
||||
## Dependency Injection
|
||||
|
||||
Plates is designed to be easily passed around your application and easily injected in your controllers or other application objects. Simply pass an instance of the `Engine` to any consuming objects, and then use either the `make()` method to create a new template, or the `render()` method to render it immediately. For example:
|
||||
|
||||
~~~ php
|
||||
class Controller
|
||||
{
|
||||
private $templates;
|
||||
|
||||
public function __construct(League\Plates\Engine $templates)
|
||||
{
|
||||
$this->templates = $templates;
|
||||
}
|
||||
|
||||
// Create a template object
|
||||
public function getIndex()
|
||||
{
|
||||
$template = $this->templates->make('home');
|
||||
|
||||
return $template->render();
|
||||
}
|
||||
|
||||
// Render a template directly
|
||||
public function getIndex()
|
||||
{
|
||||
return $this->templates->render('home');
|
||||
}
|
||||
}
|
||||
~~~
|
||||
@@ -0,0 +1,6 @@
|
||||
+++
|
||||
title = "Extensions"
|
||||
[menu.main]
|
||||
identifier = "extensions"
|
||||
weight = 4
|
||||
+++
|
||||
@@ -0,0 +1,57 @@
|
||||
+++
|
||||
title = "Asset"
|
||||
[menu.main]
|
||||
parent = "extensions"
|
||||
weight = 1
|
||||
+++
|
||||
|
||||
The asset extension can be used to quickly create "cache busted" asset URLs in your templates. This is particularly helpful for aggressively cached files that can potentially change in the future, such as CSS files, JavaScript files and images. It works by appending the timestamp of the file's last update to its URL. For example, `/css/all.css` becomes `/css/all.1373577602.css`. As long as the file does not change, the timestamp remains the same and caching occurs. However, if the file is changed, a new URL is automatically generated with a new timestamp, and visitors receive the new file.
|
||||
|
||||
## Installing the asset extension
|
||||
|
||||
The asset extension comes packaged with Plates but is not enabled by default, as it requires extra parameters passed to it at instantiation.
|
||||
|
||||
~~~ php
|
||||
// Load asset extension
|
||||
$engine->loadExtension(new League\Plates\Extension\Asset('/path/to/public/assets/', true));
|
||||
~~~
|
||||
|
||||
The first constructor parameter is the file system path of the assets directory. The second is an optional `boolean` parameter that if set to true uses the filename caching method (ie. `file.1373577602.css`) instead of the default query string method (ie. `file.css?v=1373577602`).
|
||||
|
||||
## Filename caching
|
||||
|
||||
To make filename caching work, some URL rewriting is required:
|
||||
|
||||
### Apache example
|
||||
~~~ php
|
||||
<IfModule mod_rewrite.c>
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteRule ^(.+)\.(\d+)\.(js|css|png|jpg|gif)$ $1.$3 [L]
|
||||
</IfModule>
|
||||
~~~
|
||||
|
||||
### Nginx example
|
||||
|
||||
~~~ php
|
||||
location ~* (.+)\.(?:\d+)\.(js|css|png|jpg|jpeg|gif)$ {
|
||||
try_files $uri $1.$2;
|
||||
}
|
||||
~~~
|
||||
|
||||
## Using the asset extension
|
||||
|
||||
~~~ php
|
||||
<html>
|
||||
<head>
|
||||
<title>Asset Extension Example</title>
|
||||
<link rel="stylesheet" href="<?=$this->asset('/css/all.css')?>" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<img src="<?=$this->asset('/img/logo.png')?>">
|
||||
|
||||
</body>
|
||||
</html>
|
||||
~~~
|
||||
@@ -0,0 +1,13 @@
|
||||
+++
|
||||
title = "Community"
|
||||
[menu.main]
|
||||
parent = "extensions"
|
||||
weight = 3
|
||||
+++
|
||||
|
||||
This is a list of all the known community extensions for the Plates library. Please feel free to submit a [Pull Request](https://github.com/thephpleague/plates) to add your extension to this list.
|
||||
|
||||
- [Laravel Provider](https://github.com/franzliedke/laravel-plates)
|
||||
- [Attributes Rendering](https://github.com/RobinDev/platesAttributes) - Transforms arrays into html tag attributes.
|
||||
- [Includer](https://github.com/odahcam/plates-includer) - Include your assets in an expert way.
|
||||
- [Tapestry](https://github.com/tapestry-cloud/tapestry) - A blog aware, Plates based static site generator.
|
||||
@@ -0,0 +1,81 @@
|
||||
+++
|
||||
title = "URI"
|
||||
[menu.main]
|
||||
parent = "extensions"
|
||||
weight = 2
|
||||
+++
|
||||
|
||||
The URI extension is designed to make URI checks within templates easier. The most common use is marking the current page in a menu as "selected". It only has one function, `uri()`, but can do a number of helpful tasks depending on the parameters passed to it.
|
||||
|
||||
## Installing the URI extension
|
||||
|
||||
The URI extension comes packaged with Plates but is not enabled by default, as it requires an extra parameter passed to it at instantiation.
|
||||
|
||||
~~~ php
|
||||
// Load URI extension using global variable
|
||||
$engine->loadExtension(new League\Plates\Extension\URI($_SERVER['PATH_INFO']));
|
||||
|
||||
// Load URI extension using a HttpFoundation's request object
|
||||
$engine->loadExtension(new League\Plates\Extension\URI($request->getPathInfo()));
|
||||
~~~
|
||||
|
||||
## URI example
|
||||
|
||||
~~~ php
|
||||
<ul>
|
||||
<li <?=$this->uri('/', 'class="selected"')?>><a href="/">Home</a></li>
|
||||
<li <?=$this->uri('/about', 'class="selected"')?>><a href="/about">About</a></li>
|
||||
<li <?=$this->uri('/products', 'class="selected"')?>><a href="/products">Products</a></li>
|
||||
<li <?=$this->uri('/contact', 'class="selected"')?>><a href="/contact">Contact</a></li>
|
||||
</ul>
|
||||
~~~
|
||||
|
||||
## Using the URI extension
|
||||
|
||||
Get the whole URI.
|
||||
|
||||
~~~ php
|
||||
<?=$this->uri()?>
|
||||
~~~
|
||||
|
||||
Get a specified segment of the URI.
|
||||
|
||||
~~~ php
|
||||
<?=$this->uri(1)?>
|
||||
~~~
|
||||
|
||||
Check if a specific segment of the URI (first parameter) equals a given string (second parameter). Returns `true` on success or `false` on failure.
|
||||
|
||||
~~~ php
|
||||
<?php if ($this->uri(1, 'home')): ?>
|
||||
~~~
|
||||
|
||||
Check if a specific segment of the URI (first parameter) equals a given string (second parameter). Returns string (third parameter) on success or `false` on failure.
|
||||
|
||||
~~~ php
|
||||
<?=$this->uri(1, 'home', 'success')?>
|
||||
~~~
|
||||
|
||||
Check if a specific segment of the URI (first parameter) equals a given string (second parameter). Returns string (third parameter) on success or string (fourth parameter) on failure.
|
||||
|
||||
~~~ php
|
||||
<?=$this->uri(1, 'home', 'success', 'fail')?>
|
||||
~~~
|
||||
|
||||
Check if a regular expression string matches the current URI. Returns `true` on success or `false` on failure.
|
||||
|
||||
~~~ php
|
||||
<?php if($this->uri('/home')): ?>
|
||||
~~~
|
||||
|
||||
Check if a regular expression string (first parameter) matches the current URI. Returns string (second parameter) on success or `false` on failure.
|
||||
|
||||
~~~ php
|
||||
<?=$this->uri('/home', 'success')?>
|
||||
~~~
|
||||
|
||||
Check if a regular expression string (first parameter) matches the current URI. Returns string (second parameter) on success or string (third parameter) on failure.
|
||||
|
||||
~~~ php
|
||||
<?=$this->uri('/home', 'success', 'fail')?>
|
||||
~~~
|
||||
@@ -0,0 +1,6 @@
|
||||
+++
|
||||
title = "Getting Started"
|
||||
[menu.main]
|
||||
identifier = "getting-started"
|
||||
weight = 1
|
||||
+++
|
||||
@@ -0,0 +1,33 @@
|
||||
+++
|
||||
title = "Installation"
|
||||
[menu.main]
|
||||
parent = "getting-started"
|
||||
weight = 3
|
||||
+++
|
||||
|
||||
## Using Composer
|
||||
|
||||
Plates is available on [Packagist](https://packagist.org/packages/league/plates) and can be installed using [Composer](https://getcomposer.org/). This can be done by running the following command or by updating your `composer.json` file.
|
||||
|
||||
~~~ bash
|
||||
composer require league/plates
|
||||
~~~
|
||||
|
||||
{{< code-filename composer.json >}}
|
||||
~~~ javascript
|
||||
{
|
||||
"require": {
|
||||
"league/plates": "3.*"
|
||||
}
|
||||
}
|
||||
~~~
|
||||
|
||||
Be sure to also include your Composer autoload file in your project:
|
||||
|
||||
~~~ php
|
||||
require 'vendor/autoload.php';
|
||||
~~~
|
||||
|
||||
## Downloading .zip file
|
||||
|
||||
This project is also available for download as a `.zip` file on GitHub. Visit the [releases page](https://github.com/thephpleague/plates/releases), select the version you want, and click the "Source code (zip)" download button.
|
||||
@@ -0,0 +1,50 @@
|
||||
+++
|
||||
title = "Simple Example"
|
||||
[menu.main]
|
||||
parent = "getting-started"
|
||||
weight = 2
|
||||
+++
|
||||
|
||||
Here is a simple example of how to use Plates. We will assume the following directory stucture:
|
||||
|
||||
~~~
|
||||
`-- path
|
||||
`-- to
|
||||
`-- templates
|
||||
|-- template.php
|
||||
|-- profile.php
|
||||
~~~
|
||||
|
||||
## Within your controller
|
||||
|
||||
~~~ php
|
||||
// Create new Plates instance
|
||||
$templates = new League\Plates\Engine('/path/to/templates');
|
||||
|
||||
// Render a template
|
||||
echo $templates->render('profile', ['name' => 'Jonathan']);
|
||||
~~~
|
||||
|
||||
## The page template
|
||||
|
||||
{{< code-filename profile.php >}}
|
||||
~~~ php
|
||||
<?php $this->layout('template', ['title' => 'User Profile']) ?>
|
||||
|
||||
<h1>User Profile</h1>
|
||||
<p>Hello, <?=$this->e($name)?></p>
|
||||
~~~
|
||||
|
||||
## The layout template
|
||||
|
||||
{{< code-filename template.php >}}
|
||||
~~~ php
|
||||
<html>
|
||||
<head>
|
||||
<title><?=$this->e($title)?></title>
|
||||
</head>
|
||||
<body>
|
||||
<?=$this->section('content')?>
|
||||
</body>
|
||||
</html>
|
||||
~~~
|
||||
@@ -0,0 +1,6 @@
|
||||
+++
|
||||
title = "Templates"
|
||||
[menu.main]
|
||||
identifier = "templates"
|
||||
weight = 3
|
||||
+++
|
||||
@@ -0,0 +1,60 @@
|
||||
+++
|
||||
title = "Data"
|
||||
linkTitle = "Templates Data"
|
||||
[menu.main]
|
||||
parent = "templates"
|
||||
weight = 2
|
||||
+++
|
||||
|
||||
It's very common to share application data (variables) with a template. Data can be whatever you want: strings, arrays, objects, etc. Plates allows you set both template specific data as well as shared template data.
|
||||
|
||||
## Assign data
|
||||
|
||||
Assigning data is done from within your application code, such as a controller. There are a number of ways to assign the data, depending on how you structure your objects.
|
||||
|
||||
~~~ php
|
||||
// Create new Plates instance
|
||||
$templates = new League\Plates\Engine('/path/to/templates');
|
||||
|
||||
// Assign via the engine's render method
|
||||
echo $templates->render('profile', ['name' => 'Jonathan']);
|
||||
|
||||
// Assign via the engine's make method
|
||||
$template = $templates->make('profile', ['name' => 'Jonathan']);
|
||||
|
||||
// Assign directly to a template object
|
||||
$template = $templates->make('profile');
|
||||
$template->data(['name' => 'Jonathan']);
|
||||
~~~
|
||||
|
||||
## Accessing data
|
||||
|
||||
Template data is available as locally scoped variables at the time of rendering. Continuing with the example above, here is how you would [escape]({{< relref "templates/escaping.md" >}}) and output the "name" value in a template:
|
||||
|
||||
~~~ php
|
||||
<p>Hello <?=$this->e($name)?></p>
|
||||
~~~
|
||||
|
||||
<p class="message-notice">Prior to Plates 3.0, variables were accessed using the <code>$this</code> pseudo-variable. This is no longer possible. Use the locally scoped variables instead.</p>
|
||||
|
||||
## Preassigned and shared data
|
||||
|
||||
If you have data that you want assigned to a specific template each time that template is rendered throughout your application, the `addData()` function can help organize that code in one place.
|
||||
|
||||
~~~ php
|
||||
$templates->addData(['name' => 'Jonathan'], 'emails::welcome');
|
||||
~~~
|
||||
|
||||
You can pressaign data to more than one template by passing an array of templates:
|
||||
|
||||
~~~ php
|
||||
$templates->addData(['name' => 'Jonathan'], ['login', 'template']);
|
||||
~~~
|
||||
|
||||
To assign data to ALL templates, simply omit the second parameter:
|
||||
|
||||
~~~ php
|
||||
$templates->addData(['name' => 'Jonathan']);
|
||||
~~~
|
||||
|
||||
Keep in mind that shared data is assigned to a template when it's first created, meaning any conflicting data assigned that's afterwards to a specific template will overwrite the shared data. This is generally desired behavior.
|
||||
@@ -0,0 +1,49 @@
|
||||
+++
|
||||
title = "Escaping"
|
||||
linkTitle = "Templates Escaping"
|
||||
[menu.main]
|
||||
parent = "templates"
|
||||
weight = 8
|
||||
+++
|
||||
|
||||
Escaping is a form of [data filtering](http://www.phptherightway.com/#data_filtering) which sanitizes unsafe, user supplied input prior to outputting it as HTML. Plates provides two shortcuts to the `htmlspecialchars()` function.
|
||||
|
||||
## Escaping example
|
||||
|
||||
~~~ php
|
||||
<h1>Hello, <?=$this->escape($name)?></h1>
|
||||
|
||||
<!-- Using the alternative, shorthand function -->
|
||||
<h1>Hello, <?=$this->e($name)?></h1>
|
||||
~~~
|
||||
|
||||
## Batch function calls
|
||||
|
||||
The escape functions also support [batch]({{< relref "templates/functions.md#batch-function-calls" >}}) function calls, which allow you to apply multiple functions, including native PHP functions, to a variable at one time.
|
||||
|
||||
~~~ php
|
||||
<p>Welcome <?=$this->e($name, 'strip_tags|strtoupper')?></p>
|
||||
~~~
|
||||
|
||||
## Escaping HTML attributes
|
||||
|
||||
<p class="message-notice">It's VERY important to always double quote HTML attributes that contain escaped variables, otherwise your template will still be open to injection attacks.</p>
|
||||
|
||||
Some [libraries](http://framework.zend.com/manual/2.1/en/modules/zend.escaper.escaping-html-attributes.html) go as far as having a special function for escaping HTML attributes. However, this is somewhat redundant considering that if a developer forgets to properly quote an HTML attribute, they will likely also forget to use this special function. Here is how you properly escape HTML attributes:
|
||||
|
||||
~~~ php
|
||||
<!-- Good -->
|
||||
<img src="portrait.jpg" alt="<?=$this->e($name)?>">
|
||||
|
||||
<!-- BAD -->
|
||||
<img src="portrait.jpg" alt='<?=$this->e($name)?>'>
|
||||
|
||||
<!-- BAD -->
|
||||
<img src="portrait.jpg" alt=<?=$this->e($name)?>>
|
||||
~~~
|
||||
|
||||
## Automatic escaping
|
||||
|
||||
Probably the biggest drawbacks to native PHP templates is the inability to auto-escape variables properly. Template languages like Twig and Smarty can identify "echoed" variables during a parsing stage and automatically escape them. This cannot be done in native PHP as the language does not offer overloading functionality for it's output functions (ie. `print` and `echo`).
|
||||
|
||||
Don't worry, escaping can still be done safely, it just means you are responsible for manually escaping each variable on output. Consider creating a snippet for one of the above, built-in escaping functions to make this process easier.
|
||||
@@ -0,0 +1,46 @@
|
||||
+++
|
||||
title = "Functions"
|
||||
linkTitle = "Templates Functions"
|
||||
[menu.main]
|
||||
parent = "templates"
|
||||
weight = 3
|
||||
+++
|
||||
|
||||
Template functions in Plates are accessed using the `$this` pseudo-variable.
|
||||
|
||||
~~~ php
|
||||
<p>Hello, <?=$this->escape($name)?></p>
|
||||
~~~
|
||||
|
||||
|
||||
## Custom fuctions
|
||||
|
||||
In addition to the functions included with Plates, it's also possible to add [one-off functions]({{< relref "engine/functions.md" >}}), or even groups of functions, known as [extensions]({{< relref "engine/extensions.md" >}}).
|
||||
|
||||
## Batch function calls
|
||||
|
||||
Sometimes you need to apply more than function to a variable in your templates. This can become somewhat illegible. The `batch()` function helps by allowing you to apply multiple functions, including native PHP functions, to a variable at one time.
|
||||
|
||||
~~~ php
|
||||
<!-- Example without using batch -->
|
||||
<p>Welcome <?=$this->escape(strtoupper(strip_tags($name)))?></p>
|
||||
|
||||
<!-- Example using batch -->
|
||||
<p>Welcome <?=$this->batch($name, 'strip_tags|strtoupper|escape')?></p>
|
||||
~~~
|
||||
|
||||
The [escape]({{< relref "templates/escaping.md" >}}) functions also support batch function calls.
|
||||
|
||||
~~~ php
|
||||
<p>Welcome <?=$this->e($name, 'strip_tags|strtoupper')?></p>
|
||||
~~~
|
||||
|
||||
The batch functions works well for "piped" functions that accept one parameter, modify it, and then return it. It's important to note that they execute functions left to right and will favour extension functions over native PHP functions if there are conflicts.
|
||||
|
||||
~~~ php
|
||||
<!-- Will output: JONATHAN -->
|
||||
<?=$this->batch('Jonathan', 'escape|strtolower|strtoupper')?>
|
||||
|
||||
<!-- Will output: jonathan -->
|
||||
<?=$this->batch('Jonathan', 'escape|strtoupper|strtolower')?>
|
||||
~~~
|
||||
@@ -0,0 +1,63 @@
|
||||
+++
|
||||
title = "Inheritance"
|
||||
linkTitle = "Templates Inheritance"
|
||||
[menu.main]
|
||||
parent = "templates"
|
||||
weight = 7
|
||||
+++
|
||||
|
||||
By combining [layouts]({{< relref "templates/layouts.md" >}}) and [sections]({{< relref "templates/sections.md" >}}), Plates allows you to "build up" your pages using predefined sections. This is best understand using an example:
|
||||
|
||||
## Inheritance example
|
||||
|
||||
The following example illustrates a pretty standard website. Start by creating a site template, which includes your header and footer as well as any predefined content [sections]({{< relref "templates/sections.md" >}}). Notice how Plates makes it possible to even set default section content, in the event that a page doesn't define it.
|
||||
|
||||
{{< code-filename template.php >}}
|
||||
|
||||
~~~ php
|
||||
<html>
|
||||
<head>
|
||||
<title><?=$this->e($title)?></title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<img src="logo.png">
|
||||
|
||||
<div id="page">
|
||||
<?=$this->section('page')?>
|
||||
</div>
|
||||
|
||||
<div id="sidebar">
|
||||
<?php if ($this->section('sidebar')): ?>
|
||||
<?=$this->section('sidebar')?>
|
||||
<?php else: ?>
|
||||
<?=$this->fetch('default-sidebar')?>
|
||||
<?php endif ?>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
~~~
|
||||
|
||||
With the template defined, any page can now "implement" this [layout]({{< relref "templates/layouts.md" >}}). Notice how each section of content is defined between the `start()` and `end()` functions.
|
||||
|
||||
{{< code-filename profile.php >}}
|
||||
|
||||
~~~ php
|
||||
<?php $this->layout('template', ['title' => 'User Profile']) ?>
|
||||
|
||||
<?php $this->start('page') ?>
|
||||
<h1>Welcome!</h1>
|
||||
<p>Hello <?=$this->e($name)?></p>
|
||||
<?php $this->stop() ?>
|
||||
|
||||
<?php $this->start('sidebar') ?>
|
||||
<ul>
|
||||
<li><a href="/link">Example Link</a></li>
|
||||
<li><a href="/link">Example Link</a></li>
|
||||
<li><a href="/link">Example Link</a></li>
|
||||
<li><a href="/link">Example Link</a></li>
|
||||
<li><a href="/link">Example Link</a></li>
|
||||
</ul>
|
||||
<?php $this->stop() ?>
|
||||
~~~
|
||||
@@ -0,0 +1,104 @@
|
||||
+++
|
||||
title = "Layouts"
|
||||
linkTitle = "Templates Layouts"
|
||||
[menu.main]
|
||||
parent = "templates"
|
||||
weight = 5
|
||||
+++
|
||||
|
||||
The `layout()` function allows you to define a layout template that a template will implement. It's like having separate header and footer templates in one file.
|
||||
|
||||
## Define a layout
|
||||
|
||||
The `layout()` function can be called anywhere in a template, since the layout template is actually rendered second. Typically it's placed at the top of the file.
|
||||
|
||||
~~~ php
|
||||
<?php $this->layout('template') ?>
|
||||
|
||||
<h1>User Profile</h1>
|
||||
<p>Hello, <?=$this->e($name)?></p>
|
||||
~~~
|
||||
|
||||
This function also works with [folders]({{< relref "engine/folders.md" >}}):
|
||||
|
||||
~~~ php
|
||||
<?php $this->layout('shared::template') ?>
|
||||
~~~
|
||||
|
||||
## Assign data
|
||||
|
||||
To assign data (variables) to a layout template, pass them as an array to the `layout()` function. This data will then be available as locally scoped variables within the layout template.
|
||||
|
||||
~~~ php
|
||||
<?php $this->layout('template', ['title' => 'User Profile']) ?>
|
||||
~~~
|
||||
|
||||
## Accessing the content
|
||||
|
||||
To access the rendered template content within the layout, use the `section()` function, passing `'content'` as the section name. This will return all outputted content from the template that hasn't been defined in a [section]({{< relref "templates/sections.md" >}}).
|
||||
|
||||
~~~ php
|
||||
<html>
|
||||
<head>
|
||||
<title><?=$this->e($title)?></title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<?=$this->section('content')?>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
~~~
|
||||
|
||||
## Stacked layouts
|
||||
|
||||
Plates allows stacking of layouts, allowing even further simplification and organization of templates. Instead of just using one main layout, it's possible to break templates into more specific layouts, which themselves implement a main layout. Consider this example:
|
||||
|
||||
### The main site layout
|
||||
|
||||
{{< code-filename template.php >}}
|
||||
|
||||
~~~ php
|
||||
<html>
|
||||
<head>
|
||||
<title><?=$this->e($title)?></title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<?=$this->section('content')?>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
~~~
|
||||
|
||||
### The blog layout
|
||||
|
||||
{{< code-filename blog.php >}}
|
||||
|
||||
~~~ php
|
||||
<?php $this->layout('template', ['title' => $title]) ?>
|
||||
|
||||
<h1>The Blog</h1>
|
||||
|
||||
<section>
|
||||
<article>
|
||||
<?=$this->section('content')?>
|
||||
</article>
|
||||
<aside>
|
||||
<?=$this->insert('blog/sidebar')?>
|
||||
</aside>
|
||||
</section>
|
||||
~~~
|
||||
|
||||
### A blog article
|
||||
|
||||
{{< code-filename blog-article.php >}}
|
||||
|
||||
~~~ php
|
||||
<?php $this->layout('blog', ['title' => $article->title]) ?>
|
||||
|
||||
<h2><?=$this->e($article->title)?></h2>
|
||||
<article>
|
||||
<?=$this->e($article->content)?>
|
||||
</article>
|
||||
~~~
|
||||
@@ -0,0 +1,43 @@
|
||||
+++
|
||||
title = "Nesting"
|
||||
linkTitle = "Templates Nesting"
|
||||
[menu.main]
|
||||
parent = "templates"
|
||||
weight = 4
|
||||
+++
|
||||
|
||||
Including another template into the current template is done using the `insert()` function:
|
||||
|
||||
~~~ php
|
||||
<?php $this->insert('partials/header') ?>
|
||||
|
||||
<p>Your content.</p>
|
||||
|
||||
<?php $this->insert('partials/footer') ?>
|
||||
~~~
|
||||
|
||||
The `insert()` function also works with [folders]({{< relref "engine/folders.md" >}}):
|
||||
|
||||
~~~ php
|
||||
<?php $this->insert('partials::header') ?>
|
||||
~~~
|
||||
|
||||
## Alternative syntax
|
||||
|
||||
The `insert()` function automatically outputs the rendered template. If you prefer to manually output the response, use the `fetch()` function instead:
|
||||
|
||||
~~~ php
|
||||
<?=$this->fetch('partials/header')?>
|
||||
~~~
|
||||
|
||||
## Assign data
|
||||
|
||||
To assign data (variables) to a nested template, pass them as an array to the `insert()` or `fetch()` functions. This data will then be available as locally scoped variables within the nested template.
|
||||
|
||||
~~~ php
|
||||
<?php $this->insert('partials/header', ['name' => 'Jonathan']) ?>
|
||||
|
||||
<p>Your content.</p>
|
||||
|
||||
<?php $this->insert('partials/footer') ?>
|
||||
~~~
|
||||
@@ -0,0 +1,72 @@
|
||||
+++
|
||||
title = "Overview"
|
||||
linkTitle = "Templates Overview"
|
||||
[menu.main]
|
||||
parent = "templates"
|
||||
weight = 1
|
||||
+++
|
||||
|
||||
Plates templates are very simple PHP objects. Generally you'll want to create these using the two factory methods, `make()` and `render()`, in the [engine]({{< relref "engine/overview.md" >}}). For example:
|
||||
|
||||
~~~ php
|
||||
// Create new Plates instance
|
||||
$templates = new League\Plates\Engine('/path/to/templates');
|
||||
|
||||
// Render a template in a subdirectory
|
||||
echo $templates->render('partials/header');
|
||||
|
||||
// Render a template
|
||||
echo $templates->render('profile', ['name' => 'Jonathan']);
|
||||
~~~
|
||||
|
||||
For more information about how Plates is designed to be easily added to your application, see the section on [dependency injection]({{< relref "engine/overview.md#dependency-injection" >}}).
|
||||
|
||||
## Manually creating templates
|
||||
|
||||
It's also possible to create templates manually. The only dependency they require is an instance of the [engine]({{< relref "engine/overview.md" >}}) object. For example:
|
||||
|
||||
~~~ php
|
||||
// Create new Plates instance
|
||||
$templates = new League\Plates\Engine('/path/to/templates');
|
||||
|
||||
// Create a new template
|
||||
$template = new League\Plates\Template\Template($templates, 'profile');
|
||||
|
||||
// Render the template
|
||||
echo $template->render(['name' => 'Jonathan']);
|
||||
|
||||
// You can also render the template using the toString() magic method
|
||||
echo $template;
|
||||
~~~
|
||||
|
||||
## Check if a template exists
|
||||
|
||||
When dynamically loading templates, you may need to check if they exist. This can be done using the engine's `exists()` method:
|
||||
|
||||
~~~ php
|
||||
if ($templates->exists('articles::beginners_guide')) {
|
||||
// It exists!
|
||||
}
|
||||
~~~
|
||||
|
||||
You can also run this check on an existing template:
|
||||
|
||||
~~~ php
|
||||
if ($template->exists()) {
|
||||
// It exists!
|
||||
}
|
||||
~~~
|
||||
|
||||
## Get a template path
|
||||
|
||||
To get a template path from its name, use the engine's `path()` method:
|
||||
|
||||
~~~ php
|
||||
$path = $templates->path('articles::beginners_guide');
|
||||
~~~
|
||||
|
||||
You can also get the path from an existing template:
|
||||
|
||||
~~~ php
|
||||
$path = $template->path();
|
||||
~~~
|
||||
@@ -0,0 +1,83 @@
|
||||
+++
|
||||
title = "Sections"
|
||||
linkTitle = "Templates Sections"
|
||||
[menu.main]
|
||||
parent = "templates"
|
||||
weight = 6
|
||||
+++
|
||||
|
||||
The `start()` and `stop` functions allow you to build sections (or blocks) of content within your template, and instead of them being rendered directly, they are saved for use elsewhere. For example, in your [layout]({{< relref "templates/layouts.md" >}}) template.
|
||||
|
||||
## Creating sections
|
||||
|
||||
You define the name of the section with the `start()` function. To end a section call the `stop()` function.
|
||||
|
||||
~~~ php
|
||||
<?php $this->start('welcome') ?>
|
||||
|
||||
<h1>Welcome!</h1>
|
||||
<p>Hello <?=$this->e($name)?></p>
|
||||
|
||||
<?php $this->stop() ?>
|
||||
~~~
|
||||
|
||||
## Stacking section content
|
||||
|
||||
By default, when you render a section its content will overwrite any existing content for that section. However, it's possible to append/prepend (or stack) the content instead using the `push()` or `unshift()` method respectively. This can be useful for specifying any JavaScript libraries or CSS files required by your child views.
|
||||
|
||||
~~~ php
|
||||
<?php $this->push('scripts') ?>
|
||||
<script src="example.js"></script>
|
||||
<?php $this->end() ?>
|
||||
|
||||
<?php $this->unshift('styles') ?>
|
||||
<link rel="stylesheet" href="example.css" />
|
||||
<?php $this->end() ?>
|
||||
~~~
|
||||
|
||||
<p class="message-notice">The <code>end()</code> function is simply an alias of <code>stop()</code>. These functions can be used interchangeably.</p>
|
||||
|
||||
## Accessing section content
|
||||
|
||||
Access rendered section content using the name you assigned in the `start()` method. This variable can be accessed from the current template and layout templates using the `section()` function.
|
||||
|
||||
~~~ php
|
||||
<?=$this->section('welcome')?>
|
||||
~~~
|
||||
|
||||
<p class="message-notice">Prior to Plates 3.0, accessing template content was done using either the <code>content()</code> or <code>child()</code> functions. For consistency with sections, this is no longer possible.</p>
|
||||
|
||||
## Default section content
|
||||
|
||||
In situations where a page doesn't implement a particular section, it's helpful to assign default content. There are a couple ways to do this:
|
||||
|
||||
### Defining it inline
|
||||
|
||||
If the default content can be defined in a single line of code, it's best to simply pass it as the second parameter of the `section()` function.
|
||||
|
||||
~~~ php
|
||||
<div id="sidebar">
|
||||
<?=$this->section('sidebar', $this->fetch('default-sidebar')?>
|
||||
</div>
|
||||
~~~
|
||||
|
||||
### Use an if statement
|
||||
|
||||
If the default content requires more than a single line of code, it's best to use a simple if statement to check if a section exists, and otherwise display the default.
|
||||
|
||||
~~~ php
|
||||
<div id="sidebar">
|
||||
<?php if ($this->section('sidebar')): ?>
|
||||
<?=$this->section('sidebar')?>
|
||||
<?php else: ?>
|
||||
<ul>
|
||||
<li><a href="/link">Example Link</a></li>
|
||||
<li><a href="/link">Example Link</a></li>
|
||||
<li><a href="/link">Example Link</a></li>
|
||||
<li><a href="/link">Example Link</a></li>
|
||||
<li><a href="/link">Example Link</a></li>
|
||||
</ul>
|
||||
<?php endif ?>
|
||||
</div>
|
||||
~~~
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
+++
|
||||
title = "Syntax"
|
||||
linkTitle = "Templates Syntax"
|
||||
[menu.main]
|
||||
parent = "templates"
|
||||
weight = 9
|
||||
+++
|
||||
|
||||
While the actual syntax you use in your templates is entirely your choice (it's just PHP after all), we suggest the following syntax guidelines to help keep templates clean and legible.
|
||||
|
||||
## Guidelines
|
||||
|
||||
- Always use HTML with inline PHP. Never use blocks of PHP.
|
||||
- Always escape potentially dangerous variables prior to outputting using the built-in escape functions. More on escaping [here]({{< relref "templates/escaping.md" >}}).
|
||||
- Always use the short echo syntax (`<?=`) when outputting variables. For all other inline PHP code, use full the `<?php` tag. Do not use [short tags](http://us3.php.net/manual/en/ini.core.php#ini.short-open-tag).
|
||||
- Always use the [alternative syntax for control structures](http://php.net/manual/en/control-structures.alternative-syntax.php), which are designed to make templates more legible.
|
||||
- Never use PHP curly brackets.
|
||||
- Only ever have one statement in each PHP tag.
|
||||
- Avoid using semicolons. They are not needed when there is only one statement per PHP tag.
|
||||
- Never use the `use` operator. Templates should not be interacting with classes in this way.
|
||||
- Never use the `for`, `while` or `switch` control structures. Instead use `if` and `foreach`.
|
||||
- Avoid variable assignment.
|
||||
|
||||
## Syntax example
|
||||
|
||||
Here is an example of a template that complies with the above syntax rules.
|
||||
|
||||
~~~ php
|
||||
<?php $this->layout('template', ['title' => 'User Profile']) ?>
|
||||
|
||||
<h1>Welcome!</h1>
|
||||
<p>Hello <?=$this->e($name)?></p>
|
||||
|
||||
<h2>Friends</h2>
|
||||
<ul>
|
||||
<?php foreach($friends as $friend): ?>
|
||||
<li>
|
||||
<a href="/profile/<?=$this->e($friend->id)?>">
|
||||
<?=$this->e($friend->name)?>
|
||||
</a>
|
||||
</li>
|
||||
<?php endforeach ?>
|
||||
</ul>
|
||||
|
||||
<?php if ($invitations): ?>
|
||||
<h2>Invitations</h2>
|
||||
<p>You have some friend invites!</p>
|
||||
<?php endif ?>
|
||||
~~~
|
||||
Reference in New Issue
Block a user