Playing around with Gutenberg blocks to achieve a taxonomy terms list. First experiments.
This commit is contained in:
parent
d324963874
commit
1271348834
|
@ -26,6 +26,7 @@ class GutenbergBlock {
|
||||||
private function add_gutenberg_blocks_actions() {
|
private function add_gutenberg_blocks_actions() {
|
||||||
//add_action('init', array($this, 'register_tainacan_collections_carousel'));
|
//add_action('init', array($this, 'register_tainacan_collections_carousel'));
|
||||||
add_action('init', array($this, 'register_tainacan_items_grid'));
|
add_action('init', array($this, 'register_tainacan_items_grid'));
|
||||||
|
add_action('init', array($this, 'register_tainacan_terms_list'));
|
||||||
|
|
||||||
add_action('init', array($this, 'add_plugin_settings'));
|
add_action('init', array($this, 'add_plugin_settings'));
|
||||||
|
|
||||||
|
@ -104,6 +105,29 @@ class GutenbergBlock {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function register_tainacan_terms_list(){
|
||||||
|
global $TAINACAN_BASE_URL;
|
||||||
|
|
||||||
|
wp_register_script(
|
||||||
|
'terms-list',
|
||||||
|
$TAINACAN_BASE_URL . '/assets/gutenberg_terms_list-components.js',
|
||||||
|
array('wp-blocks', 'wp-element', 'wp-components', 'wp-editor', 'underscore')
|
||||||
|
);
|
||||||
|
|
||||||
|
wp_register_style(
|
||||||
|
'terms-list',
|
||||||
|
$TAINACAN_BASE_URL . '/assets/css/tainacan-gutenberg-blocks-style.css',
|
||||||
|
array('wp-edit-blocks')
|
||||||
|
);
|
||||||
|
|
||||||
|
if(function_exists('register_block_type')) {
|
||||||
|
register_block_type( 'tainacan/terms-list', array(
|
||||||
|
'editor_script' => 'terms-list',
|
||||||
|
'style' => 'terms-list'
|
||||||
|
) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function get_plugin_js_settings(){
|
public function get_plugin_js_settings(){
|
||||||
global $TAINACAN_BASE_URL;
|
global $TAINACAN_BASE_URL;
|
||||||
|
|
||||||
|
@ -122,5 +146,6 @@ class GutenbergBlock {
|
||||||
|
|
||||||
//wp_localize_script( 'collections-carousel', 'tainacan_plugin', $settings );
|
//wp_localize_script( 'collections-carousel', 'tainacan_plugin', $settings );
|
||||||
wp_localize_script( 'items-grid', 'tainacan_plugin', $settings );
|
wp_localize_script( 'items-grid', 'tainacan_plugin', $settings );
|
||||||
|
wp_localize_script( 'terms-list', 'tainacan_plugin', $settings );
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,357 @@
|
||||||
|
const { registerBlockType } = wp.blocks;
|
||||||
|
|
||||||
|
const { __ } = wp.i18n;
|
||||||
|
|
||||||
|
const { Button, Modal, Autocomplete, TextareaControl, QueryControls, Placeholder, CheckboxControl } = wp.components;
|
||||||
|
|
||||||
|
const { InspectorControls } = wp.editor;
|
||||||
|
|
||||||
|
import tainacan from '../../api-client/axios.js';
|
||||||
|
import qs from 'qs';
|
||||||
|
|
||||||
|
registerBlockType('tainacan/terms-list', {
|
||||||
|
title: __('Tainacan Terms List', 'tainacan'),
|
||||||
|
icon: 'list-view',
|
||||||
|
category: 'tainacan-blocks',
|
||||||
|
attributes: {
|
||||||
|
terms2: {
|
||||||
|
type: Array,
|
||||||
|
default: []
|
||||||
|
},
|
||||||
|
terms: {
|
||||||
|
type: 'array',
|
||||||
|
source: 'query',
|
||||||
|
selector: 'li>a',
|
||||||
|
query: {
|
||||||
|
url: {
|
||||||
|
type: 'string',
|
||||||
|
source: 'children',
|
||||||
|
selector: 'a',
|
||||||
|
attribute: 'href'
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
type: 'string',
|
||||||
|
source: 'text'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: []
|
||||||
|
},
|
||||||
|
isOpen: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
content: {
|
||||||
|
type: 'array',
|
||||||
|
source: 'children',
|
||||||
|
selector: 'div'
|
||||||
|
},
|
||||||
|
termsPerPage: {
|
||||||
|
type: Number,
|
||||||
|
default: 12
|
||||||
|
},
|
||||||
|
query: {
|
||||||
|
type: Object,
|
||||||
|
default: {}
|
||||||
|
},
|
||||||
|
URLTaxonomyID: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
tainacanURL: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
showItemsCount: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
},
|
||||||
|
supports: {
|
||||||
|
html: false
|
||||||
|
},
|
||||||
|
edit({ attributes, setAttributes, className, isSelected }){
|
||||||
|
let { terms, terms2, isOpen, content, termsPerPage, query, URLTaxonomyID, tainacanURL, showItemsCount } = attributes;
|
||||||
|
|
||||||
|
function prepareTerm(term) {
|
||||||
|
return (
|
||||||
|
<li style={{
|
||||||
|
listStyle: 'none',
|
||||||
|
display: 'list-item'
|
||||||
|
}}>
|
||||||
|
<a
|
||||||
|
style={{
|
||||||
|
// TODO
|
||||||
|
}}
|
||||||
|
href={term.url} target="_blank">
|
||||||
|
{ term.name ? term.name : '' }
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTerms(taxonomyID, query) {
|
||||||
|
if(taxonomyID) {
|
||||||
|
return tainacan.get(
|
||||||
|
`/taxonomy/${taxonomyID}/terms`
|
||||||
|
// `/collection/${collectionID}/items?${query}`
|
||||||
|
)
|
||||||
|
.then(response => {
|
||||||
|
return response.data;
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error(error);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return tainacan.get(`/items?${query}`)
|
||||||
|
.then(response => {
|
||||||
|
return response.data;
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error(error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setContent(terms){
|
||||||
|
setAttributes({
|
||||||
|
content: (
|
||||||
|
<div style={{ margin: '12px' }}>
|
||||||
|
<ul
|
||||||
|
style={{
|
||||||
|
MozColumnCount: 4,
|
||||||
|
MozColumnGap: '7rem',
|
||||||
|
MozColumnRule: 'none',
|
||||||
|
WebkitColumnCount: 4,
|
||||||
|
WebkitColumnGap: '7rem',
|
||||||
|
WebkitColumnRule: 'none',
|
||||||
|
columnCount: 4,
|
||||||
|
columnGap: '7rem',
|
||||||
|
columnRule: 'none'
|
||||||
|
}}>
|
||||||
|
{ terms }
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateQuery(query) {
|
||||||
|
let queryString = qs.stringify(query);
|
||||||
|
|
||||||
|
getTerms(URLTaxonomyID, queryString).then(data => {
|
||||||
|
terms = [];
|
||||||
|
|
||||||
|
data.map((term) => {
|
||||||
|
terms.push(prepareTerm(term));
|
||||||
|
});
|
||||||
|
|
||||||
|
setAttributes({terms: terms});
|
||||||
|
setAttributes({terms2: data});
|
||||||
|
setContent(terms);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseURL(tainacanURLP) {
|
||||||
|
tainacanURL = tainacanURLP;
|
||||||
|
setAttributes({tainacanURL: tainacanURLP});
|
||||||
|
|
||||||
|
if (!tainacanURLP || !tainacanURLP.includes('tainacan_admin')){
|
||||||
|
setAttributes({query: ''});
|
||||||
|
setAttributes({URLTaxonomyID: ''});
|
||||||
|
setAttributes({termsPerPage: 0});
|
||||||
|
setAttributes({terms: []});
|
||||||
|
setAttributes({terms2: []});
|
||||||
|
|
||||||
|
setContent([]);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
let tainacanURLSplited = tainacanURL.split('?');
|
||||||
|
|
||||||
|
let rawQuery = tainacanURLSplited[2];
|
||||||
|
let rawURL = tainacanURLSplited[1];
|
||||||
|
|
||||||
|
let parsedQuery = qs.parse(rawQuery);
|
||||||
|
|
||||||
|
if(parsedQuery.fetch_only && !parsedQuery.fetch_only.includes('title')){
|
||||||
|
parsedQuery.fetch_only += ',title';
|
||||||
|
}
|
||||||
|
|
||||||
|
let URLTaxID = rawURL.match(/\/(\d+)\/?/);
|
||||||
|
URLTaxonomyID = URLTaxID != undefined ? URLTaxID[1]: URLTaxID;
|
||||||
|
console.log(URLTaxonomyID)
|
||||||
|
getTerms(URLTaxonomyID, qs.stringify(parsedQuery)).then(data => {
|
||||||
|
terms = [];
|
||||||
|
setAttributes({terms: terms});
|
||||||
|
|
||||||
|
data.map((term) => {
|
||||||
|
terms.push(prepareTerm(term));
|
||||||
|
});
|
||||||
|
|
||||||
|
setAttributes({query: parsedQuery});
|
||||||
|
setAttributes({URLTaxonomyID: URLTaxonomyID});
|
||||||
|
setAttributes({termsPerPage: Number(parsedQuery.perpage)});
|
||||||
|
setAttributes({terms: terms});
|
||||||
|
setAttributes({terms2: data});
|
||||||
|
setContent(terms);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function mountBlock(termsA) {
|
||||||
|
let termsP = [];
|
||||||
|
|
||||||
|
for (const term of termsA){
|
||||||
|
termsP.push(prepareTerm(term));
|
||||||
|
}
|
||||||
|
|
||||||
|
terms = termsP;
|
||||||
|
setAttributes({terms: termsP});
|
||||||
|
setContent(termsP);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(content && content.length && content[0].type){
|
||||||
|
mountBlock(terms);
|
||||||
|
}
|
||||||
|
|
||||||
|
// function fetchTaxonomies(query) {
|
||||||
|
// console.log(query)
|
||||||
|
// return ['1', '2', '3'];
|
||||||
|
// }
|
||||||
|
|
||||||
|
// const completers = [{
|
||||||
|
// name: 'taxonomy-list-autocomplete',
|
||||||
|
// triggerPrefix: '/',
|
||||||
|
// options: query => fetchTaxonomies(query),
|
||||||
|
// getOptionLabel: option => (
|
||||||
|
// <span>{ option }</span>
|
||||||
|
// )
|
||||||
|
// }]
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={className}>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<InspectorControls>
|
||||||
|
<div style={{marginTop: '20px'}}>
|
||||||
|
<CheckboxControl
|
||||||
|
heading={__('Show terms count', 'tainacan')}
|
||||||
|
label={__('yes', 'tainacan')}
|
||||||
|
checked={ showItemsCount }
|
||||||
|
onChange={ ( isChecked ) => {
|
||||||
|
showItemsCount = isChecked;
|
||||||
|
|
||||||
|
mountBlock(terms2);
|
||||||
|
|
||||||
|
setAttributes({showItemsCount: isChecked});
|
||||||
|
} }
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</InspectorControls>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{ isSelected ? (
|
||||||
|
<div style={{
|
||||||
|
marginBottom: '20px',
|
||||||
|
}}>
|
||||||
|
<Button
|
||||||
|
isDefault
|
||||||
|
onClick={() => setAttributes({isOpen: true})}>{ terms.length ? __('Update terms list', 'tainacan') : __('Add term', 'tainacan')}</Button>
|
||||||
|
</div>
|
||||||
|
) : null
|
||||||
|
}
|
||||||
|
|
||||||
|
{ !terms.length ? (
|
||||||
|
<Placeholder
|
||||||
|
icon={(
|
||||||
|
<img
|
||||||
|
width={96}
|
||||||
|
src={`${tainacan_plugin.base_url}/admin/images/tainacan_logo_header.svg`}
|
||||||
|
alt="Tainacan Logo"/>
|
||||||
|
)}
|
||||||
|
/>) : null
|
||||||
|
}
|
||||||
|
|
||||||
|
{/* <Autocomplete completers={ completers }>
|
||||||
|
{ ( { isExpanded, listBoxId, activeId } ) => (
|
||||||
|
<div
|
||||||
|
contentEditable
|
||||||
|
suppressContentEditableWarning
|
||||||
|
aria-autocomplete="list"
|
||||||
|
aria-expanded={ isExpanded }
|
||||||
|
aria-owns={ listBoxId }
|
||||||
|
aria-activedescendant={ activeId }
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
) }
|
||||||
|
</Autocomplete> */}
|
||||||
|
|
||||||
|
{ isOpen ?
|
||||||
|
<Modal
|
||||||
|
shouldCloseOnClickOutside={ false }
|
||||||
|
shouldCloneOnEsc={false}
|
||||||
|
focusOnMount={false}
|
||||||
|
title={ __('Add terms', 'tainacan') }
|
||||||
|
onRequestClose={ () => setAttributes({isOpen: false}) }>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<TextareaControl
|
||||||
|
label={__(`Paste a Tainacan sharing URL for a Taxonomy terms list`, 'tainacan')}
|
||||||
|
type="url"
|
||||||
|
value={tainacanURL}
|
||||||
|
rows={8}
|
||||||
|
onChange={ (tainacanURL) => parseURL( tainacanURL ) }
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{ Object.keys(query).length && query.perpage && tainacanURL ? (
|
||||||
|
<div>
|
||||||
|
<QueryControls
|
||||||
|
numberOfItems={termsPerPage}
|
||||||
|
onNumberOfItemsChange={
|
||||||
|
(numberOfItems) => {
|
||||||
|
query.perpage = !numberOfItems ? 1 : numberOfItems;
|
||||||
|
termsPerPage = query.perpage;
|
||||||
|
|
||||||
|
setAttributes({termsPerPage: termsPerPage});
|
||||||
|
|
||||||
|
_.debounce(updateQuery(query), 300);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
) : null
|
||||||
|
}
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<Button isDefault onClick={ () => setAttributes({isOpen: false}) }>
|
||||||
|
{ __('Close', 'tainacan') }
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</Modal> : null }
|
||||||
|
|
||||||
|
<div style={{ margin: '12px' }}>
|
||||||
|
<ul
|
||||||
|
style={{
|
||||||
|
MozColumnCount: 4,
|
||||||
|
MozColumnGap: '7rem',
|
||||||
|
MozColumnRule: 'none',
|
||||||
|
WebkitColumnCount: 4,
|
||||||
|
WebkitColumnGap: '7rem',
|
||||||
|
WebkitColumnRule: 'none',
|
||||||
|
columnCount: 4,
|
||||||
|
columnGap: '7rem',
|
||||||
|
columnRule: 'none'
|
||||||
|
}}>
|
||||||
|
{ terms }
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
save({ attributes }){
|
||||||
|
const { content } = attributes;
|
||||||
|
|
||||||
|
return <div>{ content }</div>
|
||||||
|
}
|
||||||
|
});
|
|
@ -0,0 +1,3 @@
|
||||||
|
.wp-block-tainacan-terms-list {
|
||||||
|
|
||||||
|
}
|
|
@ -9,6 +9,7 @@ module.exports = {
|
||||||
user_admin: './src/admin/js/main.js',
|
user_admin: './src/admin/js/main.js',
|
||||||
//gutenberg_collections_carousel: './src/gutenberg-blocks/tainacan-collections/collections-carousel/index.js',
|
//gutenberg_collections_carousel: './src/gutenberg-blocks/tainacan-collections/collections-carousel/index.js',
|
||||||
gutenberg_items_grid: './src/gutenberg-blocks/tainacan-items/items-grid/index.js',
|
gutenberg_items_grid: './src/gutenberg-blocks/tainacan-items/items-grid/index.js',
|
||||||
|
gutenberg_terms_list: './src/gutenberg-blocks/tainacan-terms/terms-list/index.js',
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
path: path.resolve(__dirname, './src/assets/'),
|
path: path.resolve(__dirname, './src/assets/'),
|
||||||
|
|
Loading…
Reference in New Issue