Last active
January 21, 2022 12:00
-
-
Save vanpariyar/2221450ff22495b06622b515515209a2 to your computer and use it in GitHub Desktop.
Create sidebar for the custom tag and post type selection on WordPress editor formally Gutenberg with Dynamic block
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"apiVersion": 2, | |
"name": "demo/content-with-sidebar", | |
"version": "0.1.0", | |
"title": "Content With Sidebar Block", | |
"category": "demo", | |
"attributes": { | |
"mediaURL": { | |
"type": "string", | |
"default": "" | |
}, | |
"mediaAlt": { | |
"type": "string", | |
"default": "" | |
}, | |
"technologies": { | |
"type": "object", | |
"default": {} | |
}, | |
"services": { | |
"type": "object", | |
"default": {} | |
}, | |
"serviceHeadingTag": { | |
"type":"string", | |
"default": "h3" | |
}, | |
"serviceHeading": { | |
"type":"string", | |
"default": "Services Provided" | |
}, | |
"technologiesHeadingTag": { | |
"type":"string", | |
"default": "h3" | |
}, | |
"technologiesHeading": { | |
"type":"string", | |
"default": "Technologies Used" | |
}, | |
"tagText": { | |
"type":"string", | |
"default": "Tags" | |
}, | |
"shareText": { | |
"type":"string", | |
"default": "Share this case study" | |
}, | |
"title":{ | |
"type":"string", | |
"default": "" | |
}, | |
"link":{ | |
"type":"string", | |
"default": "" | |
}, | |
"excerpt":{ | |
"type":"string", | |
"default": "" | |
}, | |
"tags":{ | |
"type":"array", | |
"default": [] | |
} | |
}, | |
"description": "This Block can be used in the Case study and Project details page", | |
"supports": { | |
"html": false, | |
"align": ["full"] | |
}, | |
"textdomain": "realmdigital", | |
"editorScript": "file:index.js", | |
"editorStyle": "file:index.css" | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Retrieves the translation of text. | |
* | |
* @see https://developer.wordpress.org/block-editor/packages/packages-i18n/ | |
*/ | |
import { __ } from '@wordpress/i18n' | |
import { Button, CheckboxControl, PanelBody, PanelRow, RadioControl, Spinner, TextControl } from '@wordpress/components' | |
import { useSelect, select } from '@wordpress/data' | |
import { useState, useEffect } from '@wordpress/element' | |
export const TechImage = ({ mediaId }) => { | |
const post = useSelect( | |
select => { | |
let query = { | |
include: [mediaId], | |
} | |
const selectedTechnologies = select('core').getMedia(mediaId) || [] | |
return selectedTechnologies | |
}, | |
[mediaId], | |
) | |
return <img src={post.source_url} alt={post.alt_text} /> | |
} | |
export const ServicesDisplay = ({ props }) => { | |
const { | |
attributes: { services }, | |
setAttributes, | |
} = props | |
const posts = useSelect( | |
select => { | |
let query = { | |
include: Object.keys(services), | |
} | |
const selectedServices = select('core').getEntityRecords('postType', 'service', query) || [] | |
return selectedServices | |
}, | |
[services], | |
) | |
return ( | |
<ul className="related-article-list"> | |
{posts && | |
posts.map((post, key) => { | |
return ( | |
<li key={key}> | |
<a href={post.link} title={post.title.rendered}> | |
{post.title.rendered} | |
</a> | |
</li> | |
) | |
})} | |
</ul> | |
) | |
} | |
export const TagDisplay = ({ tag }) => { | |
const tagObject = useSelect(select => { | |
const selectedTags = select('core').getEntityRecord('taxonomy', 'post_tag', tag) || [] | |
return selectedTags | |
}, []) | |
return ( | |
<> | |
{tagObject && ( | |
<li> | |
<a href={tagObject.link} title={tagObject.name}> | |
{tagObject.name} | |
</a> | |
</li> | |
)} | |
</> | |
) | |
} | |
export const TechnologyDisplay = ({ props }) => { | |
const { | |
attributes: { technologies }, | |
setAttributes, | |
} = props | |
const posts = useSelect( | |
select => { | |
let query = { | |
include: Object.keys(technologies), | |
} | |
const selectedTechnologies = select('core').getEntityRecords('postType', 'technology', query) || [] | |
return selectedTechnologies | |
}, | |
[technologies], | |
) | |
return ( | |
<ul> | |
{posts && | |
posts.map((post, key) => { | |
return ( | |
<li key={key}> | |
<a href={post.link} title={post.title.rendered}> | |
<TechImage mediaId={post.featured_media} /> | |
</a> | |
</li> | |
) | |
})} | |
</ul> | |
) | |
} | |
export const ServicesSelector = ({ props }) => { | |
const { | |
attributes: { services }, | |
setAttributes, | |
} = props | |
const [searchTerm, setSearchTerm] = useState('') | |
const [checkedObj, setCheckedObj] = useState(services) | |
const options = useSelect( | |
select => { | |
let dynamicOptions = [] | |
let query = { | |
per_page: 10, // set -1 to display ALL | |
search: searchTerm, | |
} | |
const posts = select('core').getEntityRecords('postType', 'service', query) || [] | |
if (posts) { | |
dynamicOptions = posts.map((post, key) => { | |
return { | |
id: post.id, | |
label: post.title.rendered, | |
value: post.slug, | |
} | |
}) | |
} | |
return dynamicOptions | |
}, | |
[searchTerm, services], | |
) | |
return ( | |
<> | |
<TextControl | |
label={__('Type to filter Services')} | |
help={__('Suggestions will show below')} | |
value={searchTerm} | |
placeholder={__('Type Your Keyword')} | |
onChange={setSearchTerm} | |
/> | |
{options.length ? ( | |
options.map((v, key) => ( | |
<CheckboxControl | |
key={key} | |
className="check_items" | |
label={v.value} | |
checked={checkedObj[v.id] == null ? '' : checkedObj[v.id]} | |
onChange={check => { | |
let tempCheckedObject = { ...checkedObj } | |
check ? (tempCheckedObject[v.id] = true) : delete tempCheckedObject[v.id] | |
setAttributes({ services: { ...tempCheckedObject } }) | |
setCheckedObj(tempCheckedObject) | |
}} | |
/> | |
)) | |
) : ( | |
<div> | |
<Spinner /> No Result Found | |
</div> | |
)} | |
{<hr />} | |
</> | |
) | |
} | |
export const TechnologySelector = ({ props }) => { | |
const { | |
attributes: { technologies }, | |
setAttributes, | |
} = props | |
const [searchTerm, setSearchTerm] = useState('') | |
const [checkedObj, setCheckedObj] = useState(technologies) | |
const options = useSelect( | |
select => { | |
let dynamicOptions = [] | |
let query = { | |
per_page: 10, // set -1 to display ALL | |
search: searchTerm, | |
} | |
const posts = select('core').getEntityRecords('postType', 'technology', query) || [] | |
if (posts) { | |
dynamicOptions = posts.map((post, key) => { | |
return { | |
id: post.id, | |
label: post.title.rendered, | |
value: post.slug, | |
} | |
}) | |
} | |
return dynamicOptions | |
}, | |
[searchTerm, technologies], | |
) | |
return ( | |
<> | |
<TextControl | |
label={__('Type to Filter Technologies')} | |
help={__('Suggestions will show below')} | |
value={searchTerm} | |
placeholder={__('Type Your Keyword')} | |
onChange={setSearchTerm} | |
/> | |
{options.length ? ( | |
options.map((v, key) => ( | |
<CheckboxControl | |
key={key} | |
className="check_items" | |
label={v.value} | |
checked={checkedObj[v.id] == null ? '' : checkedObj[v.id]} | |
onChange={check => { | |
let tempCheckedObject = { ...checkedObj } | |
check ? (tempCheckedObject[v.id] = true) : delete tempCheckedObject[v.id] | |
setAttributes({ technologies: { ...tempCheckedObject } }) | |
setCheckedObj(tempCheckedObject) | |
}} | |
/> | |
)) | |
) : ( | |
<div> | |
<Spinner /> No Result Found | |
</div> | |
)} | |
{<hr />} | |
</> | |
) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
add_filter('register_block_type_args', function ($settings, $name) { | |
if ($name == 'demo/content-with-sidebar') { | |
$settings['render_callback'] = 'demo_blocks_content_with_sidebar'; | |
} | |
return $settings; | |
}, null, 2); | |
function demo_blocks_content_with_sidebar($block_attributes, $content) | |
{ | |
/** | |
* Getting author ID for the post | |
*/ | |
global $post; | |
$author_id = $post->post_author; | |
$related_articles_count = 3; | |
ob_start(); | |
?> | |
<section class="article-detail-section case-study-detail-section"> | |
<div class="container"> | |
<div class="article-wrapper"> | |
<div class="article-left-block cms-content"> | |
<div class="content-block"> | |
<?php echo $content;?> | |
</div> | |
</div> | |
<div class="article-right-block"> | |
<div class="right-block-wrapper"> | |
<div class="article-right-inner"> | |
<div class="share-block"> | |
<p><?php echo $block_attributes['shareText'];?></p> | |
<ul class="social-share"> | |
<li> | |
<a target="_blank" href="https://facebook.com/sharer/sharer.php?u=<?php echo urlencode(get_the_permalink()); ?>" target="_blank" rel="noopener" aria-label="Share on Facebook"><img src="<?php echo get_template_directory_uri(); ?>/public/images/facebook.svg" alt="Facebook-logo" /></a> | |
</li> | |
<li> | |
<a target="_blank" href="https://twitter.com/intent/tweet/?text=<?php echo urlencode(get_the_title()); ?>&url=<?php echo urlencode(get_the_permalink()); ?>" target="_blank" rel="noopener" aria-label="Share on Twitter"><img src="<?php echo get_template_directory_uri(); ?>/public/images/twitter.svg" alt="Twitter-logo" /></a> | |
</li> | |
<li> | |
<a target="_blank" href="https://www.linkedin.com/shareArticle?mini=true&url=<?php echo urlencode(get_the_permalink()); ?>&title=<?php echo get_the_title(); ?>.&summary=<?php echo urlencode(get_the_excerpt()); ?>&source=<?php echo urlencode(get_the_permalink()); ?>" target="_blank" rel="noopener" aria-label="Share on LinkedIn"><img src="<?php echo get_template_directory_uri(); ?>/public/images/linkedin.svg" alt="Linekdin-logo" /></a> | |
</li> | |
</ul> | |
</div> | |
<div class="related-article-block services-block"> | |
<h3><?php echo $block_attributes['serviceHeading'];?></h3> | |
<?php if (isset($block_attributes['technologiesHeading'])) :?> | |
<ul class="related-article-list"> | |
<?php foreach ($block_attributes['services'] as $service => $value) :?> | |
<li> | |
<a href="<?php the_permalink($service);?>" title="<?php echo get_the_title($service)?>"><?php echo get_the_title($service)?></a> | |
<?php endforeach;?> | |
</ul> | |
<?php endif;?> | |
</div> | |
<div class="technology-block"> | |
<h3><?php echo $block_attributes['technologiesHeading'];?></h3> | |
<?php if (isset($block_attributes['technologiesHeading'])) :?> | |
<ul> | |
<?php foreach ($block_attributes['technologies'] as $technology => $value) :?> | |
<li> | |
<a href="<?php the_permalink($technology);?>" title="<?php echo get_the_title($technology)?>"><img src="<?php echo get_the_post_thumbnail_url($technology)?>" alt="<?php echo get_the_title($technology)?>" /></a> | |
</li> | |
<?php endforeach;?> | |
</ul> | |
<?php endif;?> | |
</div> | |
<div class="article-tag-block"> | |
<h3><?php echo $block_attributes['tagText'];?></h3> | |
<?php | |
$post_tags = get_the_terms($post, 'post_tag'); | |
if ($post_tags && !is_wp_error($post_tags)) : ?> | |
<ul class="article-tag-list"> | |
<?php foreach ($post_tags as $tag) : ?> | |
<li><a href="<?php echo get_tag_link($tag->term_id) ?>" title="<?php echo $tag->name?>"><?php echo $tag->name?></a></li> | |
<?php endforeach ?> | |
</ul> | |
<?php endif?> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</section> | |
<?php | |
$return_html = ob_get_clean(); | |
return $return_html; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Retrieves the translation of text. | |
* | |
* @see https://developer.wordpress.org/block-editor/packages/packages-i18n/ | |
*/ | |
import { __ } from '@wordpress/i18n' | |
/** | |
* React hook that is used to mark the block wrapper element. | |
* It provides all the necessary props like the class name. | |
* | |
* @see https://developer.wordpress.org/block-editor/packages/packages-block-editor/#useBlockProps | |
*/ | |
import { InnerBlocks, InspectorControls, RichText, useBlockProps } from '@wordpress/block-editor' | |
/** | |
* Lets webpack process CSS, SASS or SCSS files referenced in JavaScript files. | |
* Those files can contain any CSS code that gets applied to the editor. | |
* | |
* @see https://www.npmjs.com/package/@wordpress/scripts#using-css | |
*/ | |
import './editor.scss' | |
import { Button, CheckboxControl, PanelBody, PanelRow, RadioControl, Spinner, TextControl } from '@wordpress/components' | |
import { useSelect, select } from '@wordpress/data' | |
import { useState, useEffect } from '@wordpress/element' | |
import Heading from '../components/Heading' | |
import { ServicesSelector, TechnologySelector, TagDisplay, ServicesDisplay, TechnologyDisplay } from './components' | |
/** | |
* The edit function describes the structure of your block in the context of the | |
* editor. This represents what the editor will render when the block is used. | |
* | |
* @see https://developer.wordpress.org/block-editor/developers/block-api/block-edit-save/#edit | |
* | |
* @return {WPElement} Element to render. | |
*/ | |
const InspectorControlPanel = ({ props }) => { | |
return ( | |
<PanelBody title={__('Control Panel ⚙️')} initialOpen={true}> | |
<PanelRow className="realm-selector-list d-block"> | |
<ServicesSelector props={props} /> | |
</PanelRow> | |
<PanelRow className="realm-selector-list d-block"> | |
<TechnologySelector props={props} /> | |
</PanelRow> | |
</PanelBody> | |
) | |
} | |
export default function Edit(props) { | |
const blockProps = useBlockProps({ | |
className: 'article-detail-section case-study-detail-section', | |
}) | |
const { | |
attributes: { technologies, services, shareText, tagText, technologiesHeading, serviceHeading }, | |
setAttributes, | |
} = props | |
const title = select('core/editor').getEditedPostAttribute('title') || '' | |
const link = select('core/editor').getEditedPostAttribute('link') || '' | |
const excerpt = select('core/editor').getEditedPostAttribute('excerpt') || '' | |
const tags = select('core/editor').getEditedPostAttribute('tags') || '' | |
return ( | |
<> | |
<InspectorControls> | |
<InspectorControlPanel props={props} /> | |
</InspectorControls> | |
<section {...blockProps}> | |
<div className="container"> | |
<div className="article-wrapper"> | |
<div className="article-left-block cms-content"> | |
<InnerBlocks /> | |
</div> | |
<div className="article-right-block"> | |
<div className="right-block-wrapper"> | |
<div className="article-right-inner"> | |
<div className="share-block"> | |
<RichText | |
tagName="p" | |
value={shareText} | |
allowedFormats={['core/bold', 'core/italic']} | |
onChange={shareText => setAttributes({ shareText })} | |
placeholder={__('Heading...')} | |
/> | |
<ul className="social-share"> | |
<li> | |
<a | |
target="_blank" | |
href={`https://facebook.com/sharer/sharer.php?u=${encodeURIComponent( | |
link, | |
)}`} | |
target="_blank" | |
rel="noopener" | |
aria-label="Share on Facebook" | |
> | |
<img | |
src="../../app/themes/realmdigital/public/images/facebook.svg" | |
alt="Facebook-logo" | |
/> | |
</a> | |
</li> | |
<li> | |
<a | |
target="_blank" | |
href={`https://twitter.com/intent/tweet/?text=${encodeURIComponent( | |
title, | |
)}&url=${encodeURIComponent(link)}`} | |
target="_blank" | |
rel="noopener" | |
aria-label="Share on Twitter" | |
> | |
<img | |
src="../../app/themes/realmdigital/public/images/twitter.svg" | |
alt="Twitter-logo" | |
/> | |
</a> | |
</li> | |
<li> | |
<a | |
target="_blank" | |
href={`https://www.linkedin.com/shareArticle?mini=true&url=${encodeURI( | |
link, | |
)}&title=${encodeURIComponent( | |
title, | |
)}.&summary=${encodeURIComponent( | |
excerpt, | |
)}&source=${encodeURIComponent(link)}`} | |
target="_blank" | |
rel="noopener" | |
aria-label="Share on LinkedIn" | |
> | |
<img | |
src="../../app/themes/realmdigital/public/images/linkedin.svg" | |
alt="Linekdin-logo" | |
/> | |
</a> | |
</li> | |
</ul> | |
</div> | |
<div className="related-article-block services-block"> | |
<RichText | |
tagName="h3" | |
value={serviceHeading} | |
allowedFormats={['core/bold', 'core/italic']} | |
onChange={serviceHeading => setAttributes({ serviceHeading })} | |
placeholder={__('Heading...')} | |
/> | |
<ServicesDisplay props={props} /> | |
</div> | |
<div className="technology-block"> | |
<RichText | |
tagName="h3" | |
value={technologiesHeading} | |
allowedFormats={['core/bold', 'core/italic']} | |
onChange={technologiesHeading => setAttributes({ technologiesHeading })} | |
placeholder={__('Heading...')} | |
/> | |
<TechnologyDisplay props={props} /> | |
</div> | |
{tags.length ? ( | |
<div className="article-tag-block"> | |
<RichText | |
tagName="h3" | |
value={technologiesHeading} | |
allowedFormats={['core/bold', 'core/italic']} | |
onChange={technologiesHeading => setAttributes({ technologiesHeading })} | |
placeholder={__('Heading...')} | |
/> | |
<ul className="article-tag-list"> | |
{tags.map((tag, key) => { | |
return <TagDisplay tag={tag} key={key} /> | |
})} | |
</ul> | |
</div> | |
) : ( | |
'' | |
)} | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</section> | |
</> | |
) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* The following styles get applied inside the editor only. | |
* | |
* Replace them with your own styles or remove the file completely. | |
*/ | |
.wp-block-demo-content-with-sidebar .realm-selector-list { | |
display: block; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Registers a new block provided a unique name and an object defining its behavior. | |
* | |
* @see https://developer.wordpress.org/block-editor/reference-guides/block-api/block-registration/ | |
*/ | |
import { registerBlockType } from '@wordpress/blocks' | |
/** | |
* Lets webpack process CSS, SASS or SCSS files referenced in JavaScript files. | |
* All files containing `style` keyword are bundled together. The code used | |
* gets applied both to the front of your site and to the editor. | |
* | |
* @see https://www.npmjs.com/package/@wordpress/scripts#using-css | |
*/ | |
import './style.scss' | |
/** | |
* Internal dependencies | |
*/ | |
import Edit from './edit' | |
import save from './save' | |
import icons from '../components/icons' | |
/** | |
* Every block starts by registering a new block type definition. | |
* | |
* @see https://developer.wordpress.org/block-editor/reference-guides/block-api/block-registration/ | |
*/ | |
registerBlockType('demo/content-with-sidebar', { | |
/** | |
* @see ./edit.js | |
*/ | |
edit: Edit, | |
/** | |
* @see ./save.js | |
*/ | |
save, | |
icon: icons.realmdigitalLogo, | |
}) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Retrieves the translation of text. | |
* | |
* @see https://developer.wordpress.org/block-editor/packages/packages-i18n/ | |
*/ | |
import { __ } from '@wordpress/i18n' | |
/** | |
* React hook that is used to mark the block wrapper element. | |
* It provides all the necessary props like the class name. | |
* | |
* @see https://developer.wordpress.org/block-editor/packages/packages-block-editor/#useBlockProps | |
*/ | |
import { InnerBlocks } from '@wordpress/block-editor' | |
/** | |
* The save function defines the way in which the different attributes should | |
* be combined into the final markup, which is then serialized by the block | |
* editor into `post_content`. | |
* | |
* @see https://developer.wordpress.org/block-editor/developers/block-api/block-edit-save/#save | |
* | |
* @return {WPElement} Element to render. | |
*/ | |
export default function save(props) { | |
return <InnerBlocks.Content /> | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* The following styles get applied both on the front of your site | |
* and in the editor. | |
* | |
* Replace them with your own styles or remove the file completely. | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment