Skip to content

Commit

Permalink
Initial Commit
Browse files Browse the repository at this point in the history
  • Loading branch information
devtronic committed Jan 17, 2018
0 parents commit 16d117a
Show file tree
Hide file tree
Showing 11 changed files with 189 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/vendor/
composer.lock
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Twig Compose Environment
A **quick and dirty** solution for multiple sub templates in twig

## Installation
```bash
$ composer require devtronic/twig-compose
```

## Usage

Every sub template **must** extend from the base template
```php
<?php
$loader = new \Twig_Loader_Filesystem(''); // or whatever
$twig = new Devtronic\TwigCompose\Environment($loader); // instead of Twig_Environment

$template = $twig->compose('base.html.twig', ['pluginA.html.twig', 'pluginB.html.twig']); // Take a look in tests/res

echo $template->render([
// Your template data
]);

```
26 changes: 26 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"name": "devtronic/twig-compose",
"description": "Compose twig templates from multiple child templates",
"type": "library",
"require": {
"php": "5.6 || ^7.0",
"twig/twig": "1.* || 2.*"
},
"require-dev": {
"phpunit/phpunit": "^5.7"
},
"license": "MIT",
"authors": [
{
"name": "Julian Finkler",
"email": "[email protected]"
}
],
"minimum-stability": "stable",
"autoload": {
"psr-4": {
"Devtronic\\TwigCompose\\": "src/",
"Devtronic\\Tests\\TwigCompose\\": "tests/"
}
}
}
12 changes: 12 additions & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<phpunit bootstrap="tests/autoload.php">
<testsuites>
<testsuite name="Test Suite">
<directory suffix="Test.php">./tests/</directory>
</testsuite>
</testsuites>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">./src</directory>
</whitelist>
</filter>
</phpunit>
74 changes: 74 additions & 0 deletions src/Environment.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php

namespace Devtronic\TwigCompose;

use Twig_Environment;
use Twig_Loader_Array;

class Environment extends Twig_Environment
{
/**
* Compose a template with N sub templates
*
* @param string $baseTemplate The base template
* @param string[] $subTemplates The sub templates
*
* @return \Twig_TemplateWrapper The Template
*
* @throws \Twig_Error_Loader
* @throws \Twig_Error_Runtime
* @throws \Twig_Error_Syntax
*/
public function compose($baseTemplate, $subTemplates)
{
$baseTemplatePath = $this->getExactPath($baseTemplate);
$templates = [$baseTemplate => file_get_contents($baseTemplatePath)];
foreach ($subTemplates as $template) {
$templates[md5($template . uniqid()) . '.html.twig'] = file_get_contents($this->getExactPath($template));
}

$i = 0;
$prevKey = null;
foreach ($templates as $hash => $template) {
if ($i < 2) {
$i++;
$prevKey = $hash;
continue;
}

if (strstr($template, $baseTemplatePath)) {
$template = str_replace($baseTemplatePath, $prevKey, $template);
}

if (strstr($template, $baseTemplate)) {
$template = str_replace($baseTemplate, $prevKey, $template);
}
$templates[$hash] = $template;
$prevKey = $hash;
}
end($templates);
$newTemplate = key($templates);

$loader = new Twig_Loader_Array($templates);
$originalLoader = $this->getLoader();
$this->setLoader($loader);
$templateWrapper = $this->load($newTemplate);
$this->setLoader($originalLoader);

return $templateWrapper;
}

/**
* Gets the exact template path
*
* @param string $name The template name
* @return string The template path
*
* @throws \Twig_Error_Loader
* @throws \Twig_Error_Syntax
*/
private function getExactPath($name)
{
return $this->resolveTemplate($name)->getSourceContext()->getPath();
}
}
17 changes: 17 additions & 0 deletions tests/EnvironmentTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace Devtronic\Tests\TwigCompose;

use Devtronic\TwigCompose\Environment;
use PHPUnit\Framework\TestCase;

class EnvironmentTest extends TestCase
{
public function testCompose()
{
$loader = new \Twig_Loader_Filesystem(__DIR__ . '/res');
$twig = new Environment($loader);
$template = $twig->compose('base.html.twig', ['pluginA.html.twig', 'pluginB.html.twig']);
$this->assertSame(file_get_contents(__DIR__ . '/expected.html'), $template->render(['what' => 'World']));
}
}
3 changes: 3 additions & 0 deletions tests/autoload.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<?php

require_once __DIR__ . '/../vendor/autoload.php';
11 changes: 11 additions & 0 deletions tests/expected.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<title>Great title</title>

<meta charset="UTF-8">
</head>
<body>
<h1>Hello World</h1>
</body>
</html>
9 changes: 9 additions & 0 deletions tests/res/base.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<!DOCTYPE html>
<html>
<head>
{% block head '' %}
</head>
<body>
{% block body '' %}
</body>
</html>
4 changes: 4 additions & 0 deletions tests/res/pluginA.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{% extends 'base.html.twig' %}
{% block head %}
{{ parent() }}<title>Great title</title>
{% endblock %}
8 changes: 8 additions & 0 deletions tests/res/pluginB.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{% extends 'base.html.twig' %}
{% block head %}
{{ parent() }}
<meta charset="UTF-8">
{% endblock %}
{% block body %}
<h1>Hello {{ what }}</h1>
{% endblock %}

0 comments on commit 16d117a

Please sign in to comment.