Skip to content

Commit e246469

Browse files
authored
Merge pull request #144 from ericsizemore/add-interface-adapters
feat: add storage interface and support for file or db based templates
2 parents cc32412 + 43a7c97 commit e246469

21 files changed

+558
-296
lines changed

.gitattributes

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,8 @@
77
*.xml text
88

99
# Ignore all test and documentation with "export-ignore".
10-
/.github export-ignore
11-
/examples export-ignore
12-
/tests export-ignore
10+
/.github export-ignore
11+
/tests export-ignore
1312
/.gitattributes export-ignore
1413
/.gitignore export-ignore
1514
/.php-cs-fixer.dist.php export-ignore

.php-cs-fixer.dist.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,6 @@
186186
->setLineEnding("\n")
187187
->setFinder(
188188
PhpCsFixer\Finder::create()
189-
->in(__DIR__ . '/examples')
190189
->in(__DIR__ . '/src')
191190
->in(__DIR__ . '/tests')
192191
)

CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1919
* Psalm
2020
* RectorPHP
2121
* Added template caching via `PSR-6` support.
22+
* Added support for filesystem storage and database storage of templates.
23+
* Adds: `Storage\FilesystemStorage`, `Storage\DatabaseStorage`, and `Storage\StorageInterface`.
24+
* Added library specific exceptions:
25+
* `Exception\TemplateHasNoContentException`
26+
* `Exception\TemplateNotFoundException`
27+
* `Exception\TemplateVariablesException`
2228

2329
### Changed
2430

@@ -27,6 +33,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2733
* Bumped minimum PHP version requirement to 8.2
2834
* Updated header docblock in each source file to be more compact.
2935
* Updated with new coding standards and fixes to issues reported by Psalm.
36+
* Updated the `README.md` file to be more thorough.
37+
* Changed the exceptions thrown in various situations:
38+
* Instead of `InvalidArgumentException` when a template isn't found, `Exception\TemplateNotFoundException` is thrown instead.
39+
* Instead of `LogicException` when no template variables are set, `Exception\TemplateVariablesException` is thrown instead.
40+
* Instead of `RuntimeException` when a template does not return content, `Exception\TemplateHasNoContentException` is thrown instead.
41+
42+
### Removed
43+
44+
* Removed the `examples` directory and files, and added examples directly to the `README`.
3045

3146

3247
## [2.0.1] - 2023-12-20

README.md

Lines changed: 98 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,13 @@
1212
<!-- Remove until 3.x release
1313
[![License](https://img.shields.io/packagist/l/esi/simple_tpl.svg)](https://packagist.org/packages/esi/simple_tpl)
1414
-->
15-
[Simple Template Engine](http://github.com/ericsizemore/simple_tpl/) is a small, simple text-based template parsing engine that works on text replacement.
1615

17-
> [!IMPORTANT]
18-
> The `master` branch currently holds the work in progress version `3.x`, which is a break from the backward compatibility promise. This will be resolved once 3.0.0 is released.
19-
> Since `3.x` is under development, it is not recommended to use in a production environment. The public api, implementations, etc. can (and will likely) change.
16+
[Simple Template Engine](http://github.com/ericsizemore/simple_tpl/) is a small, simple text-based template parsing engine that works on text replacement.
2017

2118
> [!IMPORTANT]
22-
> The `3.x` branch is mostly an introduction of caching templates. As this is in development, I'm playing around with a few different ideas. For example, right now it just caches
23-
> the entire template after it has been parsed (so it caches template + content). This can and will likely change as I continue testing out different approaches.
19+
> The `master` branch currently holds the work-in-progress version `3.x`, which is a break from the backward compatibility promise.
20+
> This will be resolved once `3.0.0` is released. Since `3.x` is under development, it is not recommended to use in a production environment.
21+
> The public API, implementations, etc., can (and will likely) change.
2422
2523
---
2624

@@ -29,30 +27,111 @@
2927
Compatible with PHP >= 8.2 and can be installed with [Composer](https://getcomposer.org).
3028

3129
```bash
32-
$ composer require esi/simple_tpl
30+
$ composer require esi/simple_tpl:^3.0
3331
```
3432

35-
### Usage
33+
## Usage
34+
35+
### Storage
36+
37+
There are two storage implementations available: `Storage\FilesystemStorage` and `Storage\DatabaseStorage`.
38+
Both storage implementations implement the `Storage\StorageInterface` interface, with only one defined method: `loadTemplate()`.
39+
40+
**NOTE:** If you wish to have a system for deleting or updating the templates themselves, you would need to implement this on your own.
41+
This library only searches for templates that have already been created, by name, then parses them with a `key => value` associative array of variables.
42+
43+
#### Filesystem Storage
44+
45+
The `FilesystemStorage` implementation allows you to use regular files for your templates.
46+
Your template files are expected to end with the `.tpl` extension. I plan to allow the ability to use different extensions later.
3647

37-
Basic usage, without providing a cache library:
48+
1. Create a `FilesystemStorage` instance with the path/directory to where your templates are located.
49+
2. Pass this instance to the `Template` class when creating it.
3850

51+
Let's say you had a template called `example_template.tpl` within the `./templates/` directory.
52+
53+
Template file:
54+
```html
55+
<!DOCTYPE HTML>
56+
<html lang="en">
57+
<head>
58+
<meta http-equiv="content-type" content="text/html" />
59+
<title>{title}</title>
60+
</head>
61+
<body>
62+
<p>{content}</p>
63+
</body>
64+
</html>
65+
```
66+
67+
PHP to parse the template:
3968
```php
4069
use Esi\SimpleTpl\Template;
70+
use Esi\SimpleTpl\Storage\FilesystemStorage;
4171

42-
$tpl = new Template();
72+
$templateStorage = new FilesystemStorage('./templates/');
73+
$template = new Template($templateStorage);
4374

44-
$tpl->setTplVars([
45-
'title' => 'Simple Template Engine Test',
46-
'content' => 'This is a test of the Simple Template Engine class by Eric Sizemore.',
75+
$template->setTplVars([
76+
'title' => 'Hello, World!',
77+
'content' => 'This is a simple template engine.'
4778
]);
4879

49-
// Parse the template file
50-
$tpl->display(__DIR__ . '/some_template.tpl');
80+
echo $template->parse('example_template');
5181
```
5282

83+
When calling `display()` or `parse()`, you only need to provide the file name without extension.
84+
For example, if your template file is `mytemplate.tpl`, you would call either of these methods with `mytemplate`.
85+
86+
#### Database Storage
87+
88+
The `DatabaseStorage` implementation allows you to use a database for your templates.
89+
90+
1. Create a `PDO` instance with your database details to create a connection.
91+
2. Create a `DatabaseStorage` instance and pass the `PDO` instance to it.
92+
3. Pass the `DatabaseStorage` instance to the `Template` class when creating it.
93+
94+
Let's say the content of the `example_template` is the same as in the [filesystem example](#filesystem-storage):
95+
96+
```php
97+
use Esi\SimpleTpl\Template;
98+
use Esi\SimpleTpl\Storage\DatabaseTemplateStorage;
99+
use PDO;
100+
101+
$pdo = new PDO('mysql:host=localhost;dbname=templates', 'user', 'password');
102+
$templateStorage = new DatabaseTemplateStorage($pdo);
103+
$template = new Template($templateStorage);
104+
105+
$template->setTplVars([
106+
'title' => 'Hello, World!',
107+
'content' => 'This is a simple template engine.'
108+
]);
109+
110+
echo $template->parse('example_template');
111+
```
112+
113+
`DatabaseStorage` does not allow specifying custom table or field/column names. It expects a table named `templates` with, at minimum, two columns
114+
named `name` (for the template name) and `content` (for the template content). I plan to allow the ability to use custom table and field/column names later.
115+
116+
An example on how this table may be structured:
117+
118+
```sql
119+
CREATE TABLE IF NOT EXISTS `templates` (
120+
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
121+
`name` VARCHAR(255) NOT NULL,
122+
`content` MEDIUMTEXT NOT NULL,
123+
PRIMARY KEY (`id`),
124+
UNIQUE KEY `name` (`name`)
125+
)
126+
```
127+
128+
### Caching
129+
53130
If you would like to utilize caching for templates, you will need to provide the library a [PSR-6](https://www.php-fig.org/psr/psr-6/) cache implementation.
54131
You can view a list of packages that provide this implementation on [Packagist](https://packagist.org/providers/psr/cache-implementation).
55132

133+
Whether you use `FilesystemStorage` or `DatabaseStorage`, you can use caching for either by passing an object that implements `\Psr\Cache\CacheItemPoolInterface`.
134+
56135
For example:
57136

58137
```bash
@@ -61,9 +140,12 @@ $ composer require symfony/cache:^7.2
61140

62141
```php
63142
use Esi\SimpleTpl\Template;
143+
use Esi\SimpleTpl\Storage\FilesystemStorage;
64144
use Symfony\Component\Cache\Adapter\AbstractAdapter;
65145

66-
$tpl = new Template(
146+
$templateStorage = new FilesystemStorage('/path/to/templates');
147+
$template = new Template(
148+
$templateStorage,
67149
/**
68150
* Symfony's AbstractAdapter::createSystemCache() returns the best possible adapter that your runtime supports.
69151
* Generally, it will create a cache via PHP files (Opcache must be enabled via opcache.enable in php.ini), and chain that with APCu if your system supports it.
@@ -77,8 +159,6 @@ $tpl = new Template(
77159
// ... assign vars, parse /display template, etc ...
78160
```
79161

80-
Some basic examples have also been provided within the [`examples`](./examples) folder.
81-
82162
## About
83163

84164
### Requirements

SECURITY.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
## Supported Versions
44

55
| Version | Supported |
6-
| ------- | ------------------ |
6+
|---------|--------------------|
77
| 3.0.x | :white_check_mark: |
88
| 2.0.x | :white_check_mark: |
99
| 1.0.x | :x: |

composer.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,11 @@
3939
"psalm/plugin-phpunit": "^0.19.0",
4040
"rector/rector": "^2.0",
4141
"symfony/cache": "^7.2",
42-
"vimeo/psalm": "dev-master"
42+
"vimeo/psalm": "^6.0",
43+
"ext-pdo": "*"
44+
},
45+
"suggest": {
46+
"ext-pdo": "To use the DatabaseStorage option."
4347
},
4448
"minimum-stability": "dev",
4549
"prefer-stable": true,

0 commit comments

Comments
 (0)