Skip to content

Commit 05eed81

Browse files
docs: update README to enhance clarity and detail on features
1 parent 658ecf9 commit 05eed81

1 file changed

Lines changed: 164 additions & 33 deletions

File tree

README.md

Lines changed: 164 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
[![GitHub license](https://img.shields.io/github/license/CodeWithKyrian/jinja-php.svg)](https://github.com/codewithkyrian/jinja-php/blob/main/LICENSE)
66
[![GitHub release](https://img.shields.io/github/release/CodeWithKyrian/jinja-php.svg)](https://github.com/byjg/php-jinja/releases/)
77

8-
A minimalistic **zero-dependency** PHP implementation of the Jinja templating engine, specifically designed for parsing and rendering
8+
A **zero-dependency** PHP implementation of the Jinja templating engine, specifically designed for parsing and rendering
99
machine learning (ML) chat templates. This project is heavily inspired by HuggingFace's Jinja template engine in
1010
JavaScript, intended primarily for ML chat templates, but is versatile enough to be used for general purposes of parsing
1111
most Jinja templates.
@@ -18,9 +18,9 @@ Install Jinja PHP through Composer:
1818
composer require codewithkyrian/jinja-php
1919
```
2020

21-
## Usage
21+
## Quick Start
2222

23-
Heres how you can use Jinja PHP to render a template:
23+
Here's how you can use Jinja PHP to render a template:
2424

2525
```php
2626
$sourceString = "{{ bos_token }}{% for message in messages %}{% if (message['role'] == 'user') != (loop.index0 % 2 == 0) %}{{ raise_exception('Conversation roles must alternate user/assistant/user/assistant/...') }}{% endif %}{% if message['role'] == 'user' %}{{ '[INST] ' + message['content'] + ' [/INST]' }}{% elif message['role'] == 'assistant' %}{{ message['content'] + eos_token + ' ' }}{% else %}{{ raise_exception('Only user and assistant roles are supported!') }}{% endif %}{% endfor %}";
@@ -38,67 +38,198 @@ $args = [
3838
];
3939

4040
$template = new Template($sourceString);
41-
4241
$rendered = $template->render($args);
4342
// <s>[INST] Hello! [/INST]Hi! How are you?</s> [INST] I am doing great. [/INST]That is great to hear.</s>
4443
```
4544

46-
## Advanced Usage
45+
## Features
46+
47+
### **Supported Features**
48+
49+
#### **Control Structures**
50+
- **Conditional Statements**: `{% if %}`, `{% elif %}`, `{% else %}`, `{% endif %}`
51+
- **For Loops**: `{% for %}`, `{% else %}`, `{% endfor %}` with loop variables (`loop.index`, `loop.index0`, `loop.first`, `loop.last`, `loop.length`, `loop.previtem`, `loop.nextitem`)
52+
- **Break/Continue**: `{% break %}`, `{% continue %}` for loop control
53+
- **Ternary Expressions**: `{{ value if condition else other_value }}`
54+
55+
#### **Variables & Data**
56+
- **Variable Output**: `{{ variable }}`
57+
- **Negative Array Indexing**: `messages[-1]`, `array[-2]` (Python-style)
58+
- **Object/Array Access**: `user.name`, `messages[0]['content']`
59+
- **Null Literals**: `none`, `None`
60+
- **Boolean Literals**: `true`, `false`, `True`, `False`
61+
- **String Concatenation**: `{{ "Hello" ~ " " ~ "World" }}`
62+
63+
#### **Macros & Functions**
64+
- **Macros**: `{% macro name(arg1, arg2) %}...{% endmacro %}` with `{{ name() }}` calls
65+
- **Function Calls**: `{{ function(arg1, arg2) }}`
66+
- **Keyword Arguments**: `{{ function(param1=value1, param2=value2) }}`
67+
- **Spread Arguments**: `{{ function(*args) }}`
68+
69+
#### **Filters**
70+
- **String Filters**: `lower`, `upper`, `title`, `capitalize`, `strip`, `lstrip`, `rstrip`
71+
- **String Manipulation**: `replace`, `split`, `startswith`, `endswith`, `indent`
72+
- **Array Filters**: `length`, `join`, `map`, `reverse`, `sort`
73+
- **Data Filters**: `tojson`, `default`
74+
- **Custom Filter Blocks**: `{% filter filter_name %}...{% endfilter %}`
4775

48-
Jinja PHP supports various control structures from Jinja templates. Here are some examples:
76+
#### **Advanced Features**
77+
- **Comments**: `{# This is a comment #}`
78+
- **Set Statements**: `{% set variable = value %}` and block sets `{% set variable %}{% endset %}`
79+
- **Call Blocks**: `{% call macro_name() %}...{% endcall %}`
80+
- **Exception Handling**: `{{ raise_exception('Error message') }}`
81+
- **String Concatenation**: Multiple string literals and `~` operator
4982

50-
### Conditional Statements:
83+
#### **Built-in Functions**
84+
- `range()`: Generate number sequences
85+
- `raise_exception()`: Throw runtime exceptions
86+
- `len()`: Get length of arrays/strings
5187

52-
```js
88+
### 🔄 **Partially Supported Features**
89+
90+
- **Complex Expressions**: Most Jinja expressions work, but some edge cases may differ
91+
- **Template Inheritance**: Basic support (limited)
92+
- **Custom Filters**: Can be added via the Environment class
93+
- **Whitespace Control**: Basic support with `{%-` and `-%}`
94+
95+
### **Not Yet Supported**
96+
97+
- **Template Inheritance**: `{% extends %}`, `{% block %}`, `{% include %}`
98+
- **Custom Functions**: User-defined functions
99+
- **Advanced Filters**: Some complex filters like `groupby`, `batch`
100+
101+
## Usage Examples
102+
103+
### **Conditional Statements**
104+
105+
```php
53106
{% if user.isActive %}
54-
"Hello," {{ user.name }}!
107+
Hello, {{ user.name }}!
108+
{% elif user.isGuest %}
109+
Hello, Guest!
55110
{% else %}
56-
"Hello, Guest!"
111+
Please log in.
57112
{% endif %}
58-
59113
```
60114

61-
### For Loops
115+
### **For Loops with Loop Variables**
62116

63-
```js
64-
<ul>
117+
```php
65118
{% for user in users %}
66-
<li>{{ user.name }}</li>
119+
{{ loop.index }} - {{ user.name }}
120+
{% if loop.first %}First user{% endif %}
121+
{% if loop.last %}Last user{% endif %}
67122
{% else %}
68-
<li>No users found.</li>
123+
No users found.
69124
{% endfor %}
70-
</ul>
71125
```
72126

73-
```js
74-
{% for user in users %}
75-
{{ loop.index }} - {{ user.name }}
127+
### **Macros**
128+
129+
```php
130+
{% macro format_user(user) %}
131+
<div class="user">
132+
<h3>{{ user.name|title }}</h3>
133+
<p>{{ user.email|lower }}</p>
134+
</div>
135+
{% endmacro %}
136+
137+
{{ format_user(current_user) }}
138+
```
139+
140+
### **String Manipulation**
141+
142+
```php
143+
{{ "Hello World!"|upper|replace("WORLD", "PHP") }}
144+
{{ " hello "|strip|capitalize }}
145+
{{ "apple,banana,cherry"|split(",")|join(" and ") }}
146+
{{ "Hello" ~ " " ~ "World" }}
147+
```
148+
149+
### **Array Operations**
150+
151+
```php
152+
{% for item in items|sort %}
153+
{{ item }}
76154
{% endfor %}
155+
156+
{{ messages[-1]['content'] }} {# Last message #}
157+
{{ array|length }} {# Array length #}
77158
```
78159

79-
### Variable Filters
160+
### **Set Statements**
80161

81-
```js
82-
{{ "Hello World!"|lower }}
162+
```php
163+
{% set greeting = "Hello, " ~ user.name %}
164+
{{ greeting }}
165+
166+
{% set user_info %}
167+
Name: {{ user.name }}
168+
Email: {{ user.email }}
169+
{% endset %}
170+
{{ user_info|indent(2) }}
83171
```
84172

85-
## Comprehensive Feature Support
173+
### **Filter Blocks**
86174

87-
Jinja PHP is designed to be robust and feature-rich, offering support for a wide range of functionalities beyond the
88-
basics of templating. This includes handling exceptions, using default string methods like `strip()` or `upper()`,
89-
working with dictionaries, and much more. If there's a feature you need that isn't currently implemented in Jinja PHP,
90-
we encourage you to [request it](https://github.com/codewithkyrian/jinja-php/issues/new). Additionally, if you're
91-
proficient with PHP and understand the internals of templating engines, consider contributing to the project by
92-
submitting a pull request with your proposed feature.
175+
```php
176+
{% filter upper %}
177+
This text will be uppercase
178+
{% endfilter %}
179+
```
93180

94-
## Testing
181+
### **Comments**
182+
183+
```php
184+
{# This is a comment that won't appear in output #}
185+
{{ variable }} {# Inline comment #}
186+
```
187+
188+
## Advanced Usage
189+
190+
### **Error Handling**
191+
192+
```php
193+
{% if user.role == 'admin' %}
194+
Admin panel
195+
{% else %}
196+
{{ raise_exception('Access denied') }}
197+
{% endif %}
198+
```
95199

96-
Jinja PHP comes with a suite of tests to ensure functionality remains consistent and reliable. To run the tests:
200+
### **Complex Expressions**
97201

202+
```php
203+
{{ (user.isActive and user.hasPermission) or user.isAdmin }}
204+
{{ messages|length > 0 and messages[-1].role == 'user' }}
205+
{{ "Hello" if user.name else "Guest" }}
98206
```
207+
208+
## Testing
209+
210+
Jinja PHP comes with a comprehensive test suite to ensure functionality remains consistent and reliable. To run the tests:
211+
212+
```shell
99213
composer test
100214
```
101215

216+
The test suite includes:
217+
- Unit tests for all language features
218+
- End-to-end template processing tests
219+
- Error handling and edge case tests
220+
221+
## Performance
222+
223+
Jinja PHP is designed for performance with:
224+
- Zero external dependencies
225+
- Efficient tokenization and parsing
226+
- Optimized runtime execution
227+
- Memory-conscious design
228+
229+
## Contributing
230+
231+
Jinja PHP is designed to be robust and feature-rich, offering support for a wide range of functionalities. If there's a feature you need that isn't currently implemented, we encourage you to [request it](https://github.com/codewithkyrian/jinja-php/issues/new). Additionally, if you're proficient with PHP and understand the internals of templating engines, consider contributing to the project by submitting a pull request with your proposed feature.
232+
102233
## Contributors
103234

104235
- [Kyrian Obikwelu](https://github.com/CodeWithKyrian)
@@ -117,4 +248,4 @@ to [open an issue](https://github.com/CodeWithKyrian/jinja-php/issues/new/choose
117248
## License
118249

119250
This project is licensed under the MIT License. See
120-
the [LICENSE](https://github.com/codewithkyrian/jinja-php/blob/main/LICENSE) file for more information.
251+
the [LICENSE](https://github.com/CodeWithKyrian/jinja-php/blob/main/LICENSE) file for more information.

0 commit comments

Comments
 (0)