Skip to content

Commit 0c48feb

Browse files
committed
Merge branch 'dev'
2 parents 51fdd96 + 3d395ba commit 0c48feb

File tree

6 files changed

+196
-143
lines changed

6 files changed

+196
-143
lines changed

README.md

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
# Data Transform Plugin for Pattern Lab PHP
1+
# Data Transform Plugin for Pattern Lab
2+
3+
This plugin now only works with Twig PatternEngine. You can use old 0.x versions of the plugin for Mustache PatternEngine.
4+
25

36
## Installation
47

@@ -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 core 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+
Please note that global data from the `_data` directory is considered to be pattern-specific data and will overwrite data inherited from a parent pattern. If you want to override data of an included pattern you can use 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: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
},
2525
"require": {
2626
"php": ">=5.5.9",
27+
"pattern-lab/core": "^2.6.3",
2728
"pattern-lab/patternengine-twig": "^2.0.0"
2829
}
2930
}
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
<?php
2+
3+
namespace aleksip\DataTransformPlugin;
4+
5+
use Drupal\Core\Template\Attribute;
6+
use PatternLab\Data;
7+
use PatternLab\PatternData;
8+
use PatternLab\PatternEngine;
9+
10+
class DataTransformer
11+
{
12+
protected $env;
13+
protected $reservedKeys;
14+
protected $patternDataStore;
15+
protected $processed;
16+
17+
public function __construct(\Twig_Environment $env)
18+
{
19+
$this->env = $env;
20+
// TODO: Add an accessor function for $reservedKeys to the Data class?
21+
$this->reservedKeys = array("cacheBuster","link","patternSpecific","patternLabHead","patternLabFoot");
22+
$this->patternDataStore = PatternData::get();
23+
$this->processed = array();
24+
}
25+
26+
public function run()
27+
{
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);
34+
}
35+
}
36+
37+
protected function isProcessed($pattern)
38+
{
39+
return isset($this->processed[$pattern]);
40+
}
41+
42+
protected function setProcessed($pattern)
43+
{
44+
$this->processed[$pattern] = true;
45+
}
46+
47+
protected function processPattern($pattern)
48+
{
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+
$dataStore = Data::get();
60+
foreach (array_keys($patternSpecificData) as $key) {
61+
if (!isset($dataStore['patternSpecific'][$pattern]['data'][$key])) {
62+
// Value is default global data.
63+
if (is_object($dataStore[$key])) {
64+
$patternSpecificData[$key] = clone $dataStore[$key];
65+
}
66+
}
67+
}
68+
Data::initPattern($pattern);
69+
Data::setPatternData($pattern, $patternSpecificData);
70+
$this->setProcessed($pattern);
71+
}
72+
73+
protected function processData($data)
74+
{
75+
foreach (array_keys($data) as $key) {
76+
if (!in_array($key, $this->reservedKeys)) {
77+
$data = $this->processKey($data, $key);
78+
}
79+
}
80+
81+
return $data;
82+
}
83+
84+
protected function processKey($data, $key)
85+
{
86+
$value = $data[$key];
87+
if (is_array($value)) {
88+
foreach (array_keys($value) as $subKey) {
89+
$value = $this->processKey($value, $subKey);
90+
}
91+
if (isset($value['Attribute()']) && is_array($value['Attribute()'])) {
92+
$data[$key] = new Attribute($value['Attribute()']);
93+
}
94+
elseif (isset($value['include()']) && is_array($value['include()']) && isset($value['include()']['pattern'])) {
95+
$pattern = $value['include()']['pattern'];
96+
if (is_string($pattern) && isset($this->patternDataStore[$pattern])) {
97+
if (!isset($value['include()']['with']) || !is_array($value['include()']['with'])) {
98+
if (!isset($value['include()']['only'])) {
99+
$patternData = $this->getProcessedPatternSpecificData($pattern);
100+
}
101+
else {
102+
$patternData = array();
103+
}
104+
}
105+
elseif (!isset($value['include()']['only'])) {
106+
$patternData = $this->getProcessedPatternSpecificData($pattern, $value['include()']['with']);
107+
}
108+
else {
109+
$patternData = $value['include()']['with'];
110+
}
111+
$data[$key] = $this->renderPattern($pattern, $patternData);
112+
}
113+
}
114+
elseif (isset($value['join()']) && is_array($value['join()'])) {
115+
$data[$key] = join($value['join()']);
116+
}
117+
else {
118+
$data[$key] = $value;
119+
}
120+
}
121+
elseif (is_string($value) && isset($this->patternDataStore[$value]) && $key !== 'pattern') {
122+
$data[$key] = $this->renderPattern($value, $this->getProcessedPatternSpecificData($value));
123+
}
124+
125+
return $data;
126+
}
127+
128+
public function getProcessedPatternSpecificData($pattern, $extraData = array())
129+
{
130+
$this->processPattern($pattern);
131+
132+
return Data::getPatternSpecificData($pattern, $extraData);
133+
}
134+
135+
protected function renderPattern($pattern, $data)
136+
{
137+
if (isset($this->patternDataStore[$pattern]['patternRaw'])) {
138+
foreach (array_keys($data) as $key) {
139+
$data = $this->cloneObjects($data, $key);
140+
}
141+
$pattern = $this->env->render(
142+
$this->patternDataStore[$pattern]['patternRaw'],
143+
$data
144+
);
145+
}
146+
147+
return $pattern;
148+
}
149+
150+
protected function cloneObjects($data, $key)
151+
{
152+
$value = $data[$key];
153+
if (is_array($value)) {
154+
foreach (array_keys($value) as $subKey) {
155+
$value = $this->cloneObjects($value, $subKey);
156+
}
157+
$data[$key] = $value;
158+
}
159+
elseif (is_object($value)) {
160+
$data[$key] = clone $value;
161+
}
162+
163+
return $data;
164+
}
165+
}

src/aleksip/DataTransformPlugin/Helper.php

Lines changed: 0 additions & 124 deletions
This file was deleted.

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
}

0 commit comments

Comments
 (0)