{"id":13760166,"url":"https://github.com/knowler/sage-gutenberg-acf-tailwind-example","last_synced_at":"2025-05-10T10:31:38.612Z","repository":{"id":114063538,"uuid":"199908754","full_name":"knowler/sage-gutenberg-acf-tailwind-example","owner":"knowler","description":"An example implementation of an ACF-based Gutenberg block builder with Sage 10 (pre-alpha).","archived":true,"fork":false,"pushed_at":"2019-07-31T22:42:19.000Z","size":358,"stargazers_count":6,"open_issues_count":0,"forks_count":3,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-11-16T17:41:02.133Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/knowler.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2019-07-31T18:26:39.000Z","updated_at":"2024-06-03T13:54:07.000Z","dependencies_parsed_at":"2024-01-20T05:04:18.729Z","dependency_job_id":null,"html_url":"https://github.com/knowler/sage-gutenberg-acf-tailwind-example","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/knowler%2Fsage-gutenberg-acf-tailwind-example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/knowler%2Fsage-gutenberg-acf-tailwind-example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/knowler%2Fsage-gutenberg-acf-tailwind-example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/knowler%2Fsage-gutenberg-acf-tailwind-example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/knowler","download_url":"https://codeload.github.com/knowler/sage-gutenberg-acf-tailwind-example/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253401338,"owners_count":21902660,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-03T13:01:04.632Z","updated_at":"2025-05-10T10:31:38.277Z","avatar_url":"https://github.com/knowler.png","language":"PHP","funding_links":[],"categories":["PHP"],"sub_categories":[],"readme":"# Sage 10 + Gutenberg + ACF (+ Tailwind)\n\n(Work in Progress — Feedback and improvements to this workflow are welcome)\n\nThis is an example workflow for Sage 10 with an ACF block\nbuilder. For the CSS framework, we’ll build our own with\nTailwind.\n\n## What’s happening?\n\nFirst off all, in order to effectively use Tailwind with\nGutenberg in a way that is not invasive to a typical\nutility-first workflow, we need to do some CSS magic. Gutenberg\nwraps the frontend preview with a lot of CSS which has some\nagressive specificity. Since utility classes in functional CSS\nframeworks tend to have a low specificity\u003csup\u003e1\u003c/sup\u003e we need to\nincrease the specificity without bloating the public facing\nstylesheet and punishing the visitor. We can achieve this by\ncreating two stylesheets: `app.css` and `editor.css`. Now, we\naren’t creating a second stylesheet to write a massive amount of\neditor specific styles in, because that would be a waste of\ntime. What we’ll do with this second stylsheet is import\n`app.css` and then set the base styles for the\n`.acf-block-preview` element. Those base styles should match any\nstyles you’ve attached to the body.\n\n```css\n@import \"app.css\";\n\n/** These are styles we’ve attached to the body */\n.acf-block-preview {\n  @apply bg-black text-white font-sans;\n\n  /** Force children of this block to inherit its body styles */\n  \u0026 * {\n    color: inherit;\n    font-family: inherit;\n  }\n}\n```\n\nNow we can share the PostCSS plugin stack between these two\nstylesheet, but we can add `postcss-wrap` to the editor one, and\nwrap it’s styles with `.acf-block-preview`. This effectively\nscopes the styles to the block preview and gives it enough of a\nspecificity boost (in most cases) to avoid being overriden by\nthe greedy rules of the editor.\n\n\u003csmall\u003e\n\u003csup\u003e1\u003c/sup\u003e Some methodologies like ITCSS prescribes utilities\nto include `!important` — this is not the case with Tailwind or\nTachyons).\n\u003c/small\u003e\n\n## A Flexible Content Block\n\nFinal HTML:\n\n```html\n\u003csection class=\"bg-indigo-700 text-white py-8\"\u003e\n  \u003cdiv class=\"container flex flex-wrap\"\u003e\n    \u003ch2 class=\"w-full font-bold text-s4\"\u003eTest\u003c/h2\u003e\n  \u003c/div\u003e\n\u003c/section\u003e\n```\n\nHere is the Blade template for the Section component itself:\n\n```html\n\u003csection class=\"{{ $classes }} py-8\"\u003e\n  \u003cdiv class=\"container flex flex-wrap\"\u003e\n    {!! $content !!}\n  \u003c/div\u003e\n\u003c/section\u003e\n```\n\nThe view composer for our section block collects the flexible\ncontent layouts and determines how to render them.\n\nIf a layout requires itself to be full width, it will just\nrender the component itself:\n\n```html\n\u003ch{{ $level }} class=\"w-full font-bold {{ $classes }}\"\u003e{{ $slot }}\u003c/h{{ $level }}\u003e\n```\n\nOtherwise, it will wrap the component with a `\u003cdiv\u003e` where it\ncan apply any styling options that the block (or the parent) has\nspecified. These might be the column width or gutter settings.\n\n```html\n\u003cdiv class=\"{{ $classes }}\"\u003e\n  @include($view, $data)\n\u003c/div\u003e\n```\n\n## Composing Blocks\n\n1. Create view in `resources/views/blocks/\u003cmy-block\u003e.blade.php`.\n2. Create fields schema in `resources/fields/blocks/\u003cmy-block\u003e.php`.\n3. Create view composer in `app/Composers/\u003cMyBlock\u003e.php`.\n    * Register this in `config/view.php`.\n\n## Composing Components (Pseudo-Blocks)\n\n1. Create view in `resources/views/component/\u003cmy-component\u003e.blade.php`.\n2. Create fields schema in `resources/fields/partial/\u003cmy-component\u003e.php`.\n3. Create view composer in `app/Composers/\u003cMyComponent\u003e.php`.\n    * Register this in `config/view.php`.\n\n## Design Controls\n\nDesign controls are reusable ACF fields which can be shared\nbetween blocks and components. This methodology works very well\nwith Tailwind.\n\nWe define our controls in: `resources/fields/controls`.\n\nEach of these files just returns an associative array. That area\nlooks something like this:\n\n```php\n\u003c?php\n\nreturn [\n  'Black' =\u003e 'bg-black',\n  'White' =\u003e 'bg-white',\n  'Indigo' =\u003e 'bg-indigo-700',\n];\n```\n\nHow this works is that the ACF field uses the keys in the\nassociative array and then the View Composer uses a helper\nfunction which resolves the design choices into class names.\nThis is good because we never want to save class names to the\ndatabase.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fknowler%2Fsage-gutenberg-acf-tailwind-example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fknowler%2Fsage-gutenberg-acf-tailwind-example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fknowler%2Fsage-gutenberg-acf-tailwind-example/lists"}