close
Skip to content

Update/ai image filename context#471

Merged
dkotter merged 11 commits into
WordPress:developfrom
saarnilauri:update/ai-image-filename-context
May 5, 2026
Merged

Update/ai image filename context#471
dkotter merged 11 commits into
WordPress:developfrom
saarnilauri:update/ai-image-filename-context

Conversation

@saarnilauri
Copy link
Copy Markdown
Contributor

@saarnilauri saarnilauri commented Apr 24, 2026

What?

Closes #402

Derives a descriptive, slugified filename for AI-generated images from the context that uploadImage() already has locally (alt text, which falls back to the prompt), so attachments land in the Media Library as e.g. getting-started-with-the-wordpress-block-editor.png instead of ai-generated-image-<timestamp>.png.

Why?

All AI-generated images currently land in the Media Library as ai-generated-image-<timestamp>.png. That filename:

  • carries no context about the image content,
  • is not SEO-friendly,
  • makes images hard to scan in the Media Library, and
  • provides no visible hint to distinguish between multiple AI-generated images of different posts.

The issue asks for context-aware filenames derived from the post title or prompt. The plugin already computes the descriptive string we need (alt_text, which is either the generated alt text or the prompt fallback) inside uploadImage(), one line above where title is set from it. The filename can be derived from the same source with no change to the four call sites.

How?

Implementation follows the direction from @dkotter in the issue thread:

  • Client-side only — no shared PHP helper, no schema change, no new public API.
  • Uses cleanForSlug from @wordpress/url for normalization (lowercase, punctuation stripped, hyphen-separated).
  • Capped at 75 characters, trimmed on a hyphen boundary when possible.
  • No ai-generated-image- prefix — just the slug.
  • Empty/whitespace input → filename is omitted, and the existing PHP default (ai-generated-image-<timestamp>) kicks in. This satisfies the issue's fallback requirement without any PHP source changes.

Changes:

  • src/utils/text.ts — adds slugifyForFilename( text, length = 75 ). Runs cleanForSlug, truncates on a hyphen boundary (reusing the same ≥50%-of-length rule as the existing trimText), returns an empty string when the input has no slug-worthy characters.
  • src/features/image-generation/functions/upload-image.ts — derives params.filename from params.alt_text via the new helper. Omits the param when the slug is empty.
  • tests/Integration/Includes/Abilities/Image_ImportTest.php — strengthens test_execute_callback_uses_defaults to assert the ai-generated-image-<timestamp> format is preserved for the empty-slug fallback path.

All four existing uploadImage() call sites (GenerateFeaturedImage, GenerateImageStandalone, GenerateImageInlineModal, MediaLibraryImageEditor) are untouched — the filename is derived centrally.

Use of AI Tools

AI assistance: Yes
Tool(s): Claude Code
Model(s): Claude Opus 4.7
Used for: Code exploration, implementation of the slug helper and wiring in upload-image.ts, PHP test extension. All output was reviewed and edited before submission; manual testing in WordPress Playground (WP 7.0-RC2, PHP 8.3, Gutenberg 23.0.0) was performed by me.

Testing Instructions

Requires an image-generation provider configured (e.g. OpenAI API key).

  1. Enable the Image generation feature under the AI settings.
  2. Open a published post with a distinctive title (e.g. "Getting started with the WordPress block editor") and generate a featured image. In the Media Library, confirm the new attachment's filename is a hyphenated slug derived from the post/alt text — not ai-generated-image-<timestamp>.png.
  3. Generate a featured image for a post with a long title. Confirm the filename is capped near 75 characters and trimmed on a hyphen boundary.
  4. Insert an AI image inline inside a post with a prompt like A red bicycle leaning against a stone wall at sunset. Confirm the Media Library filename reflects the prompt/alt text.
  5. Generate an image from the Media Library (no post context). Confirm the filename is still a prompt-based slug, not the timestamp fallback.
  6. Run the test suites:
    • npm run test:php
    • npm run test:e2e

Screenshots

image

Changelog Entry

Changed - AI-generated images are now saved with descriptive, slugified filenames derived from the post title or prompt instead of ai-generated-image-<timestamp>.

Open WordPress Playground Preview

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 24, 2026

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: saarnilauri <laurisaarni@git.wordpress.org>
Co-authored-by: dkotter <dkotter@git.wordpress.org>
Co-authored-by: dhrupo <dhrupo@git.wordpress.org>
Co-authored-by: jeffpaul <jeffpaul@git.wordpress.org>
Co-authored-by: hi0001234d <emptyopssphere@git.wordpress.org>
Co-authored-by: kishan-ranawat <kishanranawat@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 24, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 69.17%. Comparing base (7b74298) to head (3c7b9dd).

Additional details and impacted files
@@            Coverage Diff             @@
##             develop     #471   +/-   ##
==========================================
  Coverage      69.16%   69.17%           
  Complexity       981      981           
==========================================
  Files             63       63           
  Lines           4648     4649    +1     
==========================================
+ Hits            3215     3216    +1     
  Misses          1433     1433           
Flag Coverage Δ
unit 69.17% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@saarnilauri
Copy link
Copy Markdown
Contributor Author

@dkotter You said "keep this focused on the client-side only for now", which I read as: no shared PHP helper, no schema widening. I'd also like to confirm whether that applies to a filter hook too.

The original issue asked for a wpai_generated_image_filename filter so site owners can customize the final name. I can either:

  • (a) Skip the filter for now — strictly client-side. The PHP fallback (ai-generated-image-<timestamp>) stays untouched, and the slug just flows through sanitize_file_name() like any other caller-supplied filename. Smallest surface area.
  • (b) Add the filter anyway — one line in Import_Base64_Image::import_image() wrapping the final sanitized filename. Gives the extensibility the issue asks for, still no schema/helper changes.

What are your thoughts?

@dkotter
Copy link
Copy Markdown
Collaborator

dkotter commented Apr 24, 2026

You said "keep this focused on the client-side only for now", which I read as: no shared PHP helper, no schema widening. I'd also like to confirm whether that applies to a filter hook too.

Yeah, comment was mostly about adding a PHP helper. I'm totally fine adding a new filter though so feel free to move forward with that

@dhrupo
Copy link
Copy Markdown

dhrupo commented Apr 28, 2026

I reviewed this while comparing it against my duplicate PR #480. I think the centralized client-side approach here is the better direction and it matches the guidance from the issue thread more closely.\n\nOne thing I wanted to flag from that comparison: issue #402 explicitly asks for an prefix and a unique suffix/timestamp. This PR improves the context part well, but currently drops both of those pieces.\n\nI’m closing #480 so discussion can stay here. If it helps, I’m happy to help fold any useful part of that PR into this one instead of keeping two parallel approaches open.

@dhrupo
Copy link
Copy Markdown

dhrupo commented Apr 28, 2026

I reviewed this while comparing it against my duplicate PR #480. I think the centralized client-side approach here is the better direction and it matches the guidance from the issue thread more closely.

One thing I wanted to flag from that comparison: issue #402 explicitly asks for an ai-generated-image- prefix and a unique suffix/timestamp. This PR improves the context part well, but currently drops both of those pieces.

I’m closing #480 so discussion can stay here. If it helps, I’m happy to help fold any useful part of that PR into this one instead of keeping two parallel approaches open.

@saarnilauri
Copy link
Copy Markdown
Contributor Author

Would like to hear @dkotter thoughts on what @dhrupo flags, in the comment above.

@dkotter
Copy link
Copy Markdown
Collaborator

dkotter commented Apr 28, 2026

One thing I wanted to flag from that comparison: issue #402 explicitly asks for an ai-generated-image- prefix and a unique suffix/timestamp. This PR improves the context part well, but currently drops both of those pieces.

While yes, this is mentioned in the attached Issue, I don't think that's a requirement and I actually don't think that's the right slug to use.

Right now we use ai-generated-image-<timestamp> to ensure we have unique slugs for each image. With the approach here to switch to using the context provided, there's no need to have the timestamp anymore (can already easily see when an image was added to WordPress) and keeping the ai-generated-image part also doesn't add any value (other than a quick glance, this is an AI generated image, which we can handle that in a better way if that's desired functionality)

@saarnilauri
Copy link
Copy Markdown
Contributor Author

@dkotter @jeffpaul ready for your review.

Comment thread includes/Abilities/Image/Import_Base64_Image.php Outdated
@saarnilauri
Copy link
Copy Markdown
Contributor Author

@dkotter the changes you requested are have been implemented.

@dkotter dkotter merged commit 6afc763 into WordPress:develop May 5, 2026
18 checks passed
simison pushed a commit to simison/ai that referenced this pull request May 25, 2026
* Add the slugifyForFilename utility function
* Use the slugifyForFilename utility function to set the filename.
* Add wpai_generated_image_filename filter
* Only pass the filename to the wpai_generated_image_filename filter and not the extension.

Co-authored-by: saarnilauri <laurisaarni@git.wordpress.org>
Co-authored-by: dkotter <dkotter@git.wordpress.org>
Co-authored-by: dhrupo <dhrupo@git.wordpress.org>
Co-authored-by: jeffpaul <jeffpaul@git.wordpress.org>
Co-authored-by: hi0001234d <emptyopssphere@git.wordpress.org>
Co-authored-by: kishan-ranawat <kishanranawat@git.wordpress.org>
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.

Core AI: Improve AI Generated Image Naming for Featured Images (Include AI Prefix + Context) (WP 7.0 RC)

4 participants