Skip to content

Instantly share code, notes, and snippets.

@Jehu
Created September 19, 2025 16:00
Show Gist options
  • Save Jehu/c7211b626104aa5a46e189a15e9a2dd0 to your computer and use it in GitHub Desktop.
Save Jehu/c7211b626104aa5a46e189a15e9a2dd0 to your computer and use it in GitHub Desktop.
EtchWP Image Enhancement for WordPress
<?php
/**
* Etch Image Enhancement for WordPress
*
* Enhances Etch page builder images by automatically adding missing attributes:
* - srcset (responsive image sources)
* - width & height (extracted from filename or metadata)
* - alt text (from attachment meta or title)
* - sizes (responsive sizing hints)
*
* This is a standalone enhancement that can be used independently of other plugins.
*
* Usage in child theme's functions.php:
*
* $etch_enhancement_file = get_stylesheet_directory() . '/inc/etch-image-enhancement.php';
* if (file_exists($etch_enhancement_file)) {
* require_once $etch_enhancement_file;
* }
*
*/
// Prevent direct access
if (!defined('ABSPATH')) {
exit;
}
// Toggle to enable/disable image attribute enhancement
// Set to false to disable srcset, dimensions, alt, and sizes attribute addition
if (!defined('ETCH_ENHANCE_IMAGE_ATTRIBUTES')) {
define('ETCH_ENHANCE_IMAGE_ATTRIBUTES', true);
}
// Only hook if enhancement is enabled
if (ETCH_ENHANCE_IMAGE_ATTRIBUTES) {
// Add support for Etch page builder - hook AFTER Etch processes images
add_filter('render_block', 'etch_enhancement_filter_images', 15, 2);
}
/**
* Apply image enhancements to images in Etch blocks
*/
function etch_enhancement_filter_images($block_content, $block)
{
// Process etch/block blocks (which contain the actual images)
if ('etch/block' !== ($block['blockName'] ?? '')) {
return $block_content;
}
// Apply enhancements to images in the block content
$block_content = preg_replace_callback(
'/<img([^>]+)src=["\']([^"\']*wp-content\/uploads[^"\']*)["\']([^>]*)>/i',
'etch_enhancement_enhance_image',
$block_content
);
return $block_content;
}
/**
* Enhance individual Etch image with missing attributes
*/
function etch_enhancement_enhance_image($matches)
{
$full_tag = $matches[0];
$src = $matches[2];
// Try to get attachment ID from src URL
$attachment_id = attachment_url_to_postid($src);
// If that fails, try a more comprehensive search
if (!$attachment_id) {
$attachment_id = etch_enhancement_find_attachment_by_filename($src);
}
if (!$attachment_id) {
return $full_tag;
}
// Enhance image with missing attributes
$full_tag = etch_enhancement_add_attributes($full_tag, $attachment_id);
return $full_tag;
}
/**
* Enhance image tag with missing attributes (srcset, dimensions, alt, sizes)
* Only adds attributes if they don't already exist (even if empty)
*/
function etch_enhancement_add_attributes($img_tag, $attachment_id)
{
// Get attachment metadata and post data
$metadata = wp_get_attachment_metadata($attachment_id);
$attachment = get_post($attachment_id);
if (!$metadata || !$attachment) {
return $img_tag;
}
$attributes_to_add = [];
// Extract dimensions from filename if present (e.g., my-image-1440x960.webp)
$src_url = '';
if (preg_match('/src=["\']([^"\']*)["\']/', $img_tag, $src_matches)) {
$src_url = $src_matches[1];
}
$width = null;
$height = null;
if ($src_url) {
$filename = basename($src_url);
if (preg_match('/-(\d+)x(\d+)\.[^.]+$/', $filename, $size_matches)) {
$width = intval($size_matches[1]);
$height = intval($size_matches[2]);
}
}
// Fallback to metadata dimensions if no size found in filename
if (!$width && isset($metadata['width'])) {
$width = $metadata['width'];
}
if (!$height && isset($metadata['height'])) {
$height = $metadata['height'];
}
// Add width if not present
if (strpos($img_tag, 'width=') === false && $width) {
$attributes_to_add[] = 'width="' . $width . '"';
}
// Add height if not present
if (strpos($img_tag, 'height=') === false && $height) {
$attributes_to_add[] = 'height="' . $height . '"';
}
// Add alt if not present or empty
$alt_text = get_post_meta($attachment_id, '_wp_attachment_image_alt', true);
if ($alt_text) {
// Check if alt attribute is missing or empty
if (strpos($img_tag, 'alt=') === false) {
// No alt attribute, add it
$attributes_to_add[] = 'alt="' . esc_attr($alt_text) . '"';
} elseif (preg_match('/alt=["\']["\']/', $img_tag)) {
// Alt attribute exists but is empty, replace it
$img_tag = preg_replace('/alt=["\']["\']/', 'alt="' . esc_attr($alt_text) . '"', $img_tag);
}
}
// Add srcset if not present
if (strpos($img_tag, 'srcset=') === false) {
$srcset = wp_get_attachment_image_srcset($attachment_id);
if ($srcset) {
$attributes_to_add[] = 'srcset="' . esc_attr($srcset) . '"';
}
}
// Add sizes if not present (and srcset was added)
if (strpos($img_tag, 'sizes=') === false && strpos($img_tag, 'srcset=') === false) {
$sizes = wp_get_attachment_image_sizes($attachment_id);
if ($sizes) {
$attributes_to_add[] = 'sizes="' . esc_attr($sizes) . '"';
}
}
// Add all missing attributes to the img tag
if (!empty($attributes_to_add)) {
$attributes_string = ' ' . implode(' ', $attributes_to_add);
$img_tag = str_replace('<img', '<img' . $attributes_string, $img_tag);
}
return $img_tag;
}
/**
* Find attachment ID by searching for filename in database
*/
function etch_enhancement_find_attachment_by_filename($src)
{
global $wpdb;
// Extract filename from URL
$filename = basename($src);
// Remove size suffixes (e.g., -1440x960, -scaled, etc.)
$base_filename = preg_replace('/-\d+x\d+\./', '.', $filename);
$base_filename = preg_replace('/-scaled\./', '.', $base_filename);
// Also get the original filename without any suffix
$original_filename = preg_replace('/-[^.]*\./', '.', $filename);
// Search for attachments with matching filenames
$query = $wpdb->prepare(
"SELECT post_id FROM {$wpdb->postmeta}
WHERE meta_key = '_wp_attached_file'
AND (meta_value LIKE %s OR meta_value LIKE %s OR meta_value LIKE %s)
LIMIT 1",
'%' . $filename,
'%' . $base_filename,
'%' . $original_filename
);
$attachment_id = $wpdb->get_var($query);
if (!$attachment_id) {
// Try searching in the guid field as a last resort
$query = $wpdb->prepare(
"SELECT ID FROM {$wpdb->posts}
WHERE post_type = 'attachment'
AND guid LIKE %s
LIMIT 1",
'%' . $original_filename
);
$attachment_id = $wpdb->get_var($query);
}
return $attachment_id ? intval($attachment_id) : null;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment