Playing around with Gutenberg blocks to achieve a taxonomy terms list. First experiments.

This commit is contained in:
Mateus Machado Luna 2019-01-28 17:06:39 -02:00
parent d324963874
commit 1271348834
4 changed files with 386 additions and 0 deletions

View File

@ -26,6 +26,7 @@ class GutenbergBlock {
private function add_gutenberg_blocks_actions() {
//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_terms_list'));
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(){
global $TAINACAN_BASE_URL;
@ -122,5 +146,6 @@ class GutenbergBlock {
//wp_localize_script( 'collections-carousel', 'tainacan_plugin', $settings );
wp_localize_script( 'items-grid', 'tainacan_plugin', $settings );
wp_localize_script( 'terms-list', 'tainacan_plugin', $settings );
}
}

View File

@ -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>
}
});

View File

@ -0,0 +1,3 @@
.wp-block-tainacan-terms-list {
}

View File

@ -9,6 +9,7 @@ module.exports = {
user_admin: './src/admin/js/main.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_terms_list: './src/gutenberg-blocks/tainacan-terms/terms-list/index.js',
},
output: {
path: path.resolve(__dirname, './src/assets/'),