Plugin Directory

Changeset 3406218


Ignore:
Timestamp:
11/30/2025 04:08:00 PM (4 months ago)
Author:
iansvo
Message:

Update to version 1.0.1

Location:
content-area-block
Files:
3 deleted
11 edited
8 copied

Legend:

Unmodified
Added
Removed
  • content-area-block/tags/1.0.1/build/index.asset.php

    r3402104 r3406218  
    1 <?php return array('dependencies' => array('react-jsx-runtime', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-core-data', 'wp-data', 'wp-editor', 'wp-element', 'wp-hooks', 'wp-i18n'), 'version' => '7e0b176223b22e53e510');
     1<?php return array('dependencies' => array('react-jsx-runtime', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-core-data', 'wp-data', 'wp-editor', 'wp-element', 'wp-hooks', 'wp-i18n'), 'version' => '3ce08443ee2ecb3af289');
  • content-area-block/tags/1.0.1/build/index.js

    r3402104 r3406218  
    1 (()=>{"use strict";const e=window.wp.blocks,t=window.wp.i18n,o=window.wp.data,n=window.wp.editor,s=window.wp.blockEditor,l=window.wp.element,a=window.wp.components,r=window.wp.coreData,c=window.ReactJSXRuntime,i=(0,l.createContext)({});const u=[],d=[{value:"allow",label:(0,t.__)("Allow","content-area-block")},{value:"disallow",label:(0,t.__)("Disallow","content-area-block")}];function p({parentLayout:o,layoutClassNames:n,userCanEdit:a,postType:i,postId:u,tagName:d="div"}){const[,,p]=(0,r.useEntityProp)("postType",i,"content",u),k=(0,s.useBlockProps)({className:n}),w=(0,l.useMemo)((()=>p?.raw?(0,e.parse)(p.raw):[]),[p?.raw]),_=(0,s.__experimentalUseBlockPreview)({blocks:w,props:k,layout:o});return a?(0,c.jsx)("div",{..._}):p?.protected?(0,c.jsx)(d,{...k,children:(0,c.jsx)(s.Warning,{children:(0,t.__)("This content is password protected.","content-area-block")})}):(0,c.jsx)(d,{...k,dangerouslySetInnerHTML:{__html:p?.rendered}})}function k({layout:t,context:n={},attributes:a={}}){const{allowedBlocks:i=[],disallowedBlocks:d=[],blockFilter:p="allow"}=a,k=(0,o.useSelect)((e=>{const{getSettings:t}=e(s.store);return t()?.supportsLayout}),[]),w=(0,s.useSettings)(["layout"])[0]||{},_=t&&t.inherit?w:t,{blocks:b,onChange:y,onInput:x}=function({attributes:t,context:n}){const{postType:s,postId:a}=n,c=(0,r.useEntityId)("postType",s),i=null!=a?a:c,{metaKey:d}=t,p=`${d}_blocks`,k=(0,o.useSelect)((e=>{const{getEditedEntityRecord:t}=e("core");return t("postType",s,i)}),[s,i]),{meta:w}=k,_=(0,l.useMemo)((()=>w?.[d]||""),[w,d]),[b,y]=(0,l.useState)((()=>k?.[p])),x=(0,l.useMemo)((()=>b||(k?.[p]?k[p]:_?(0,e.parse)(_):u)),[b,k,p,_]),{editEntityRecord:m,__unstableCreateUndoLevel:g}=(0,o.useDispatch)(r.store);(0,l.useEffect)((()=>{k?.[p]&&b&&y(null)}),[k,p,b]);const h=(0,l.useCallback)((t=>{if(x===t)return g("postType",s,i);const o=(0,e.__unstableSerializeAndClean)(t);y(t);const n={[p]:t,meta:{...w,[d]:o}};m("postType",s,i,n,{isCached:!1})}),[p,x,m,w,d,i,s,g]),C=(0,l.useCallback)((t=>{y(t);const o=(0,e.__unstableSerializeAndClean)(t),n={[p]:t,meta:{...w,[d]:o}};m("postType",s,i,n,{isCached:!0})}),[p,m,w,d,i,s]);return{blocks:x,onChange:h,onInput:C}}({attributes:a,context:n}),m=(0,l.useMemo)((()=>{const t=(0,e.getBlockTypes)(),o="allow"===p?i:t.map((({name:e})=>e));return"disallow"===p?o.filter((e=>!d.includes(e))):o}),[p,i,d]),g=(0,s.useBlockProps)(),h=(0,s.useInnerBlocksProps)(g,{value:b,onInput:x,onChange:y,__experimentalLayout:k?_:void 0,allowedBlocks:m.length>0?m:void 0,template:b?.length?void 0:[["core/paragraph"]]});return(0,c.jsx)("div",{...h})}function w(e){const{context:{queryId:t,postType:n,postId:s}={}}=e,l=Number.isFinite(t),a=(i="postType",u=n,d=s,(0,o.useSelect)((e=>e(r.store).canUser("update",{kind:i,name:u,id:d})),[i,u,d]));var i,u,d;return a&&!l?(0,c.jsx)(k,{...e}):(0,c.jsx)(p,{userCanEdit:a,postType:n,postId:s})}function _({metaKey:e=""}){const o=(0,s.useBlockProps)();return(0,c.jsx)("div",{...o,children:(0,c.jsx)("p",{children:e?(0,t.sprintf)(
     1(()=>{"use strict";const e=window.wp.blocks,t=window.wp.i18n,o=window.wp.data,n=window.wp.editor,s=window.wp.blockEditor,l=window.wp.element,a=window.wp.components,r=window.wp.coreData,c=window.ReactJSXRuntime,i=(0,l.createContext)({});const u=[],d=[{value:"allow",label:(0,t.__)("Allow","content-area-block")},{value:"disallow",label:(0,t.__)("Disallow","content-area-block")}];function p({parentLayout:o,layoutClassNames:n,userCanEdit:a,postType:i,postId:u,tagName:d="div"}){const[,,p]=(0,r.useEntityProp)("postType",i,"content",u),k=(0,s.useBlockProps)({className:n}),w=(0,l.useMemo)((()=>p?.raw?(0,e.parse)(p.raw):[]),[p?.raw]),_=(0,s.__experimentalUseBlockPreview)({blocks:w,props:k,layout:o});return a?(0,c.jsx)("div",{..._}):p?.protected?(0,c.jsx)(d,{...k,children:(0,c.jsx)(s.Warning,{children:(0,t.__)("This content is password protected.","content-area-block")})}):(0,c.jsx)(d,{...k,dangerouslySetInnerHTML:{__html:p?.rendered}})}function k({layout:t,context:n={},attributes:a={}}){const{allowedBlocks:i=[],disallowedBlocks:d=[],blockFilter:p="allow"}=a,k=(0,o.useSelect)((e=>{const{getSettings:t}=e(s.store);return t()?.supportsLayout}),[]),w=(0,s.useSettings)(["layout"])[0]||{},_=t&&t.inherit?w:t,{blocks:b,onChange:y,onInput:x}=function({attributes:t,context:n}){const{postType:s,postId:a}=n,c=(0,r.useEntityId)("postType",s),i=null!=a?a:c,{metaKey:d}=t,p=`${d}_blocks`,k=(0,o.useSelect)((e=>{const{getEditedEntityRecord:t}=e("core");return t("postType",s,i)}),[s,i]),{meta:w}=k,_=(0,l.useMemo)((()=>w?.[d]||""),[w,d]),[b,y]=(0,l.useState)((()=>k?.[p])),x=(0,l.useMemo)((()=>b||(k?.[p]?k[p]:_?(0,e.parse)(_):u)),[b,k,p,_]),{editEntityRecord:m,__unstableCreateUndoLevel:g}=(0,o.useDispatch)(r.store);(0,l.useEffect)((()=>{k?.[p]&&b&&y(null)}),[k,p,b]);const h=(0,l.useCallback)((t=>{if(x===t)return g("postType",s,i);const o=(0,e.__unstableSerializeAndClean)(t);y(t);const n={[p]:t,meta:{...w,[d]:o}};m("postType",s,i,n,{isCached:!1})}),[p,x,m,w,d,i,s,g]),C=(0,l.useCallback)((t=>{y(t);const o=(0,e.__unstableSerializeAndClean)(t),n={[p]:t,meta:{...w,[d]:o}};m("postType",s,i,n,{isCached:!0})}),[p,m,w,d,i,s]);return{blocks:x,onChange:h,onInput:C}}({attributes:a,context:n}),m=(0,l.useMemo)((()=>{const t=(0,e.getBlockTypes)();let o="allow"===p?i:t.map((({name:e})=>e));return o="disallow"===p?o.filter((e=>!d.includes(e))):o,o.length>0&&!o.includes("core/paragraph")&&(o=["core/paragraph",...o]),o}),[p,i,d]),g=(0,s.useBlockProps)(),h=(0,s.useInnerBlocksProps)(g,{value:b,onInput:x,onChange:y,__experimentalLayout:k?_:void 0,allowedBlocks:m.length>0?m:void 0,template:b?.length?void 0:[["core/paragraph"]],__experimentalDefaultBlock:{name:"core/paragraph"},__experimentalDirectInsert:!0});return(0,c.jsx)("div",{...h})}function w(e){const{context:{queryId:t,postType:n,postId:s}={}}=e,l=Number.isFinite(t),a=(i="postType",u=n,d=s,(0,o.useSelect)((e=>e(r.store).canUser("update",{kind:i,name:u,id:d})),[i,u,d]));var i,u,d;return a&&!l?(0,c.jsx)(k,{...e}):(0,c.jsx)(p,{userCanEdit:a,postType:n,postId:s})}function _({metaKey:e=""}){const o=(0,s.useBlockProps)();return(0,c.jsx)("div",{...o,children:(0,c.jsx)("p",{children:e?(0,t.sprintf)(
    22// Translators: %s is the metaKey attribute value.
    33// Translators: %s is the metaKey attribute value.
  • content-area-block/tags/1.0.1/build/render.php

    r3336929 r3406218  
    4040
    4141$meta_key = $attributes['metaKey'] ?? '';
    42 // When inside the main loop, we want to use queried object
    43 // so that `the_preview` for the current post can apply.
    44 // We force this behavior by omitting the third argument (post ID) from the `get_the_content`.
    45 $content = $meta_key ? get_post_meta( $block_post_id, $meta_key, true ) ?? $content : '';
     42$content  = $meta_key ? get_post_meta( $block_post_id, $meta_key, true ) ?? $content : '';
    4643
    47 /** This filter is documented in wp-includes/post-template.php */
    48 $content = apply_filters( 'the_content', str_replace( ']]>', ']]&gt;', $content ) );
     44/**
     45 * Filter the block's frontend output.
     46 *
     47 * @param string $parsed_content The parsed block content for output.
     48 * @param int    $block_post_id  The current post ID the block is displaying in.
     49 * @param array  $attributes     The block attributes.
     50 * @param string $content        The original unparsed block content.
     51 * @param object $block          The current parsed block object.
     52 *
     53 * @return The block content for output on the frontend.
     54 */
     55$output = apply_filters(
     56    'content_area_block_content',
     57    do_blocks( str_replace( ']]>', ']]&gt;', $content ) ),
     58    $block_post_id,
     59    $attributes,
     60    $content,
     61    $block
     62);
    4963unset( $seen_ids[ $block_post_id ] );
    5064
    51 if ( empty( $content ) ) {
     65if ( empty( $output ) ) {
    5266    return '';
    5367}
    5468
    55 echo $content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
     69echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
  • content-area-block/tags/1.0.1/content-area-block.php

    r3402104 r3406218  
    33 * Plugin Name:       Content Area Block
    44 * Description:       Add an outlet for blocks in a template that stores block data in a meta field.
    5  * Version:           1.0.0
     5 * Version:           1.0.1
    66 * Requires at least: 6.7
    77 * Requires PHP:      7.4
  • content-area-block/tags/1.0.1/package.json

    r3336929 r3406218  
    11{
    22    "name": "content-area-block",
    3     "version": "0.1.0",
     3    "version": "1.0.1",
    44    "description": "Example block scaffolded with Create Block tool.",
    55    "author": "The WordPress Contributors",
  • content-area-block/tags/1.0.1/readme.txt

    r3402107 r3406218  
    33Tags:              block, fse, site-editor, content, template
    44Tested up to:      6.8
    5 Stable tag:        1.0.0
     5Stable tag:        1.0.1
    66License:           GPL-2.0-or-later
    77License URI:       https://www.gnu.org/licenses/gpl-2.0.html
     
    99
    1010Adds a block content area to a site editor template and stores the blocks in a specified meta field. By default, the plugin will add a new meta field called `extra_content_area` for all post types which you can use to store the block markup.
     11
     12== Description ==
     13
     14This block allows you to add an additional block content area to a site-editor template and store the block output inside a meta field. By default, WordPress posts or pages may only store blocks in one place: post_content. These blocks are output on the page using the core/post-content block. This block allows you to have multiple "outlets" where you can add blocks so you can have post-specific blocks appear in more than one location in the template.
     15
     16The block is a fork of the core/post-content block that uses a customized version of the useEntityBlockEditor hook which supports meta keys. The blocks for your content area are then stored inside that meta key (instead of post_content). This allows you to keep the blocks separate and you can use as many of these on a single template as you want (but in most cases 2 is probably enough). It's all up to you!
     17
     18== Requirements ==
     19
     201. Using this plugin requires you to enable template previews (which will let you visually see the new content area you're adding). This can be enabled on any given post or page, but you can optionally set it on by default using a filter.
     212. Your theme must be a block theme (i.e. it uses the site editor). This won't work for a hybrid or classic theme (which has no concept of live template preview in the block editor).
     22
     23== Hooks ==
    1124
    1225If you want to disable this meta key's registration, add the following to your theme or plugin:
     
    1730`
    1831
    19 == Description ==
     32For advanced users, there is also a filter for the entire block's output. See the below snippet from render.php:
    2033
    21 This block allows you to add an additional block content area to a site-editor template and store the block output inside a meta field.
    22 
    23 Note: Using this plugin requires you to enable template previews (which will let you visually see the new content area you're adding). This can be enabled on any given post or page, but you can optionally set it on by default using a filter.
     34`
     35<?php
     36/**
     37 * Filter the block's frontend output.
     38 *
     39 * @param string $parsed_content The parsed block content for output.
     40 * @param int    $block_post_id  The current post ID the block is displaying in.
     41 * @param array  $attributes     The block attributes.
     42 * @param string $content        The original unparsed block content.
     43 * @param object $block          The current parsed block object.
     44 *
     45 * @return The block content for output on the frontend.
     46 */
     47$output = apply_filters(
     48    'content_area_block_content',
     49    do_blocks( str_replace( ']]>', ']]&gt;', $content ) ),
     50    $block_post_id,
     51    $attributes,
     52    $content,
     53    $block
     54);
     55`
    2456
    2557== Contributing ==
     
    4072== Changelog ==
    4173
     74= 1.0.1 =
     75* Additional minor bug fixes, improve filtering.
     76
    4277= 1.0.0 =
    4378* Fixed issues with undo, paste, and default block display.
  • content-area-block/tags/1.0.1/src/edit.js

    r3402104 r3406218  
    115115        const blockTypes = getBlockTypes();
    116116
    117         const list =
     117        let list =
    118118            blockFilter === 'allow'
    119119                ? allowedBlocks
    120120                : blockTypes.map( ( { name } ) => name );
    121121
    122         return blockFilter === 'disallow'
    123             ? list.filter(
    124                     ( blockType ) => ! disallowedBlocks.includes( blockType )
    125               )
    126             : list;
     122        list =
     123            blockFilter === 'disallow'
     124                ? list.filter(
     125                        ( blockType ) => ! disallowedBlocks.includes( blockType )
     126                  )
     127                : list;
     128
     129        // Always ensure paragraph is available
     130        if ( list.length > 0 && ! list.includes( 'core/paragraph' ) ) {
     131            list = [ 'core/paragraph', ...list ];
     132        }
     133
     134        return list;
    127135    }, [ blockFilter, allowedBlocks, disallowedBlocks ] );
    128136
     
    136144            allowedBlocksList.length > 0 ? allowedBlocksList : undefined,
    137145        template: ! blocks?.length ? [ [ 'core/paragraph' ] ] : undefined,
     146        __experimentalDefaultBlock: { name: 'core/paragraph' },
     147        __experimentalDirectInsert: true,
    138148    } );
    139149
  • content-area-block/tags/1.0.1/src/render.php

    r3336929 r3406218  
    4040
    4141$meta_key = $attributes['metaKey'] ?? '';
    42 // When inside the main loop, we want to use queried object
    43 // so that `the_preview` for the current post can apply.
    44 // We force this behavior by omitting the third argument (post ID) from the `get_the_content`.
    45 $content = $meta_key ? get_post_meta( $block_post_id, $meta_key, true ) ?? $content : '';
     42$content  = $meta_key ? get_post_meta( $block_post_id, $meta_key, true ) ?? $content : '';
    4643
    47 /** This filter is documented in wp-includes/post-template.php */
    48 $content = apply_filters( 'the_content', str_replace( ']]>', ']]&gt;', $content ) );
     44/**
     45 * Filter the block's frontend output.
     46 *
     47 * @param string $parsed_content The parsed block content for output.
     48 * @param int    $block_post_id  The current post ID the block is displaying in.
     49 * @param array  $attributes     The block attributes.
     50 * @param string $content        The original unparsed block content.
     51 * @param object $block          The current parsed block object.
     52 *
     53 * @return The block content for output on the frontend.
     54 */
     55$output = apply_filters(
     56    'content_area_block_content',
     57    do_blocks( str_replace( ']]>', ']]&gt;', $content ) ),
     58    $block_post_id,
     59    $attributes,
     60    $content,
     61    $block
     62);
    4963unset( $seen_ids[ $block_post_id ] );
    5064
    51 if ( empty( $content ) ) {
     65if ( empty( $output ) ) {
    5266    return '';
    5367}
    5468
    55 echo $content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
     69echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
  • content-area-block/trunk/build/index.asset.php

    r3402104 r3406218  
    1 <?php return array('dependencies' => array('react-jsx-runtime', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-core-data', 'wp-data', 'wp-editor', 'wp-element', 'wp-hooks', 'wp-i18n'), 'version' => '7e0b176223b22e53e510');
     1<?php return array('dependencies' => array('react-jsx-runtime', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-core-data', 'wp-data', 'wp-editor', 'wp-element', 'wp-hooks', 'wp-i18n'), 'version' => '3ce08443ee2ecb3af289');
  • content-area-block/trunk/build/index.js

    r3402104 r3406218  
    1 (()=>{"use strict";const e=window.wp.blocks,t=window.wp.i18n,o=window.wp.data,n=window.wp.editor,s=window.wp.blockEditor,l=window.wp.element,a=window.wp.components,r=window.wp.coreData,c=window.ReactJSXRuntime,i=(0,l.createContext)({});const u=[],d=[{value:"allow",label:(0,t.__)("Allow","content-area-block")},{value:"disallow",label:(0,t.__)("Disallow","content-area-block")}];function p({parentLayout:o,layoutClassNames:n,userCanEdit:a,postType:i,postId:u,tagName:d="div"}){const[,,p]=(0,r.useEntityProp)("postType",i,"content",u),k=(0,s.useBlockProps)({className:n}),w=(0,l.useMemo)((()=>p?.raw?(0,e.parse)(p.raw):[]),[p?.raw]),_=(0,s.__experimentalUseBlockPreview)({blocks:w,props:k,layout:o});return a?(0,c.jsx)("div",{..._}):p?.protected?(0,c.jsx)(d,{...k,children:(0,c.jsx)(s.Warning,{children:(0,t.__)("This content is password protected.","content-area-block")})}):(0,c.jsx)(d,{...k,dangerouslySetInnerHTML:{__html:p?.rendered}})}function k({layout:t,context:n={},attributes:a={}}){const{allowedBlocks:i=[],disallowedBlocks:d=[],blockFilter:p="allow"}=a,k=(0,o.useSelect)((e=>{const{getSettings:t}=e(s.store);return t()?.supportsLayout}),[]),w=(0,s.useSettings)(["layout"])[0]||{},_=t&&t.inherit?w:t,{blocks:b,onChange:y,onInput:x}=function({attributes:t,context:n}){const{postType:s,postId:a}=n,c=(0,r.useEntityId)("postType",s),i=null!=a?a:c,{metaKey:d}=t,p=`${d}_blocks`,k=(0,o.useSelect)((e=>{const{getEditedEntityRecord:t}=e("core");return t("postType",s,i)}),[s,i]),{meta:w}=k,_=(0,l.useMemo)((()=>w?.[d]||""),[w,d]),[b,y]=(0,l.useState)((()=>k?.[p])),x=(0,l.useMemo)((()=>b||(k?.[p]?k[p]:_?(0,e.parse)(_):u)),[b,k,p,_]),{editEntityRecord:m,__unstableCreateUndoLevel:g}=(0,o.useDispatch)(r.store);(0,l.useEffect)((()=>{k?.[p]&&b&&y(null)}),[k,p,b]);const h=(0,l.useCallback)((t=>{if(x===t)return g("postType",s,i);const o=(0,e.__unstableSerializeAndClean)(t);y(t);const n={[p]:t,meta:{...w,[d]:o}};m("postType",s,i,n,{isCached:!1})}),[p,x,m,w,d,i,s,g]),C=(0,l.useCallback)((t=>{y(t);const o=(0,e.__unstableSerializeAndClean)(t),n={[p]:t,meta:{...w,[d]:o}};m("postType",s,i,n,{isCached:!0})}),[p,m,w,d,i,s]);return{blocks:x,onChange:h,onInput:C}}({attributes:a,context:n}),m=(0,l.useMemo)((()=>{const t=(0,e.getBlockTypes)(),o="allow"===p?i:t.map((({name:e})=>e));return"disallow"===p?o.filter((e=>!d.includes(e))):o}),[p,i,d]),g=(0,s.useBlockProps)(),h=(0,s.useInnerBlocksProps)(g,{value:b,onInput:x,onChange:y,__experimentalLayout:k?_:void 0,allowedBlocks:m.length>0?m:void 0,template:b?.length?void 0:[["core/paragraph"]]});return(0,c.jsx)("div",{...h})}function w(e){const{context:{queryId:t,postType:n,postId:s}={}}=e,l=Number.isFinite(t),a=(i="postType",u=n,d=s,(0,o.useSelect)((e=>e(r.store).canUser("update",{kind:i,name:u,id:d})),[i,u,d]));var i,u,d;return a&&!l?(0,c.jsx)(k,{...e}):(0,c.jsx)(p,{userCanEdit:a,postType:n,postId:s})}function _({metaKey:e=""}){const o=(0,s.useBlockProps)();return(0,c.jsx)("div",{...o,children:(0,c.jsx)("p",{children:e?(0,t.sprintf)(
     1(()=>{"use strict";const e=window.wp.blocks,t=window.wp.i18n,o=window.wp.data,n=window.wp.editor,s=window.wp.blockEditor,l=window.wp.element,a=window.wp.components,r=window.wp.coreData,c=window.ReactJSXRuntime,i=(0,l.createContext)({});const u=[],d=[{value:"allow",label:(0,t.__)("Allow","content-area-block")},{value:"disallow",label:(0,t.__)("Disallow","content-area-block")}];function p({parentLayout:o,layoutClassNames:n,userCanEdit:a,postType:i,postId:u,tagName:d="div"}){const[,,p]=(0,r.useEntityProp)("postType",i,"content",u),k=(0,s.useBlockProps)({className:n}),w=(0,l.useMemo)((()=>p?.raw?(0,e.parse)(p.raw):[]),[p?.raw]),_=(0,s.__experimentalUseBlockPreview)({blocks:w,props:k,layout:o});return a?(0,c.jsx)("div",{..._}):p?.protected?(0,c.jsx)(d,{...k,children:(0,c.jsx)(s.Warning,{children:(0,t.__)("This content is password protected.","content-area-block")})}):(0,c.jsx)(d,{...k,dangerouslySetInnerHTML:{__html:p?.rendered}})}function k({layout:t,context:n={},attributes:a={}}){const{allowedBlocks:i=[],disallowedBlocks:d=[],blockFilter:p="allow"}=a,k=(0,o.useSelect)((e=>{const{getSettings:t}=e(s.store);return t()?.supportsLayout}),[]),w=(0,s.useSettings)(["layout"])[0]||{},_=t&&t.inherit?w:t,{blocks:b,onChange:y,onInput:x}=function({attributes:t,context:n}){const{postType:s,postId:a}=n,c=(0,r.useEntityId)("postType",s),i=null!=a?a:c,{metaKey:d}=t,p=`${d}_blocks`,k=(0,o.useSelect)((e=>{const{getEditedEntityRecord:t}=e("core");return t("postType",s,i)}),[s,i]),{meta:w}=k,_=(0,l.useMemo)((()=>w?.[d]||""),[w,d]),[b,y]=(0,l.useState)((()=>k?.[p])),x=(0,l.useMemo)((()=>b||(k?.[p]?k[p]:_?(0,e.parse)(_):u)),[b,k,p,_]),{editEntityRecord:m,__unstableCreateUndoLevel:g}=(0,o.useDispatch)(r.store);(0,l.useEffect)((()=>{k?.[p]&&b&&y(null)}),[k,p,b]);const h=(0,l.useCallback)((t=>{if(x===t)return g("postType",s,i);const o=(0,e.__unstableSerializeAndClean)(t);y(t);const n={[p]:t,meta:{...w,[d]:o}};m("postType",s,i,n,{isCached:!1})}),[p,x,m,w,d,i,s,g]),C=(0,l.useCallback)((t=>{y(t);const o=(0,e.__unstableSerializeAndClean)(t),n={[p]:t,meta:{...w,[d]:o}};m("postType",s,i,n,{isCached:!0})}),[p,m,w,d,i,s]);return{blocks:x,onChange:h,onInput:C}}({attributes:a,context:n}),m=(0,l.useMemo)((()=>{const t=(0,e.getBlockTypes)();let o="allow"===p?i:t.map((({name:e})=>e));return o="disallow"===p?o.filter((e=>!d.includes(e))):o,o.length>0&&!o.includes("core/paragraph")&&(o=["core/paragraph",...o]),o}),[p,i,d]),g=(0,s.useBlockProps)(),h=(0,s.useInnerBlocksProps)(g,{value:b,onInput:x,onChange:y,__experimentalLayout:k?_:void 0,allowedBlocks:m.length>0?m:void 0,template:b?.length?void 0:[["core/paragraph"]],__experimentalDefaultBlock:{name:"core/paragraph"},__experimentalDirectInsert:!0});return(0,c.jsx)("div",{...h})}function w(e){const{context:{queryId:t,postType:n,postId:s}={}}=e,l=Number.isFinite(t),a=(i="postType",u=n,d=s,(0,o.useSelect)((e=>e(r.store).canUser("update",{kind:i,name:u,id:d})),[i,u,d]));var i,u,d;return a&&!l?(0,c.jsx)(k,{...e}):(0,c.jsx)(p,{userCanEdit:a,postType:n,postId:s})}function _({metaKey:e=""}){const o=(0,s.useBlockProps)();return(0,c.jsx)("div",{...o,children:(0,c.jsx)("p",{children:e?(0,t.sprintf)(
    22// Translators: %s is the metaKey attribute value.
    33// Translators: %s is the metaKey attribute value.
  • content-area-block/trunk/build/render.php

    r3336929 r3406218  
    4040
    4141$meta_key = $attributes['metaKey'] ?? '';
    42 // When inside the main loop, we want to use queried object
    43 // so that `the_preview` for the current post can apply.
    44 // We force this behavior by omitting the third argument (post ID) from the `get_the_content`.
    45 $content = $meta_key ? get_post_meta( $block_post_id, $meta_key, true ) ?? $content : '';
     42$content  = $meta_key ? get_post_meta( $block_post_id, $meta_key, true ) ?? $content : '';
    4643
    47 /** This filter is documented in wp-includes/post-template.php */
    48 $content = apply_filters( 'the_content', str_replace( ']]>', ']]&gt;', $content ) );
     44/**
     45 * Filter the block's frontend output.
     46 *
     47 * @param string $parsed_content The parsed block content for output.
     48 * @param int    $block_post_id  The current post ID the block is displaying in.
     49 * @param array  $attributes     The block attributes.
     50 * @param string $content        The original unparsed block content.
     51 * @param object $block          The current parsed block object.
     52 *
     53 * @return The block content for output on the frontend.
     54 */
     55$output = apply_filters(
     56    'content_area_block_content',
     57    do_blocks( str_replace( ']]>', ']]&gt;', $content ) ),
     58    $block_post_id,
     59    $attributes,
     60    $content,
     61    $block
     62);
    4963unset( $seen_ids[ $block_post_id ] );
    5064
    51 if ( empty( $content ) ) {
     65if ( empty( $output ) ) {
    5266    return '';
    5367}
    5468
    55 echo $content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
     69echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
  • content-area-block/trunk/content-area-block.php

    r3402104 r3406218  
    33 * Plugin Name:       Content Area Block
    44 * Description:       Add an outlet for blocks in a template that stores block data in a meta field.
    5  * Version:           1.0.0
     5 * Version:           1.0.1
    66 * Requires at least: 6.7
    77 * Requires PHP:      7.4
  • content-area-block/trunk/package.json

    r3336929 r3406218  
    11{
    22    "name": "content-area-block",
    3     "version": "0.1.0",
     3    "version": "1.0.1",
    44    "description": "Example block scaffolded with Create Block tool.",
    55    "author": "The WordPress Contributors",
  • content-area-block/trunk/readme.txt

    r3402107 r3406218  
    33Tags:              block, fse, site-editor, content, template
    44Tested up to:      6.8
    5 Stable tag:        1.0.0
     5Stable tag:        1.0.1
    66License:           GPL-2.0-or-later
    77License URI:       https://www.gnu.org/licenses/gpl-2.0.html
     
    99
    1010Adds a block content area to a site editor template and stores the blocks in a specified meta field. By default, the plugin will add a new meta field called `extra_content_area` for all post types which you can use to store the block markup.
     11
     12== Description ==
     13
     14This block allows you to add an additional block content area to a site-editor template and store the block output inside a meta field. By default, WordPress posts or pages may only store blocks in one place: post_content. These blocks are output on the page using the core/post-content block. This block allows you to have multiple "outlets" where you can add blocks so you can have post-specific blocks appear in more than one location in the template.
     15
     16The block is a fork of the core/post-content block that uses a customized version of the useEntityBlockEditor hook which supports meta keys. The blocks for your content area are then stored inside that meta key (instead of post_content). This allows you to keep the blocks separate and you can use as many of these on a single template as you want (but in most cases 2 is probably enough). It's all up to you!
     17
     18== Requirements ==
     19
     201. Using this plugin requires you to enable template previews (which will let you visually see the new content area you're adding). This can be enabled on any given post or page, but you can optionally set it on by default using a filter.
     212. Your theme must be a block theme (i.e. it uses the site editor). This won't work for a hybrid or classic theme (which has no concept of live template preview in the block editor).
     22
     23== Hooks ==
    1124
    1225If you want to disable this meta key's registration, add the following to your theme or plugin:
     
    1730`
    1831
    19 == Description ==
     32For advanced users, there is also a filter for the entire block's output. See the below snippet from render.php:
    2033
    21 This block allows you to add an additional block content area to a site-editor template and store the block output inside a meta field.
    22 
    23 Note: Using this plugin requires you to enable template previews (which will let you visually see the new content area you're adding). This can be enabled on any given post or page, but you can optionally set it on by default using a filter.
     34`
     35<?php
     36/**
     37 * Filter the block's frontend output.
     38 *
     39 * @param string $parsed_content The parsed block content for output.
     40 * @param int    $block_post_id  The current post ID the block is displaying in.
     41 * @param array  $attributes     The block attributes.
     42 * @param string $content        The original unparsed block content.
     43 * @param object $block          The current parsed block object.
     44 *
     45 * @return The block content for output on the frontend.
     46 */
     47$output = apply_filters(
     48    'content_area_block_content',
     49    do_blocks( str_replace( ']]>', ']]&gt;', $content ) ),
     50    $block_post_id,
     51    $attributes,
     52    $content,
     53    $block
     54);
     55`
    2456
    2557== Contributing ==
     
    4072== Changelog ==
    4173
     74= 1.0.1 =
     75* Additional minor bug fixes, improve filtering.
     76
    4277= 1.0.0 =
    4378* Fixed issues with undo, paste, and default block display.
  • content-area-block/trunk/src/edit.js

    r3402104 r3406218  
    115115        const blockTypes = getBlockTypes();
    116116
    117         const list =
     117        let list =
    118118            blockFilter === 'allow'
    119119                ? allowedBlocks
    120120                : blockTypes.map( ( { name } ) => name );
    121121
    122         return blockFilter === 'disallow'
    123             ? list.filter(
    124                     ( blockType ) => ! disallowedBlocks.includes( blockType )
    125               )
    126             : list;
     122        list =
     123            blockFilter === 'disallow'
     124                ? list.filter(
     125                        ( blockType ) => ! disallowedBlocks.includes( blockType )
     126                  )
     127                : list;
     128
     129        // Always ensure paragraph is available
     130        if ( list.length > 0 && ! list.includes( 'core/paragraph' ) ) {
     131            list = [ 'core/paragraph', ...list ];
     132        }
     133
     134        return list;
    127135    }, [ blockFilter, allowedBlocks, disallowedBlocks ] );
    128136
     
    136144            allowedBlocksList.length > 0 ? allowedBlocksList : undefined,
    137145        template: ! blocks?.length ? [ [ 'core/paragraph' ] ] : undefined,
     146        __experimentalDefaultBlock: { name: 'core/paragraph' },
     147        __experimentalDirectInsert: true,
    138148    } );
    139149
  • content-area-block/trunk/src/render.php

    r3336929 r3406218  
    4040
    4141$meta_key = $attributes['metaKey'] ?? '';
    42 // When inside the main loop, we want to use queried object
    43 // so that `the_preview` for the current post can apply.
    44 // We force this behavior by omitting the third argument (post ID) from the `get_the_content`.
    45 $content = $meta_key ? get_post_meta( $block_post_id, $meta_key, true ) ?? $content : '';
     42$content  = $meta_key ? get_post_meta( $block_post_id, $meta_key, true ) ?? $content : '';
    4643
    47 /** This filter is documented in wp-includes/post-template.php */
    48 $content = apply_filters( 'the_content', str_replace( ']]>', ']]&gt;', $content ) );
     44/**
     45 * Filter the block's frontend output.
     46 *
     47 * @param string $parsed_content The parsed block content for output.
     48 * @param int    $block_post_id  The current post ID the block is displaying in.
     49 * @param array  $attributes     The block attributes.
     50 * @param string $content        The original unparsed block content.
     51 * @param object $block          The current parsed block object.
     52 *
     53 * @return The block content for output on the frontend.
     54 */
     55$output = apply_filters(
     56    'content_area_block_content',
     57    do_blocks( str_replace( ']]>', ']]&gt;', $content ) ),
     58    $block_post_id,
     59    $attributes,
     60    $content,
     61    $block
     62);
    4963unset( $seen_ids[ $block_post_id ] );
    5064
    51 if ( empty( $content ) ) {
     65if ( empty( $output ) ) {
    5266    return '';
    5367}
    5468
    55 echo $content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
     69echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
Note: See TracChangeset for help on using the changeset viewer.