Skip to content

Commit e3adc32

Browse files
committed
All the things
1 parent 812b8ef commit e3adc32

11 files changed

+486
-1
lines changed

.editorconfig

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
root = true
2+
3+
[*]
4+
indent_style = tab
5+
indent_size = 4
6+
charset = utf-8
7+
end_of_line = lf
8+
insert_final_newline = true
9+
trim_trailing_whitespace = true
10+
11+
[*.{yml, json}]
12+
indent_style = space
13+
indent_size = 2
14+
15+
[*.md]
16+
trim_trailing_whitespace = false

.gitattributes

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
README.md export-ignore
2+
CHANGELOG.md export-ignore
3+
/resources export-ignore
4+
.gitignore export-ignore
5+
.gitattributes export-ignore
6+
.editorconfig export-ignore
7+
/docs export-ignore
8+
docker-compose.yml export-ignore

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.idea

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
## 1.0.0 - 2020-02-12
2+
- Initial release 🎉

README.md

+103-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,104 @@
1-
# atom
1+
# Atom
22
Adding enhanced modularity to Craft CMS Twig templating
3+
4+
## Installation
5+
6+
```shell
7+
$ composer require ether/atom
8+
```
9+
10+
## Usage
11+
12+
Create a folder called `_atoms` in your `templates` directory (this can be
13+
customised, see [Config](#config)).
14+
15+
### Basic
16+
17+
In this folder you can create re-usable twig templates, or atoms (a.k.a.
18+
modules, components, molecules). You can access the atoms in twig using the
19+
following syntax:
20+
21+
```twig
22+
{% x:my-atom %}
23+
```
24+
25+
The above will include `_atoms/my-atom` in your template. If `my-atom`
26+
doesn't exist then nothing will be output.
27+
28+
### Parameters
29+
30+
You can pass parameters to your atom which will be exposed within the atom. The
31+
current template context is NOT passed to the atom, so any global variables will
32+
have to be passed manually.
33+
34+
```twig
35+
{% x:my-atom { heading: "Hello world!" } %}
36+
```
37+
38+
In the above example, `my-atom` will be given access to the `heading` variable.
39+
If `heading` isn't passed then the variable will be undefined. You'll want to
40+
check variable availability with `is defined` or `|default`.
41+
42+
### Children
43+
44+
Children can also be passed to atoms:
45+
46+
```twig
47+
{% x:my-atom { heading: "Hello world!" } %}
48+
<p>This is my atom</p>
49+
<p>There are many like it, but this is mine</p>
50+
<p>{{ myVariable }}</p>
51+
{% endx %}
52+
```
53+
54+
Children are rendered in the parent context, not the atoms. This means any
55+
variables you pass to the atom will not be available in the children (unless
56+
they are also available in the parent context).
57+
58+
Children are rendered within the atom using the `children` variable, which will
59+
contain the rendered contents of the children or `null` if no children are
60+
defined.
61+
62+
```twig
63+
{# Contents of `_atoms/my-atom` #}
64+
<div>
65+
<h1>{{ heading }}</h1>
66+
{{ children }}
67+
</div>
68+
```
69+
70+
### Nested
71+
72+
Atoms can be nested inside other atoms!
73+
74+
```twig
75+
{% x:my-atom %}
76+
{% x:another-atom %}
77+
{% endx %}
78+
```
79+
80+
### Sub-folders
81+
82+
You can store atoms in folders within your `_atoms` directory. For example, if
83+
you had an atom at `_atoms/cards/news`, you could access it using the following
84+
syntax:
85+
86+
```twig
87+
{% x:cards/news %}
88+
```
89+
90+
### Dynamic Atoms
91+
92+
You can render atoms with dynamic names by wrapping the atom name in square
93+
brackets:
94+
95+
```twig
96+
{% set myVar = 'example-atom' %}
97+
98+
{% x:[myVar] %}
99+
```
100+
101+
## Config
102+
103+
You can configure Atom by creating a `atom.php` file in your `config` folder.
104+
See [config.php](./src/config.php) for the available settings.

composer.json

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"name": "ether/atom",
3+
"description": "Adding enhanced modularity to Craft CMS Twig templating",
4+
"version": "1.0.0",
5+
"type": "craft-plugin",
6+
"license": "MIT",
7+
"minimum-stability": "dev",
8+
"require": {
9+
"craftcms/cms": "^3.5.0"
10+
},
11+
"autoload": {
12+
"psr-4": {
13+
"ether\\atom\\": "src/"
14+
}
15+
},
16+
"support": {
17+
"email": "[email protected]",
18+
"docs": "https://docs.ethercreative.co.uk/atom",
19+
"source": "https://github.com/ethercreative/atom",
20+
"issues": "https://github.com/ethercreative/atom/issues"
21+
},
22+
"extra": {
23+
"handle": "atom",
24+
"name": "Atom",
25+
"developer": "Ether Creative",
26+
"developerUrl": "https://ethercreative.co.uk",
27+
28+
"class": "ether\\atom\\Atom",
29+
"schemaVersion": "1.0.0"
30+
}
31+
}

src/Atom.php

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<?php
2+
3+
namespace ether\atom;
4+
5+
use Craft;
6+
use craft\base\Plugin;
7+
use ether\atom\web\twig\Extension;
8+
use Twig\Error\LoaderError;
9+
use Twig\Error\RuntimeError;
10+
use Twig\Error\SyntaxError;
11+
use Twig\Markup;
12+
use yii\base\Exception;
13+
14+
class Atom extends Plugin
15+
{
16+
17+
private static $_config = [];
18+
19+
public function init ()
20+
{
21+
parent::init();
22+
23+
self::$_config = require __DIR__ . '/config.php';
24+
if (file_exists(CRAFT_BASE_PATH . '/config/atom.php'))
25+
{
26+
self::$_config = array_merge(
27+
self::$_config,
28+
require CRAFT_BASE_PATH . '/config/atom.php'
29+
);
30+
}
31+
32+
Craft::$app->getView()->registerTwigExtension(
33+
new Extension()
34+
);
35+
}
36+
37+
/**
38+
* Renders an atom
39+
*
40+
* @param string $handle
41+
* @param array $variables
42+
* @param string|null $children
43+
*
44+
* @throws Exception
45+
* @throws LoaderError
46+
* @throws RuntimeError
47+
* @throws SyntaxError
48+
*/
49+
public static function renderAtom (
50+
string $handle,
51+
array $variables = [],
52+
string $children = null
53+
) : void {
54+
$view = Craft::$app->getView();
55+
56+
$template = self::$_config['atoms'] . '/' . $handle;
57+
58+
$variables['children'] = new Markup($children, 'utf8');
59+
60+
if (!$view->doesTemplateExist($template))
61+
{
62+
Craft::error(
63+
"Error locating template: {$template}",
64+
__METHOD__
65+
);
66+
67+
return;
68+
}
69+
70+
echo $view->renderTemplate($template, $variables);
71+
}
72+
73+
}

src/config.php

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
return [
4+
/**
5+
* ### Atoms Root
6+
*
7+
* _Defaults to `_atoms`_
8+
*
9+
* The location of your atoms, relative to your `templates` directory.
10+
*/
11+
'atoms' => '_atoms',
12+
];

src/web/twig/Extension.php

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
namespace ether\atom\web\twig;
4+
5+
use ether\atom\web\twig\tokenparsers\AtomTokenParser;
6+
use Twig\Extension\AbstractExtension;
7+
8+
class Extension extends AbstractExtension
9+
{
10+
11+
public function getTokenParsers (): array
12+
{
13+
return [
14+
new AtomTokenParser(),
15+
];
16+
}
17+
18+
}

src/web/twig/nodes/AtomNode.php

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
namespace ether\atom\web\twig\nodes;
4+
5+
use ether\atom\Atom;
6+
use Twig\Compiler;
7+
use Twig\Node\Expression\ArrayExpression;
8+
use Twig\Node\Node;
9+
use Twig\Node\NodeCaptureInterface;
10+
11+
class AtomNode extends Node implements NodeCaptureInterface
12+
{
13+
14+
public function compile (Compiler $compiler)
15+
{
16+
$isVariableName = $this->getAttribute('isVariableName');
17+
$handle = $this->getAttribute('handle');
18+
/** @var ArrayExpression $data */
19+
$data = $this->getAttribute('data');
20+
$value = $this->getNode('value');
21+
22+
$compiler
23+
->addDebugInfo($this)
24+
->write('ob_start();' . PHP_EOL)
25+
->subcompile($value)
26+
->write(Atom::class . '::renderAtom(');
27+
28+
if ($isVariableName)
29+
$compiler->subcompile($handle);
30+
else
31+
$compiler->write('\'' . $handle . '\'');
32+
33+
$compiler
34+
->write(', ')
35+
->raw($data->compile($compiler) . ', ')
36+
->raw('ob_get_clean());' . PHP_EOL);
37+
}
38+
39+
}

0 commit comments

Comments
 (0)