Skip to content

Conversation

@enejb
Copy link
Member

@enejb enejb commented Dec 5, 2025

!!! Do not merge

Screen.Recording.2025-12-04.at.3.46.02.PM.mov

Proposed changes:

  • This PR adds a "reusable form" block that lets us insert a reusable form from anywhere.

Other information:

  • Have you written new tests for your changes, if applicable?
  • Have you checked the E2E test CI results, and verified that your changes do not break them?
  • Have you tested your changes on WordPress.com, if applicable (if so, you'll see a generated comment below with a script to run)?

Jetpack product discussion

Does this pull request change what data or activity we track or use?

No

Testing instructions:

You need to feature enable with a filter somoething like this.

add_filter( 'jetpack_block_editor_feature_flags', 'eb_register_feature' );
function eb_register_feature( $flags ) {
    $flags['reusable-forms'] = true;
    return $flags;
}

In this version you should be able to create a new jetpack-form
custom post type by going to /wp-admin/post-new.php?post_type=jetpack-form

insert a form block there. (currently there is no restriction in what kind of block you can insert but the idea is to only be able to insert a form block via the block inserter.

enejb added 2 commits December 4, 2025 13:55
Introduces a new reusable form block with supporting TypeScript files and updates block registration to use the dist folder. The block's metadata and editor integration are enhanced, and the webpack config is updated to build and copy the new block assets correctly.
@enejb enejb requested review from a team and Copilot December 5, 2025 00:12
@enejb enejb added [Type] Enhancement Changes to an existing feature — removing, adding, or changing parts of it [Status] Needs Review This PR is ready for review. [Package] Forms labels Dec 5, 2025
@github-actions
Copy link
Contributor

github-actions bot commented Dec 5, 2025

Are you an Automattician? Please test your changes on all WordPress.com environments to help mitigate accidental explosions.

  • To test on WoA, go to the Plugins menu on a WoA dev site. Click on the "Upload" button and follow the upgrade flow to be able to upload, install, and activate the Jetpack Beta plugin. Once the plugin is active, go to Jetpack > Jetpack Beta, select your plugin (Jetpack), and enable the add/resuable-form-block branch.
  • To test on Simple, run the following command on your sandbox:
bin/jetpack-downloader test jetpack add/resuable-form-block

Interested in more tips and information?

  • In your local development environment, use the jetpack rsync command to sync your changes to a WoA dev blog.
  • Read more about our development workflow here: PCYsg-eg0-p2
  • Figure out when your changes will be shipped to customers here: PCYsg-eg5-p2

@github-actions github-actions bot added [Block] Contact Form Form block (also see Contact Form label) [Feature] Contact Form labels Dec 5, 2025
@github-actions
Copy link
Contributor

github-actions bot commented Dec 5, 2025

Thank you for your PR!

When contributing to Jetpack, we have a few suggestions that can help us test and review your patch:

  • ✅ Include a description of your PR changes.
  • 🔴 Add a "[Status]" label (In Progress, Needs Review, ...).
  • ✅ Add a "[Type]" label (Bug, Enhancement, Janitorial, Task).
  • ✅ Add testing instructions.
  • ✅ Specify whether this PR includes any changes to data or privacy.
  • 🔴 Add changelog entries to affected projects

This comment will be updated as you work on your PR and make changes. If you think that some of those checks are not needed for your PR, please explain why you think so. Thanks for cooperation 🤖


🔴 Action required: Please add missing changelog entries for the following projects: projects/packages/forms

Use the Jetpack CLI tool to generate changelog entries by running the following command: jetpack changelog add.
Guidelines: /docs/writing-a-good-changelog-entry.md


Follow this PR Review Process:

  1. Ensure all required checks appearing at the bottom of this PR are passing.
  2. Make sure to test your changes on all platforms that it applies to. You're responsible for the quality of the code you ship.
  3. You can use GitHub's Reviewers functionality to request a review.
  4. When it's reviewed and merged, you will be pinged in Slack to deploy the changes to WordPress.com simple once the build is done.

If you have questions about anything, reach out in #jetpack-developers for guidance!

@github-actions github-actions bot added [Status] Needs Author Reply We need more details from you. This label will be auto-added until the PR meets all requirements. and removed [Status] Needs Review This PR is ready for review. labels Dec 5, 2025
Copilot finished reviewing on behalf of enejb December 5, 2025 00:16
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds a reusable form block (jetpack/form) that enables users to insert forms from the jetpack-form custom post type anywhere on their site. The implementation is feature-flagged behind reusable-forms and includes both frontend rendering and editor capabilities.

Key Changes

  • New reusable form block with reference-based rendering system
  • Webpack configuration update to preserve block directory structure
  • Server-side rendering via Form_Block::render() that fetches and renders form content

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
projects/packages/forms/tools/webpack.config.blocks.js Modified CopyWebpackPlugin to preserve directory structure for block.json files, added entry point for new form block
projects/packages/forms/src/class-reusable-forms.php Added block registration call to initialize the new jetpack/form block
projects/packages/forms/src/blocks/form/index.tsx Block registration with feature flag check and Material Design icon
projects/packages/forms/src/blocks/form/edit.tsx Editor component handling form loading, error states, and inner block rendering
projects/packages/forms/src/blocks/form/class-form-block.php Server-side block registration and rendering callback that fetches form content by reference
projects/packages/forms/src/blocks/form/block.json Block metadata defining attributes, supports, and configuration

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +54 to +61
// No ref specified
if ( ! ref ) {
return (
<div { ...blockProps }>
<Warning>{ __( 'No form selected. Please select a form.', 'jetpack-forms' ) }</Warning>
</div>
);
}
Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

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

The condition check order is incorrect. The code checks if ref is missing (line 55) after already checking if the form is missing (line 46). However, when ref is falsy, the useEntityRecord and useEntityBlockEditor hooks at lines 13-18 will be called with undefined or 0, which could cause unnecessary API requests or errors. The check for !ref should be moved before using it in the hooks to avoid this issue.

Copilot uses AI. Check for mistakes.
return '';
}

unset( $content );
Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

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

The $content parameter is unused and immediately unset. Instead of unsetting it, consider removing it from the function signature or using a comment to indicate it's intentionally unused (e.g., // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable or similar). Alternatively, if it's required by the WordPress block render callback signature, add a PHPDoc comment explaining why it's present but unused.

Copilot uses AI. Check for mistakes.
if ( ! $form_post || 'jetpack-form' !== $form_post->post_type ) {
return '';
}

Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

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

Missing security check for post status. The code retrieves and renders a form post without verifying its status. It should check that the post is published (or at least not trashed) before rendering it. Consider adding a check like if ( 'publish' !== $form_post->post_status ) to ensure only published forms are displayed on the frontend.

Suggested change
// Only render published forms
if ( 'publish' !== $form_post->post_status ) {
return '';
}

Copilot uses AI. Check for mistakes.
if ( ! $form_post || 'jetpack-form' !== $form_post->post_type ) {
return '';
}

Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

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

Missing capability check for viewing the form. The code doesn't verify that the current user has permission to view the referenced form. This could potentially expose private or draft forms to unauthorized users. Consider adding a capability check using current_user_can() or checking the post's visibility status before rendering.

Suggested change
// Check if the current user can view the form post
$post_status = get_post_status( $form_post );
if ( 'publish' !== $post_status && ! current_user_can( 'edit_post', $form_post->ID ) ) {
return '';
}

Copilot uses AI. Check for mistakes.
Comment on lines +41 to +62
public static function render( $atts, $content = '' ) {
// Get the form reference ID
$ref = isset( $atts['ref'] ) ? absint( $atts['ref'] ) : 0;

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

unset( $content );

// Get the referenced form post
$form_post = get_post( $ref );

// Verify the post exists and is a jetpack-form post type
if ( ! $form_post || 'jetpack-form' !== $form_post->post_type ) {
return '';
}

// Return the form content rendered with do_blocks
return do_blocks( $form_post->post_content );
}
}
Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

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

Missing test coverage for the new Form_Block class. The repository has comprehensive test coverage for other blocks (see tests/php/contact-form/ directory), but there are no tests for the new Form_Block::render() method. Consider adding tests to verify:

  • Rendering with valid ref
  • Handling of missing/invalid ref
  • Post type validation
  • Edge cases like non-existent posts

Copilot uses AI. Check for mistakes.
Comment on lines 9 to 65
export default function FormEdit( { attributes } ) {
const { ref } = attributes;

// Fetch the form post from the jetpack-form post type
const { record, hasResolved } = useEntityRecord( 'postType', 'jetpack-form', ref );

// Get the blocks from the form post
const [ blocks, onInput, onChange ] = useEntityBlockEditor( 'postType', 'jetpack-form', {
id: ref,
} );

// Check if the form is missing
const isMissing = hasResolved && ! record;

// Get the block props for the wrapper
const blockProps = useBlockProps( {
className: 'wp-block-jetpack-form',
} );

// Get inner blocks props for rendering the form blocks
const innerBlocksProps = useInnerBlocksProps( blockProps, {
value: blocks,
onInput,
onChange,
renderAppender: blocks?.length ? undefined : () => null,
} );

// Loading state
if ( ! hasResolved ) {
return (
<div { ...blockProps }>
<Spinner />
</div>
);
}

// Missing or invalid form
if ( isMissing ) {
return (
<div { ...blockProps }>
<Warning>{ __( 'Form not found. Please select a valid form.', 'jetpack-forms' ) }</Warning>
</div>
);
}

// No ref specified
if ( ! ref ) {
return (
<div { ...blockProps }>
<Warning>{ __( 'No form selected. Please select a form.', 'jetpack-forms' ) }</Warning>
</div>
);
}

// Render the form blocks
return <div { ...innerBlocksProps } />;
}
Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

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

Missing test coverage for the FormEdit component. The repository has comprehensive test coverage for other components (see tests/js/ directory), but there are no tests for the new FormEdit component. Consider adding tests to verify:

  • Loading state rendering
  • Error handling for missing forms
  • Error handling for missing ref
  • Proper block rendering with valid data

Copilot uses AI. Check for mistakes.
@jp-launch-control
Copy link

jp-launch-control bot commented Dec 5, 2025

Code Coverage Summary

Cannot generate coverage summary while tests are failing. 🤐

Please fix the tests, or re-run the Code coverage job if it was something being flaky.

Full summary · PHP report · JS report

absoluteFilename
);
return relativePath;
},
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do we need this change?

}
},
"editorScript": "file:./index.js"
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if naming could be adjusted for better clarity, and to distingguish the new reusable form functionality we're adding from the Jetpack Forms package/product name and our long standing form block.

We now have:

  • A "reusable forms" class that registers a "jetpack-form" post type
  • A "class-form-block" that registers a "jetpack/form" block that lives in the "src/blocks/form" folder
  • A "REST_Jetpack_Form_Controller" that instatiates with "jetpack-form"
  • All of this is in the context of a plugin call Jetppack Forms that already is build around a "contact-form" block.

If we settle the the 'reusable' terminology, we might use naming like below. These names would be hard to confuse with the long standing form block or generic Jetpack Forms package naming.

  • CPT slug: jetpack-reusable-form
  • Block name: jetpack/reusable-form
  • Folder: src/blocks/reusable-form
  • Class names: REST_Jetpack_Reusable_Form_Controller, Reusable_Form_Block, etc.

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

Labels

[Block] Contact Form Form block (also see Contact Form label) [Feature] Contact Form [Package] Forms [Status] Needs Author Reply We need more details from you. This label will be auto-added until the PR meets all requirements. [Type] Enhancement Changes to an existing feature — removing, adding, or changing parts of it

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants