Add link-target and auto-redirect options to booking/login blocks
CI / Coding Standards (pull_request) Successful in 51s
CI / No Debug Code (pull_request) Successful in 3s
CI / Tests (PHP 8.2) (pull_request) Successful in 50s
CI / Tests (PHP 8.3) (pull_request) Successful in 1m2s
CI / Build Plugin Zip (pull_request) Has been skipped
CI / Tests (PHP 8.1) (pull_request) Successful in 53s
CI / PHPStan (pull_request) Successful in 1m24s
CI / Coding Standards (pull_request) Successful in 51s
CI / No Debug Code (pull_request) Successful in 3s
CI / Tests (PHP 8.2) (pull_request) Successful in 50s
CI / Tests (PHP 8.3) (pull_request) Successful in 1m2s
CI / Build Plugin Zip (pull_request) Has been skipped
CI / Tests (PHP 8.1) (pull_request) Successful in 53s
CI / PHPStan (pull_request) Successful in 1m24s
The booking block gains a loginPageId attribute choosing which page its logged-out "log in to book a lesson" link points to (default remains the WordPress login screen), and the student-login block gains a bookingPageId attribute controlling the logged-in "View available lessons" link and the post-login redirect target (default remains the current page). Both blocks also gain an autoRedirect toggle, off by default, that sends the visitor straight to the target page; block rendering starts after output, so the redirect runs on template_redirect by parsing the queried page's content for the block, with a self-target guard against redirect loops. The link targets are also available to the shortcodes as login_page_id/booking_page_id. Also fixes a pre-existing fatal: WordPress passes an empty string (not an array) to shortcode callbacks when a shortcode is used without attributes, so bare [us_booking] etc. threw a TypeError against the strictly-typed render(array $atts) methods. ShortcodeRegistrar now wraps each callback to normalize non-array attribute values. Closes #51 Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
+89
-3
@@ -4,10 +4,44 @@
|
||||
|
||||
const { registerBlockType } = wp.blocks;
|
||||
const { createElement: el } = wp.element;
|
||||
const { useBlockProps } = wp.blockEditor;
|
||||
const { useBlockProps, InspectorControls } = wp.blockEditor;
|
||||
const { PanelBody, SelectControl, ToggleControl } = wp.components;
|
||||
const { useSelect } = wp.data;
|
||||
const ServerSideRender = wp.serverSideRender;
|
||||
const { __ } = wp.i18n;
|
||||
|
||||
/**
|
||||
* Dropdown of published pages with a leading "default" choice.
|
||||
* Values are page IDs; 0 means the default behaviour.
|
||||
*/
|
||||
function PageSelect(props) {
|
||||
const pages = useSelect(
|
||||
(select) => select('core').getEntityRecords('postType', 'page', {
|
||||
per_page: -1,
|
||||
orderby: 'title',
|
||||
order: 'asc',
|
||||
status: 'publish',
|
||||
_fields: 'id,title',
|
||||
}),
|
||||
[]
|
||||
);
|
||||
|
||||
const options = [{ label: props.defaultLabel, value: '0' }].concat(
|
||||
(pages || []).map((page) => ({
|
||||
label: (page.title && page.title.rendered) || __('(no title)', 'unsupervised-schedular'),
|
||||
value: String(page.id),
|
||||
}))
|
||||
);
|
||||
|
||||
return el(SelectControl, {
|
||||
label: props.label,
|
||||
help: props.help,
|
||||
value: String(props.value || 0),
|
||||
options: options,
|
||||
onChange: (value) => props.onChange(parseInt(value, 10) || 0),
|
||||
});
|
||||
}
|
||||
|
||||
const blocks = [
|
||||
{
|
||||
name: 'us-scheduler/booking',
|
||||
@@ -16,6 +50,27 @@
|
||||
icon: 'calendar-alt',
|
||||
keywords: ['booking', 'lesson', 'schedule'],
|
||||
shortcode: 'us_booking',
|
||||
attributes: {
|
||||
loginPageId: { type: 'number', default: 0 },
|
||||
autoRedirect: { type: 'boolean', default: false },
|
||||
},
|
||||
inspector: (attributes, setAttributes) => el(
|
||||
PanelBody,
|
||||
{ title: __('Logged-out visitors', 'unsupervised-schedular') },
|
||||
el(PageSelect, {
|
||||
label: __('Login page', 'unsupervised-schedular'),
|
||||
help: __('Where the log-in link sends visitors who are not logged in.', 'unsupervised-schedular'),
|
||||
defaultLabel: __('WordPress login screen', 'unsupervised-schedular'),
|
||||
value: attributes.loginPageId,
|
||||
onChange: (loginPageId) => setAttributes({ loginPageId }),
|
||||
}),
|
||||
el(ToggleControl, {
|
||||
label: __('Redirect automatically', 'unsupervised-schedular'),
|
||||
help: __('Send logged-out visitors straight to the login page instead of showing a link.', 'unsupervised-schedular'),
|
||||
checked: !!attributes.autoRedirect,
|
||||
onChange: (autoRedirect) => setAttributes({ autoRedirect }),
|
||||
})
|
||||
),
|
||||
},
|
||||
{
|
||||
name: 'us-scheduler/student-login',
|
||||
@@ -24,6 +79,27 @@
|
||||
icon: 'admin-users',
|
||||
keywords: ['login', 'student', 'sign in'],
|
||||
shortcode: 'us_student_login',
|
||||
attributes: {
|
||||
bookingPageId: { type: 'number', default: 0 },
|
||||
autoRedirect: { type: 'boolean', default: false },
|
||||
},
|
||||
inspector: (attributes, setAttributes) => el(
|
||||
PanelBody,
|
||||
{ title: __('Logged-in visitors', 'unsupervised-schedular') },
|
||||
el(PageSelect, {
|
||||
label: __('Booking page', 'unsupervised-schedular'),
|
||||
help: __('Where students are sent after logging in, and where the link shown to already-logged-in visitors points.', 'unsupervised-schedular'),
|
||||
defaultLabel: __('This page', 'unsupervised-schedular'),
|
||||
value: attributes.bookingPageId,
|
||||
onChange: (bookingPageId) => setAttributes({ bookingPageId }),
|
||||
}),
|
||||
el(ToggleControl, {
|
||||
label: __('Redirect automatically', 'unsupervised-schedular'),
|
||||
help: __('Send logged-in visitors straight to the booking page instead of showing a link. Requires a booking page to be chosen.', 'unsupervised-schedular'),
|
||||
checked: !!attributes.autoRedirect,
|
||||
onChange: (autoRedirect) => setAttributes({ autoRedirect }),
|
||||
})
|
||||
),
|
||||
},
|
||||
{
|
||||
name: 'us-scheduler/student-register',
|
||||
@@ -52,9 +128,19 @@
|
||||
category: 'widgets',
|
||||
keywords: def.keywords,
|
||||
supports: { html: false, multiple: false },
|
||||
attributes: def.attributes || {},
|
||||
example: {},
|
||||
edit: function Edit() {
|
||||
return el('div', useBlockProps(), el(ServerSideRender, { block: def.name }));
|
||||
edit: function Edit(props) {
|
||||
const inspector = def.inspector
|
||||
? el(InspectorControls, {}, def.inspector(props.attributes, props.setAttributes))
|
||||
: null;
|
||||
|
||||
return el(
|
||||
'div',
|
||||
useBlockProps(),
|
||||
inspector,
|
||||
el(ServerSideRender, { block: def.name, attributes: props.attributes })
|
||||
);
|
||||
},
|
||||
save: () => null,
|
||||
transforms: {
|
||||
|
||||
Reference in New Issue
Block a user