{"id":232836,"date":"2025-08-14T16:30:09","date_gmt":"2025-08-14T16:30:09","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/synced-patterns-for-themes\/"},"modified":"2026-08-29T16:35:18","modified_gmt":"2026-08-29T16:35:18","slug":"synced-patterns-for-themes","status":"publish","type":"plugin","link":"https:\/\/xho.wordpress.org\/plugins\/synced-patterns-for-themes\/","author":23275903,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"2.0.1","stable_tag":"2.0.1","tested":"7.1","requires":"6.8","requires_php":"7.4","requires_plugins":null,"header_name":"Synced Patterns for Themes","header_author":"Twenty Bellows","header_description":"Empower Themes to provide Synced Patterns","assets_banners_color":"","last_updated":"2026-08-29 16:35:18","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/github.com\/Twenty-Bellows\/synced-patterns-for-themes","header_author_uri":"https:\/\/twentybellows.com","rating":0,"author_block_rating":0,"active_installs":20,"downloads":706,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.0.0":{"tag":"1.0.0","author":"twentybellows","date":"2025-08-14 16:29:39","revision":3344784},"1.2.0":{"tag":"1.2.0","author":"twentybellows","date":"2025-08-14 17:10:45","revision":3344797},"1.2.1":{"tag":"1.2.1","author":"twentybellows","date":"2025-08-14 17:30:54","revision":3344801},"2.0.0":{"tag":"2.0.0","author":"twentybellows","date":"2026-08-28 13:49:59","revision":3670465},"2.0.1":{"tag":"2.0.1","author":"twentybellows","date":"2026-08-29 16:35:18","revision":3671725}},"upgrade_notice":{"2.0.0":"<p>A rewrite. Theme patterns are no longer copied into the database: <code>Synced: yes<\/code>\nnow keeps a pattern linked to its file instead. The <code>pb_block<\/code> posts version 1\ncreated are unused and safe to delete. Requires WordPress 6.8.<\/p>"},"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3344797,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3344797,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256},"icon.svg":{"filename":"icon.svg","revision":3344797,"resolution":false,"location":"assets","locale":false}},"assets_banners":[],"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.0.0","1.2.0","1.2.1","2.0.0","2.0.1"],"block_files":[],"assets_screenshots":[],"screenshots":[]},"plugin_section":[],"plugin_tags":[246427,189590,18850,253727,1249],"plugin_category":[43],"plugin_contributors":[214562,241275],"plugin_business_model":[],"class_list":["post-232836","plugin","type-plugin","status-publish","hentry","plugin_tags-block-bindings","plugin_tags-block-patterns","plugin_tags-patterns","plugin_tags-synced-patterns","plugin_tags-themes","plugin_category-customization","plugin_contributors-pbking","plugin_contributors-twentybellows","plugin_committers-twentybellows"],"banners":[],"icons":{"svg":"https:\/\/ps.w.org\/synced-patterns-for-themes\/assets\/icon.svg?rev=3344797","icon":"https:\/\/ps.w.org\/synced-patterns-for-themes\/assets\/icon.svg?rev=3344797","icon_2x":false,"generated":false},"screenshots":[],"raw_content":"<!--section=description-->\n<p>A theme pattern is usually two things at once: a design, and the words that happen\nto be sitting in it. Reuse the design and you copy the words with it \u2014 so a theme\nthat wants five hero sections ships five near-identical patterns.<\/p>\n\n<p>This plugin separates the two. A pattern marks the parts of itself that are meant\nto be filled in, and any other pattern \u2014 or template, or post \u2014 can then use that\ndesign and say what goes in it:<\/p>\n\n<pre><code>&lt;!-- wp:pattern {\"slug\":\"mytheme\/hero\",\"content\":{\"headline\":{\"content\":\"Built for the long haul\"}}} \/--&gt;\n<\/code><\/pre>\n\n<p>One design pattern. As many uses as you like, each with its own content, all\nexpressed in theme files.<\/p>\n\n<p>The <code>content<\/code> attribute here is not new: it is the same attribute WordPress\nalready puts on a synced pattern when you edit one of its fields. All this plugin\ndoes is let a theme pattern accept it too.<\/p>\n\n<h4>Marking the parts to fill in<\/h4>\n\n<p>In the design pattern, give each block you want filled a name and mark it as a\nslot. This is core's Pattern Overrides syntax, unchanged:<\/p>\n\n<pre><code>&lt;!-- wp:heading {\"metadata\":{\"name\":\"headline\",\"bindings\":{\"__default\":{\"source\":\"core\/pattern-overrides\"}}}} --&gt;\n&lt;h2 class=\"wp-block-heading\"&gt;Headline goes here&lt;\/h2&gt;\n&lt;!-- \/wp:heading --&gt;\n\n\nmetadata.name names the slot. `__default` opens up every attribute the block\n<\/code><\/pre>\n\n<p>supports, and is the form to reach for: it is the only one WordPress will let\nsomeone type into inside a synced pattern.<\/p>\n\n<p>Naming attributes one by one instead \u2014 <code>{\"content\":{\"source\":\"core\/pattern-overrides\"}}<\/code> \u2014\nalso works when the content comes from markup, and is worth using when you want\nto fill exactly one attribute and leave the rest alone.<\/p>\n\n<h4>Filling them in<\/h4>\n\n<p>Anywhere a pattern can be used, <code>content<\/code> supplies the values \u2014 keyed by slot\nname, then by attribute name:<\/p>\n\n<pre><code>&lt;!-- wp:pattern {\"slug\":\"mytheme\/hero\",\"content\":{\n    \"headline\": { \"content\": \"Built for the long haul\" },\n    \"photo\":    { \"url\": \"\u2026\/roof.jpg\", \"alt\": \"A tin roof\" }\n}} \/--&gt;\n<\/code><\/pre>\n\n<p>Any slot you leave out keeps the design pattern's own content, so a pattern's\ndefaults double as its documentation.<\/p>\n\n<h4>Keeping a pattern linked<\/h4>\n\n<p>By default a pattern is a starting point: insert it and you get ordinary blocks\nyou are free to change. Add <code>Synced: yes<\/code> to a pattern's header and it behaves\nlike a synced pattern instead:<\/p>\n\n<pre><code>&lt;?php\n\/**\n * Title: Notice\n * Slug: mytheme\/notice\n * Synced: yes\n *\/\n?&gt;\n<\/code><\/pre>\n\n<p>Inserting it stores a reference rather than a copy. The design is rendered from\nthe theme file and cannot be edited on the page \u2014 only the content slots can.\nEdit the file and every notice on the site changes with it, keeping whatever\ncontent each one was given.<\/p>\n\n<p>The block toolbar offers <strong>Reset<\/strong>, which puts the pattern's own content back,\nand <strong>Detach<\/strong>, which breaks the link and leaves ordinary editable blocks with\nthe instance's content baked in.<\/p>\n\n<p>Unlike version 1, nothing is copied into the database to make this work: the\ntheme file stays the only source of truth.<\/p>\n\n<p>Slots in a synced pattern have to bind with <code>__default<\/code>. WordPress renders any\nother binding read-only inside an instance \u2014 that is its rule, not this\nplugin's.<\/p>\n\n<h4>Where it works<\/h4>\n\n<p>Patterns, templates, template parts, post content, and patterns inside other\npatterns, to any depth.<\/p>\n\n<p>Inserting an ordinary pattern that fills another gives you plain editable blocks\nwith the right content already in them. Inserting one marked <code>Synced: yes<\/code> gives\nyou a live instance instead, still linked to its file.<\/p>\n\n<h4>What can be filled<\/h4>\n\n<p>The blocks and attributes WordPress supports for Pattern Overrides:<\/p>\n\n<ul>\n<li>Paragraph and Heading \u2014 <code>content<\/code><\/li>\n<li>Image \u2014 <code>url<\/code>, <code>alt<\/code>, <code>title<\/code>, <code>id<\/code><\/li>\n<li>Button \u2014 <code>text<\/code>, <code>url<\/code>, <code>linkTarget<\/code>, <code>rel<\/code><\/li>\n<li>List Item \u2014 <code>content<\/code> (WordPress 7.1 and later)<\/li>\n<\/ul>\n\n<p>The list is core's, not this plugin's, so it grows as core's does.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Install and activate the plugin.<\/li>\n<li>Add <code>metadata.name<\/code> and a <code>core\/pattern-overrides<\/code> binding to each block in a\ntheme pattern you want to fill in.<\/li>\n<li>Use that pattern from another pattern, template or post, passing a <code>content<\/code>\nattribute on the pattern block.<\/li>\n<li>Optionally add <code>Synced: yes<\/code> to the design pattern's header, so inserting it\nkeeps it linked to the file rather than copying it.<\/li>\n<\/ol>\n\n<p>No settings, no admin screen. Nothing is written to the database.<\/p>\n\n<!--section=faq-->\n<dl>\n<dt id=\"do%20i%20need%20to%20mark%20my%20patterns%20as%20synced%3F\"><h3>Do I need to mark my patterns as synced?<\/h3><\/dt>\n<dd><p>Only if you want them to stay linked when someone inserts them. Filling a\npattern's content from block markup needs no header at all.<\/p>\n\n<pre><code>Synced: yes means what it says now \u2014 the pattern is inserted as a reference to\n<\/code><\/pre>\n\n<p>the theme file, and edits to that file reach every use. Version 1 used the same\nheader to copy the pattern into the database as a <code>wp_block<\/code>; version 2 keeps\nthe file as the only source of truth.<\/p><\/dd>\n<dt id=\"can%20a%20plugin%27s%20patterns%20be%20synced%3F\"><h3>Can a plugin's patterns be synced?<\/h3><\/dt>\n<dd><p>Yes. A plugin's patterns have no file header to read, so they opt in through a\nfilter:<\/p>\n\n<pre><code>add_filter( 'synced_patterns_for_themes_synced_patterns', function ( $slugs ) {\n    $slugs[] = 'myplugin\/notice';\n    return $slugs;\n} );\n<\/code><\/pre><\/dd>\n<dt id=\"what%20happens%20to%20the%20posts%20version%201%20created%3F\"><h3>What happens to the posts version 1 created?<\/h3><\/dt>\n<dd><p>They stop being used. They are <code>pb_block<\/code> posts, invisible in the admin, and safe\nto delete.<\/p><\/dd>\n<dt id=\"is%20this%20the%20same%20as%20pattern%20overrides%20on%20a%20synced%20pattern%3F\"><h3>Is this the same as Pattern Overrides on a synced pattern?<\/h3><\/dt>\n<dd><p>It is the same mechanism, aimed somewhere else. Pattern Overrides let a <em>person<\/em>\nfill in a synced pattern from the editor, and the values live in the database.\nThis lets a <em>theme<\/em> fill in a pattern from block markup, and the values live in\nthe theme.<\/p><\/dd>\n<dt id=\"should%20the%20design%20pattern%20be%20hidden%20from%20the%20inserter%3F\"><h3>Should the design pattern be hidden from the inserter?<\/h3><\/dt>\n<dd><p>It depends which half you are using. A pattern that only ever gets filled in from\nmarkup has little to offer on its own, so <code>Inserter: no<\/code> keeps it out of the way.\nA pattern marked <code>Synced: yes<\/code> is meant to be inserted, so leave it visible \u2014 the\nplugin makes sure it is offered exactly once, as a live instance.<\/p><\/dd>\n<dt id=\"why%20does%20the%20patterns%20screen%20say%20%22not%20synced%22%3F\"><h3>Why does the Patterns screen say \"Not synced\"?<\/h3><\/dt>\n<dd><p>Because WordPress decides that label by pattern type, not by behaviour: every\npattern that is not a user pattern is reported as unsynced, with no filter to\nchange it. The lock beside it is right \u2014 the pattern lives in a file and cannot\nbe edited from the admin \u2014 but the wording is WordPress's, and this plugin\ncannot correct it.<\/p><\/dd>\n<dt id=\"does%20it%20work%20in%20the%20site%20editor%3F\"><h3>Does it work in the site editor?<\/h3><\/dt>\n<dd><p>Yes. Patterns, templates and template parts are all composed before the editor\nloads them, so what you see is what the front end renders.<\/p><\/dd>\n<dt id=\"what%20if%20i%20use%20a%20slot%20name%20that%20the%20design%20pattern%20doesn%27t%20have%3F\"><h3>What if I use a slot name that the design pattern doesn't have?<\/h3><\/dt>\n<dd><p>Nothing happens. Unknown slots are ignored, and slots with no value keep the\ndesign pattern's own content.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>2.0.1<\/h4>\n\n<ul>\n<li>Does not load when Pattern Builder 2.0+ is active.<\/li>\n<li>The cached synced-pattern lookup is flushed when the theme is switched.<\/li>\n<\/ul>\n\n<h4>2.0.0<\/h4>\n\n<ul>\n<li>A pattern block can carry a <code>content<\/code> attribute, so one pattern supplies the\nwords for another pattern's design. Works in patterns, templates, template\nparts and post content, and through patterns nested in patterns.<\/li>\n<li><code>Synced: yes<\/code> in a pattern header keeps a pattern linked when someone inserts\nit: the page stores a reference, the design renders from the theme file and\ncannot be edited there, and editing the file reaches every instance.<\/li>\n<li>Nothing is copied into the database any more. The <code>pb_block<\/code> post type version\n1 created, the twelve capabilities it granted, the writes it made on every\nrequest, and the REST filters that made those posts look like reusable blocks\nare all gone.<\/li>\n<li>Patterns come from wherever WordPress registers them \u2014 parent themes, child\nthemes, <code>.php<\/code> and <code>.html<\/code> files, and plugins \u2014 instead of a glob over the\nactive theme's <code>patterns\/*.php<\/code>.<\/li>\n<li>Added the <code>synced_patterns_for_themes_synced_patterns<\/code> filter, so patterns\nregistered by a plugin can be synced too.<\/li>\n<li>Slots in a synced pattern must bind with <code>__default<\/code>; WordPress renders any\nother binding read-only inside an instance.<\/li>\n<li>Requires WordPress 6.8 and PHP 7.4.<\/li>\n<\/ul>\n\n<h4>1.2.0<\/h4>\n\n<ul>\n<li>Added block bindings support for pattern content.<\/li>\n<\/ul>\n\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>Initial release.<\/li>\n<\/ul>","raw_excerpt":"Let block markup supply the content for a pattern, so one pattern can carry the design and another can carry the words.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/xho.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/232836","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/xho.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/xho.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/xho.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=232836"}],"author":[{"embeddable":true,"href":"https:\/\/xho.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/twentybellows"}],"wp:attachment":[{"href":"https:\/\/xho.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=232836"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/xho.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=232836"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/xho.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=232836"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/xho.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=232836"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/xho.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=232836"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/xho.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=232836"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}