Skip to content

Commit b035623

Browse files
committed
New block: Knowledge Base Articles
1 parent c5a2464 commit b035623

File tree

12 files changed

+540
-11
lines changed

12 files changed

+540
-11
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
{
2+
"$schema": "https://schemas.wp.org/trunk/block.json",
3+
"apiVersion": 3,
4+
"name": "knowledgebase/articles",
5+
"version": "2.3.0",
6+
"title": "Knowledge Base Articles",
7+
"category": "design",
8+
"icon": "book",
9+
"keywords": [
10+
"knowledgbase",
11+
"articles",
12+
"kb"
13+
],
14+
"description": "Display the Knowledge Base Articles",
15+
"supports": {
16+
"html": false
17+
},
18+
"attributes": {
19+
"className": {
20+
"type": "string",
21+
"default": ""
22+
},
23+
"limit": {
24+
"type": "string",
25+
"default": ""
26+
},
27+
"showExcerpt": {
28+
"type": "boolean",
29+
"default": false
30+
},
31+
"termID": {
32+
"type": "string",
33+
"default": ""
34+
},
35+
"title": {
36+
"type": "string",
37+
"default": ""
38+
}
39+
},
40+
"example": {},
41+
"textdomain": "knowledgebase",
42+
"editorScript": "file:./index.js",
43+
"editorStyle": "file:./index.css"
44+
}

includes/blocks/build/kb-articles/index-rtl.css

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<?php return array('dependencies' => array('react', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-core-data', 'wp-data', 'wp-i18n', 'wp-server-side-render'), 'version' => 'af27dffe54569e88bed6');

includes/blocks/build/kb-articles/index.css

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

includes/blocks/build/kb-articles/index.js

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

includes/blocks/class-blocks.php

Lines changed: 71 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
namespace WebberZone\Knowledge_Base\Blocks;
1010

11+
use WebberZone\Knowledge_Base\Frontend\Display;
12+
1113
// If this file is called directly, abort.
1214
if ( ! defined( 'WPINC' ) ) {
1315
die;
@@ -38,8 +40,9 @@ public function __construct() {
3840
*/
3941
public function register_blocks() {
4042
$blocks = array(
41-
'kb' => 'render_kb_block',
42-
'alerts' => 'render_alerts_block',
43+
'kb' => 'render_kb_block',
44+
'alerts' => 'render_alerts_block',
45+
'kb-articles' => 'render_articles_block',
4346
);
4447

4548
foreach ( $blocks as $block_name => $render_callback ) {
@@ -52,6 +55,24 @@ public function register_blocks() {
5255
}
5356
}
5457

58+
/**
59+
* Maps JavaScript attribute names to PHP attribute names.
60+
*
61+
* @since 2.3.0
62+
*
63+
* @param array $attributes The block attributes.
64+
* @param array $mappings Array of mappings with PHP attributes as keys and JS attributes as values.
65+
* @return array Modified attributes array with mapped values.
66+
*/
67+
private function map_attributes( $attributes, $mappings ) {
68+
foreach ( $mappings as $php_attr => $js_attr ) {
69+
if ( isset( $attributes[ $js_attr ] ) ) {
70+
$attributes[ $php_attr ] = $attributes[ $js_attr ];
71+
}
72+
}
73+
return $attributes;
74+
}
75+
5576
/**
5677
* Renders the `knowledgebase/knowledgebase` block on server.
5778
*
@@ -71,11 +92,7 @@ public function render_kb_block( $attributes ) {
7192
'extra_class' => 'className',
7293
);
7394

74-
foreach ( $mappings as $php_attr => $js_attr ) {
75-
if ( isset( $attributes[ $js_attr ] ) ) {
76-
$attributes[ $php_attr ] = $attributes[ $js_attr ];
77-
}
78-
}
95+
$attributes = $this->map_attributes( $attributes, $mappings );
7996

8097
$arguments = array_merge(
8198
$attributes,
@@ -113,4 +130,51 @@ public function render_kb_block( $attributes ) {
113130
public function render_alerts_block( $attributes, $content, $block ) {
114131
return wp_kses_post( $content );
115132
}
133+
134+
/**
135+
* Renders the `knowledgebase/articles` block on server.
136+
*
137+
* @since 2.3.0
138+
*
139+
* @param array $attributes The block attributes.
140+
*
141+
* @return string Returns the post content with latest posts added.
142+
*/
143+
public function render_articles_block( $attributes ) {
144+
$mappings = array(
145+
'term_id' => 'termID',
146+
'show_excerpt' => 'showExcerpt',
147+
);
148+
149+
$attributes = $this->map_attributes( $attributes, $mappings );
150+
151+
$limit = (int) ( ! empty( $attributes['limit'] ) ? $attributes['limit'] : wzkb_get_option( 'limit', 5 ) );
152+
153+
$show_excerpt = isset( $attributes['show_excerpt'] ) ? (bool) $attributes['show_excerpt'] : false;
154+
155+
if ( empty( $attributes['term_id'] ) ) {
156+
return '';
157+
}
158+
159+
$term = get_term( (int) $attributes['term_id'], 'wzkb_category' );
160+
161+
if ( empty( $term ) || is_wp_error( $term ) ) {
162+
return '';
163+
}
164+
165+
$list_of_posts = Display::get_posts_by_term(
166+
$term,
167+
0,
168+
array(
169+
'show_excerpt' => $show_excerpt,
170+
'limit' => $limit,
171+
)
172+
);
173+
174+
if ( empty( $list_of_posts ) ) {
175+
return __( 'No articles found.', 'knowledgebase' );
176+
}
177+
178+
return $list_of_posts;
179+
}
116180
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
{
2+
"$schema": "https://schemas.wp.org/trunk/block.json",
3+
"apiVersion": 3,
4+
"name": "knowledgebase/articles",
5+
"version": "2.3.0",
6+
"title": "Knowledge Base Articles",
7+
"category": "design",
8+
"icon": "book",
9+
"keywords": ["knowledgbase", "articles", "kb"],
10+
"description": "Display the Knowledge Base Articles",
11+
"supports": {
12+
"html": false
13+
},
14+
"attributes": {
15+
"className": {
16+
"type": "string",
17+
"default": ""
18+
},
19+
"limit": {
20+
"type": "string",
21+
"default": ""
22+
},
23+
"showExcerpt": {
24+
"type": "boolean",
25+
"default": false
26+
},
27+
"termID": {
28+
"type": "string",
29+
"default": ""
30+
},
31+
"title": {
32+
"type": "string",
33+
"default": ""
34+
}
35+
},
36+
"example": {},
37+
"textdomain": "knowledgebase",
38+
"editorScript": "file:./index.js",
39+
"editorStyle": "file:./index.css"
40+
}
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
import { __ } from '@wordpress/i18n';
2+
import ServerSideRender from '@wordpress/server-side-render';
3+
import { useBlockProps, InspectorControls } from '@wordpress/block-editor';
4+
import { useSelect } from '@wordpress/data';
5+
import { store as coreStore } from '@wordpress/core-data';
6+
7+
import {
8+
Disabled,
9+
ComboboxControl,
10+
ToggleControl,
11+
PanelBody,
12+
PanelRow,
13+
Spinner,
14+
TextControl,
15+
Notice,
16+
} from '@wordpress/components';
17+
18+
import './editor.scss';
19+
20+
export default function Edit({ attributes, setAttributes }) {
21+
const { termID, limit, showExcerpt } = attributes;
22+
23+
const blockProps = useBlockProps();
24+
25+
const { terms, hasResolved, error } = useSelect((select) => {
26+
const query = { per_page: -1 };
27+
const selectorArgs = ['taxonomy', 'wzkb_category', query];
28+
29+
try {
30+
return {
31+
terms: select(coreStore).getEntityRecords(...selectorArgs),
32+
hasResolved: select(coreStore).hasFinishedResolution(
33+
'getEntityRecords',
34+
selectorArgs
35+
),
36+
error: null,
37+
};
38+
} catch (fetchError) {
39+
return {
40+
terms: [],
41+
hasResolved: true,
42+
error: fetchError,
43+
};
44+
}
45+
}, []);
46+
47+
const termOptions =
48+
terms?.map((term) => ({
49+
label: `${term.name} (#${term.id})`,
50+
value: term.id.toString(),
51+
})) || [];
52+
53+
const handleLimitChange = (newLimit) => {
54+
const parsedLimit = parseInt(newLimit, 10);
55+
setAttributes({
56+
limit: isNaN(parsedLimit) || parsedLimit <= 0 ? 5 : parsedLimit,
57+
});
58+
};
59+
60+
return (
61+
<>
62+
<InspectorControls>
63+
{error && (
64+
<Notice status="error" isDismissible={false}>
65+
{__(
66+
'Error loading categories. Please try again.',
67+
'knowledgebase'
68+
)}
69+
</Notice>
70+
)}
71+
72+
<PanelBody
73+
title={__(
74+
'Knowledge Base Articles Settings',
75+
'knowledgebase'
76+
)}
77+
initialOpen={true}
78+
>
79+
<PanelRow>
80+
{!hasResolved ? (
81+
<Spinner />
82+
) : (
83+
<ComboboxControl
84+
label={__(
85+
'Select Knowledge Base Section',
86+
'knowledgebase'
87+
)}
88+
value={termID}
89+
onChange={(value) =>
90+
setAttributes({ termID: value })
91+
}
92+
options={termOptions}
93+
help={__(
94+
'Search and select a knowledge base section',
95+
'knowledgebase'
96+
)}
97+
/>
98+
)}
99+
</PanelRow>
100+
<PanelRow>
101+
<TextControl
102+
label={__('Number of posts', 'knowledgebase')}
103+
value={limit}
104+
type="number"
105+
min="1"
106+
onChange={handleLimitChange}
107+
help={__(
108+
'Enter the number of posts to display (default: 5)',
109+
'knowledgebase'
110+
)}
111+
/>
112+
</PanelRow>
113+
<PanelRow>
114+
<ToggleControl
115+
label={__('Show excerpt', 'knowledgebase')}
116+
help={
117+
showExcerpt
118+
? __(
119+
'Excerpt is displayed',
120+
'knowledgebase'
121+
)
122+
: __('No excerpt shown', 'knowledgebase')
123+
}
124+
checked={showExcerpt}
125+
onChange={() =>
126+
setAttributes({
127+
showExcerpt: !showExcerpt,
128+
})
129+
}
130+
/>
131+
</PanelRow>
132+
</PanelBody>
133+
</InspectorControls>
134+
135+
<div {...blockProps}>
136+
<Disabled>
137+
<ServerSideRender
138+
block="knowledgebase/articles"
139+
attributes={attributes}
140+
/>
141+
</Disabled>
142+
</div>
143+
</>
144+
);
145+
}

0 commit comments

Comments
 (0)