2016-07-24 22:05:10 +02:00
|
|
|
|
# twigc
|
|
|
|
|
|
|
|
|
|
**twigc** is a user-friendly command-line utility for rendering (compiling)
|
|
|
|
|
[Twig](http://twig.sensiolabs.org/) templates. It's well suited for testing and
|
|
|
|
|
for interacting with Twig through shell scripts and other command-line
|
|
|
|
|
applications.
|
|
|
|
|
|
2018-06-02 08:42:26 +02:00
|
|
|
|
## Usage
|
2016-07-24 22:05:10 +02:00
|
|
|
|
|
2018-06-02 08:42:26 +02:00
|
|
|
|
**twigc** can render Twig templates supplied via either standard input or a file
|
|
|
|
|
path.
|
2016-07-24 22:05:10 +02:00
|
|
|
|
|
2018-06-02 08:42:26 +02:00
|
|
|
|
```
|
|
|
|
|
Usage: twigc [options] [<template>]
|
2016-07-24 22:05:10 +02:00
|
|
|
|
|
|
|
|
|
Options:
|
2018-06-02 08:42:26 +02:00
|
|
|
|
-h, --help Display this usage help and exit
|
|
|
|
|
-V, --version Display version information and exit
|
|
|
|
|
--credits Display dependency information and exit
|
|
|
|
|
--cache <dir> Enable caching to specified directory
|
|
|
|
|
-d, --dir <dir> Add specified search directory to loader
|
|
|
|
|
-e, --escape <strategy> Specify default auto-escaping strategy
|
|
|
|
|
-E, --env Derive input data from environment
|
|
|
|
|
-j, --json <dict/file> Derive input data from specified JSON file or
|
|
|
|
|
dictionary string
|
|
|
|
|
-p, --pair <input> Derive input data from specified key=value pair
|
|
|
|
|
--query <input> Derive input data from specified URL query string
|
|
|
|
|
-s, --strict Throw exception when undefined variable is referenced
|
2016-07-24 22:05:10 +02:00
|
|
|
|
```
|
|
|
|
|
|
2018-06-02 08:42:26 +02:00
|
|
|
|
### Passing input data
|
|
|
|
|
|
|
|
|
|
Input data can be passed to the template using a simple key=value syntax with
|
|
|
|
|
`-p`:
|
2016-07-24 22:05:10 +02:00
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
% twigc -p 'name=dana' <<< 'Hello, {{ name }}!'
|
|
|
|
|
Hello, dana!
|
|
|
|
|
```
|
|
|
|
|
|
2018-06-02 08:42:26 +02:00
|
|
|
|
Of course, only basic string values can be provided this way. For more complex
|
|
|
|
|
data, you can use the JSON option `-j`:
|
2016-07-24 22:05:10 +02:00
|
|
|
|
|
|
|
|
|
```
|
2018-06-02 08:42:26 +02:00
|
|
|
|
% twigc -j '{"numbers": [1, 2, 3]}' <<< '{{ numbers|join("... ") }}!'
|
2016-07-24 22:05:10 +02:00
|
|
|
|
1... 2... 3!
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
JSON data can also be provided by file path or on standard input:
|
|
|
|
|
|
|
|
|
|
```
|
2018-06-02 08:42:26 +02:00
|
|
|
|
# JSON from file, template from standard input
|
2016-07-24 22:05:10 +02:00
|
|
|
|
% cat numbers.json
|
2018-06-02 08:42:26 +02:00
|
|
|
|
{"numbers": [1, 2, 3]}
|
2016-07-24 22:05:10 +02:00
|
|
|
|
% twigc -j numbers.json <<< '{{ numbers|join("... ") }}!'
|
|
|
|
|
1... 2... 3!
|
|
|
|
|
|
2018-06-02 08:42:26 +02:00
|
|
|
|
# JSON from standard input, template from file
|
2016-07-24 22:05:10 +02:00
|
|
|
|
% cat numbers.twig
|
|
|
|
|
{{ numbers|join("... ") }}!
|
2018-06-02 08:42:26 +02:00
|
|
|
|
% twigc -j - numbers.twig <<< '{"numbers": [1, 2, 3]}'
|
|
|
|
|
1... 2... 3!
|
2016-07-24 22:05:10 +02:00
|
|
|
|
```
|
|
|
|
|
|
2018-06-02 08:42:26 +02:00
|
|
|
|
(**twigc** determines whether the argument to `-j` is a dictionary string or a
|
|
|
|
|
file name based on whether the first character is a `{`; if you have a file name
|
|
|
|
|
that looks like that, use the absolute path or put `./` in front of it — for
|
|
|
|
|
example, `twigc -j './{myfile}.json'`.)
|
|
|
|
|
|
|
|
|
|
If
|
|
|
|
|
[`variables_order`](http://php.net/manual/en/ini.core.php#ini.variables-order)
|
|
|
|
|
is configured appropriately in your `php.ini`, you can use the `-E` option to
|
|
|
|
|
inherit input data from the environment:
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
% NAME=dana twigc -E <<< 'Hello, {{ NAME }}!'
|
|
|
|
|
Hello, dana!
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
(If you *don't* have `E` in `variables_order`, you'll get an error.)
|
|
|
|
|
|
|
|
|
|
Lastly, there's a `--query` option in case you want to pass input as a URL query
|
|
|
|
|
string:
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
% twigc --query '?foo=&name=dana&bar=' <<< 'Hello, {{ name }}!'
|
|
|
|
|
Hello, dana!
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
All of the aforementioned input options can be given multiple times and in any
|
|
|
|
|
combination, but the values associated with each input type override other
|
|
|
|
|
values with the same name using the following order of precedence (from lowest
|
|
|
|
|
to highest): environment, query, JSON, pair. In other words:
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
# Pair has higher precedence than environment
|
|
|
|
|
% name=foo twigc -p name=bar -E <<< '{{ name }} wins'
|
|
|
|
|
bar wins
|
|
|
|
|
|
|
|
|
|
# JSON has higher precedence than query
|
|
|
|
|
% twigc -j '{"name": "foo"}' --query name=bar <<< '{{ name }} wins'
|
|
|
|
|
foo wins
|
|
|
|
|
|
|
|
|
|
# Inputs of the same type have equal precedence and are taken in the order given
|
|
|
|
|
% twigc -j '{"name": "foo"}' -p name=bar -p name=baz <<< '{{ name }} wins'
|
|
|
|
|
baz wins
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Configuring auto-escaping
|
|
|
|
|
|
2016-07-24 22:05:10 +02:00
|
|
|
|
Normally, input data is [auto-escaped](http://twig.sensiolabs.org/doc/api.html)
|
2018-06-02 08:42:26 +02:00
|
|
|
|
during rendering based on the template file extension (or disabled by default if
|
|
|
|
|
using standard input), but this is configurable:
|
2016-07-24 22:05:10 +02:00
|
|
|
|
|
|
|
|
|
```
|
2018-06-02 08:42:26 +02:00
|
|
|
|
# No auto-escaping by default on standard input
|
2016-07-24 22:05:10 +02:00
|
|
|
|
% twigc -p 'html=<p>Hello!</p>' <<< '{{ html }}'
|
2016-07-30 06:08:56 +02:00
|
|
|
|
<p>Hello!</p>
|
2016-07-24 22:05:10 +02:00
|
|
|
|
|
2018-06-02 08:42:26 +02:00
|
|
|
|
# Explicit HTML auto-escaping
|
|
|
|
|
% twigc -e html -p 'html=<p>Hello!</p>' <<< '{{ html }}'
|
2016-07-30 06:08:56 +02:00
|
|
|
|
<p>Hello!</p>
|
2016-07-24 22:05:10 +02:00
|
|
|
|
|
2018-06-02 08:42:26 +02:00
|
|
|
|
# Explicit JavaScript auto-escaping
|
|
|
|
|
% twigc -e js -p 'html=<p>Hello!</p>' <<< '{{ html }}'
|
2016-07-24 22:05:10 +02:00
|
|
|
|
\x3Cp\x3EHello\x21\x3C\x2Fp\x3E
|
|
|
|
|
|
2018-06-02 08:42:26 +02:00
|
|
|
|
# Explicit URL auto-escaping
|
|
|
|
|
% twigc -e url -p 'html=<p>Hello!</p>' <<< '{{ html }}'
|
2016-07-30 06:08:56 +02:00
|
|
|
|
%3Cp%3EHello%21%3C%2Fp%3E
|
2016-07-24 22:05:10 +02:00
|
|
|
|
```
|
|
|
|
|
|
2018-06-02 08:42:26 +02:00
|
|
|
|
Of course, you can always control escaping from within the template using the
|
|
|
|
|
[`escape`](https://twig.symfony.com/doc/2.x/filters/escape.html) filter.
|
|
|
|
|
|
|
|
|
|
The following auto-escape methods are available:
|
|
|
|
|
|
|
|
|
|
* **`none`** (aka **`false`**, **`no`**, **`never`**, &c.) —
|
|
|
|
|
No escaping is performed; the input is rendered as-is. This is the default for
|
|
|
|
|
templates taken from standard input and for files with unrecognised
|
|
|
|
|
extensions.
|
|
|
|
|
|
|
|
|
|
* **`html`** (aka **`true`**, **`yes`**, **`always`**, &c.) —
|
|
|
|
|
Ampersand-escaping as suitable for inclusion in an HTML body. This is the most
|
|
|
|
|
common escaping method used for rendering Web pages with Twig, and the default
|
|
|
|
|
method used by the `escape` filter.
|
|
|
|
|
|
|
|
|
|
* **`css`** —
|
|
|
|
|
Hex-escaping as suitable for inclusion in a CSS value or identifier.
|
|
|
|
|
|
|
|
|
|
* **`html_attr`** —
|
|
|
|
|
Ampersand-escaping as suitable for inclusion in an HTML attribute value. This
|
|
|
|
|
is similar to the `html` method, but more characters are escaped.
|
|
|
|
|
|
|
|
|
|
* **`js`** —
|
|
|
|
|
Hex-escaping as suitable for inclusion in a JavaScript string or identifier.
|
|
|
|
|
|
|
|
|
|
* **`json`** —
|
|
|
|
|
Serialisation according to JSON rules. Strings are quoted and escaped,
|
|
|
|
|
integers are left bare, &c. JSON escaping can often be used to produce strings
|
|
|
|
|
for config files and even languages like C (though incompatibilities do exist
|
|
|
|
|
— be careful).
|
|
|
|
|
|
|
|
|
|
* **`sh`** —
|
|
|
|
|
Double-quoting and meta-character escaping according to shell rules. This
|
|
|
|
|
method uses double-quoted strings rather than the single-quote method used by
|
|
|
|
|
e.g. `escapeshellarg()` because it is more compatible with software that
|
|
|
|
|
supports only a sub-set of the shell's string syntax (such as 'dotenv'
|
|
|
|
|
libraries).
|
|
|
|
|
|
|
|
|
|
* **`url`** —
|
|
|
|
|
Percent-escaping as suitable for inclusion in a URL path segment or query
|
|
|
|
|
parameter.
|
|
|
|
|
|
|
|
|
|
### Enabling strict mode
|
|
|
|
|
|
2016-07-24 22:05:10 +02:00
|
|
|
|
By default, references in the template to undefined variables are silently
|
2018-06-02 08:42:26 +02:00
|
|
|
|
ignored, but you can make Twig throw an exception with the `-s` option:
|
2016-07-24 22:05:10 +02:00
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
% twigc <<< 'Hello, {{ name }}!'
|
|
|
|
|
Hello, !
|
|
|
|
|
|
|
|
|
|
% twigc -s <<< 'Hello, {{ name }}!'
|
2018-06-02 08:42:26 +02:00
|
|
|
|
twigc: Variable "name" does not exist in "-" at line 1.
|
2016-07-24 22:05:10 +02:00
|
|
|
|
```
|
|
|
|
|
|
2018-06-02 08:42:26 +02:00
|
|
|
|
Use of this option is recommended for reliability in scripting scenarios.
|
|
|
|
|
|
|
|
|
|
### Specifying search directories
|
|
|
|
|
|
|
|
|
|
If a template file name was provided, the file's parent directory is
|
|
|
|
|
automatically added as an include search path; if standard input was used, no
|
|
|
|
|
search path is set at all by default. In either case, one or more additional
|
|
|
|
|
search paths can be explicitly supplied on the command line:
|
2016-07-24 22:05:10 +02:00
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
% cat include.twig
|
|
|
|
|
Hello!
|
|
|
|
|
|
|
|
|
|
% twigc <<< '{% include "include.twig" %}'
|
2018-06-02 08:42:26 +02:00
|
|
|
|
twigc: Template "include.twig" is not defined in "-" at line 1.
|
2016-07-24 22:05:10 +02:00
|
|
|
|
|
|
|
|
|
% twigc -d '.' <<< '{% include "include.twig" %}'
|
|
|
|
|
Hello!
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Installation
|
|
|
|
|
|
|
|
|
|
**twigc** is provided as a self-contained executable archive; to download it,
|
|
|
|
|
see the [releases](https://github.com/okdana/twigc/releases) page.
|
|
|
|
|
|
2018-06-02 08:42:26 +02:00
|
|
|
|
Of course, you can also build it from source:
|
2016-07-24 22:05:10 +02:00
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
% git clone https://github.com/okdana/twigc
|
|
|
|
|
% cd twigc
|
|
|
|
|
% make
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Requirements
|
|
|
|
|
|
2018-06-02 08:42:26 +02:00
|
|
|
|
The **twigc** executable archive is bundled with Twig and all of its other
|
|
|
|
|
dependencies; the only thing you need to run it is PHP version 7.0 or higher.
|
|
|
|
|
|
|
|
|
|
## Limitations, todos, requests
|
|
|
|
|
|
|
|
|
|
Earlier versions of this tool were implemented in the manner of a Symfony
|
|
|
|
|
Console application. I like Symfony components a lot, but the way Console
|
|
|
|
|
handles arguments in particular leaves a great deal to be desired if you're
|
|
|
|
|
trying to create something that works like a traditional UNIX CLI tool — the API
|
|
|
|
|
is confused, the functionality is limited, and worst of all it's buggy. I ended
|
|
|
|
|
up switching out the Console application/command/input components for a lazier
|
|
|
|
|
and uglier, but ultimately better-behaved, design incorporating the GetOpt.php
|
|
|
|
|
library.
|
|
|
|
|
|
|
|
|
|
If you have any ideas as to how to improve on this situation, please let me
|
|
|
|
|
know.
|
|
|
|
|
|
|
|
|
|
I'd also like to achieve the following goals at some point:
|
|
|
|
|
|
|
|
|
|
* Add to Packagist
|
|
|
|
|
* Improve unit/integration tests
|
|
|
|
|
* Create man page
|
|
|
|
|
* Create zsh completion function
|
|
|
|
|
|
|
|
|
|
In the longer term, if i get really bored, maybe i'll add more input and escape
|
|
|
|
|
methods. One thing that occurred to me is a custom escape option that takes an
|
|
|
|
|
arbitrary escape character and a mask of characters to be escaped with it. For
|
|
|
|
|
example, `-e 'custom:%:%'` might escape `printf(3)` format strings. idk
|
|
|
|
|
|
|
|
|
|
Anyway, if you find a bug or have a request, please let me know.
|
2016-07-24 22:05:10 +02:00
|
|
|
|
|
|
|
|
|
## Licence and acknowledgements
|
|
|
|
|
|
2018-06-02 08:42:26 +02:00
|
|
|
|
**twigc** itself is available under the MIT licence. For information about the licences
|
2016-07-24 22:05:10 +02:00
|
|
|
|
of its dependencies, run `twigc --credits`.
|
|
|
|
|
|
|
|
|
|
The `\Dana\Twigc\PharCompiler` class used to build the executable archive is
|
|
|
|
|
based on
|
|
|
|
|
[`\Composer\Compiler`](https://github.com/composer/composer/blob/master/src/Composer/Compiler.php).
|
|
|
|
|
|
|
|
|
|
## See also
|
|
|
|
|
|
|
|
|
|
* [twigphp/Twig](https://github.com/twigphp/Twig) —
|
|
|
|
|
The Twig project on GitHub.
|
2018-06-02 08:42:26 +02:00
|
|
|
|
|
2016-07-24 22:05:10 +02:00
|
|
|
|
* [farazdagi/twig-cli](https://github.com/farazdagi/twig-cli) —
|
|
|
|
|
Another project that aims to bring Twig to the command line. It's actually
|
|
|
|
|
quite similar in design (though no code is shared); it just didn't have the
|
2018-06-02 08:42:26 +02:00
|
|
|
|
features i wanted and isn't actively developed.
|
|
|
|
|
|
2016-07-24 22:05:10 +02:00
|
|
|
|
* [twigjs/twig.js](https://github.com/twigjs/twig.js) —
|
|
|
|
|
A pure JavaScript implementation of Twig. It comes with its own command-line
|
|
|
|
|
tool, `twigjs`, which can be used to render Twig templates, but it's quite
|
|
|
|
|
limited.
|
2018-06-02 08:42:26 +02:00
|
|
|
|
|
2016-07-24 22:05:10 +02:00
|
|
|
|
* [indigojs/twig-cli](https://github.com/indigojs/twig-cli) —
|
|
|
|
|
Another command-line Twig renderer based on Twig.js. Its functionality is very
|
|
|
|
|
similar to (almost exactly the same as?) `twigjs`.
|
2018-06-02 08:42:26 +02:00
|
|
|
|
|
2016-07-24 22:05:10 +02:00
|
|
|
|
* [mattrobenolt/jinja2-cli](https://github.com/mattrobenolt/jinja2-cli) —
|
|
|
|
|
A command-line [Jinja2](http://jinja.pocoo.org/) renderer. Very comparable to
|
|
|
|
|
**twigc** in terms of features.
|
|
|
|
|
|