Skip to content

LNHU-225: Custom post type and editor UI dropdown for Hero Images - #232

Open
djanelle-mit wants to merge 7 commits into
masterfrom
lnhu-225
Open

djanelle-mit wants to merge 7 commits into
masterfrom
lnhu-225

Conversation

@djanelle-mit

@djanelle-mit djanelle-mit commented Sep 24, 2026 •

Copy link
Copy Markdown

Developer

This work adds a plugin that introduces a new custom post type "Hero Images". This plugin also contains the homepage hero image block, which now allows the editor to select a hero image from the CPT via a dropdown in the block editor UI.

This is the first instance of our architectural decision to colocate the definitions of new data objects with all the instances of where they're rendered.

Stylesheets

  • Any theme or plugin whose stylesheets have changed has had its version
    string incremented.

Secrets

  • All new secrets have been added to Pantheon tiers
  • Relevant secrets have been updated in Github Actions
  • All new secrets documented in README

Documentation

  • Project documentation has been updated
  • No documentation changes are needed

Accessibility

  • ANDI or Wave has been run in accordance to
    our guide and
    all issues introduced by these changes have been resolved or opened as new
    issues (link to those issues in the Pull Request details above)

Stakeholder approval

  • Stakeholder approval has been confirmed
  • Stakeholder approval is not needed

Dependencies

YES | NO dependencies are updated

Code Reviewer

  • The commit message is clear and follows our guidelines
    (not just this pull request message)
  • The changes have been verified
  • The documentation has been updated or is unnecessary
  • New dependencies are appropriate or there were no changes

@djanelle-mit
djanelle-mit marked this pull request as draft September 24, 2026 19:44
@djanelle-mit
djanelle-mit marked this pull request as ready for review September 29, 2026 18:28

@matt-bernhardt matt-bernhardt left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'm flagging two changes (one of which I'm probably happy to let go if it's being too strict). The rest are non-blocking comments about some details that I see here and there.

Overall, I like where this gets us - being able to manage these images via the CMS instead of via PRs is a significant improvement on both of our workloads.

* @see https://make.wordpress.org/core/2025/03/13/more-efficient-block-type-registration-in-6-8/
* @see https://make.wordpress.org/core/2024/10/17/new-block-type-registration-apis-to-improve-performance-in-wordpress-6-7/
*/
function register_blocks() {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Non-blocking comment:

I'm a little uneasy about conflating hooks to classes and hooks to functions like this, but not so much that I'm going to ask for a change now. It may never be an issue, in which case no harm done.

It wouldn't be difficult to swap this to a class method if it does turn out to be problematic.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

This is a place where Copilot did the scaffolding, and I definitely need to understand this distinction better.

Do you have an example or pseudo code for the distinction between the two options?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

There's a proof of concept for the difference at #236. This isn't something I expect to merge, but it shows what the alternative implementation would be. This function itself is pretty simple, and doesn't pollute the root PHP script terribly - so I'm happy to leave it for now. If we end up adding more complexity to this plugin, however, this might become more warranted.

'hero_images',
'meta',
array(
'get_callback' => function( $data, $field, $request, $type ) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Maybe a requested change?

PHPCS is flagging the need for a space between function and the parentheses on this line. If you'd rather not deal with this now, I'm happy to leave it be - but I'm hoping to tackle a maintenance ticket for our plugins soon-ish that would pick it up at that point.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Would the maintenance ticket for the plugins apply this across the board (vs making a tactical fix only for this instance)? I think I'll leave this as-is for now.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The scope of the maintenance ticket is a bit nebulous - I've just been noticing that there's a small amount of technical debt like this in otherwise-clean plugins, and I've found it much easier to "hold the line" if we're always starting from a clean slate, rather than "there's a small number of things we're ignoring". It's a lot more noticeable when previously empty output now has something, than when a list of two items becomes a list of three.

}

// Require the necessary classes.
require_once( plugin_dir_path( __FILE__ ) . 'src/class-heroimage.php' );

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Non-blocking comment:

require_once does not need parentheses (it is a statement, not a function). What you've got here is consistent with all other plugins, so I like that we're being consistent here. I'm mentioning it now so that there's background when I set up a PR to change all of these plugins at the same time as part of a maintenance ticket.

"label": "Citation",
"name": "citation",
"type": "text",
"instructions": "The text used to credit the source of the hero image, e.g. \"Muriel Cooper personal archives\".",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Requested change:

Could we provide an example that uses different content for this citation field than what's used in the citation link text field? Setting this instruction to something like from the Muriel Cooper personal archives would make the distinction between the two fields a bit clearer, IMO.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Good call! Updated.

<?php if ( $hero_credit ) : ?>
<span class="hero-image-credit">
<?php
// phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped -- built from esc_html()/esc_url() pieces above.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Non-blocking comments:

  1. It looks like you've been using PHPCS locally, if you're selectively turning off checks like this? How has that process been so far?
  2. If I follow the logic of the variable names used on lines 47-57, I wonder if the final output should be $escaped_hero_credit to reflect that the contents have already been processed via an escaping function?
  3. I think I like the approach of relying on context-specific escaping functions while compiling the value - if we wanted to be particularly robust while still enforcing escaping at this level, we could use wp_kses to strip out all markup except for the link with the expected attributes here, and satisfy the requirements of this sniff.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

  1. I've been using CoPilot to help move things around or scaffold things, and PHPCS and the npm run build are always run as part of those. It's been helping my commits be more consistent, so it's easier to see when something is actually changed versus me forgetting to format something correctly.
  2. Yes, I think being as crisp as possible with variables names makes a ton of sense. Updated.
  3. I'm not sure I follow what this means

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

There's a proof of concept for using wp_kses at #237 - as with the other alternate, this isn't something I expect to be merged - just a demonstration for how the pattern works. We wouldn't necessarily drop the compilation step from lines 47-57, all those escaping and protection steps are likely still necessary (certainly the esc_url and esc_attr methods are doing work that wp_kses doesn't) - but it would allow us not to turn off the protection of the sniff at the rendering line, while still enforcing an allowlist of only the markup we expect to be present.

@matt-bernhardt matt-bernhardt left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I see the updated instructions values, which is the one thing I felt most strongly about. I've set up demonstrations for the two code patterns you asked about, but left them as draft because I don't expect them to merge - they're for discussion purposes only.

:shipit:

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.

2 participants