PluginProbe
QuickWebP – WebP & AVIF Image Optimizer, Compression & SEO for WordPress / 4.1.1
QuickWebP – WebP & AVIF Image Optimizer, Compression & SEO for WordPress v4.1.1
4.1.1 4.1.0 4.0.1 4.0.0 3.3.1 3.3.0 trunk 1.0.0 2.0.0 2.1.0 3.0.0 3.1.0 3.2.0 3.2.1 3.2.2 3.2.3 3.2.4 3.2.5 3.2.6 3.2.7 3.2.8
quickwebp / admin / templates / page-settings.php

page-settings.php in QuickWebP – WebP & AVIF Image Optimizer, Compression & SEO for WordPress 4.1.1, at admin/templates/page-settings.php

1,022 lines 56.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
3
4 /**
5 * The admin settings of the plugin.
6 * @since 1.0.0
7 */
8 ?>
9 <div class="quickwebp-settings-v2" data-current-profile="<?php echo esc_attr( $profile_label ); ?>">
10
11 <header class="quickwebp-hero">
12 <h1><?php esc_html_e( 'QuickWebP Settings', 'quickwebp' ); ?></h1>
13 <p><?php esc_html_e( 'Configure your image workflow with coherent presets, guarded options, and an optimized media delivery strategy.', 'quickwebp' ); ?></p>
14 </header>
15
16 <form action="" method="post" class="quickwebp-settings-form">
17 <div class="quickwebp-layout">
18 <main class="quickwebp-main">
19 <?php if ( $show_onboarding ) : ?>
20 <section class="quickwebp-card" id="quickwebp-onboarding">
21 <div class="quickwebp-card-head">
22 <h2><?php esc_html_e( 'Quick setup assistant', 'quickwebp' ); ?></h2>
23 <p><?php esc_html_e( 'Start from a recommended profile and refine only what you need.', 'quickwebp' ); ?></p>
24 </div>
25 <div class="quickwebp-card-body">
26 <div class="quickwebp-onboarding-grid">
27 <button type="button" class="quickwebp-onboarding-option quickwebp-onboarding-apply" data-profile="new-site">
28 <strong><?php esc_html_e( 'New site with few media', 'quickwebp' ); ?></strong>
29 <span><?php esc_html_e( 'Replace originals on upload for the simplest and fastest workflow.', 'quickwebp' ); ?></span>
30 </button>
31 <button type="button" class="quickwebp-onboarding-option quickwebp-onboarding-apply" data-profile="existing-site">
32 <strong><?php esc_html_e( 'Existing site with many media', 'quickwebp' ); ?></strong>
33 <span><?php esc_html_e( 'Keep originals, enable rewrite delivery, and run bulk optimization.', 'quickwebp' ); ?></span>
34 </button>
35 </div>
36 <p class="quickwebp-onboarding-feedback" aria-live="polite"></p>
37 </div>
38 </section>
39 <?php endif; ?>
40
41 <section class="quickwebp-card" id="quickwebp-conversion">
42 <div class="quickwebp-card-head">
43 <h2><?php esc_html_e( 'Conversion and Delivery', 'quickwebp' ); ?></h2>
44 <p><?php esc_html_e( 'Define how images are converted, preserved, and delivered on frontend pages.', 'quickwebp' ); ?></p>
45 </div>
46 <div class="quickwebp-card-body">
47 <table class="form-table">
48
49 <?php $this->render_component( array(
50 'type' => 'button-group',
51 'name' => 'quickwebp_settings_conversion',
52 'label' => __( 'Image Format Optimization', 'quickwebp' ),
53 'default' => quickwebp_settings_default( 'quickwebp_settings_conversion' ),
54 'options' => array(
55 array(
56 'label' => __( 'Off', 'quickwebp' ),
57 'color' => '#000000',
58 'desc' => __( '0% saved', 'quickwebp' ),
59 'value' => '0',
60 'classes' => 'toggle-with-children',
61 ),
62 array(
63 'label' => __( 'WebP', 'quickwebp' ),
64 'color' => '#316BFF',
65 'desc' => __( '≈ −30% on average across a site', 'quickwebp' ),
66 'value' => '1',
67 'classes' => 'toggle-with-children',
68 ),
69 array(
70 'label' => __( 'AVIF', 'quickwebp' ),
71 'color' => '#16A34A',
72 'desc' => __( '≈ −50% on average across a site', 'quickwebp' ),
73 'value' => '2',
74 'classes' => 'toggle-with-children',
75 'parent_classes' => 'quickwebp__pro-popup-open',
76 'disabled' => ! $license_valid || ! $php_version_valid,
77 'taglines' => array(
78 array(
79 'label' => 'Pro',
80 'value' => 'pro',
81 'show' => ! $license_valid,
82 ),
83 array(
84 'label' => 'Requires PHP 8.1+',
85 'value' => 'pro',
86 'show' => ! $php_version_valid,
87 ),
88 array(
89 'label' => __( 'Recommended', 'quickwebp' ),
90 'value' => 'recommended',
91 'show' => true,
92 ),
93 ),
94 )
95 )
96 ) ); ?>
97
98 <tbody class="form-table children">
99
100 <?php $this->render_component( array(
101 'type' => 'button-group',
102 'name' => 'quickwebp_settings_conversion_quality',
103 'label' => __( 'Image Quality', 'quickwebp' ),
104 'default' => quickwebp_settings_default( 'quickwebp_settings_conversion_quality' ),
105 'options' => array(
106 array(
107 'label' => __( 'Low', 'quickwebp' ),
108 'value' => 'low',
109 'color' => '#E74C3C',
110 'desc' => __( 'Smallest size', 'quickwebp' ),
111 ),
112 array(
113 'label' => __( 'Medium', 'quickwebp' ),
114 'value' => 'medium',
115 'color' => '#E67E22',
116 'desc' => __( 'Good balance', 'quickwebp' ),
117 ),
118 array(
119 'label' => __( 'High', 'quickwebp' ),
120 'value' => 'high',
121 'color' => '#16A34A',
122 'desc' => __( 'High quality & good size', 'quickwebp' ),
123 'taglines' => array(
124 array(
125 'label' => __( 'Recommended', 'quickwebp' ),
126 'value' => 'recommended',
127 'show' => true,
128 ),
129 ),
130 ),
131 array(
132 'label' => __( 'Extra High', 'quickwebp' ),
133 'value' => 'extra_high',
134 'color' => '#2563EB',
135 'desc' => __( 'Maximum quality', 'quickwebp' ),
136 ),
137 )
138 ) ); ?>
139
140 <tr>
141 <th><label><?php esc_html_e( 'Preview', 'quickwebp' ); ?></label></th>
142 <td>
143 <?php include QUICKWEBP_PLUGIN_PATH . 'admin/templates/popup-settings-preview.php'; ?>
144 </td>
145 </tr>
146
147 <?php $this->render_component( array(
148 'type' => 'checkbox',
149 'name' => 'quickwebp_settings_conversion_ignore_webp',
150 'label' => __( 'Do not compress images already in same format', 'quickwebp' ),
151 'default' => quickwebp_settings_default( 'quickwebp_settings_conversion_ignore_webp' ),
152 'options' => array(
153 array(
154 'label' => '',
155 'value' => 'checked'
156 )
157 )
158 ) ); ?>
159
160 <?php $this->render_component( array(
161 'type' => 'checkbox',
162 'name' => 'quickwebp_settings_conversion_save_original',
163 'label' => __( 'Save original images', 'quickwebp' ),
164 'default' => quickwebp_settings_default( 'quickwebp_settings_conversion_save_original' ),
165 'options' => array(
166 array(
167 'label' => '',
168 'value' => 'checked'
169 )
170 )
171 ) ); ?>
172
173 <tr class="quickwebp-guidance-row">
174 <th>
175 <label><?php esc_html_e( 'Consistency guidance', 'quickwebp' ); ?></label>
176 </th>
177 <td>
178 <div class="quickwebp-guidance-box">
179 <p class="quickwebp-guidance-message" aria-live="polite"></p>
180 </div>
181 </td>
182 </tr>
183
184 <?php
185 $quickwebp_description_for_nginx = $is_nginx ? __( "If you choose to use rewrite rules, the file conf/quickwebp.conf will be created and must be included into the server's configuration file (then restart the server).", 'quickwebp' ) : '';
186
187 $this->render_component( array(
188 'type' => 'radio',
189 'name' => 'quickwebp_settings_conversion_display_webp_mode',
190 'label' => __( 'Display images in WebP format on the site', 'quickwebp' ),
191 'description' => sprintf(
192 // translators: %s is a placeholder for the description for nginx.
193 __( 'If activated, this option allows to deliver optimized images in bulk via QuickWebP in WebP format (useless for images converted to import). %s', 'quickwebp' ),
194 $quickwebp_description_for_nginx
195 ),
196 'default' => quickwebp_settings_default( 'quickwebp_settings_conversion_display_webp_mode' ),
197 'options' => array(
198 array(
199 'label' => __( 'Deactivate', 'quickwebp' ),
200 'value' => 'disabled'
201 ),
202 array(
203 'label' => __( 'Use <picture> tags', 'quickwebp' ),
204 'value' => 'picture'
205 ),
206 array(
207 'label' => sprintf(
208 // translators: %s is a placeholder for the text "(beta)" if the server is Nginx.
209 __( 'Use rewrite rules %s', 'quickwebp' ),
210 $is_nginx ? '(beta)' : ''
211 ),
212 'value' => 'rewrite'
213 )
214 )
215 ) );
216 ?>
217
218 <tr class="quickwebp-display-warning-row" style="display:none;">
219 <th>
220 <label><?php esc_html_e( 'Why this is locked', 'quickwebp' ); ?></label>
221 </th>
222 <td>
223 <p class="quickwebp-display-warning"></p>
224 </td>
225 </tr>
226
227 <tr class="quickwebp-row-bulk-optimization">
228 <th>
229 <label><?php esc_html_e( 'Bulk optimization', 'quickwebp' ); ?></label>
230 </th>
231 <td>
232 <?php include QUICKWEBP_PLUGIN_PATH . 'admin/templates/bulk-optimization.php'; ?>
233 </td>
234 </tr>
235
236 </tbody>
237
238 </table>
239 </div>
240 </section>
241
242 <section class="quickwebp-card" id="quickwebp-resize">
243 <div class="quickwebp-card-head">
244 <h2><?php esc_html_e( 'Resize', 'quickwebp' ); ?></h2>
245 <p><?php esc_html_e( 'Keep your uploads under control to reduce bandwidth and processing costs.', 'quickwebp' ); ?></p>
246 </div>
247 <div class="quickwebp-card-body">
248 <table class="form-table">
249 <?php $this->render_component( array(
250 'type' => 'toggle',
251 'name' => 'quickwebp_settings_resize',
252 'label' => __( 'Enable/disable image resizing', 'quickwebp' ),
253 'default' => quickwebp_settings_default( 'quickwebp_settings_resize' ),
254 'classes' => 'toggle-with-children',
255 'description' => __( 'By default, WordPress limits the maximum width of uploaded images to 2560 pixels.', 'quickwebp' ),
256 ) ); ?>
257
258 <tbody class="form-table children">
259 <?php $this->render_component( array(
260 'type' => 'number',
261 'name' => 'quickwebp_settings_resize_value',
262 'label' => __( 'Max size', 'quickwebp' ),
263 'default' => quickwebp_settings_default( 'quickwebp_settings_resize_value' )
264 ) ); ?>
265 </tbody>
266 </table>
267 </div>
268 </section>
269
270 <section class="quickwebp-card" id="quickwebp-seo">
271 <div class="quickwebp-card-head">
272 <h2><?php esc_html_e( 'SEO metadata automation', 'quickwebp' ); ?></h2>
273 <p><?php esc_html_e( 'Auto-fill media fields from image names for a faster editorial workflow.', 'quickwebp' ); ?></p>
274 </div>
275 <div class="quickwebp-card-body">
276 <table class="form-table">
277 <?php $this->render_component( array(
278 'type' => 'toggle',
279 'name' => 'quickwebp_settings_completion',
280 'label' => __( 'Enable/disable smart media completion for SEO', 'quickwebp' ),
281 'default' => quickwebp_settings_default( 'quickwebp_settings_completion' ),
282 'classes' => 'toggle-with-children',
283 'description' => __( 'This feature will automatically complete the media information (title, caption, alt text, description) from the image name.', 'quickwebp' ),
284 ) ); ?>
285
286 <tbody class="form-table children">
287 <?php $this->render_component( array(
288 'type' => 'checkbox',
289 'name' => 'quickwebp_settings_completion_options',
290 'default' => quickwebp_settings_default( 'quickwebp_settings_completion_options' ),
291 'options' => array(
292 array(
293 'label' => __( 'Title completion from image name', 'quickwebp' ),
294 'value' => 'title',
295 ),
296 array(
297 'label' => __( 'Caption completion from image name.', 'quickwebp' ),
298 'value' => 'caption',
299 ),
300 array(
301 'label' => __( 'Alt text completion from image name.', 'quickwebp' ),
302 'value' => 'alt',
303 ),
304 array(
305 'label' => __( 'Description completion from image name.', 'quickwebp' ),
306 'value' => 'description',
307 )
308 )
309 ) ); ?>
310 </tbody>
311 </table>
312
313 <div class="quickwebp-seo-example">
314 <h3><?php esc_html_e( 'Live example', 'quickwebp' ); ?></h3>
315 <p><?php esc_html_e( 'Use a descriptive filename once (including spaces or apostrophes), and metadata is auto-filled from that original filename without the extension.', 'quickwebp' ); ?></p>
316 <input
317 type="text"
318 class="quickwebp-seo-example-input"
319 value="Men's Summer Shoes - Limited Edition 2026.jpg"
320 aria-label="<?php echo esc_attr__( 'SEO metadata example filename', 'quickwebp' ); ?>"
321 >
322
323 <div class="quickwebp-seo-example-grid">
324 <div class="quickwebp-seo-example-item">
325 <strong><?php esc_html_e( 'Title', 'quickwebp' ); ?></strong>
326 <span class="quickwebp-seo-preview-title"></span>
327 </div>
328 <div class="quickwebp-seo-example-item">
329 <strong><?php esc_html_e( 'Caption', 'quickwebp' ); ?></strong>
330 <span class="quickwebp-seo-preview-caption"></span>
331 </div>
332 <div class="quickwebp-seo-example-item">
333 <strong><?php esc_html_e( 'Alt text', 'quickwebp' ); ?></strong>
334 <span class="quickwebp-seo-preview-alt"></span>
335 </div>
336 <div class="quickwebp-seo-example-item">
337 <strong><?php esc_html_e( 'Description', 'quickwebp' ); ?></strong>
338 <span class="quickwebp-seo-preview-description"></span>
339 </div>
340 </div>
341 </div>
342 </div>
343 </section>
344
345 <section class="quickwebp-card" id="quickwebp-tools">
346 <div class="quickwebp-card-head">
347 <h2><?php esc_html_e( 'Other tools', 'quickwebp' ); ?></h2>
348 <p><?php esc_html_e( 'Fine tune file naming, paste behavior, and local image processing.', 'quickwebp' ); ?></p>
349 </div>
350 <div class="quickwebp-card-body">
351 <table class="form-table">
352 <?php $this->render_component( array(
353 'type' => 'toggle',
354 'name' => 'quickwebp_settings_cleanup',
355 'label' => __( 'Enable/disable file name cleanup', 'quickwebp' ),
356 'default' => quickwebp_settings_default( 'quickwebp_settings_cleanup' ),
357 // 'description' => __( 'Remove special characters from file names.', 'quickwebp' ),
358 ) ); ?>
359
360 <tr class="quickwebp-cleanup-example-row">
361 <th>
362
363 </th>
364 <td>
365 <div class="quickwebp-cleanup-example">
366 <p><?php esc_html_e( 'Use a filename with spaces, apostrophes, or accents to preview the cleaned filename.', 'quickwebp' ); ?></p>
367 <input
368 type="text"
369 class="quickwebp-cleanup-example-input"
370 value="Men's Summer Shoes - Limited Edition 2026.jpg"
371 aria-label="<?php echo esc_attr__( 'Cleanup filename example input', 'quickwebp' ); ?>"
372 >
373 <div class="quickwebp-cleanup-example-grid">
374 <div class="quickwebp-cleanup-example-item">
375 <strong><?php esc_html_e( 'Original filename', 'quickwebp' ); ?></strong>
376 <span class="quickwebp-cleanup-preview-original"></span>
377 </div>
378 <div class="quickwebp-cleanup-example-item">
379 <strong><?php esc_html_e( 'Cleaned filename', 'quickwebp' ); ?></strong>
380 <span class="quickwebp-cleanup-preview-cleaned"></span>
381 </div>
382 </div>
383 </div>
384 </td>
385 </tr>
386
387 <?php $this->render_component( array(
388 'type' => 'toggle',
389 'name' => 'quickwebp_settings_paste_image',
390 'label' => __( 'Enable/disable paste picture directly (beta)', 'quickwebp' ),
391 'default' => quickwebp_settings_default( 'quickwebp_settings_paste_image' ),
392 'description' => __( 'With this feature you can paste directly your picture in WordPress media.', 'quickwebp' ),
393 ) ); ?>
394
395 <?php $this->render_component( array(
396 'type' => 'toggle',
397 'name' => 'quickwebp_settings_debug_mode',
398 'label' => __( 'Enable/disable debug mode', 'quickwebp' ),
399 'default' => quickwebp_settings_default( 'quickwebp_settings_debug_mode' ),
400 'description' => sprintf(
401 /* translators: %s: debug log path. */
402 __( 'Write detailed optimization logs to %s.', 'quickwebp' ),
403 quickwebp_get_debug_log_path()
404 ),
405 ) ); ?>
406 </table>
407 </div>
408 </section>
409
410 <section class="quickwebp-card" id="quickwebp-migration">
411 <div class="quickwebp-card-head">
412 <h2><?php esc_html_e( 'Migration notice', 'quickwebp' ); ?></h2>
413 <p><?php esc_html_e( 'QuickWebP is now available inside WPMasterToolKit.', 'quickwebp' ); ?></p>
414 </div>
415 <div class="quickwebp-card-body">
416 <p><?php esc_html_e( 'QuickWebP is now part of the WPMasterToolKit plugin. You can download it for free on the WordPress repository.', 'quickwebp' ); ?></p>
417 <video autoplay loop muted controls class="quickwebp-migration-video">
418 <source src="<?php echo esc_url( QUICKWEBP_PLUGIN_URL . 'public/assets/video/wpmastertoolkit.mp4' ); ?>" type="video/mp4">
419 <?php esc_html_e( 'Your browser does not support the video tag.', 'quickwebp' ); ?>
420 </video>
421 <?php if ( $wpmtk_is_active ) : ?>
422 <p><strong><?php esc_html_e( 'You can now deactivate QuickWebP and finish the migration.', 'quickwebp' ); ?></strong></p>
423 <?php else : ?>
424 <p>
425 <a href="<?php echo esc_url( admin_url( 'plugin-install.php?s=wpmastertoolkit&tab=search&type=term' ) ); ?>" class="button button-primary" target="_blank"><?php esc_html_e( 'Download WPMasterToolKit', 'quickwebp' ); ?></a>
426 <a href="https://wordpress.org/plugins/wpmastertoolkit/" class="button button-secondary" target="_blank"><?php esc_html_e( 'Download WPMasterToolKit from wordpress.org', 'quickwebp' ); ?></a>
427 </p>
428 <?php endif; ?>
429 </div>
430 </section>
431
432 <div class="quickwebp-submit-wrap">
433 <?php submit_button( __( 'Save settings', 'quickwebp' ), 'primary', 'submit', false ); ?>
434 <p class="quickwebp-submit-note"><?php esc_html_e( 'Your consistency rules are enforced automatically when saving.', 'quickwebp' ); ?></p>
435 </div>
436
437 <div class="quickwebp-credits">
438 <p>
439 <?php esc_html_e( 'This plugin is developed by', 'quickwebp' ); ?>
440 <a href="https://webdeclic.com/" target="_blank">Webdeclic</a>.
441 <?php esc_html_e( 'You can support this project here:', 'quickwebp' ); ?>
442 <a href="https://www.buymeacoffee.com/ludwig" target="_blank"><?php esc_html_e( 'Buy me a coffee', 'quickwebp' ); ?></a>.
443 </p>
444 <p>
445 <?php esc_html_e( 'You can show all Webdeclic plugins on', 'quickwebp' ); ?>
446 <a href="https://wordpress.org/plugins/search/webdeclic/" target="_blank">wordpress.org</a>.
447 </p>
448 </div>
449 </main>
450
451 <aside class="quickwebp-aside">
452 <div class="quickwebp-aside-inner">
453 <section class="quickwebp-card">
454 <div class="quickwebp-card-head">
455 <h2><?php esc_html_e( 'Live configuration summary', 'quickwebp' ); ?></h2>
456 <p><?php esc_html_e( 'This panel updates instantly while you edit your settings.', 'quickwebp' ); ?></p>
457 </div>
458 <div class="quickwebp-card-body">
459 <ul class="quickwebp-summary-list">
460 <li>
461 <span class="quickwebp-summary-label"><?php esc_html_e( 'Conversion', 'quickwebp' ); ?></span>
462 <span class="quickwebp-summary-value quickwebp-summary-conversion-side"><?php echo esc_html( $conversion_enabled ? __( 'Enabled', 'quickwebp' ) : __( 'Disabled', 'quickwebp' ) ); ?></span>
463 </li>
464 <li>
465 <span class="quickwebp-summary-label"><?php esc_html_e( 'Original images', 'quickwebp' ); ?></span>
466 <span class="quickwebp-summary-value quickwebp-summary-originals-side"><?php echo esc_html( $save_original_enabled ? __( 'Preserved', 'quickwebp' ) : __( 'Replaced', 'quickwebp' ) ); ?></span>
467 </li>
468 <li>
469 <span class="quickwebp-summary-label"><?php esc_html_e( 'Frontend display', 'quickwebp' ); ?></span>
470 <span class="quickwebp-summary-value quickwebp-summary-display-side"><?php echo esc_html( $display_mode ); ?></span>
471 </li>
472 <li>
473 <span class="quickwebp-summary-label"><?php esc_html_e( 'Bulk optimization', 'quickwebp' ); ?></span>
474 <span class="quickwebp-summary-value quickwebp-summary-bulk-side"><?php echo esc_html( $save_original_enabled ? __( 'Available', 'quickwebp' ) : __( 'Unavailable', 'quickwebp' ) ); ?></span>
475 </li>
476 </ul>
477 </div>
478 </section>
479
480 <section class="quickwebp-card">
481 <div class="quickwebp-card-head">
482 <h2><?php esc_html_e( 'Quick navigation', 'quickwebp' ); ?></h2>
483 </div>
484 <div class="quickwebp-card-body quickwebp-quick-links">
485 <?php if ( $show_onboarding ) : ?>
486 <a href="#quickwebp-onboarding"><?php esc_html_e( 'Quick setup assistant', 'quickwebp' ); ?></a>
487 <?php endif; ?>
488 <a href="#quickwebp-conversion"><?php esc_html_e( 'Conversion and delivery', 'quickwebp' ); ?></a>
489 <a href="#quickwebp-resize"><?php esc_html_e( 'Resize', 'quickwebp' ); ?></a>
490 <a href="#quickwebp-seo"><?php esc_html_e( 'SEO metadata automation', 'quickwebp' ); ?></a>
491 <a href="#quickwebp-tools"><?php esc_html_e( 'Other tools', 'quickwebp' ); ?></a>
492 <a href="#quickwebp-migration"><?php esc_html_e( 'Migration notice', 'quickwebp' ); ?></a>
493 </div>
494 </section>
495
496 <section class="quickwebp-card">
497 <div class="quickwebp-card-head">
498 <h2><?php esc_html_e( 'License', 'quickwebp' ); ?></h2>
499 </div>
500 <div class="quickwebp-card-body quickwebp-license">
501 <div class="quickwebp-license__status">
502 <div class="quickwebp-license__status__text"><?php esc_html_e( 'State', 'quickwebp' ); ?>:</div>
503 <div class="quickwebp-license__status__icon <?php echo $license_valid ? 'valid' : 'invalid'; ?>"></div>
504 </div>
505
506 <div class="quickwebp-license__link">
507 <a href="<?php echo esc_url( admin_url( 'admin.php?page=quickwebp-manage-license' ) ); ?>" class="<?php echo $license_valid ? 'valid' : 'invalid'; ?>">
508 <?php if ( $license_valid ) : ?>
509 <?php echo wp_kses( file_get_contents( QUICKWEBP_PLUGIN_PATH . 'public/assets/svg/key-disable.svg' ), quickwebp_allowed_tags_for_svg_files() ); ?>
510 <?php esc_html_e( 'Deactivate the license', 'quickwebp' ); ?>
511 <?php else : ?>
512 <?php echo wp_kses( file_get_contents( QUICKWEBP_PLUGIN_PATH . 'public/assets/svg/key.svg' ), quickwebp_allowed_tags_for_svg_files() ); ?>
513 <?php esc_html_e( 'Activate the license', 'quickwebp' ); ?>
514 <?php endif; ?>
515 </a>
516 </div>
517 </div>
518 </section>
519 </div>
520 </aside>
521 </div>
522 </form>
523
524 <?php if ( ! $license_valid ): ?>
525 <div class="quickwebp__pro-popup">
526 <div class="quickwebp__pro-popup__overlay"></div>
527 <div class="quickwebp__pro-popup__content">
528 <div class="quickwebp__pro-popup__content__header">
529 <div class="quickwebp__pro-popup__content__header__text">
530 <div class="quickwebp__pro-popup__content__header__text__subtitle">
531 <div class="quickwebp__pro-popup__content__header__text__subtitle__tag"><?php esc_html_e( 'Pro', 'quickwebp' ); ?></div>
532 <div class="quickwebp__pro-popup__content__header__text__subtitle__text"><?php esc_html_e( 'AVIF Format', 'quickwebp' ); ?></div>
533 </div>
534 <div class="quickwebp__pro-popup__content__header__text__title">
535 <?php esc_html_e( 'Go further with', 'quickwebp' ); ?>
536 <span class="highlight"> AVIF</span>
537 </div>
538 <div class="quickwebp__pro-popup__content__header__text__desc">
539 <?php esc_html_e( 'The next-generation image format, available with', 'quickwebp' ); ?>
540 <span class="highlight">QuickWebP Pro.</span>
541 </div>
542 </div>
543
544 <div class="quickwebp__pro-popup__content__header__close">
545 <?php echo wp_kses( file_get_contents( QUICKWEBP_PLUGIN_PATH . 'public/assets/svg/close.svg' ), quickwebp_allowed_tags_for_svg_files() ); ?>
546 </div>
547 </div>
548 <div class="quickwebp__pro-popup__content__body">
549 <div class="quickwebp__pro-popup__content__body__top">
550 <div class="quickwebp__pro-popup__content__body__top__item">
551 <div class="quickwebp__pro-popup__content__body__top__item__icon">
552 <?php echo wp_kses( file_get_contents( QUICKWEBP_PLUGIN_PATH . 'public/assets/svg/gauge.svg' ), quickwebp_allowed_tags_for_svg_files() ); ?>
553 </div>
554 <div class="quickwebp__pro-popup__content__body__top__item__text">
555 <div class="quickwebp__pro-popup__content__body__top__item__text__title">-50%</div>
556 <div class="quickwebp__pro-popup__content__body__top__item__text__desc"><?php esc_html_e( 'Vs jpeg/png on average', 'quickwebp' ); ?></div>
557 </div>
558 </div>
559
560 <div class="quickwebp__pro-popup__content__body__top__item second">
561 <div class="quickwebp__pro-popup__content__body__top__item__icon">
562 <?php echo wp_kses( file_get_contents( QUICKWEBP_PLUGIN_PATH . 'public/assets/svg/chart-line.svg' ), quickwebp_allowed_tags_for_svg_files() ); ?>
563 </div>
564 <div class="quickwebp__pro-popup__content__body__top__item__text">
565 <div class="quickwebp__pro-popup__content__body__top__item__text__title">-30%</div>
566 <div class="quickwebp__pro-popup__content__body__top__item__text__desc"><?php esc_html_e( 'Vs webp on average', 'quickwebp' ); ?></div>
567 </div>
568 </div>
569
570 <div class="quickwebp__pro-popup__content__body__top__item third">
571 <div class="quickwebp__pro-popup__content__body__top__item__icon">
572 <?php echo wp_kses( file_get_contents( QUICKWEBP_PLUGIN_PATH . 'public/assets/svg/global.svg' ), quickwebp_allowed_tags_for_svg_files() ); ?>
573 </div>
574 <div class="quickwebp__pro-popup__content__body__top__item__text">
575 <div class="quickwebp__pro-popup__content__body__top__item__text__title">100%</div>
576 <div class="quickwebp__pro-popup__content__body__top__item__text__desc"><?php esc_html_e( 'of modern browsers supported', 'quickwebp' ); ?></div>
577 </div>
578 </div>
579 </div>
580
581 <div class="quickwebp__pro-popup__content__body__middle">
582 <div class="quickwebp__pro-popup__content__body__middle__item">
583 <div class="quickwebp__pro-popup__content__body__middle__item__icon">
584 <?php echo wp_kses( file_get_contents( QUICKWEBP_PLUGIN_PATH . 'public/assets/svg/check-mark.svg' ), quickwebp_allowed_tags_for_svg_files() ); ?>
585 </div>
586 <div class="quickwebp__pro-popup__content__body__middle__item__text">
587 <strong><?php echo wp_kses_post(
588 // translators: %s is a placeholder for the text "</strong>".
589 sprintf( __( 'The best compression available %s images typically half the size of your originals.', 'quickwebp' ), '</strong>' )
590 ); ?>
591 </div>
592 </div>
593
594 <div class="quickwebp__pro-popup__content__body__middle__item">
595 <div class="quickwebp__pro-popup__content__body__middle__item__icon">
596 <?php echo wp_kses( file_get_contents( QUICKWEBP_PLUGIN_PATH . 'public/assets/svg/check-mark.svg' ), quickwebp_allowed_tags_for_svg_files() ); ?>
597 </div>
598 <div class="quickwebp__pro-popup__content__body__middle__item__text">
599 <strong><?php echo wp_kses_post(
600 // translators: %s is a placeholder for the text "</strong>".
601 sprintf( __( 'Sharper images at lower weight %s for faster pages and better Core Web Vitals.', 'quickwebp' ), '</strong>' )
602 ); ?>
603 </div>
604 </div>
605
606 <div class="quickwebp__pro-popup__content__body__middle__item">
607 <div class="quickwebp__pro-popup__content__body__middle__item__icon">
608 <?php echo wp_kses( file_get_contents( QUICKWEBP_PLUGIN_PATH . 'public/assets/svg/check-mark.svg' ), quickwebp_allowed_tags_for_svg_files() ); ?>
609 </div>
610 <div class="quickwebp__pro-popup__content__body__middle__item__text">
611 <strong><?php echo wp_kses_post(
612 // translators: %s is a placeholder for the text "</strong>".
613 sprintf( __( 'Automatic fallback %s so older browsers keep receiving a compatible format.', 'quickwebp' ), '</strong>' )
614 ); ?>
615 </div>
616 </div>
617
618 </div>
619
620 <div class="quickwebp__pro-popup__content__body__bottom">
621 <div class="quickwebp__pro-popup__content__body__bottom__upgrade">
622 <a href="<?php echo esc_url( quickwebp_get_pro_url( 'settings-upgrade-popup' ) ); ?>" class="quickwebp__pro-popup__content__body__bottom__upgrade__link" target="_blank">
623 <span class="quickwebp__pro-popup__content__body__bottom__upgrade__link__icon">
624 <?php echo wp_kses( file_get_contents( QUICKWEBP_PLUGIN_PATH . 'public/assets/svg/crown.svg' ), quickwebp_allowed_tags_for_svg_files() ); ?>
625 </span>
626 <?php esc_html_e( 'Upgrade to QuickWebP Pro', 'quickwebp' ); ?>
627 </a>
628 </div>
629
630 <div class="quickwebp__pro-popup__content__body__bottom__license">
631 <a href="<?php echo esc_url( admin_url( 'admin.php?page=quickwebp-manage-license' ) ); ?>" class="quickwebp__pro-popup__content__body__bottom__license__link">
632 <span class="quickwebp__pro-popup__content__body__bottom__license__link__icon">
633 <?php echo wp_kses( file_get_contents( QUICKWEBP_PLUGIN_PATH . 'public/assets/svg/shield-check.svg' ), quickwebp_allowed_tags_for_svg_files() ); ?>
634 </span>
635 <?php esc_html_e( 'I already have a license', 'quickwebp' ); ?>
636 </a>
637 </div>
638 </div>
639 </div>
640 </div>
641 </div>
642 <?php endif; ?>
643
644 <script>
645 document.addEventListener('DOMContentLoaded', function () {
646 const conversionToggles = document.querySelectorAll('input[type="radio"][name="quickwebp_settings_conversion"]');
647 const saveOriginalCheckbox = document.querySelector('input[type="checkbox"][name="quickwebp_settings_conversion_save_original[]"]');
648 const displayModeInputs = document.querySelectorAll('input[type="radio"][name="quickwebp_settings_conversion_display_webp_mode"]');
649 const disabledDisplayModeInput = document.querySelector('input[type="radio"][name="quickwebp_settings_conversion_display_webp_mode"][value="disabled"]');
650 const pictureDisplayModeInput = document.querySelector('input[type="radio"][name="quickwebp_settings_conversion_display_webp_mode"][value="picture"]');
651 const rewriteDisplayModeInput = document.querySelector('input[type="radio"][name="quickwebp_settings_conversion_display_webp_mode"][value="rewrite"]');
652 const bulkRow = document.querySelector('.quickwebp-row-bulk-optimization');
653 const guidanceMessage = document.querySelector('.quickwebp-guidance-message');
654 const displayWarningRow = document.querySelector('.quickwebp-display-warning-row');
655 const displayWarningText = document.querySelector('.quickwebp-display-warning');
656 const onboardingButtons = document.querySelectorAll('.quickwebp-onboarding-apply');
657 const onboardingFeedback = document.querySelector('.quickwebp-onboarding-feedback');
658 const seoExampleInput = document.querySelector('.quickwebp-seo-example-input');
659 const seoPreviewTitle = document.querySelector('.quickwebp-seo-preview-title');
660 const seoPreviewCaption = document.querySelector('.quickwebp-seo-preview-caption');
661 const seoPreviewAlt = document.querySelector('.quickwebp-seo-preview-alt');
662 const seoPreviewDescription = document.querySelector('.quickwebp-seo-preview-description');
663 const completionToggle = document.querySelector('input[type="checkbox"][name="quickwebp_settings_completion"]');
664 const completionOptionInputs = document.querySelectorAll('input[type="checkbox"][name="quickwebp_settings_completion_options[]"]');
665 const cleanupToggle = document.querySelector('input[type="checkbox"][name="quickwebp_settings_cleanup"]');
666 const cleanupExampleInput = document.querySelector('.quickwebp-cleanup-example-input');
667 const cleanupPreviewOriginal = document.querySelector('.quickwebp-cleanup-preview-original');
668 const cleanupPreviewCleaned = document.querySelector('.quickwebp-cleanup-preview-cleaned');
669
670 const displayModeRow = displayModeInputs.length ? displayModeInputs[0].closest('tr') : null;
671 const disabledDisplayModeLabel = disabledDisplayModeInput ? disabledDisplayModeInput.closest('label') : null;
672 const conversionCard = document.querySelector('#quickwebp-conversion');
673
674 const summary = {
675 sideConversion: document.querySelector('.quickwebp-summary-conversion-side'),
676 sideOriginals: document.querySelector('.quickwebp-summary-originals-side'),
677 sideDisplay: document.querySelector('.quickwebp-summary-display-side'),
678 sideBulk: document.querySelector('.quickwebp-summary-bulk-side')
679 };
680
681 const strings = {
682 noOriginals: <?php echo wp_json_encode( __( 'Current mode: originals are replaced on upload. Frontend display mode and bulk optimization are hidden because they are designed for preserved originals.', 'quickwebp' ) ); ?>,
683 withOriginals: <?php echo wp_json_encode( __( 'Current mode: originals are preserved. Choose a frontend display strategy and run bulk optimization for existing media.', 'quickwebp' ) ); ?>,
684 conversionOff: <?php echo wp_json_encode( __( 'Conversion is disabled. Frontend display mode is forced to Deactivate.', 'quickwebp' ) ); ?>,
685 warningNoOriginals: <?php echo wp_json_encode( __( 'Display mode is locked to Deactivate because original images are not preserved.', 'quickwebp' ) ); ?>,
686 warningConversionOff: <?php echo wp_json_encode( __( 'Display mode is locked to Deactivate because image conversion is disabled.', 'quickwebp' ) ); ?>,
687 appliedNewSite: <?php echo wp_json_encode( __( 'Preset applied: New site profile. Originals are replaced and display mode is set to Deactivate.', 'quickwebp' ) ); ?>,
688 appliedExistingSite: <?php echo wp_json_encode( __( 'Preset applied: Existing site profile. Originals are preserved and rewrite mode is selected.', 'quickwebp' ) ); ?>,
689 profileNew: <?php echo wp_json_encode( __( 'New site profile', 'quickwebp' ) ); ?>,
690 profileExisting: <?php echo wp_json_encode( __( 'Existing site profile', 'quickwebp' ) ); ?>,
691 profileCustom: <?php echo wp_json_encode( __( 'Custom profile', 'quickwebp' ) ); ?>,
692 enabled: <?php echo wp_json_encode( __( 'Enabled', 'quickwebp' ) ); ?>,
693 disabled: <?php echo wp_json_encode( __( 'Disabled', 'quickwebp' ) ); ?>,
694 preserved: <?php echo wp_json_encode( __( 'Preserved', 'quickwebp' ) ); ?>,
695 replaced: <?php echo wp_json_encode( __( 'Replaced', 'quickwebp' ) ); ?>,
696 available: <?php echo wp_json_encode( __( 'Available', 'quickwebp' ) ); ?>,
697 unavailable: <?php echo wp_json_encode( __( 'Unavailable', 'quickwebp' ) ); ?>,
698 disabledPreview: <?php echo wp_json_encode( __( 'Disabled in current settings', 'quickwebp' ) ); ?>,
699 cleanupDisabledPreview: <?php echo wp_json_encode( __( 'Cleanup disabled in current settings', 'quickwebp' ) ); ?>,
700 };
701
702 function setDisplayMode(value) {
703 displayModeInputs.forEach((input) => {
704 input.checked = input.value === value;
705 });
706 }
707
708 function getSelectedDisplayMode() {
709 const selected = Array.from(displayModeInputs).find((input) => input.checked);
710 return selected ? selected.value : 'disabled';
711 }
712
713 function isSaveOriginalEnabled() {
714 return !!saveOriginalCheckbox && saveOriginalCheckbox.checked;
715 }
716
717 function isConversionEnabled() {
718 let conversionToggle = document.querySelector('input[type="radio"][name="quickwebp_settings_conversion"]:checked');
719
720 return !!conversionToggle && conversionToggle.value !== '0';
721 }
722
723 function getProfile(hasOriginals, conversionEnabled) {
724 if (!conversionEnabled) {
725 return strings.profileCustom;
726 }
727
728 return hasOriginals ? strings.profileExisting : strings.profileNew;
729 }
730
731 function updateSummary() {
732 const hasOriginals = isSaveOriginalEnabled();
733 const conversionEnabled = isConversionEnabled();
734 const displayMode = getSelectedDisplayMode();
735 const profile = getProfile(hasOriginals, conversionEnabled);
736
737 if (summary.sideConversion) {
738 summary.sideConversion.textContent = conversionEnabled ? strings.enabled : strings.disabled;
739 }
740
741 if (summary.sideOriginals) {
742 summary.sideOriginals.textContent = hasOriginals ? strings.preserved : strings.replaced;
743 }
744
745 if (summary.sideDisplay) {
746 summary.sideDisplay.textContent = displayMode;
747 }
748
749 if (summary.sideBulk) {
750 summary.sideBulk.textContent = hasOriginals && conversionEnabled ? strings.available : strings.unavailable;
751 }
752 }
753
754 function updateUiConsistency() {
755 const hasOriginals = isSaveOriginalEnabled();
756 const conversionEnabled = isConversionEnabled();
757 const forceDisabled = !hasOriginals || !conversionEnabled;
758
759 if (displayModeRow) {
760 displayModeRow.style.display = hasOriginals && conversionEnabled ? '' : 'none';
761 }
762
763 if (bulkRow) {
764 bulkRow.style.display = hasOriginals && conversionEnabled ? '' : 'none';
765 }
766
767 if (guidanceMessage) {
768 if (!conversionEnabled) {
769 guidanceMessage.textContent = strings.conversionOff;
770 } else {
771 guidanceMessage.textContent = hasOriginals ? strings.withOriginals : strings.noOriginals;
772 }
773 }
774
775 if (displayWarningRow && displayWarningText) {
776 displayWarningRow.style.display = forceDisabled ? '' : 'none';
777
778 if (!conversionEnabled) {
779 displayWarningText.textContent = strings.warningConversionOff;
780 } else {
781 displayWarningText.textContent = strings.warningNoOriginals;
782 }
783 }
784
785 if (disabledDisplayModeLabel) {
786 disabledDisplayModeLabel.style.display = hasOriginals && conversionEnabled ? 'none' : '';
787 }
788
789 if (disabledDisplayModeInput) {
790 disabledDisplayModeInput.disabled = hasOriginals && conversionEnabled;
791 }
792
793 if (forceDisabled) {
794 setDisplayMode('disabled');
795 updateSummary();
796 return;
797 }
798
799 if (disabledDisplayModeInput && disabledDisplayModeInput.checked) {
800 if (pictureDisplayModeInput) {
801 pictureDisplayModeInput.checked = true;
802 } else if (rewriteDisplayModeInput) {
803 rewriteDisplayModeInput.checked = true;
804 }
805 }
806
807 updateSummary();
808 }
809
810 function extractBaseFilename(value) {
811 if (!value) {
812 return 'example image';
813 }
814
815 const base = value.replace(/\.[^/.]+$/, '');
816 const normalized = base
817 .replace(/\s+/g, ' ')
818 .trim();
819
820 return normalized || 'example image';
821 }
822
823 function updateSeoLiveExample() {
824 if (!seoExampleInput || !seoPreviewTitle || !seoPreviewCaption || !seoPreviewAlt || !seoPreviewDescription) {
825 return;
826 }
827
828 const optionsMap = {
829 title: {
830 checked: !!document.querySelector('input[type="checkbox"][name="quickwebp_settings_completion_options[]"][value="title"]:checked'),
831 preview: seoPreviewTitle
832 },
833 caption: {
834 checked: !!document.querySelector('input[type="checkbox"][name="quickwebp_settings_completion_options[]"][value="caption"]:checked'),
835 preview: seoPreviewCaption
836 },
837 alt: {
838 checked: !!document.querySelector('input[type="checkbox"][name="quickwebp_settings_completion_options[]"][value="alt"]:checked'),
839 preview: seoPreviewAlt
840 },
841 description: {
842 checked: !!document.querySelector('input[type="checkbox"][name="quickwebp_settings_completion_options[]"][value="description"]:checked'),
843 preview: seoPreviewDescription
844 }
845 };
846
847 const completionEnabled = !!completionToggle && completionToggle.checked;
848 const baseFilename = extractBaseFilename(seoExampleInput.value);
849
850 optionsMap.title.preview.textContent = baseFilename;
851 optionsMap.caption.preview.textContent = baseFilename;
852 optionsMap.alt.preview.textContent = baseFilename;
853 optionsMap.description.preview.textContent = baseFilename;
854
855 Object.keys(optionsMap).forEach((key) => {
856 const item = optionsMap[key];
857 const container = item.preview.closest('.quickwebp-seo-example-item');
858 const isEnabled = completionEnabled && item.checked;
859
860 if (!isEnabled) {
861 item.preview.textContent = strings.disabledPreview;
862 }
863
864 if (container) {
865 container.classList.toggle('is-disabled', !isEnabled);
866 }
867 });
868 }
869
870 function sanitizeFilenamePreview(value) {
871 const inputValue = (value || '').trim();
872 if (!inputValue) {
873 return 'example-image.jpg';
874 }
875
876 const lastDot = inputValue.lastIndexOf('.');
877 const hasExtension = lastDot > 0 && lastDot < inputValue.length - 1;
878 const extension = hasExtension ? inputValue.slice(lastDot + 1).toLowerCase() : '';
879 const basename = hasExtension ? inputValue.slice(0, lastDot) : inputValue;
880
881 let normalized = basename;
882 if (normalized.normalize) {
883 normalized = normalized.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
884 }
885
886 normalized = normalized
887 .replace(/[']/g, '-')
888 .replace(/[^A-Za-z0-9\s-]/g, '')
889 .toLowerCase()
890 .trim()
891 .replace(/\s+/g, '-')
892 .replace(/-+/g, '-')
893 .replace(/^-+|-+$/g, '');
894
895 if (!normalized) {
896 normalized = 'image';
897 }
898
899 return extension ? normalized + '.' + extension : normalized;
900 }
901
902 function updateCleanupLiveExample() {
903 if (!cleanupExampleInput || !cleanupPreviewOriginal || !cleanupPreviewCleaned) {
904 return;
905 }
906
907 const original = cleanupExampleInput.value || '';
908 const cleaned = sanitizeFilenamePreview(original);
909 const isCleanupEnabled = !!cleanupToggle && cleanupToggle.checked;
910
911 cleanupPreviewOriginal.textContent = original || 'example image.jpg';
912
913 const cleanedContainer = cleanupPreviewCleaned.closest('.quickwebp-cleanup-example-item');
914 if (!isCleanupEnabled) {
915 cleanupPreviewCleaned.textContent = strings.cleanupDisabledPreview;
916 if (cleanedContainer) {
917 cleanedContainer.classList.add('is-disabled');
918 }
919 return;
920 }
921
922 cleanupPreviewCleaned.textContent = cleaned;
923 if (cleanedContainer) {
924 cleanedContainer.classList.remove('is-disabled');
925 }
926 }
927
928 onboardingButtons.forEach((button) => {
929 button.addEventListener('click', function () {
930 const profile = this.getAttribute('data-profile');
931
932 let conversionToggle = document.querySelector('input[type="radio"][name="quickwebp_settings_conversion"][value="1"]');
933 if (conversionToggle) {
934 conversionToggle.checked = true;
935 conversionToggle.dispatchEvent(new Event('change', { bubbles: true }));
936 }
937
938 if (!saveOriginalCheckbox) {
939 return;
940 }
941
942 if (profile === 'new-site') {
943 saveOriginalCheckbox.checked = false;
944 setDisplayMode('disabled');
945
946 if (onboardingFeedback) {
947 onboardingFeedback.textContent = strings.appliedNewSite;
948 }
949 }
950
951 if (profile === 'existing-site') {
952 saveOriginalCheckbox.checked = true;
953 if (rewriteDisplayModeInput) {
954 rewriteDisplayModeInput.checked = true;
955 } else {
956 setDisplayMode('picture');
957 }
958
959 if (onboardingFeedback) {
960 onboardingFeedback.textContent = strings.appliedExistingSite;
961 }
962 }
963
964 updateUiConsistency();
965
966 if (conversionCard) {
967 conversionCard.scrollIntoView({ behavior: 'smooth', block: 'start' });
968 }
969 });
970 });
971
972 if (saveOriginalCheckbox) {
973 saveOriginalCheckbox.addEventListener('change', updateUiConsistency);
974 }
975
976 conversionToggles.forEach((toggle) => {
977 toggle.addEventListener('change', updateUiConsistency);
978 });
979
980 displayModeInputs.forEach((input) => {
981 input.addEventListener('change', updateSummary);
982 });
983
984 if (seoExampleInput) {
985 seoExampleInput.addEventListener('input', updateSeoLiveExample);
986 updateSeoLiveExample();
987 }
988
989 if (cleanupExampleInput) {
990 cleanupExampleInput.addEventListener('input', updateCleanupLiveExample);
991 updateCleanupLiveExample();
992 }
993
994 if (completionToggle) {
995 completionToggle.addEventListener('change', updateSeoLiveExample);
996 }
997
998 if (cleanupToggle) {
999 cleanupToggle.addEventListener('change', updateCleanupLiveExample);
1000 }
1001
1002 completionOptionInputs.forEach((input) => {
1003 input.addEventListener('change', updateSeoLiveExample);
1004 });
1005
1006 document.querySelectorAll('.quickwebp-quick-links a[href^="#"]').forEach((anchor) => {
1007 anchor.addEventListener('click', function (event) {
1008 const target = document.querySelector(this.getAttribute('href'));
1009 if (!target) {
1010 return;
1011 }
1012
1013 event.preventDefault();
1014 target.scrollIntoView({ behavior: 'smooth', block: 'start' });
1015 });
1016 });
1017
1018 updateUiConsistency();
1019 });
1020 </script>
1021 </div>
1022