__('Thumbnail (400x300)', 'apus-theme'), 'apus-medium' => __('Medium (800x600)', 'apus-theme'), 'apus-large' => __('Large (1200x900)', 'apus-theme'), 'apus-featured-large' => __('Featured Large (1200x600)', 'apus-theme'), 'apus-featured-medium' => __('Featured Medium (800x400)', 'apus-theme'), 'apus-hero' => __('Hero (1920x800)', 'apus-theme'), 'apus-card' => __('Card (600x400)', 'apus-theme'), )); } add_filter('image_size_names_choose', 'apus_custom_image_sizes'); /** * Generate srcset and sizes attributes for responsive images * * @param int $attachment_id Image attachment ID * @param string $size Image size * @param array $additional_sizes Additional sizes to include in srcset * @return array Array with 'srcset' and 'sizes' attributes */ function apus_get_responsive_image_attrs($attachment_id, $size = 'full', $additional_sizes = array()) { if (empty($attachment_id)) { return array('srcset' => '', 'sizes' => ''); } // Get default WordPress srcset $srcset = wp_get_attachment_image_srcset($attachment_id, $size); // Get default WordPress sizes attribute $sizes = wp_get_attachment_image_sizes($attachment_id, $size); // Add additional sizes if specified if (!empty($additional_sizes)) { $srcset_array = array(); foreach ($additional_sizes as $additional_size) { $image = wp_get_attachment_image_src($attachment_id, $additional_size); if ($image) { $srcset_array[] = $image[0] . ' ' . $image[1] . 'w'; } } if (!empty($srcset_array)) { $srcset .= ', ' . implode(', ', $srcset_array); } } return array( 'srcset' => $srcset, 'sizes' => $sizes, ); } /** * Output responsive image with lazy loading * * @param int $attachment_id Image attachment ID * @param string $size Image size * @param array $attr Additional image attributes * @param bool $lazy Enable lazy loading (default: true) * @return string Image HTML */ function apus_get_responsive_image($attachment_id, $size = 'full', $attr = array(), $lazy = true) { if (empty($attachment_id)) { return ''; } // Get responsive attributes $responsive_attrs = apus_get_responsive_image_attrs($attachment_id, $size); // Merge default attributes with custom ones $default_attr = array( 'loading' => $lazy ? 'lazy' : 'eager', 'decoding' => 'async', ); // Add srcset and sizes if available if (!empty($responsive_attrs['srcset'])) { $default_attr['srcset'] = $responsive_attrs['srcset']; } if (!empty($responsive_attrs['sizes'])) { $default_attr['sizes'] = $responsive_attrs['sizes']; } $attr = array_merge($default_attr, $attr); return wp_get_attachment_image($attachment_id, $size, false, $attr); } /** * Enable lazy loading by default for all images */ function apus_add_lazy_loading_to_images($attr, $attachment, $size) { // Don't add lazy loading if explicitly disabled if (isset($attr['loading']) && $attr['loading'] === 'eager') { return $attr; } // Add lazy loading by default if (!isset($attr['loading'])) { $attr['loading'] = 'lazy'; } // Add async decoding for better performance if (!isset($attr['decoding'])) { $attr['decoding'] = 'async'; } return $attr; } add_filter('wp_get_attachment_image_attributes', 'apus_add_lazy_loading_to_images', 10, 3); /** * Add lazy loading to content images */ function apus_add_lazy_loading_to_content($content) { // Don't process if empty if (empty($content)) { return $content; } // Add loading="lazy" to images that don't have it $content = preg_replace('/]*loading=)/', 'ID) { $attr['fetchpriority'] = 'high'; $attr['loading'] = 'eager'; // Don't lazy load LCP images } return $attr; } add_filter('wp_get_attachment_image_attributes', 'apus_add_fetchpriority_to_featured_image', 20, 3); /** * Optimize image quality for uploads */ function apus_optimize_image_quality($quality, $mime_type) { // Set quality to 85% for better file size without visible quality loss if ($mime_type === 'image/jpeg') { return 85; } return $quality; } add_filter('jpeg_quality', 'apus_optimize_image_quality', 10, 2); add_filter('wp_editor_set_quality', 'apus_optimize_image_quality', 10, 2); /** * Add picture element support for WebP/AVIF with fallbacks * * @param int $attachment_id Image attachment ID * @param string $size Image size * @param array $attr Additional attributes * @return string Picture element HTML */ function apus_get_picture_element($attachment_id, $size = 'full', $attr = array()) { if (empty($attachment_id)) { return ''; } $image_src = wp_get_attachment_image_src($attachment_id, $size); if (!$image_src) { return ''; } $srcset = wp_get_attachment_image_srcset($attachment_id, $size); $sizes = wp_get_attachment_image_sizes($attachment_id, $size); $alt = get_post_meta($attachment_id, '_wp_attachment_image_alt', true); // Default attributes $default_attr = array( 'loading' => 'lazy', 'decoding' => 'async', 'alt' => $alt, ); $attr = array_merge($default_attr, $attr); // Build picture element $picture = ''; // Add AVIF source if available $avif_url = str_replace(array('.jpg', '.jpeg', '.png', '.webp'), '.avif', $image_src[0]); if ($avif_url !== $image_src[0]) { $picture .= sprintf( '', esc_attr($avif_url), esc_attr($sizes) ); } // Add WebP source if available $webp_url = str_replace(array('.jpg', '.jpeg', '.png'), '.webp', $image_src[0]); if ($webp_url !== $image_src[0]) { $picture .= sprintf( '', esc_attr($webp_url), esc_attr($sizes) ); } // Fallback img tag $picture .= wp_get_attachment_image($attachment_id, $size, false, $attr); $picture .= ''; return $picture; } /** * Disable big image threshold for high-quality images * WordPress 5.3+ scales down images larger than 2560px by default * Uncomment to disable this behavior if you need full-size images */ // add_filter('big_image_size_threshold', '__return_false'); /** * Set maximum srcset image width */ function apus_max_srcset_image_width($max_width, $size_array) { // Limit srcset to images up to 2560px wide return 2560; } add_filter('max_srcset_image_width', 'apus_max_srcset_image_width', 10, 2);