Skip to content

Commit 50355e5

Browse files
committed
Twig-only rewrite with global data support
1 parent 527b5ce commit 50355e5

File tree

5 files changed

+89
-53
lines changed

5 files changed

+89
-53
lines changed

README.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# Data Transform Plugin for Pattern Lab PHP
22

3+
This plugin now only works with Twig PatternEngine. You can use old 0.x versions of the plugin for Mustache PatternEngine.
4+
5+
36
## Installation
47

58
To install and use the plugin run:
@@ -13,12 +16,12 @@ composer require aleksip/plugin-data-transform
1316

1417
### Pattern-specific data file support for included patterns
1518

16-
Pattern Lab currently only supports global data files and a pattern-specific data file for the main pattern. This plugin adds pattern-specific data file support for included patterns. This feature only works with Twig PatternEngine.
19+
Pattern Lab currently only supports global data files and a pattern-specific data file for the main pattern. This plugin adds pattern-specific data file support for included patterns.
1720

1821

1922
### Data transform functions
2023

21-
Currently the plugin provides 3 transform functions for the data read by Pattern Lab. The examples provided are in JSON but Pattern Lab supports YAML too! These functions should work with both Twig and Mustache PatternEngines.
24+
Currently the plugin provides 3 transform functions for the data read by Pattern Lab. The examples provided are in JSON but Pattern Lab supports YAML too!
2225

2326

2427
#### Include pattern files
@@ -87,6 +90,11 @@ The value of `key` will be replaced with the joined strings. Note that in the ex
8790
The value of `key` will be replaced with an [Attribute object](https://www.drupal.org/node/2513632).
8891

8992

93+
## Global data and includes
94+
95+
If you are using global data from the `_data` directory and includes (in data files or Twig templates) please note that 1) pattern-specific data overwrites data from parent patterns by default and that 2) global data for an included pattern is considered to be pattern-specific data. If you want to override pattern-specific data of an included pattern you can do that by using the `with` keyword.
96+
97+
9098
## More examples
9199

92100
All features provided by this plugin are used extensively in [Shila Drupal Theme StarterKit](https://github.com/aleksip/starterkit-shila-drupal-theme).

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
},
2525
"require": {
2626
"php": ">=5.5.9",
27-
"pattern-lab/patternengine-twig": "0.*"
27+
"pattern-lab/core": "^2.3.0",
28+
"pattern-lab/patternengine-twig": "^2.0.0"
2829
}
2930
}

src/aleksip/DataTransformPlugin/Helper.php renamed to src/aleksip/DataTransformPlugin/DataTransformer.php

Lines changed: 58 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -5,58 +5,82 @@
55
use Drupal\Core\Template\Attribute;
66
use PatternLab\Data;
77
use PatternLab\PatternData;
8-
use PatternLab\PatternData\Helper as PatternDataHelper;
98
use PatternLab\PatternEngine;
109

11-
class Helper extends PatternDataHelper
10+
class DataTransformer
1211
{
13-
protected $patternLoader;
14-
protected $store;
12+
protected $env;
1513
protected $reservedKeys;
14+
protected $patternDataStore;
1615
protected $processed;
1716

18-
public function __construct($options = array())
17+
public function __construct(\Twig_Environment $env)
1918
{
20-
parent::__construct($options);
21-
$patternEngineBasePath = PatternEngine::getInstance()->getBasePath();
22-
$patternLoaderClass = $patternEngineBasePath . '\Loaders\PatternLoader';
23-
$this->patternLoader = new $patternLoaderClass($options);
24-
$this->store = PatternData::get();
19+
$this->env = $env;
2520
// TODO: Add an accessor function for $reservedKeys to the Data class?
26-
$this->reservedKeys = array("listItems","cacheBuster","patternLink","patternSpecific","patternLabHead","patternLabFoot");
21+
$this->reservedKeys = array("cacheBuster","link","patternSpecific","patternLabHead","patternLabFoot");
22+
$this->patternDataStore = PatternData::get();
2723
$this->processed = array();
2824
}
2925

3026
public function run()
3127
{
32-
foreach (array_keys($this->store) as $patternStoreKey) {
33-
$this->processPattern($patternStoreKey);
28+
// Process global data.
29+
$dataStore = $this->processData(Data::get());
30+
Data::replaceStore($dataStore);
31+
// Process pattern specific data.
32+
foreach (array_keys($this->patternDataStore) as $pattern) {
33+
$this->processPattern($pattern);
3434
}
3535
}
3636

37-
protected function isProcessed($patternStoreKey)
37+
protected function isProcessed($pattern)
3838
{
39-
return isset($this->processed[$patternStoreKey]);
39+
return isset($this->processed[$pattern]);
4040
}
4141

42-
protected function setProcessed($patternStoreKey)
42+
protected function setProcessed($pattern)
4343
{
44-
$this->processed[$patternStoreKey] = true;
44+
$this->processed[$pattern] = true;
4545
}
4646

47-
protected function processPattern($patternStoreKey)
47+
protected function processPattern($pattern)
4848
{
49-
$patternStoreData = $this->store[$patternStoreKey];
50-
if ($patternStoreData["category"] == "pattern" && !$this->isProcessed($patternStoreKey)) {
51-
$data = Data::getPatternSpecificData($patternStoreKey);
52-
foreach (array_keys($data) as $key) {
53-
if (!in_array($key, $this->reservedKeys)) {
54-
$data = $this->processKey($data, $key);
49+
if (
50+
$this->isProcessed($pattern)
51+
|| !isset($this->patternDataStore[$pattern])
52+
|| $this->patternDataStore[$pattern]['category'] != 'pattern'
53+
) {
54+
return;
55+
}
56+
$patternSpecificData =
57+
$this->processData(Data::getPatternSpecificData($pattern))
58+
;
59+
// Clone objects in possible default global data.
60+
$dataStore = Data::get();
61+
foreach (array_keys($patternSpecificData) as $key) {
62+
if (!isset($dataStore['patternSpecific'][$pattern]['data'][$key])) {
63+
// Value is default global data.
64+
// TODO: Array support.
65+
if (is_object($dataStore[$key])) {
66+
$patternSpecificData[$key] = clone $dataStore[$key];
5567
}
5668
}
57-
Data::setPatternData($patternStoreKey, $data);
58-
$this->setProcessed($patternStoreKey);
5969
}
70+
Data::initPattern($pattern);
71+
Data::setPatternData($pattern, $patternSpecificData);
72+
$this->setProcessed($pattern);
73+
}
74+
75+
protected function processData($data)
76+
{
77+
foreach (array_keys($data) as $key) {
78+
if (!in_array($key, $this->reservedKeys)) {
79+
$data = $this->processKey($data, $key);
80+
}
81+
}
82+
83+
return $data;
6084
}
6185

6286
protected function processKey($data, $key)
@@ -71,7 +95,7 @@ protected function processKey($data, $key)
7195
}
7296
elseif (isset($value['include()']) && is_array($value['include()']) && isset($value['include()']['pattern'])) {
7397
$pattern = $value['include()']['pattern'];
74-
if (is_string($pattern) && isset($this->store[$pattern])) {
98+
if (is_string($pattern) && isset($this->patternDataStore[$pattern])) {
7599
if (!isset($value['include()']['with']) || !is_array($value['include()']['with'])) {
76100
if (!isset($value['include()']['only'])) {
77101
$patternData = $this->getProcessedPatternSpecificData($pattern);
@@ -96,14 +120,14 @@ protected function processKey($data, $key)
96120
$data[$key] = $value;
97121
}
98122
}
99-
elseif (is_string($value) && isset($this->store[$value]) && $key !== 'pattern') {
123+
elseif (is_string($value) && isset($this->patternDataStore[$value]) && $key !== 'pattern') {
100124
$data[$key] = $this->renderPattern($value, $this->getProcessedPatternSpecificData($value));
101125
}
102126

103127
return $data;
104128
}
105129

106-
protected function getProcessedPatternSpecificData($pattern, $extraData = array())
130+
public function getProcessedPatternSpecificData($pattern, $extraData = array())
107131
{
108132
$this->processPattern($pattern);
109133

@@ -112,11 +136,11 @@ protected function getProcessedPatternSpecificData($pattern, $extraData = array(
112136

113137
protected function renderPattern($pattern, $data)
114138
{
115-
if (isset($this->store[$pattern]['patternRaw'])) {
116-
$pattern = $this->patternLoader->render([
117-
'pattern' => $this->store[$pattern]['patternRaw'],
118-
'data' => $data
119-
]);
139+
if (isset($this->patternDataStore[$pattern]['patternRaw'])) {
140+
$pattern = $this->env->render(
141+
$this->patternDataStore[$pattern]['patternRaw'],
142+
$data
143+
);
120144
}
121145

122146
return $pattern;

src/aleksip/DataTransformPlugin/PatternLabListener.php

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,28 +4,24 @@
44

55
use aleksip\DataTransformPlugin\Twig\PatternDataNodeVisitor;
66
use PatternLab\Listener;
7-
use PatternLab\PatternData\Event;
87
use PatternLab\PatternEngine\Twig\TwigUtil;
98

109
class PatternLabListener extends Listener
1110
{
1211
public function __construct()
1312
{
14-
$this->addListener('patternData.codeHelperStart', 'runHelper');
15-
$this->addListener('twigPatternLoader.customize', 'addNodeVisitor');
13+
$this->addListener(
14+
'twigPatternLoader.customize',
15+
'twigPatternLoaderCustomize'
16+
);
1617
}
1718

18-
public function runHelper(Event $event)
19+
public function twigPatternLoaderCustomize()
1920
{
20-
$options = $event->getOptions();
21-
$helper = new Helper($options);
22-
$helper->run();
23-
}
24-
25-
public function addNodeVisitor()
26-
{
27-
$instance = TwigUtil::getInstance();
28-
$instance->addNodeVisitor(new PatternDataNodeVisitor());
29-
TwigUtil::setInstance($instance);
21+
$env = TwigUtil::getInstance();
22+
$dt = new DataTransformer($env);
23+
$env->addNodeVisitor(new PatternDataNodeVisitor($dt));
24+
TwigUtil::setInstance($env);
25+
$dt->run();
3026
}
3127
}

src/aleksip/DataTransformPlugin/Twig/PatternDataNodeVisitor.php

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,17 @@
22

33
namespace aleksip\DataTransformPlugin\Twig;
44

5-
use PatternLab\Data;
5+
use aleksip\DataTransformPlugin\DataTransformer;
66

77
class PatternDataNodeVisitor extends \Twig_BaseNodeVisitor
88
{
9+
protected $dt;
10+
11+
public function __construct(DataTransformer $dt)
12+
{
13+
$this->dt = $dt;
14+
}
15+
916
protected function doEnterNode(\Twig_Node $node, \Twig_Environment $env)
1017
{
1118
return $node;
@@ -16,7 +23,7 @@ protected function doLeaveNode(\Twig_Node $node, \Twig_Environment $env)
1623
if ($node instanceof \Twig_Node_Include) {
1724
if ($node->hasNode('expr') && $node->getNode('expr')->hasAttribute('value')) {
1825
$patternStoreKey = $node->getNode('expr')->getAttribute('value');
19-
$data = Data::getPatternSpecificData($patternStoreKey);
26+
$data = $this->dt->getProcessedPatternSpecificData($patternStoreKey);
2027
if ($node instanceof \Twig_Node_Embed) {
2128
$dataNode = new PatternDataEmbedNode($node, $data);
2229
}

0 commit comments

Comments
 (0)