Skip to content

Comments

Select converted images via .htaccess#94

Open
tijmenbruggeman wants to merge 39 commits intotinify:masterfrom
wcreateweb:task/conversion-server-side
Open

Select converted images via .htaccess#94
tijmenbruggeman wants to merge 39 commits intotinify:masterfrom
wcreateweb:task/conversion-server-side

Conversation

@tijmenbruggeman
Copy link
Collaborator

This PR will extend our conversion feature with the delivery of converted images through htaccess.

When selecting and saving the delivery "htaccess", it will write the following block into the htaccess on the home path and the uploads directory.

# BEGIN tiny-compress-images
# The directives (lines) between "BEGIN tiny-compress-images" and "END tiny-compress-images" are
# dynamically generated, and should only be modified via WordPress filters.
# Any changes to the directives between these markers will be overwritten.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteOptions Inherit
RewriteCond %{HTTP_ACCEPT} image/avif
RewriteCond %{REQUEST_URI} ^(.+)\.(?:jpe?g|png|gif)$
RewriteCond %{DOCUMENT_ROOT}/%1.avif -f
RewriteCond %{QUERY_STRING} !type=original
RewriteRule (.+)\.(?:jpe?g|png|gif)$ $1.avif [T=image/avif,L]

RewriteCond %{HTTP_ACCEPT} image/webp
RewriteCond %{REQUEST_URI} ^(.+)\.(?:jpe?g|png|gif)$
RewriteCond %{DOCUMENT_ROOT}/%1.webp -f
RewriteCond %{QUERY_STRING} !type=original
RewriteRule (.+)\.(?:jpe?g|png|gif)$ $1.webp [T=image/webp,L]
</IfModule>

<IfModule mod_headers.c>
<FilesMatch "\.(jpe?g|png|gif)$">
Header append Vary Accept
</FilesMatch>
</IfModule>

<IfModule mod_mime.c>
AddType image/webp .webp
AddType image/avif .avif
</IfModule>
# END tiny-compress-images
  1. This is inserted using insert_with_markers when the setting for conversion delivery is set to server rules.
  2. There is a uninstall.php file which will delete the rule when the plug-in is uninstalled.
  3. The htaccess is stored in wp-content/uploads as we only focus on the uploads directory.

Settings
There is a new setting to allow the optimized image delivery via .htaccess. This setting is only visible when the user is on apache and has mod_rewrite.
conversion_settings

Follow-up

  • When the plug-in is installed after a previous installation and the delivery method setting is still on htaccess, it will not install the rules. Because it requires quite a bit of refactoring to reset the settings as well, this will be done in a seperate PR.

tijmenbruggeman and others added 30 commits December 22, 2025 10:14
- use global vars to detect for apache
- check if mod rewrite is available
- return object with server information
- not recommended to render html in a class
- keep view rendering logic away from business logic
Remove redundant rewrite rules that append file extensions (image.jpg.avif).
Keep only the extension replacement rules (image.avif).

- Rename install() to install_rules() and uninstall() to uninstall_rules()
- Remove duplicate AVIF and WebP rules that check for appended extensions
- Update MARKER constant to match plugin name
- Remove redundant comments and empty lines
Add delivery parameter to setConversionSettings helper to configure
picture tag or htaccess delivery methods in integration tests.
Add data-testid attribute to radio input elements to improve test
selector reliability in integration tests.
- Refactor Tiny_Apache_Rewrite to support dynamic rule toggling
- Add init() method and toggle_rules() hook for option changes
- Update get_webp_rules() to remove Chrome-specific check
- Make get_rewrite_rules() and install_rules() private
- Initialize Apache rewrite in plugin constructor
- Add conditional Tiny_Picture initialization for 'picture' delivery
- Add integration tests for htaccess delivery method

Co-Authored-By: Warp <agent@warp.dev>
@tijmenbruggeman tijmenbruggeman changed the title Task/conversion server side Select converted images via .htaccess Feb 18, 2026
@tijmenbruggeman tijmenbruggeman self-assigned this Feb 18, 2026
The logger fix has been moved to the separate diagnostic-logging branch

/**
* Detect the web server software using WordPress globals.
* WordPress sets $is_apache, $is_IIS, $is_iis7, and $is_nginx in wp-includes/vars.php
Copy link
Contributor

@rkoopmans rkoopmans Feb 20, 2026

Choose a reason for hiding this comment

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

You miss is_caddy. it is a very small market share, so no big deal but maybe add it for completeness

public static function get_capabilities() {
return array(
'server' => self::get_server_type(),
'is_apache' => self::is_apache(),
Copy link
Contributor

Choose a reason for hiding this comment

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

we have is_apache seperately here. Can just as well call $is_apache in the code block where you use it

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.

4 participants