Skip to content

Commit 142879b

Browse files
author
Jason Smith
committed
Support multiple namespaces.
1 parent b120ccf commit 142879b

File tree

7 files changed

+185
-69
lines changed

7 files changed

+185
-69
lines changed

lib/example.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-04/schema#",
3+
"category": "atom",
4+
"title": "Example",
5+
"type": "object",
6+
"format": "grid",
7+
"properties": {
8+
"text": {
9+
"title": "Text",
10+
"type": "string",
11+
"options": {
12+
"grid_columns": 4
13+
}
14+
}
15+
}
16+
}

lib/example.twig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Test sample twig template.
2+
{{- string|striptags('')|raw -}}

patternkit.info

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,6 @@ files[] = src/PatternkitDrupalCachedLib.php
1111
files[] = src/PatternkitDrupalTwigLib.php
1212
files[] = src/PatternkitEditorConfig.php
1313
files[] = src/PatternkitLibInterface.php
14+
files[] = src/PatternkitTwigWrapper.php
1415
files[] = src/PatternkitPattern.php
1516
files[] = src/PatternkitRESTLib.php

patternkit.module

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,22 @@ function patternkit_pattern_libraries() {
8686
}
8787
}
8888

89+
// Triggers initialization of the Twig wrapper.
90+
PatternkitTwigWrapper::getInstance($libraries);
91+
92+
return $libraries;
93+
}
94+
95+
/**
96+
* Implements hook_patternkit_library().
97+
*/
98+
function patternkit_patternkit_library() {
99+
$libraries = array();
100+
101+
$module_path = drupal_get_path('module', 'patternkit');
102+
$lib_path = $module_path . DIRECTORY_SEPARATOR . 'lib';
103+
$libraries[] = new PatternkitDrupalTwigLib('Example', $lib_path);
104+
89105
return $libraries;
90106
}
91107

src/PatternkitDrupalTwigLib.php

Lines changed: 34 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ class PatternkitDrupalTwigLib extends PatternkitDrupalCachedLib {
1111

1212
private $title;
1313

14+
private $metadata;
15+
1416
/**
1517
* PatternkitDrupalTwigLib constructor.
1618
*
@@ -46,6 +48,8 @@ public function fetchPatternAssets(PatternkitPattern $pattern,
4648
/**
4749
* Returns the id of the Pattern Library.
4850
*
51+
* The id also functions as the namespace for the twig templates.
52+
*
4953
* @return string
5054
* The Pattern Library id.
5155
*/
@@ -210,14 +214,12 @@ public function getEditor($subtype = NULL,
210214
* Array of metadata objects found.
211215
*/
212216
protected function getRawMetadata() {
213-
static $metadata;
214-
215217
// Use static pattern to avoid rebuilding multiple times per request.
216-
if (is_null($metadata)) {
218+
if (is_null($this->metadata)) {
217219

218220
$it = new RecursiveDirectoryIterator($this->path);
219221
$filter = ['json', 'twig'];
220-
$metadata = [];
222+
$this->metadata = [];
221223
$components = [];
222224

223225
/** @var \SplFileInfo $file */
@@ -254,8 +256,9 @@ protected function getRawMetadata() {
254256

255257
$subtype = "pk_$module_name";
256258
$pattern->subtype = $subtype;
257-
// URL is redundant for the twig based components.
258-
$pattern->url = $module_name;
259+
// URL is redundant for the twig based components, so we use it to
260+
// store namespace.
261+
$pattern->url = $this->getId();
259262
}
260263
else {
261264
// Create the pattern from defaults.
@@ -273,31 +276,30 @@ protected function getRawMetadata() {
273276
}
274277

275278
if (!empty($data['twig'])) {
276-
$twig_file = $data['twig']
277-
. DIRECTORY_SEPARATOR . $module_name . '.twig';
279+
$twig_file = $data['twig'];
278280
if (file_exists($twig_file)) {
279281
$pattern->filename = $twig_file;
280282
$pattern->template = file_get_contents($twig_file);
281283
}
282284
}
283285

284-
$metadata[$module_name] = $pattern;
286+
$this->metadata[$module_name] = $pattern;
285287
}
286288

287-
foreach ($metadata as $pattern_type => $pattern) {
289+
foreach ($this->metadata as $pattern_type => $pattern) {
288290
// Replace any $ref links with relative paths.
289291
if (!isset($pattern->schema->properties)) {
290292
continue;
291293
}
292294
$pattern->schema->properties = _patternkit_schema_ref(
293295
$pattern->schema->properties,
294-
$metadata
296+
$this->metadata
295297
);
296-
$metadata[$pattern_type] = $pattern;
298+
$this->metadata[$pattern_type] = $pattern;
297299
}
298300
}
299301

300-
return $metadata;
302+
return $this->metadata;
301303
}
302304

303305
/**
@@ -321,55 +323,11 @@ public function getRenderedPatternMarkup(
321323
$template = $pattern->filename;
322324
$variables = $config->fields;
323325

324-
return $this->renderTwigTemplate($template, $variables);
325-
}
326-
327-
/**
328-
* Returns a singleton version of the twig template engine.
329-
*
330-
* @return Twig_Environment
331-
* Twig environment object.
332-
*
333-
* @throws \Twig_Error_Loader
334-
* Twig engine instance object.
335-
*/
336-
public function getTwigInstance() {
337-
static $twig_engine;
338-
339-
if (!is_object($twig_engine)) {
340-
// Setup twig environment.
341-
// @TODO: Properly libraryize this.
342-
require_once DRUPAL_ROOT . '/sites/all/libraries/Twig/Autoloader.php';
343-
Twig_Autoloader::register();
344-
345-
$loader = new Twig_Loader_Filesystem();
346-
347-
$metadata = $this->getRawMetadata();
348-
foreach ($metadata as $module_name => $module) {
349-
if (!empty($module->filename)) {
350-
$templatesDirectory = DRUPAL_ROOT . DIRECTORY_SEPARATOR . dirname(
351-
$module->filename
352-
);
353-
354-
// Namespacing is not necessary here, as each "engine" is unique to
355-
// the "library".
356-
$loader->addPath($templatesDirectory);
357-
}
358-
}
359-
360-
$twig_engine = new Twig_Environment(
361-
$loader,
362-
array(
363-
'autorender' => (bool) variable_get('pktwig_auto_render', TRUE),
364-
'autoescape' => (bool) variable_get('pktwig_auto_escape', FALSE),
365-
'auto_reload' => (bool) variable_get('pktwig_auto_reload', FALSE),
366-
'cache' => variable_get('pktwig_template_cache_path', '/tmp/twig_compilation_cache'),
367-
'debug' => (bool) variable_get('pktwig_debug', FALSE),
368-
)
369-
);
326+
// Add the namespace, if provided.
327+
if (!empty($pattern->url)) {
328+
$template = '@' . $pattern->url . '#/' . $template;
370329
}
371-
372-
return $twig_engine;
330+
return $this->renderTwigTemplate($template, $variables);
373331
}
374332

375333
/**
@@ -385,18 +343,27 @@ public function getTwigInstance() {
385343
*/
386344
public function renderTwigTemplate($template, array $variables = array()) {
387345

388-
$content = '';
389-
if (file_exists($template)) {
346+
$namespace = '';
347+
$file = $template;
348+
349+
// If a namespace is provided, break it up.
350+
if ($template[0] == '@') {
351+
list($namespace, $file) = explode('#', $template);
352+
}
353+
354+
try {
355+
$bare = basename($file);
356+
390357
try {
391-
$twig = $this->getTwigInstance();
392-
$template = $twig->loadTemplate(basename($template));
358+
$twig = PatternkitTwigWrapper::getInstance()->getTwigInstance();
359+
$template = $twig->loadTemplate("$namespace/$bare");
393360
$content = $template->render($variables);
394361
}
395362
catch (Exception $e) {
396363
$content = t(
397364
'Twig error (!exc} "!error"',
398365
array(
399-
'!exc' => 'tst',
366+
'!exc' => get_class($e),
400367
'!error' => $e->getMessage(),
401368
)
402369
);
@@ -410,7 +377,7 @@ public function renderTwigTemplate($template, array $variables = array()) {
410377
);
411378
}
412379
}
413-
else {
380+
catch (Exception $e) {
414381
$content = t(
415382
'Template (!template) not found',
416383
array(

src/PatternkitPattern.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,9 @@ public function __construct(PatternkitLibInterface $library, $schema = array())
5252
/**
5353
* The subtype for the pattern. Typically "pk_$pattern".
5454
*
55-
* @var string
55+
* Must be unique across the site. Is used by Panels to address config, etc.
5656
*
57-
* This is mostly in use with Drupal to avoid panels namespace conflicts.
57+
* @var string
5858
*/
5959
public $subtype;
6060

src/PatternkitTwigWrapper.php

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
<?php
2+
/**
3+
* @file
4+
* customer-portal-kbase-copy
5+
*
6+
* - Created by jassmith on 2/2/18
7+
*/
8+
9+
class PatternkitTwigWrapper {
10+
11+
protected $metadata;
12+
protected $libraries;
13+
protected $twigEngine;
14+
15+
/**
16+
* PatternkitTwigWrapper constructor.
17+
*
18+
* @param array $libraries
19+
* The collection of patterns and metadata.
20+
*
21+
* @return PatternkitTwigWrapper
22+
* Returns the singleton PatternkitTwigWrapper.
23+
*/
24+
public static function getInstance(array $libraries = NULL) {
25+
static $instance;
26+
27+
if (empty($instance)) {
28+
$instance = new static($libraries);
29+
}
30+
31+
return $instance;
32+
}
33+
34+
/**
35+
* PatternkitTwigWrapper constructor.
36+
*
37+
* @param array $libraries
38+
* The collection of patterns and metadata.
39+
*/
40+
protected function __construct(array $libraries) {
41+
if (empty($libraries)) {
42+
watchdog('patternkit', 'Metadata not passed to constructor for patternTwig', WATCHDOG_ERROR);
43+
}
44+
45+
$this->libraries = $libraries;
46+
47+
// Collect all metadata.
48+
$this->metadata = [];
49+
50+
foreach ($libraries as $library) {
51+
$meta = $library->getCachedMetadata();
52+
$this->metadata = array_merge($this->metadata, $meta);
53+
}
54+
55+
// Setup twig environment.
56+
// @TODO: Properly libraryize this.
57+
require_once DRUPAL_ROOT . '/sites/all/libraries/Twig/Autoloader.php';
58+
Twig_Autoloader::register();
59+
60+
$loader = new Twig_Loader_Filesystem();
61+
62+
foreach ($this->metadata as $module_name => $module) {
63+
if (!empty($module->filename)) {
64+
$templatesDirectory = DRUPAL_ROOT . DIRECTORY_SEPARATOR . dirname(
65+
$module->filename
66+
);
67+
68+
// We put the namespace into the url, since it's otherwise unused
69+
// and serves a similar purpose.
70+
try {
71+
$loader->addPath($templatesDirectory, $module->url);
72+
73+
// To support empty namespaces (for now)
74+
$loader->addPath($templatesDirectory);
75+
}
76+
catch (Twig_Error_Loader $e) {
77+
drupal_set_message("Error loading $templatesDirectory", 'warning');
78+
watchdog(
79+
'patternkit',
80+
'Error loading @module',
81+
['@module' => $templatesDirectory],
82+
WATCHDOG_WARNING
83+
);
84+
}
85+
}
86+
}
87+
88+
$this->twigEngine = new Twig_Environment(
89+
$loader,
90+
array(
91+
'autorender' => (bool) variable_get('pktwig_auto_render', TRUE),
92+
'autoescape' => (bool) variable_get('pktwig_auto_escape', FALSE),
93+
'auto_reload' => (bool) variable_get('pktwig_auto_reload', FALSE),
94+
'cache' => variable_get('pktwig_template_cache_path', '/tmp/twig_compilation_cache'),
95+
'debug' => (bool) variable_get('pktwig_debug', FALSE),
96+
)
97+
);
98+
99+
}
100+
101+
/**
102+
* Returns a singleton version of the twig template engine.
103+
*
104+
* @return Twig_Environment
105+
* Twig environment object.
106+
*
107+
* @throws \Twig_Error_Loader
108+
* Twig engine instance object.
109+
*/
110+
public function getTwigInstance() {
111+
return $this->twigEngine;
112+
}
113+
114+
}

0 commit comments

Comments
 (0)