diff --git a/.editorconfig b/.editorconfig
index 4e745fa..6cd346f 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -12,6 +12,7 @@ end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = tab
+indent_size = 4
[*.json]
indent_style = space
diff --git a/timber-wp-acf-blocks.png b/.github/assets/timber-wp-acf-blocks.png
similarity index 100%
rename from timber-wp-acf-blocks.png
rename to .github/assets/timber-wp-acf-blocks.png
diff --git a/.gitignore b/.gitignore
index 5657f6e..57872d0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1 @@
-vendor
\ No newline at end of file
+/vendor/
diff --git a/readme.md b/README.md
similarity index 94%
rename from readme.md
rename to README.md
index 5437269..82a744f 100644
--- a/readme.md
+++ b/README.md
@@ -1,15 +1,19 @@
-
+
# Timber ACF WP Blocks
+
Generate ACF Gutenberg blocks just by adding templates to your Timber theme. This package is based heavily on [this article](https://medium.com/nicooprat/acf-blocks-avec-gutenberg-et-sage-d8c20dab6270) by [nicoprat](https://github.com/nicooprat) and the [plugin](https://github.com/MWDelaney/sage-acf-wp-blocks) by [MWDelaney](https://github.com/MWDelaney).
## Complete documentation
+
[Read the complete documentation](https://palmiak.github.io/timber-acf-wp-blocks/#/)
## Contributors
+
This plugin is build with help of contributors:
+
- [roylodder](https://github.com/roylodder)
- [BrentWMiller](https://github.com/BrentWMiller)
- [Marcin Krzemiński](https://github.com/marcinkrzeminski)
@@ -17,9 +21,10 @@ This plugin is build with help of contributors:
- [LandWire](https://github.com/landwire)
- [Viktor Szépe](https://github.com/szepeviktor)
-
## Creating blocks
+
Add twig templates to `views/blocks` which get and use ACF data. Each template requires a comment block with some data in it:
+
```twig
{#
Title: Testimonial
@@ -51,4 +56,5 @@ Add twig templates to `views/blocks` which get and use ACF data. Each template r
```
## Timber 2.0
+
**Timber ACF WP Blocks** is fully compatible with both **Timber 1.x** and **Timber 2.x** versions.
diff --git a/composer.json b/composer.json
index de5ebc7..171f89c 100644
--- a/composer.json
+++ b/composer.json
@@ -23,7 +23,12 @@
"files": ["timber-acf-wp-blocks.php"]
},
"require-dev": {
- "wp-coding-standards/wpcs": "2.0",
- "dealerdirect/phpcodesniffer-composer-installer": "0.5.0"
+ "wp-coding-standards/wpcs": "^2.0",
+ "dealerdirect/phpcodesniffer-composer-installer": "^1.0"
+ },
+ "config": {
+ "allow-plugins": {
+ "dealerdirect/phpcodesniffer-composer-installer": true
+ }
}
}
diff --git a/composer.lock b/composer.lock
index ad7c913..d8286a2 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,178 +4,43 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "e98098e95e80b3d5cd0e53706a186313",
- "packages": [
- {
- "name": "composer/installers",
- "version": "v1.9.0",
- "source": {
- "type": "git",
- "url": "https://github.com/composer/installers.git",
- "reference": "b93bcf0fa1fccb0b7d176b0967d969691cd74cca"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/composer/installers/zipball/b93bcf0fa1fccb0b7d176b0967d969691cd74cca",
- "reference": "b93bcf0fa1fccb0b7d176b0967d969691cd74cca",
- "shasum": ""
- },
- "require": {
- "composer-plugin-api": "^1.0 || ^2.0"
- },
- "replace": {
- "roundcube/plugin-installer": "*",
- "shama/baton": "*"
- },
- "require-dev": {
- "composer/composer": "1.6.* || 2.0.*@dev",
- "composer/semver": "1.0.* || 2.0.*@dev",
- "phpunit/phpunit": "^4.8.36",
- "sebastian/comparator": "^1.2.4",
- "symfony/process": "^2.3"
- },
- "type": "composer-plugin",
- "extra": {
- "class": "Composer\\Installers\\Plugin",
- "branch-alias": {
- "dev-master": "1.0-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Composer\\Installers\\": "src/Composer/Installers"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Kyle Robinson Young",
- "email": "kyle@dontkry.com",
- "homepage": "https://github.com/shama"
- }
- ],
- "description": "A multi-framework Composer library installer",
- "homepage": "https://composer.github.io/installers/",
- "keywords": [
- "Craft",
- "Dolibarr",
- "Eliasis",
- "Hurad",
- "ImageCMS",
- "Kanboard",
- "Lan Management System",
- "MODX Evo",
- "MantisBT",
- "Mautic",
- "Maya",
- "OXID",
- "Plentymarkets",
- "Porto",
- "RadPHP",
- "SMF",
- "Thelia",
- "Whmcs",
- "WolfCMS",
- "agl",
- "aimeos",
- "annotatecms",
- "attogram",
- "bitrix",
- "cakephp",
- "chef",
- "cockpit",
- "codeigniter",
- "concrete5",
- "croogo",
- "dokuwiki",
- "drupal",
- "eZ Platform",
- "elgg",
- "expressionengine",
- "fuelphp",
- "grav",
- "installer",
- "itop",
- "joomla",
- "known",
- "kohana",
- "laravel",
- "lavalite",
- "lithium",
- "magento",
- "majima",
- "mako",
- "mediawiki",
- "modulework",
- "modx",
- "moodle",
- "osclass",
- "phpbb",
- "piwik",
- "ppi",
- "puppet",
- "pxcms",
- "reindex",
- "roundcube",
- "shopware",
- "silverstripe",
- "sydes",
- "sylius",
- "symfony",
- "typo3",
- "wordpress",
- "yawik",
- "zend",
- "zikula"
- ],
- "funding": [
- {
- "url": "https://packagist.com",
- "type": "custom"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/composer/composer",
- "type": "tidelift"
- }
- ],
- "time": "2020-04-07T06:57:05+00:00"
- }
- ],
+ "content-hash": "4ed2d785c392adbaa25af80df7d7ae4d",
+ "packages": [],
"packages-dev": [
{
"name": "dealerdirect/phpcodesniffer-composer-installer",
- "version": "v0.5.0",
+ "version": "v1.0.0",
"source": {
"type": "git",
- "url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git",
- "reference": "e749410375ff6fb7a040a68878c656c2e610b132"
+ "url": "https://github.com/PHPCSStandards/composer-installer.git",
+ "reference": "4be43904336affa5c2f70744a348312336afd0da"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/e749410375ff6fb7a040a68878c656c2e610b132",
- "reference": "e749410375ff6fb7a040a68878c656c2e610b132",
+ "url": "https://api.github.com/repos/PHPCSStandards/composer-installer/zipball/4be43904336affa5c2f70744a348312336afd0da",
+ "reference": "4be43904336affa5c2f70744a348312336afd0da",
"shasum": ""
},
"require": {
- "composer-plugin-api": "^1.0",
- "php": "^5.3|^7",
- "squizlabs/php_codesniffer": "^2|^3"
+ "composer-plugin-api": "^1.0 || ^2.0",
+ "php": ">=5.4",
+ "squizlabs/php_codesniffer": "^2.0 || ^3.1.0 || ^4.0"
},
"require-dev": {
"composer/composer": "*",
+ "ext-json": "*",
+ "ext-zip": "*",
+ "php-parallel-lint/php-parallel-lint": "^1.3.1",
"phpcompatibility/php-compatibility": "^9.0",
- "sensiolabs/security-checker": "^4.1.0"
+ "yoast/phpunit-polyfills": "^1.0"
},
"type": "composer-plugin",
"extra": {
- "class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin"
+ "class": "PHPCSStandards\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin"
},
"autoload": {
"psr-4": {
- "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/"
+ "PHPCSStandards\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -188,6 +53,10 @@
"email": "franck.nijhof@dealerdirect.com",
"homepage": "http://www.frenck.nl",
"role": "Developer / IT Manager"
+ },
+ {
+ "name": "Contributors",
+ "homepage": "https://github.com/PHPCSStandards/composer-installer/graphs/contributors"
}
],
"description": "PHP_CodeSniffer Standards Composer Installer Plugin",
@@ -199,6 +68,7 @@
"codesniffer",
"composer",
"installer",
+ "phpcbf",
"phpcs",
"plugin",
"qa",
@@ -209,20 +79,24 @@
"stylecheck",
"tests"
],
- "time": "2018-10-26T13:21:45+00:00"
+ "support": {
+ "issues": "https://github.com/PHPCSStandards/composer-installer/issues",
+ "source": "https://github.com/PHPCSStandards/composer-installer"
+ },
+ "time": "2023-01-05T11:28:13+00:00"
},
{
"name": "squizlabs/php_codesniffer",
- "version": "3.5.8",
+ "version": "3.7.2",
"source": {
"type": "git",
"url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
- "reference": "9d583721a7157ee997f235f327de038e7ea6dac4"
+ "reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/9d583721a7157ee997f235f327de038e7ea6dac4",
- "reference": "9d583721a7157ee997f235f327de038e7ea6dac4",
+ "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/ed8e00df0a83aa96acf703f8c2979ff33341f879",
+ "reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879",
"shasum": ""
},
"require": {
@@ -258,22 +132,28 @@
"homepage": "https://github.com/squizlabs/PHP_CodeSniffer",
"keywords": [
"phpcs",
- "standards"
+ "standards",
+ "static analysis"
],
- "time": "2020-10-23T02:01:07+00:00"
+ "support": {
+ "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues",
+ "source": "https://github.com/squizlabs/PHP_CodeSniffer",
+ "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki"
+ },
+ "time": "2023-02-22T23:07:41+00:00"
},
{
"name": "wp-coding-standards/wpcs",
- "version": "2.0.0",
+ "version": "2.3.0",
"source": {
"type": "git",
"url": "https://github.com/WordPress/WordPress-Coding-Standards.git",
- "reference": "c9eaadaafefce36b3cb7e06eb15305b8c4cae9ce"
+ "reference": "7da1894633f168fe244afc6de00d141f27517b62"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/WordPress/WordPress-Coding-Standards/zipball/c9eaadaafefce36b3cb7e06eb15305b8c4cae9ce",
- "reference": "c9eaadaafefce36b3cb7e06eb15305b8c4cae9ce",
+ "url": "https://api.github.com/repos/WordPress/WordPress-Coding-Standards/zipball/7da1894633f168fe244afc6de00d141f27517b62",
+ "reference": "7da1894633f168fe244afc6de00d141f27517b62",
"shasum": ""
},
"require": {
@@ -281,12 +161,13 @@
"squizlabs/php_codesniffer": "^3.3.1"
},
"require-dev": {
- "dealerdirect/phpcodesniffer-composer-installer": "^0.5.0",
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.5 || ^0.6",
"phpcompatibility/php-compatibility": "^9.0",
+ "phpcsstandards/phpcsdevtools": "^1.0",
"phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0"
},
"suggest": {
- "dealerdirect/phpcodesniffer-composer-installer": "^0.4.3 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically."
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.6 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically."
},
"type": "phpcodesniffer-standard",
"notification-url": "https://packagist.org/downloads/",
@@ -296,7 +177,7 @@
"authors": [
{
"name": "Contributors",
- "homepage": "https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/graphs/contributors"
+ "homepage": "https://github.com/WordPress/WordPress-Coding-Standards/graphs/contributors"
}
],
"description": "PHP_CodeSniffer rules (sniffs) to enforce WordPress coding conventions",
@@ -305,7 +186,12 @@
"standards",
"wordpress"
],
- "time": "2019-01-16T10:13:16+00:00"
+ "support": {
+ "issues": "https://github.com/WordPress/WordPress-Coding-Standards/issues",
+ "source": "https://github.com/WordPress/WordPress-Coding-Standards",
+ "wiki": "https://github.com/WordPress/WordPress-Coding-Standards/wiki"
+ },
+ "time": "2020-05-13T23:57:56+00:00"
}
],
"aliases": [],
@@ -317,5 +203,5 @@
"php": ">=5.6"
},
"platform-dev": [],
- "plugin-api-version": "1.1.0"
+ "plugin-api-version": "2.3.0"
}
diff --git a/inc/class-timber-acf-wp-blocks.php b/inc/class-timber-acf-wp-blocks.php
new file mode 100644
index 0000000..6437d08
--- /dev/null
+++ b/inc/class-timber-acf-wp-blocks.php
@@ -0,0 +1,386 @@
+Timber ACF WP Blocks requires Timber and ACF.';
+ echo 'Check if the plugins or libraries are installed and activated.
';
+ }
+ );
+ }
+ }
+
+ /**
+ * Create blocks based on templates found in Timber's "views/blocks" directory
+ */
+ public static function timber_block_init() {
+ // Get an array of directories containing blocks.
+ $directories = self::timber_block_directory_getter();
+
+ // Check whether ACF exists before continuing.
+ foreach ( $directories as $dir ) {
+ // Sanity check whether the directory we're iterating over exists first.
+ if ( ! file_exists( \locate_template( $dir ) ) ) {
+ continue;
+ }
+
+ // Iterate over the directories provided and look for templates.
+ $template_directory = new DirectoryIterator( \locate_template( $dir ) );
+ foreach ( $template_directory as $template ) {
+
+ if ( $template->isDot() || $template->isDir() ) {
+ continue;
+ }
+
+ $file_parts = pathinfo( $template->getFilename() );
+ if ( 'twig' !== $file_parts['extension'] ) {
+ continue;
+ }
+
+ // Strip the file extension to get the slug.
+ $slug = $file_parts['filename'];
+
+ // Get header info from the found template file(s).
+ $file_path = locate_template( $dir . "/${slug}.twig" );
+ $file_headers = get_file_data(
+ $file_path,
+ array(
+ 'title' => 'Title',
+ 'description' => 'Description',
+ 'category' => 'Category',
+ 'icon' => 'Icon',
+ 'keywords' => 'Keywords',
+ 'mode' => 'Mode',
+ 'align' => 'Align',
+ 'post_types' => 'PostTypes',
+ 'supports_align' => 'SupportsAlign',
+ 'supports_align_content' => 'SupportsAlignContent',
+ 'supports_mode' => 'SupportsMode',
+ 'supports_multiple' => 'SupportsMultiple',
+ 'supports_anchor' => 'SupportsAnchor',
+ 'enqueue_style' => 'EnqueueStyle',
+ 'enqueue_script' => 'EnqueueScript',
+ 'enqueue_assets' => 'EnqueueAssets',
+ 'supports_custom_class_name' => 'SupportsCustomClassName',
+ 'supports_reusable' => 'SupportsReusable',
+ 'supports_full_height' => 'SupportsFullHeight',
+ 'example' => 'Example',
+ 'supports_jsx' => 'SupportsJSX',
+ 'parent' => 'Parent',
+ 'default_data' => 'DefaultData',
+ )
+ );
+
+ if ( empty( $file_headers['title'] ) || empty( $file_headers['category'] ) ) {
+ continue;
+ }
+
+ // Keywords exploding with quotes.
+ $keywords = str_getcsv( $file_headers['keywords'], ' ', '"' );
+
+ // Set up block data for registration.
+ $data = array(
+ 'name' => $slug,
+ 'title' => $file_headers['title'],
+ 'description' => $file_headers['description'],
+ 'category' => $file_headers['category'],
+ 'icon' => $file_headers['icon'],
+ 'keywords' => $keywords,
+ 'mode' => $file_headers['mode'],
+ 'align' => $file_headers['align'],
+ 'render_callback' => array( __CLASS__, 'timber_blocks_callback' ),
+ 'enqueue_assets' => $file_headers['enqueue_assets'],
+ 'default_data' => $file_headers['default_data'],
+ );
+
+ // Removes empty defaults.
+ $data = array_filter( $data );
+
+ // If the PostTypes header is set in the template, restrict this block
+ // to those types.
+ if ( ! empty( $file_headers['post_types'] ) ) {
+ $data['post_types'] = explode( ' ', $file_headers['post_types'] );
+ }
+ // If the SupportsAlign header is set in the template, restrict this block
+ // to those aligns.
+ if ( ! empty( $file_headers['supports_align'] ) ) {
+ $data['supports']['align'] =
+ in_array( $file_headers['supports_align'], array( 'true', 'false' ), true ) ?
+ filter_var( $file_headers['supports_align'], FILTER_VALIDATE_BOOLEAN ) :
+ explode( ' ', $file_headers['supports_align'] );
+ }
+ // If the SupportsAlignContent header is set in the template, restrict this block
+ // to those aligns.
+ if ( ! empty( $file_headers['supports_align_content'] ) ) {
+ $data['supports']['alignContent'] =
+ ('true' === $file_headers['supports_align_content'])
+ ? true
+ : ('matrix' === $file_headers['supports_align_content'] ? 'matrix' : false);
+ }
+ // If the SupportsMode header is set in the template, restrict this block
+ // mode feature.
+ if ( ! empty( $file_headers['supports_mode'] ) ) {
+ $data['supports']['mode'] = 'true' === $file_headers['supports_mode'];
+ }
+ // If the SupportsMultiple header is set in the template, restrict this block
+ // multiple feature.
+ if ( ! empty( $file_headers['supports_multiple'] ) ) {
+ $data['supports']['multiple'] = 'true' === $file_headers['supports_multiple'];
+ }
+ // If the SupportsAnchor header is set in the template, restrict this block
+ // anchor feature.
+ if ( ! empty( $file_headers['supports_anchor'] ) ) {
+ $data['supports']['anchor'] = 'true' === $file_headers['supports_anchor'];
+ }
+
+ // If the SupportsCustomClassName is set to false hides the possibilty to
+ // add custom class name.
+ if ( ! empty( $file_headers['supports_custom_class_name'] ) ) {
+ $data['supports']['customClassName'] = 'true' === $file_headers['supports_custom_class_name'];
+ }
+
+ // If the SupportsReusable is set in the templates it adds a posibility to
+ // make this block reusable.
+ if ( ! empty( $file_headers['supports_reusable'] ) ) {
+ $data['supports']['reusable'] = 'true' === $file_headers['supports_reusable'];
+ }
+
+ // If the SupportsFullHeight is set in the templates it adds a posibility to
+ // make this block full height.
+ if ( ! empty( $file_headers['supports_full_height'] ) ) {
+ $data['supports']['full_height'] = 'true' === $file_headers['supports_full_height'];
+ }
+
+ // Gives a possibility to enqueue style. If not an absoulte URL than adds
+ // theme directory.
+ if ( ! empty( $file_headers['enqueue_style'] ) ) {
+ if ( ! filter_var( $file_headers['enqueue_style'], FILTER_VALIDATE_URL ) ) {
+ $data['enqueue_style'] =
+ get_template_directory_uri() . '/' . $file_headers['enqueue_style'];
+ } else {
+ $data['enqueue_style'] = $file_headers['enqueue_style'];
+ }
+ }
+
+ // Gives a possibility to enqueue script. If not an absoulte URL than adds
+ // theme directory.
+ if ( ! empty( $file_headers['enqueue_script'] ) ) {
+ if ( ! filter_var( $file_headers['enqueue_script'], FILTER_VALIDATE_URL ) ) {
+ $data['enqueue_script'] =
+ get_template_directory_uri() . '/' . $file_headers['enqueue_script'];
+ } else {
+ $data['enqueue_script'] = $file_headers['enqueue_script'];
+ }
+ }
+
+ // Support for experimantal JSX.
+ if ( ! empty( $file_headers['supports_jsx'] ) ) {
+ // Leaving the experimaental part for 2 versions.
+ $data['supports']['__experimental_jsx'] = 'true' === $file_headers['supports_jsx'];
+ $data['supports']['jsx'] = 'true' === $file_headers['supports_jsx'];
+ }
+
+ // Support for "example".
+ if ( ! empty( $file_headers['example'] ) ) {
+ $json = json_decode( $file_headers['example'], true );
+ $example_data = null === $json ? array() : $json;
+ $example_data['is_example'] = true;
+ $data['example'] = array(
+ 'attributes' => array(
+ 'mode' => 'preview',
+ 'data' => $example_data,
+ ),
+ );
+ }
+
+ // Support for "parent".
+ if ( ! empty( $file_headers['parent'] ) ) {
+ $data['parent'] = str_getcsv( $file_headers['parent'], ' ', '"' );
+ }
+
+ // Merges the default options.
+ $data = self::timber_block_default_data( $data );
+
+ // Register the block with ACF.
+ acf_register_block_type( $data );
+ }
+ }
+ }
+
+ /**
+ * Callback to register blocks
+ *
+ * @param array $block stores all the data from ACF.
+ * @param string $content content passed to block.
+ * @param bool $is_preview checks if block is in preview mode.
+ * @param int $post_id Post ID.
+ */
+ public static function timber_blocks_callback( $block, $content = '', $is_preview = false, $post_id = 0 ) {
+ // Context compatibility.
+ if ( method_exists( 'Timber', 'context' ) ) {
+ $context = Timber::context();
+ } else {
+ $context = Timber::get_context();
+ }
+
+ // Set up the slug to be useful.
+ $slug = str_replace( 'acf/', '', $block['name'] );
+
+ $context['block'] = $block;
+ $context['post_id'] = $post_id;
+ $context['slug'] = $slug;
+ $context['is_preview'] = $is_preview;
+ $context['fields'] = \get_fields();
+ $classes = array_merge(
+ array( $slug ),
+ isset( $block['className'] ) ? array( $block['className'] ) : array(),
+ $is_preview ? array( 'is-preview' ) : array(),
+ array( 'align' . $context['block']['align'] )
+ );
+
+ $context['classes'] = implode( ' ', $classes );
+
+ $is_example = false;
+
+ if ( ! empty( $block['data']['is_example'] ) ) {
+ $is_example = true;
+ $context['fields'] = $block['data'];
+ }
+
+ $context = apply_filters( 'timber/acf-gutenberg-blocks-data', $context );
+ $context = apply_filters( 'timber/acf-gutenberg-blocks-data/' . $slug, $context );
+ $context = apply_filters( 'timber/acf-gutenberg-blocks-data/' . $block['id'], $context );
+
+ $paths = self::timber_acf_path_render( $slug, $is_preview, $is_example );
+
+ Timber::render( $paths, $context );
+ }
+
+ /**
+ * Generates array with paths and slugs
+ *
+ * @param string $slug File slug.
+ * @param bool $is_preview Checks if preview.
+ * @param bool $is_example Checks if example.
+ */
+ public static function timber_acf_path_render( $slug, $is_preview, $is_example ) {
+ $directories = self::timber_block_directory_getter();
+
+ $ret = array();
+
+ /**
+ * Filters the name of suffix for example file.
+ *
+ * @since 1.12
+ */
+ $example_identifier = apply_filters( 'timber/acf-gutenberg-blocks-example-identifier', '-example' );
+
+ /**
+ * Filters the name of suffix for preview file.
+ *
+ * @since 1.12
+ */
+ $preview_identifier = apply_filters( 'timber/acf-gutenberg-blocks-preview-identifier', '-preview' );
+
+ foreach ( $directories as $directory ) {
+ if ( $is_example ) {
+ $ret[] = $directory . "/{$slug}{$example_identifier}.twig";
+ }
+ if ( $is_preview ) {
+ $ret[] = $directory . "/{$slug}{$preview_identifier}.twig";
+ }
+ $ret[] = $directory . "/{$slug}.twig";
+ }
+
+ return $ret;
+ }
+
+ /**
+ * Generates the list of subfolders based on current directories
+ *
+ * @param array $directories File path array.
+ */
+ public static function timber_blocks_subdirectories( $directories ) {
+ $ret = array();
+
+ foreach ( $directories as $base_directory ) {
+ // Check if the folder exist.
+ if ( ! file_exists( \locate_template( $base_directory ) ) ) {
+ continue;
+ }
+
+ $template_directory = new RecursiveDirectoryIterator(
+ \locate_template( $base_directory ),
+ FilesystemIterator::KEY_AS_PATHNAME | FilesystemIterator::CURRENT_AS_SELF
+ );
+
+ if ( $template_directory ) {
+ foreach ( $template_directory as $directory ) {
+ if ( $directory->isDir() && ! $directory->isDot() ) {
+ $ret[] = $base_directory . '/' . $directory->getFilename();
+ }
+ }
+ }
+ }
+
+ return $ret;
+ }
+
+ /**
+ * Universal function to handle getting folders and subfolders
+ */
+ public static function timber_block_directory_getter() {
+ // Get an array of directories containing blocks.
+ $directories = apply_filters( 'timber/acf-gutenberg-blocks-templates', array( 'views/blocks' ) );
+
+ // Check subfolders.
+ $subdirectories = self::timber_blocks_subdirectories( $directories );
+
+ if ( ! empty( $subdirectories ) ) {
+ $directories = array_merge( $directories, $subdirectories );
+ }
+
+ return $directories;
+ }
+
+ /**
+ * Default options setter.
+ *
+ * @param array $data Header set data.
+ * @return array
+ */
+ public static function timber_block_default_data( $data ) {
+ $default_data = apply_filters( 'timber/acf-gutenberg-blocks-default-data', array() );
+ $data_array = array();
+
+ if ( ! empty( $data['default_data'] ) ) {
+ $default_data_key = $data['default_data'];
+ }
+
+ if ( isset( $default_data_key ) && ! empty( $default_data[ $default_data_key ] ) ) {
+ $data_array = $default_data[ $default_data_key ];
+ } elseif ( ! empty( $default_data['default'] ) ) {
+ $data_array = $default_data['default'];
+ }
+
+ if ( is_array( $data_array ) ) {
+ $data = array_merge( $data_array, $data );
+ }
+
+ return $data;
+ }
+}
diff --git a/phpcs.xml b/phpcs.xml
index cc58136..ca9a075 100644
--- a/phpcs.xml
+++ b/phpcs.xml
@@ -1,75 +1,75 @@
- A custom set of rules to check coding standards for Timber.
+ A custom set of rules to check coding standards for Timber.
-
+
-
- */tests/*
- *.twig
+
+ */tests/*
+ *.twig
vendor/*
timber-acf-wp-blocks.php
-
-
+
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
-
-
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/timber-acf-wp-blocks.php b/timber-acf-wp-blocks.php
index 703bc43..4f109df 100644
--- a/timber-acf-wp-blocks.php
+++ b/timber-acf-wp-blocks.php
@@ -1,408 +1,30 @@
+ * @copyright 2019 Maciej Palmowski
+ * @license MIT https://github.com/szepeviktor/palmiak_timber-acf-wp-blocks/blob/master/LICENSE
+ * @link https://palmiak.github.io/timber-acf-wp-blocks/
*/
-if ( ! class_exists( 'Timber_Acf_Wp_Blocks' ) ) {
- /**
- * Main Timber_Acf_Wp_Block Class
- */
- class Timber_Acf_Wp_Blocks {
- /**
- * Constructor
- */
- public function __construct() {
- if ( is_callable( 'add_action' )
- && is_callable( 'acf_register_block_type' )
- && class_exists( 'Timber' )
- ) {
- add_action( 'acf/init', array( __CLASS__, 'timber_block_init' ), 10, 0 );
- } elseif ( is_callable( 'add_action' ) ) {
- add_action(
- 'admin_notices',
- function() {
- echo 'Timber ACF WP Blocks requires Timber and ACF.';
- echo 'Check if the plugins or libraries are installed and activated.
';
- }
- );
- }
- }
-
-
- /**
- * Create blocks based on templates found in Timber's "views/blocks" directory
- */
- public static function timber_block_init() {
- // Get an array of directories containing blocks.
- $directories = self::timber_block_directory_getter();
-
- // Check whether ACF exists before continuing.
- foreach ( $directories as $dir ) {
- // Sanity check whether the directory we're iterating over exists first.
- if ( ! file_exists( \locate_template( $dir ) ) ) {
- return;
- }
-
- // Iterate over the directories provided and look for templates.
- $template_directory = new DirectoryIterator( \locate_template( $dir ) );
- foreach ( $template_directory as $template ) {
-
- if ( $template->isDot() || $template->isDir() ) {
- continue;
- }
-
- $file_parts = pathinfo( $template->getFilename() );
- if ( 'twig' !== $file_parts['extension'] ) {
- continue;
- }
-
- // Strip the file extension to get the slug.
- $slug = $file_parts['filename'];
-
- // Get header info from the found template file(s).
- $file_path = locate_template( $dir . "/${slug}.twig" );
- $file_headers = get_file_data(
- $file_path,
- array(
- 'title' => 'Title',
- 'description' => 'Description',
- 'category' => 'Category',
- 'icon' => 'Icon',
- 'keywords' => 'Keywords',
- 'mode' => 'Mode',
- 'align' => 'Align',
- 'post_types' => 'PostTypes',
- 'supports_align' => 'SupportsAlign',
- 'supports_align_content' => 'SupportsAlignContent',
- 'supports_mode' => 'SupportsMode',
- 'supports_multiple' => 'SupportsMultiple',
- 'supports_anchor' => 'SupportsAnchor',
- 'enqueue_style' => 'EnqueueStyle',
- 'enqueue_script' => 'EnqueueScript',
- 'enqueue_assets' => 'EnqueueAssets',
- 'supports_custom_class_name' => 'SupportsCustomClassName',
- 'supports_reusable' => 'SupportsReusable',
- 'supports_full_height' => 'SupportsFullHeight',
- 'example' => 'Example',
- 'supports_jsx' => 'SupportsJSX',
- 'parent' => 'Parent',
- 'default_data' => 'DefaultData',
- )
- );
-
- if ( empty( $file_headers['title'] ) || empty( $file_headers['category'] ) ) {
- continue;
- }
-
- // Keywords exploding with quotes.
- $keywords = str_getcsv( $file_headers['keywords'], ' ', '"' );
-
- // Set up block data for registration.
- $data = array(
- 'name' => $slug,
- 'title' => $file_headers['title'],
- 'description' => $file_headers['description'],
- 'category' => $file_headers['category'],
- 'icon' => $file_headers['icon'],
- 'keywords' => $keywords,
- 'mode' => $file_headers['mode'],
- 'align' => $file_headers['align'],
- 'render_callback' => array( __CLASS__, 'timber_blocks_callback' ),
- 'enqueue_assets' => $file_headers['enqueue_assets'],
- 'default_data' => $file_headers['default_data'],
- );
-
- // Removes empty defaults.
- $data = array_filter( $data );
-
- // If the PostTypes header is set in the template, restrict this block
- // to those types.
- if ( ! empty( $file_headers['post_types'] ) ) {
- $data['post_types'] = explode( ' ', $file_headers['post_types'] );
- }
- // If the SupportsAlign header is set in the template, restrict this block
- // to those aligns.
- if ( ! empty( $file_headers['supports_align'] ) ) {
- $data['supports']['align'] =
- in_array( $file_headers['supports_align'], array( 'true', 'false' ), true ) ?
- filter_var( $file_headers['supports_align'], FILTER_VALIDATE_BOOLEAN ) :
- explode( ' ', $file_headers['supports_align'] );
- }
- // If the SupportsAlignContent header is set in the template, restrict this block
- // to those aligns.
- if ( ! empty( $file_headers['supports_align_content'] ) ) {
- $data['supports']['alignContent'] = ('true' === $file_headers['supports_align_content']) ?
- true : (('matrix' === $file_headers['supports_align_content']) ? "matrix" : false);
- }
- // If the SupportsMode header is set in the template, restrict this block
- // mode feature.
- if ( ! empty( $file_headers['supports_mode'] ) ) {
- $data['supports']['mode'] =
- ( 'true' === $file_headers['supports_mode'] ) ? true : false;
- }
- // If the SupportsMultiple header is set in the template, restrict this block
- // multiple feature.
- if ( ! empty( $file_headers['supports_multiple'] ) ) {
- $data['supports']['multiple'] =
- ( 'true' === $file_headers['supports_multiple'] ) ? true : false;
- }
- // If the SupportsAnchor header is set in the template, restrict this block
- // anchor feature.
- if ( ! empty( $file_headers['supports_anchor'] ) ) {
- $data['supports']['anchor'] =
- ( 'true' === $file_headers['supports_anchor'] ) ? true : false;
- }
-
- // If the SupportsCustomClassName is set to false hides the possibilty to
- // add custom class name.
- if ( ! empty( $file_headers['supports_custom_class_name'] ) ) {
- $data['supports']['customClassName'] =
- ( 'true' === $file_headers['supports_custom_class_name'] ) ? true : false;
- }
-
- // If the SupportsReusable is set in the templates it adds a posibility to
- // make this block reusable.
- if ( ! empty( $file_headers['supports_reusable'] ) ) {
- $data['supports']['reusable'] =
- ( 'true' === $file_headers['supports_reusable'] ) ? true : false;
- }
-
- // If the SupportsFullHeight is set in the templates it adds a posibility to
- // make this block full height.
- if ( ! empty( $file_headers['supports_full_height'] ) ) {
- $data['supports']['full_height'] =
- ( 'true' === $file_headers['supports_full_height'] ) ? true : false;
- }
-
- // Gives a possibility to enqueue style. If not an absoulte URL than adds
- // theme directory.
- if ( ! empty( $file_headers['enqueue_style'] ) ) {
- if ( ! filter_var( $file_headers['enqueue_style'], FILTER_VALIDATE_URL ) ) {
- $data['enqueue_style'] =
- get_template_directory_uri() . '/' . $file_headers['enqueue_style'];
- } else {
- $data['enqueue_style'] = $file_headers['enqueue_style'];
- }
- }
-
- // Gives a possibility to enqueue script. If not an absoulte URL than adds
- // theme directory.
- if ( ! empty( $file_headers['enqueue_script'] ) ) {
- if ( ! filter_var( $file_headers['enqueue_script'], FILTER_VALIDATE_URL ) ) {
- $data['enqueue_script'] =
- get_template_directory_uri() . '/' . $file_headers['enqueue_script'];
- } else {
- $data['enqueue_script'] = $file_headers['enqueue_script'];
- }
- }
-
- // Support for experimantal JSX.
- if ( ! empty( $file_headers['supports_jsx'] ) ) {
- // Leaving the experimaental part for 2 versions.
- $data['supports']['__experimental_jsx'] =
- ( 'true' === $file_headers['supports_jsx'] ) ? true : false;
- $data['supports']['jsx'] =
- ( 'true' === $file_headers['supports_jsx'] ) ? true : false;
- }
-
- // Support for "example".
- if ( ! empty( $file_headers['example'] ) ) {
- $json = json_decode( $file_headers['example'], true );
- $example_data = ( null !== $json ) ? $json : array();
- $example_data['is_example'] = true;
- $data['example'] = array(
- 'attributes' => array(
- 'mode' => 'preview',
- 'data' => $example_data,
- ),
- );
- }
-
- // Support for "parent".
- if ( ! empty( $file_headers['parent'] ) ) {
- $data['parent'] = str_getcsv( $file_headers['parent'], ' ', '"' );
- }
-
- // Merges the default options.
- $data = self::timber_block_default_data( $data );
-
- // Register the block with ACF.
- acf_register_block_type( $data );
- }
- }
- }
-
- /**
- * Callback to register blocks
- *
- * @param array $block stores all the data from ACF.
- * @param string $content content passed to block.
- * @param bool $is_preview checks if block is in preview mode.
- * @param int $post_id Post ID.
- */
- public static function timber_blocks_callback( $block, $content = '', $is_preview = false, $post_id = 0 ) {
- // Context compatibility.
- if ( method_exists( 'Timber', 'context' ) ) {
- $context = Timber::context();
- } else {
- $context = Timber::get_context();
- }
-
- // Set up the slug to be useful.
- $slug = str_replace( 'acf/', '', $block['name'] );
-
- $context['block'] = $block;
- $context['post_id'] = $post_id;
- $context['slug'] = $slug;
- $context['is_preview'] = $is_preview;
- $context['fields'] = \get_fields();
- $classes = array_merge(
- array( $slug ),
- isset( $block['className'] ) ? array( $block['className'] ) : array(),
- $is_preview ? array( 'is-preview' ) : array(),
- array( 'align' . $context['block']['align'] )
- );
-
- $context['classes'] = implode( ' ', $classes );
-
- $is_example = false;
- if ( ! empty( $block['data']['is_example'] ) ) {
- $is_example = true;
- $context['fields'] = $block['data'];
- }
-
- $context = apply_filters( 'timber/acf-gutenberg-blocks-data', $context );
- $context = apply_filters( 'timber/acf-gutenberg-blocks-data/' . $slug, $context );
- $context = apply_filters( 'timber/acf-gutenberg-blocks-data/' . $block['id'], $context );
-
- $paths = self::timber_acf_path_render( $slug, $is_preview, $is_example );
-
- Timber::render( $paths, $context );
- }
-
- /**
- * Generates array with paths and slugs
- *
- * @param string $slug File slug.
- * @param bool $is_preview Checks if preview.
- * @param bool $is_example Checks if example.
- */
- public static function timber_acf_path_render( $slug, $is_preview, $is_example ) {
- $directories = self::timber_block_directory_getter();
-
- $ret = array();
-
- /**
- * Filters the name of suffix for example file.
- *
- * @since 1.12
- */
- $example_identifier = apply_filters( 'timber/acf-gutenberg-blocks-example-identifier', '-example' );
-
- /**
- * Filters the name of suffix for preview file.
- *
- * @since 1.12
- */
- $preview_identifier = apply_filters( 'timber/acf-gutenberg-blocks-preview-identifier', '-preview' );
-
- foreach ( $directories as $directory ) {
- if ( $is_example ) {
- $ret[] = $directory . "/{$slug}{$example_identifier}.twig";
- }
- if ( $is_preview ) {
- $ret[] = $directory . "/{$slug}{$preview_identifier}.twig";
- }
- $ret[] = $directory . "/{$slug}.twig";
- }
-
- return $ret;
- }
-
- /**
- * Generates the list of subfolders based on current directories
- *
- * @param array $directories File path array.
- */
- public static function timber_blocks_subdirectories( $directories ) {
- $ret = array();
-
- foreach ( $directories as $base_directory ) {
- // Check if the folder exist.
- if ( ! file_exists( \locate_template( $base_directory ) ) ) {
- continue;
- }
-
- $template_directory = new RecursiveDirectoryIterator(
- \locate_template( $base_directory ),
- FilesystemIterator::KEY_AS_PATHNAME | FilesystemIterator::CURRENT_AS_SELF
- );
-
- if ( $template_directory ) {
- foreach ( $template_directory as $directory ) {
- if ( $directory->isDir() && ! $directory->isDot() ) {
- $ret[] = $base_directory . '/' . $directory->getFilename();
- }
- }
- }
- }
-
- return $ret;
- }
-
- /**
- * Universal function to handle getting folders and subfolders
- */
- public static function timber_block_directory_getter() {
- // Get an array of directories containing blocks.
- $directories = apply_filters( 'timber/acf-gutenberg-blocks-templates', array( 'views/blocks' ) );
-
- // Check subfolders.
- $subdirectories = self::timber_blocks_subdirectories( $directories );
-
- if ( ! empty( $subdirectories ) ) {
- $directories = array_merge( $directories, $subdirectories );
- }
-
- return $directories;
- }
-
- /**
- * Default options setter.
- *
- * @param [array] $data - header set data.
- * @return [array]
- */
- public static function timber_block_default_data( $data ) {
- $default_data = apply_filters( 'timber/acf-gutenberg-blocks-default-data', array() );
- $data_array = array();
-
- if ( ! empty( $data['default_data'] ) ) {
- $default_data_key = $data['default_data'];
- }
-
- if ( isset( $default_data_key ) && ! empty( $default_data[ $default_data_key ] ) ) {
- $data_array = $default_data[ $default_data_key ];
- } elseif ( ! empty( $default_data['default'] ) ) {
- $data_array = $default_data['default'];
- }
-
- if ( is_array( $data_array ) ) {
- $data = array_merge( $data_array, $data );
- }
-
- return $data;
- }
- }
+// Prevent direct execution.
+if ( ! defined( 'ABSPATH' ) ) {
+ exit;
}
-if ( is_callable( 'add_action' ) ) {
- add_action(
- 'after_setup_theme',
- function() {
- new Timber_Acf_Wp_Blocks();
- }
- );
+/**
+ * Check if class exists before redefining it.
+ */
+if ( ! class_exists( 'Timber_Acf_Wp_Blocks' ) ) {
+ require __DIR__ . '/inc/class-timber-acf-wp-blocks.php';
}
+
+add_action(
+ 'after_setup_theme',
+ function () {
+ new Timber_Acf_Wp_Blocks();
+ }
+);