Skip to content

Conversation

@nikkifurls
Copy link
Contributor

Summary

This PR aims to address the issue outlined in #97, which involves removing the dependency on Fieldmanager for generating admin settings pages within WP Newsletter Builder and manually creating these settings pages instead. This change is intended to simplify the installation process for developers by eliminating the need for an additional plugin. Fixes #97

Changes

  • Remove Fieldmanager dependency for admin settings page creation.
  • Manually create the admin settings pages within WP Newsletter Builder.

Additional Information

During this process, consideration was given to utilizing Gutenberg for the admin edit page, as mentioned in the issue's description and supported by examples and suggestions in the issue's comments. Specifically, the use of the useOption hook from alleyinteractive/alley-scripts was proposed, along with the potential development of additional hooks or helpers for managing settings pages with Gutenberg.

Test Instructions

  1. Ensure WP Newsletter Builder is installed without Fieldmanager.
  2. Navigate to the admin settings pages for WP Newsletter Builder.
  3. Verify that all settings pages are accessible and function as expected without the Fieldmanager plugin.

References

apiFetch({ path: '/wp-newsletter-builder/v1/settings' })
.then((response) => {
setFooterSettings(response as any as FooterSettings);
setSettings(response as any as Settings);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I recognize that you didn't change the underlying code here, but it would be good to validate that what comes back from the API is in the proper shape. What I usually do here is create a function that takes an unknown parameter and guarantees a return type, and throws if it can't. The zod library is very good for this and I can help point you in the right direction for how to implement it (it's pretty straightforward but I have examples I can share).

}
}

export default function ImagePicker({
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have an image picker component available as part of block-editor-tools which I would like to use here if possible: https://github.com/alleyinteractive/alley-scripts/tree/main/packages/block-editor-tools/src/components/image-picker

// Get all posts with the nb_template post type.
const [templatePosts, setTemplatePosts] = useState([]);
useEffect(() => {
apiFetch({ path: '/wp/v2/nb_template' })
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if there are more than $posts_per_page templates? At a minimum we should fetch 100 per page, and it would be good to check the total number of pages and continue to fetch until we've got them all.

*/
const { createErrorNotice, createNotice, removeAllNotices } = noticeOperations;
const saveSettingsData = () => {
onSave().then(() => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally I prefer the async/await syntax vs. promises (it eliminates additional nesting). You can wrap an await call in try/catch to get the same behavior of .catch() and .finally() and so on.

isSaving = false,
onChange = () => {},
onSave = () => {},
} = useOption('nb_settings');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should make a custom hook for working with Newsletter Builder settings that does a few things:

  1. It would wrap useOption so that we would eliminate duplicate code where we're extracting values from the settings object.
  2. We could verify that the value returned from the call is of the proper shape and type so TypeScript is happy (and could convert this file to a TypeScript file while we're at it).
  3. We could establish defaults when values don't exist.

* @param {string} key Key to update.
* @param {string} value Value to update.
*/
const updateSettingsData = (key, value) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By creating our own custom hook we could also encapsulate this functionality so that the implementing component gets a getter and a setter for each value, for instance.

Comment on lines +27 to +28
// add_action( 'init', [ $this, 'maybe_register_settings_page' ] );
// add_filter( 'pre_update_option_' . static::SETTINGS_KEY, [ $this, 'sort_settings_on_save' ], 10, 1 );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be deleted?

* Enqueue scripts and styles for the settings page.
*/
public function enqueue_assets() {
wp_enqueue_script( 'wp-newsletter-builder-admin-email-types' );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this logic only be fired on the page where settings are set vs. on all admin pages?

if ( function_exists( 'fm_register_submenu_page' ) && \current_user_can( 'manage_options' ) ) {
\fm_register_submenu_page( static::SETTINGS_KEY, 'edit.php?post_type=nb_newsletter', __( 'Email Types', 'wp-newsletter-builder' ), __( 'Email Types', 'wp-newsletter-builder' ) );
\add_action( 'fm_submenu_' . static::SETTINGS_KEY, [ $this, 'register_fields' ] );
\fm_register_submenu_page( static::SETTINGS_KEY, 'edit.php?post_type=nb_newsletter', __( 'Email Types', 'wp-newsletter-builder' ), __( 'Email Types', 'wp-newsletter-builder' ) );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will need to remove the FM call here since we're fully removing FM as a dependency.

'schema' => [
'type' => 'array',
'properties' => [
'uuid4' => [
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd love to figure out how to not require a UUID for the settings order - maybe this is established in JS only and not saved to the DB? Maybe we find another way to establish keys to avoid issues with sorting?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Remove dependency on Fieldmanager and manually create admin pages

3 participants