Skip to content

Commit

Permalink
Add various meta fields for publications
Browse files Browse the repository at this point in the history
  • Loading branch information
jeremyfelt committed Oct 30, 2024
1 parent f572e32 commit 079a619
Show file tree
Hide file tree
Showing 5 changed files with 220 additions and 0 deletions.
1 change: 1 addition & 0 deletions js/build/publication-meta/index.asset.php
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<?php return array('dependencies' => array('wp-blocks', 'wp-components', 'wp-data', 'wp-editor', 'wp-element', 'wp-i18n', 'wp-plugins'), 'version' => '63e440f3fb6f9483ca6d');
1 change: 1 addition & 0 deletions js/build/publication-meta/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

122 changes: 122 additions & 0 deletions js/src/publication-meta/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import { registerPlugin } from '@wordpress/plugins';
import { DatePicker, TextControl, Button } from '@wordpress/components';
import { useSelect, useDispatch } from '@wordpress/data';
import { PluginDocumentSettingPanel } from '@wordpress/editor';
import { __ } from '@wordpress/i18n';
import { useState } from '@wordpress/element';
import { registerBlockBindingsSource } from '@wordpress/blocks';

const DateControl = ({ metaKey, label, value }) => {
const [isDatePickerOpen, setIsDatePickerOpen] = useState(false);
const { editPost } = useDispatch('core/editor');

let date = null;
let formattedDate = '';

if (value) {
date = new Date(value * 1000);
formattedDate = date.toLocaleDateString('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric',
});
}

return (
<>
<TextControl
label={__(label, 'organizational')}
value={formattedDate}
onClick={() => setIsDatePickerOpen(true)}
/>
{value && (
<Button
variant="secondary"
onClick={() => {
// Unset meta key
editPost({ meta: { [metaKey]: null } });
}}
>
Clear date
</Button>
)}
{isDatePickerOpen && (
<DatePicker
currentDate={date}
onChange={(value) => {
const date = new Date(value);
editPost({
meta: { [metaKey]: date.getTime() / 1000 },
});
setIsDatePickerOpen(false);
}}
/>
)}
</>
);
};

const PublicationMetaPanel = () => {
const { meta } = useSelect((select) => ({
meta: select('core/editor').getEditedPostAttribute('meta'),
}));

const { editPost } = useDispatch('core/editor');

const fields = [
{ key: 'name', label: 'Journal Name', type: 'textField' },
{ key: 'issue', label: 'Issue', type: 'textField' },
{ key: 'authors', label: 'Authors', type: 'textField' },
{ key: 'url', label: 'URL', type: 'textField' },
{ key: 'date', label: 'Date', type: 'dateField' },
];

const renderDateControl = ({ key, label }) => {
const metaKey = `organizational_publication_${key}`;

let value = meta[metaKey] || null;

return (
<DateControl
key={key}
metaKey={metaKey}
label={label}
value={value}
/>
);
};

const renderControl = ({ key, label, type }) => {
const metaKey = `organizational_publication_${key}`;

switch (type) {
case 'textField':
return (
<TextControl
key={key}
label={__(label, 'organizational')}
value={meta[metaKey]}
onChange={(value) => {
editPost({ meta: { [metaKey]: value } });
}}
/>
);
case 'dateField':
return renderDateControl({ key, label });
}
};

return (
<PluginDocumentSettingPanel
name="publication-meta-panel"
title={__('Publication Data')}
icon={<></>}
>
{fields.map(renderControl)}
</PluginDocumentSettingPanel>
);
};

registerPlugin('publication-meta-panel', {
render: PublicationMetaPanel,
});
95 changes: 95 additions & 0 deletions src/Publications.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,99 @@ class Publications extends ContentType {
* @var string
*/
public string $menu_icon = 'dashicons-book';

/**
* Meta keys automatically registered for the post type.
*
* @since 2.2.0
*
* @return array
*/
public function get_meta(): array {
return [
'organizational_publication_name' => [
'title' => 'Journal Name',
'type' => 'string',
'show_in_rest' => true,
'bindings_sources' => [],
],
'organizational_publication_issue' => [
'title' => 'Issue',
'type' => 'string',
'show_in_rest' => true,
'bindings_sources' => [],
],
'organizational_publication_authors' => [
'title' => 'Authors',
'type' => 'string',
'show_in_rest' => true,
'bindings_sources' => [],
],
'organizational_publication_url' => [
'title' => 'URL',
'type' => 'string',
'show_in_rest' => true,
'bindings_sources' => [],
],
'organizational_publication_date' => [
'title' => 'Date',
'type' => 'number',
'show_in_rest' => true,
'bindings_sources' => [
'organizational/publication-date' => [
'label' => __( 'Publication date', 'organizational' ),
'get_value_callback' => [ $this, 'get_date_source' ],
'uses_context' => array( 'postId' ),
],
],
],
];
}

/**
* Get binding source data for displaying a publication date.
*
* @since 2.2.0
*
* @param array $source_args Array containing source arguments.
* @param \WP_Block $block_instance The block instance.
* @return string The publication date or an empty string if not available.
*/
public function get_date_source( array $source_args, \WP_Block $block_instance ): string {
$post_id = $block_instance->context['postId'] ?? false;

if ( $post_id ) {
$date = get_post_meta( $post_id, 'organizational_publication_date', true );

if ( ! $date ) {
return '';
}

// Convert to date format set in WordPress settings.
$date = date_i18n( get_option( 'date_format' ), $date );

return $date;
}

return '';
}

/**
* Enqueue block editor assets used by this post type.
*/
public function enqueue_block_editor_assets(): void {
if ( 'post' !== get_current_screen()->base || get_current_screen()->post_type !== $this->post_type ) {
return;
}

$asset_data = require_once ORGANIZATIONAL_PLUGIN_DIR . '/js/build/publication-meta/index.asset.php';

wp_enqueue_script(
'organizational-publication-meta',
plugins_url( '/js/build/publication-meta/index.js', ORGANIZATIONAL_PLUGIN_FILE ),
$asset_data['dependencies'],
$asset_data['version'],
true
);
}
}
1 change: 1 addition & 0 deletions webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const TerserPlugin = require('terser-webpack-plugin');
* Retrieve all entries from subdirectories of the src directory.
*
* Valid entry points are index.js and view.js.
*
* @param sourceDir
* @param type
* @returns {object} An object of entry points.
Expand Down

0 comments on commit 079a619

Please sign in to comment.