{"id":253516,"date":"2025-10-10T11:47:35","date_gmt":"2025-10-10T11:47:35","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/image-alt-sync\/"},"modified":"2025-10-10T11:48:54","modified_gmt":"2025-10-10T11:48:54","slug":"image-alt-sync","status":"publish","type":"plugin","link":"https:\/\/pcd.wordpress.org\/plugins\/image-alt-sync\/","author":14207762,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_crdt_document":"","version":"1.4.11","stable_tag":"1.4.11","tested":"6.8.5","requires":"5.4","requires_php":"","requires_plugins":null,"header_name":"Image Alt Sync","header_author":"Laurent DUFOUR","header_description":"Replace <img> alt attributes in post content with the media library alt text. Batch processing with status\/date filters, post ID ranges, skip & exclude options, dry run logs (browser & WP-CLI).","assets_banners_color":"","last_updated":"2025-10-10 11:48:54","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"","header_author_uri":"https:\/\/www.laurentdufour.eu\/","rating":0,"author_block_rating":0,"active_installs":10,"downloads":237,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.4.11":{"tag":"1.4.11","author":"dufour_l","date":"2025-10-10 11:48:54"}},"upgrade_notice":{"1.3":"<p>Same sleek UI as 1.1 with all the newer capabilities from 1.2.<\/p>"},"ratings":[],"assets_icons":[],"assets_banners":[],"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.4.11"],"block_files":[],"assets_screenshots":[],"screenshots":[],"jetpack_post_was_ever_published":false},"plugin_section":[],"plugin_tags":[1953,17214,11137,163,186],"plugin_category":[34,50,55],"plugin_contributors":[165865],"plugin_business_model":[],"class_list":["post-253516","plugin","type-plugin","status-publish","hentry","plugin_tags-accessibility","plugin_tags-alt-text","plugin_tags-batch","plugin_tags-images","plugin_tags-seo","plugin_category-accessibility","plugin_category-media","plugin_category-seo-and-marketing","plugin_contributors-dufour_l","plugin_committers-dufour_l"],"banners":[],"icons":{"svg":false,"icon":"https:\/\/s.w.org\/plugins\/geopattern-icon\/image-alt-sync.svg","icon_2x":false,"generated":true},"screenshots":[],"raw_content":"<!--section=description-->\n<p><strong>Image Alt Sync<\/strong> scans selected posts and updates any <code>&lt;img&gt;<\/code> tags found in the post content that reference media items (class <code>wp-image-###<\/code>), and replaces their <code>alt<\/code> attributes with the attachment\u2019s <code>_wp_attachment_image_alt<\/code> value:\n- If the image is in the Media Library, it prefers the attachment\u2019s Alt Text.\n- If no attachment alt is set, it falls back to the image filename (without extension) or the post title (configurable in the UI).\n- Optionally skip images that aren\u2019t found in the Media Library.\n- Optionally restrict by image file extensions (e.g. <code>jpg,webp<\/code>).<\/p>\n\n<p>Run in <strong>dry run<\/strong> first to see exactly what would change. The log shows each post processed and any per-image alt changes.<\/p>\n\n<p><strong>Highlights<\/strong>\n- Processes <strong>per post<\/strong> in <strong>batches<\/strong> with a <strong>customizable delay<\/strong> (default 100 posts, 1s).\n- Filter by <strong>post status<\/strong> and <strong>date range<\/strong> (quick buttons: Today, Yesterday, Last week, Last month, YTD, All).\n- <strong>Validate<\/strong> that \u201cDate after\u201d \u2264 \u201cDate before\u201d.\n- Limit by <strong>Post ID range<\/strong> with buttons to auto-fill <strong>lowest<\/strong> and <strong>highest<\/strong> post IDs.\n- <strong>Skip posts without <code>&lt;img&gt;<\/code><\/strong> (optional).\n- <strong>Exclude image extensions<\/strong> (comma-separated, e.g. <code>.svg,.gif<\/code>).\n- <strong>Dry run<\/strong> (browser &amp; WP-CLI) shows clickable post IDs, post titles, <strong>filenames<\/strong>, and detailed <strong>old \u2192 new<\/strong> alt replacements.\n- Only processes posts that have at least one <strong>image attachment<\/strong>.<\/p>\n\n<p>For more details you can send mail with your suggestions, recommendation to dufour_l@hotmail.com<\/p>\n\n<h3>Usage<\/h3>\n\n<ol>\n<li>Choose your filters (date range, min\/max post ID, or \u201cApply to all posts\u201d).<\/li>\n<li>Set <strong>Batch size<\/strong> and optional <strong>Delay<\/strong> between batches to throttle load.<\/li>\n<li>Choose a <strong>Date Range<\/strong>, or click a shortcut button (autofills <strong>Date after<\/strong>\/<strong>Date before<\/strong>).<\/li>\n<li>(Optional) Enter <strong>Lowest\/Highest Post ID<\/strong> or click the quick-fill buttons.<\/li>\n<li>(Optional) Check <strong>Skip posts without <code>&lt;img&gt;<\/code><\/strong>.<\/li>\n<li>(Optional) Enter <strong>Exclude extensions<\/strong> like <code>.svg,.gif<\/code>.<\/li>\n<li>Optionally enable <strong>Dry run<\/strong> to preview changes without saving.<\/li>\n<li>Click <strong>Start<\/strong>. Progress and detailed per-post changes appear in the log.<\/li>\n<li>If needed, click <strong>Stop<\/strong> to pause after the current batch finishes.<\/li>\n<\/ol>\n\n<p><strong>Tips<\/strong>\n- Use the \u201cLowest ID\u201d and \u201cHighest ID\u201d buttons to auto-fill the ID range.\n- Use the extension filter (e.g. <code>jpg, jpeg, png, webp<\/code>) to target specific image types.\n- Check \u201cSkip images not in media library\u201d to avoid external or missing files.<\/p>\n\n<h3>Usage (WP-CLI)<\/h3>\n\n<p>From your WordPress root:<\/p>\n\n<pre><code>wp image-alt-sync run --status=publish --after=2025-01-01 --before=2025-08-13 --batch-size=100 --delay=1 --dry-run --low-id=1 --high-id=9999 --skip-noimg=1 --exclude-ext=\".svg,.gif\"\n<\/code><\/pre>\n\n<p><strong>Args<\/strong>\n- <code>--status=<\/code> publish|pending|draft|any (default: publish)\n- <code>--after=<\/code> YYYY-MM-DD (optional)\n- <code>--before=<\/code> YYYY-MM-DD (optional)\n- <code>--batch-size=<\/code> integer (default: 100)\n- <code>--delay=<\/code> seconds (float, default: 1)\n- <code>--dry-run<\/code> flag (no changes saved if provided)\n- <code>--low-id=<\/code> minimum post ID (optional)\n- <code>--high-id=<\/code> maximum post ID (optional)\n- <code>--skip-noimg=<\/code> 1|0 (default 0)\n- <code>--exclude-ext=<\/code> comma-separated list like <code>.svg,.gif<\/code><\/p>\n\n<h3>Credits<\/h3>\n\n<p>Crafted with \u2764\ufe0f for accessible content.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Download the ZIP and install via <strong>Plugins \u2192 Add New \u2192 Upload Plugin<\/strong>.<\/li>\n<li>Activate <strong>Image Alt Sync<\/strong>.<\/li>\n<li>Go to <strong>Tools \u2192 Image Alt Sync<\/strong>.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id='will%20it%20update%20the%20media%20library%20alt%20text%3F'><h3>Will it update the Media Library alt text?<\/h3><\/dt>\n<dd><p>No. This tool updates <code>&lt;img alt=\"\"&gt;<\/code> <strong>inside post content<\/strong>. It does not edit attachment fields.<\/p><\/dd>\n<dt id='does%20dry%20run%20modify%20anything%3F'><h3>Does Dry Run modify anything?<\/h3><\/dt>\n<dd><p>No changes are saved during Dry Run. You\u2019ll only see a preview in the log.<\/p><\/dd>\n<dt id='which%20%60%3Cimg%3E%60%20tags%20are%20updated%3F'><h3>Which `` tags are updated?<\/h3><\/dt>\n<dd><p>Tags containing a class <code>wp-image-###<\/code> so we can map to the attachment ID and read its media-library alt text.<\/p><\/dd>\n<dt id='does%20it%20also%20change%20the%20media%20alt%20in%20the%20library%3F'><h3>Does it also change the media alt in the library?<\/h3><\/dt>\n<dd><p>No\u2014this version focuses on replacing <code>alt<\/code> inside post content from the media library value.<\/p><\/dd>\n<dt id='what%20if%20an%20%60%3Cimg%3E%60%20has%20no%20%60alt%60%3F'><h3>What if an `` has no `alt`?<\/h3><\/dt>\n<dd><p>The plugin injects <code>alt=\"...\"<\/code> based on the media alt.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.4.6 \/ 1.4.7 \/ 1.4.8 \/ 1.4.9 \/ 1.4.10 \/ 1.4.11<\/h4>\n\n<ul>\n<li>Fix: Code cleanup<\/li>\n<\/ul>\n\n<h4>1.4.5<\/h4>\n\n<ul>\n<li>Added two new date button ( last 4 weeks, since first of the month )<\/li>\n<\/ul>\n\n<h4>1.4.4<\/h4>\n\n<ul>\n<li>Fix: Code cleanup<\/li>\n<\/ul>\n\n<h4>1.4.2 \/ 1.4.3<\/h4>\n\n<ul>\n<li>Fix: Copyright sanitization.<\/li>\n<\/ul>\n\n<h4>1.4.1<\/h4>\n\n<ul>\n<li>Fix: Ajax not working.<\/li>\n<li>Add private to the post status<\/li>\n<li>Tested in Wordpress 6.8.2<\/li>\n<\/ul>\n\n<h4>1.4<\/h4>\n\n<ul>\n<li>Fix: Eliminated <code>[object Object]<\/code> messages by robust JSON\/error-string logging.<\/li>\n<li>Improvement: Processing now <strong>continues<\/strong> when a post\/batch fails; errors are reported in the log.<\/li>\n<li>Security: Added nonce checks to all AJAX endpoints.<\/li>\n<li>DX: Structured JavaScript in a separate file and passed <code>ajaxurl<\/code>\/<code>nonce<\/code> via <code>wp_localize_script<\/code>.<\/li>\n<li>UI: Clearer batch progress messages and safer scrolling of the log.<\/li>\n<\/ul>\n\n<h4>1.3<\/h4>\n\n<ul>\n<li>Restored the v1.1 UI while keeping the v1.2 functionality and enhancements.<\/li>\n<li>Post ID range quick-fill buttons; dry run shows filenames and detailed changes.<\/li>\n<li>Maintains batching, delay, status\/date filters, and WP-CLI parity.<\/li>\n<\/ul>\n\n<h4>1.2<\/h4>\n\n<ul>\n<li>Replace <code>alt<\/code> inside <code>&lt;img&gt;<\/code> tags using media alt; added ID ranges, skip &amp; exclude options.<\/li>\n<\/ul>\n\n<h4>1.1<\/h4>\n\n<ul>\n<li>Batch processing; status\/date filters; dry run logging; WP-CLI support.<\/li>\n<\/ul>","raw_excerpt":"Replace  tag alt attributes in posts with the alt stored in the media library. Batch processing, date\/status filters, ID ranges, skip &amp; exclude op &hellip;","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/253516","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=253516"}],"author":[{"embeddable":true,"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/dufour_l"}],"wp:attachment":[{"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=253516"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=253516"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=253516"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=253516"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=253516"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/pcd.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=253516"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}