PluginProbe
QuickWebP – WebP & AVIF Image Optimizer, Compression & SEO for WordPress / 4.0.1
QuickWebP – WebP & AVIF Image Optimizer, Compression & SEO for WordPress v4.0.1
4.1.2 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.0.1, at admin/templates/page-settings.php

1,010 lines 55.4 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 </table>
395 </div>
396 </section>
397
398 <section class="quickwebp-card" id="quickwebp-migration">
399 <div class="quickwebp-card-head">
400 <h2><?php esc_html_e( 'Migration notice', 'quickwebp' ); ?></h2>
401 <p><?php esc_html_e( 'QuickWebP is now available inside WPMasterToolKit.', 'quickwebp' ); ?></p>
402 </div>
403 <div class="quickwebp-card-body">
404 <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>
405 <video autoplay loop muted controls class="quickwebp-migration-video">
406 <source src="<?php echo esc_url( QUICKWEBP_PLUGIN_URL . 'public/assets/video/wpmastertoolkit.mp4' ); ?>" type="video/mp4">
407 <?php esc_html_e( 'Your browser does not support the video tag.', 'quickwebp' ); ?>
408 </video>
409 <?php if ( $wpmtk_is_active ) : ?>
410 <p><strong><?php esc_html_e( 'You can now deactivate QuickWebP and finish the migration.', 'quickwebp' ); ?></strong></p>
411 <?php else : ?>
412 <p>
413 <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>
414 <a href="https://wordpress.org/plugins/wpmastertoolkit/" class="button button-secondary" target="_blank"><?php esc_html_e( 'Download WPMasterToolKit from wordpress.org', 'quickwebp' ); ?></a>
415 </p>
416 <?php endif; ?>
417 </div>
418 </section>
419
420 <div class="quickwebp-submit-wrap">
421 <?php submit_button( __( 'Save settings', 'quickwebp' ), 'primary', 'submit', false ); ?>
422 <p class="quickwebp-submit-note"><?php esc_html_e( 'Your consistency rules are enforced automatically when saving.', 'quickwebp' ); ?></p>
423 </div>
424
425 <div class="quickwebp-credits">
426 <p>
427 <?php esc_html_e( 'This plugin is developed by', 'quickwebp' ); ?>
428 <a href="https://webdeclic.com/" target="_blank">Webdeclic</a>.
429 <?php esc_html_e( 'You can support this project here:', 'quickwebp' ); ?>
430 <a href="https://www.buymeacoffee.com/ludwig" target="_blank"><?php esc_html_e( 'Buy me a coffee', 'quickwebp' ); ?></a>.
431 </p>
432 <p>
433 <?php esc_html_e( 'You can show all Webdeclic plugins on', 'quickwebp' ); ?>
434 <a href="https://wordpress.org/plugins/search/webdeclic/" target="_blank">wordpress.org</a>.
435 </p>
436 </div>
437 </main>
438
439 <aside class="quickwebp-aside">
440 <div class="quickwebp-aside-inner">
441 <section class="quickwebp-card">
442 <div class="quickwebp-card-head">
443 <h2><?php esc_html_e( 'Live configuration summary', 'quickwebp' ); ?></h2>
444 <p><?php esc_html_e( 'This panel updates instantly while you edit your settings.', 'quickwebp' ); ?></p>
445 </div>
446 <div class="quickwebp-card-body">
447 <ul class="quickwebp-summary-list">
448 <li>
449 <span class="quickwebp-summary-label"><?php esc_html_e( 'Conversion', 'quickwebp' ); ?></span>
450 <span class="quickwebp-summary-value quickwebp-summary-conversion-side"><?php echo esc_html( $conversion_enabled ? __( 'Enabled', 'quickwebp' ) : __( 'Disabled', 'quickwebp' ) ); ?></span>
451 </li>
452 <li>
453 <span class="quickwebp-summary-label"><?php esc_html_e( 'Original images', 'quickwebp' ); ?></span>
454 <span class="quickwebp-summary-value quickwebp-summary-originals-side"><?php echo esc_html( $save_original_enabled ? __( 'Preserved', 'quickwebp' ) : __( 'Replaced', 'quickwebp' ) ); ?></span>
455 </li>
456 <li>
457 <span class="quickwebp-summary-label"><?php esc_html_e( 'Frontend display', 'quickwebp' ); ?></span>
458 <span class="quickwebp-summary-value quickwebp-summary-display-side"><?php echo esc_html( $display_mode ); ?></span>
459 </li>
460 <li>
461 <span class="quickwebp-summary-label"><?php esc_html_e( 'Bulk optimization', 'quickwebp' ); ?></span>
462 <span class="quickwebp-summary-value quickwebp-summary-bulk-side"><?php echo esc_html( $save_original_enabled ? __( 'Available', 'quickwebp' ) : __( 'Unavailable', 'quickwebp' ) ); ?></span>
463 </li>
464 </ul>
465 </div>
466 </section>
467
468 <section class="quickwebp-card">
469 <div class="quickwebp-card-head">
470 <h2><?php esc_html_e( 'Quick navigation', 'quickwebp' ); ?></h2>
471 </div>
472 <div class="quickwebp-card-body quickwebp-quick-links">
473 <?php if ( $show_onboarding ) : ?>
474 <a href="#quickwebp-onboarding"><?php esc_html_e( 'Quick setup assistant', 'quickwebp' ); ?></a>
475 <?php endif; ?>
476 <a href="#quickwebp-conversion"><?php esc_html_e( 'Conversion and delivery', 'quickwebp' ); ?></a>
477 <a href="#quickwebp-resize"><?php esc_html_e( 'Resize', 'quickwebp' ); ?></a>
478 <a href="#quickwebp-seo"><?php esc_html_e( 'SEO metadata automation', 'quickwebp' ); ?></a>
479 <a href="#quickwebp-tools"><?php esc_html_e( 'Other tools', 'quickwebp' ); ?></a>
480 <a href="#quickwebp-migration"><?php esc_html_e( 'Migration notice', 'quickwebp' ); ?></a>
481 </div>
482 </section>
483
484 <section class="quickwebp-card">
485 <div class="quickwebp-card-head">
486 <h2><?php esc_html_e( 'License', 'quickwebp' ); ?></h2>
487 </div>
488 <div class="quickwebp-card-body quickwebp-license">
489 <div class="quickwebp-license__status">
490 <div class="quickwebp-license__status__text"><?php esc_html_e( 'State', 'quickwebp' ); ?>:</div>
491 <div class="quickwebp-license__status__icon <?php echo $license_valid ? 'valid' : 'invalid'; ?>"></div>
492 </div>
493
494 <div class="quickwebp-license__link">
495 <a href="<?php echo esc_url( admin_url( 'admin.php?page=quickwebp-manage-license' ) ); ?>" class="<?php echo $license_valid ? 'valid' : 'invalid'; ?>">
496 <?php if ( $license_valid ) : ?>
497 <?php echo wp_kses( file_get_contents( QUICKWEBP_PLUGIN_PATH . 'public/assets/svg/key-disable.svg' ), quickwebp_allowed_tags_for_svg_files() ); ?>
498 <?php esc_html_e( 'Deactivate the license', 'quickwebp' ); ?>
499 <?php else : ?>
500 <?php echo wp_kses( file_get_contents( QUICKWEBP_PLUGIN_PATH . 'public/assets/svg/key.svg' ), quickwebp_allowed_tags_for_svg_files() ); ?>
501 <?php esc_html_e( 'Activate the license', 'quickwebp' ); ?>
502 <?php endif; ?>
503 </a>
504 </div>
505 </div>
506 </section>
507 </div>
508 </aside>
509 </div>
510 </form>
511
512 <?php if ( ! $license_valid ): ?>
513 <div class="quickwebp__pro-popup">
514 <div class="quickwebp__pro-popup__overlay"></div>
515 <div class="quickwebp__pro-popup__content">
516 <div class="quickwebp__pro-popup__content__header">
517 <div class="quickwebp__pro-popup__content__header__text">
518 <div class="quickwebp__pro-popup__content__header__text__subtitle">
519 <div class="quickwebp__pro-popup__content__header__text__subtitle__tag"><?php esc_html_e( 'Pro', 'quickwebp' ); ?></div>
520 <div class="quickwebp__pro-popup__content__header__text__subtitle__text"><?php esc_html_e( 'AVIF Format', 'quickwebp' ); ?></div>
521 </div>
522 <div class="quickwebp__pro-popup__content__header__text__title">
523 <?php esc_html_e( 'Go further with', 'quickwebp' ); ?>
524 <span class="highlight"> AVIF</span>
525 </div>
526 <div class="quickwebp__pro-popup__content__header__text__desc">
527 <?php esc_html_e( 'The next-generation image format, available with', 'quickwebp' ); ?>
528 <span class="highlight">QuickWebP Pro.</span>
529 </div>
530 </div>
531
532 <div class="quickwebp__pro-popup__content__header__close">
533 <?php echo wp_kses( file_get_contents( QUICKWEBP_PLUGIN_PATH . 'public/assets/svg/close.svg' ), quickwebp_allowed_tags_for_svg_files() ); ?>
534 </div>
535 </div>
536 <div class="quickwebp__pro-popup__content__body">
537 <div class="quickwebp__pro-popup__content__body__top">
538 <div class="quickwebp__pro-popup__content__body__top__item">
539 <div class="quickwebp__pro-popup__content__body__top__item__icon">
540 <?php echo wp_kses( file_get_contents( QUICKWEBP_PLUGIN_PATH . 'public/assets/svg/gauge.svg' ), quickwebp_allowed_tags_for_svg_files() ); ?>
541 </div>
542 <div class="quickwebp__pro-popup__content__body__top__item__text">
543 <div class="quickwebp__pro-popup__content__body__top__item__text__title">-50%</div>
544 <div class="quickwebp__pro-popup__content__body__top__item__text__desc"><?php esc_html_e( 'Vs jpeg/png on average', 'quickwebp' ); ?></div>
545 </div>
546 </div>
547
548 <div class="quickwebp__pro-popup__content__body__top__item second">
549 <div class="quickwebp__pro-popup__content__body__top__item__icon">
550 <?php echo wp_kses( file_get_contents( QUICKWEBP_PLUGIN_PATH . 'public/assets/svg/chart-line.svg' ), quickwebp_allowed_tags_for_svg_files() ); ?>
551 </div>
552 <div class="quickwebp__pro-popup__content__body__top__item__text">
553 <div class="quickwebp__pro-popup__content__body__top__item__text__title">-30%</div>
554 <div class="quickwebp__pro-popup__content__body__top__item__text__desc"><?php esc_html_e( 'Vs webp on average', 'quickwebp' ); ?></div>
555 </div>
556 </div>
557
558 <div class="quickwebp__pro-popup__content__body__top__item third">
559 <div class="quickwebp__pro-popup__content__body__top__item__icon">
560 <?php echo wp_kses( file_get_contents( QUICKWEBP_PLUGIN_PATH . 'public/assets/svg/global.svg' ), quickwebp_allowed_tags_for_svg_files() ); ?>
561 </div>
562 <div class="quickwebp__pro-popup__content__body__top__item__text">
563 <div class="quickwebp__pro-popup__content__body__top__item__text__title">100%</div>
564 <div class="quickwebp__pro-popup__content__body__top__item__text__desc"><?php esc_html_e( 'of modern browsers supported', 'quickwebp' ); ?></div>
565 </div>
566 </div>
567 </div>
568
569 <div class="quickwebp__pro-popup__content__body__middle">
570 <div class="quickwebp__pro-popup__content__body__middle__item">
571 <div class="quickwebp__pro-popup__content__body__middle__item__icon">
572 <?php echo wp_kses( file_get_contents( QUICKWEBP_PLUGIN_PATH . 'public/assets/svg/check-mark.svg' ), quickwebp_allowed_tags_for_svg_files() ); ?>
573 </div>
574 <div class="quickwebp__pro-popup__content__body__middle__item__text">
575 <strong><?php echo wp_kses_post(
576 // translators: %s is a placeholder for the text "</strong>".
577 sprintf( __( 'The best compression available %s images typically half the size of your originals.', 'quickwebp' ), '</strong>' )
578 ); ?>
579 </div>
580 </div>
581
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( __( 'Sharper images at lower weight %s for faster pages and better Core Web Vitals.', '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( __( 'Automatic fallback %s so older browsers keep receiving a compatible format.', 'quickwebp' ), '</strong>' )
602 ); ?>
603 </div>
604 </div>
605
606 </div>
607
608 <div class="quickwebp__pro-popup__content__body__bottom">
609 <div class="quickwebp__pro-popup__content__body__bottom__upgrade">
610 <a href="<?php echo esc_url( quickwebp_get_pro_url( 'settings-upgrade-popup' ) ); ?>" class="quickwebp__pro-popup__content__body__bottom__upgrade__link" target="_blank">
611 <span class="quickwebp__pro-popup__content__body__bottom__upgrade__link__icon">
612 <?php echo wp_kses( file_get_contents( QUICKWEBP_PLUGIN_PATH . 'public/assets/svg/crown.svg' ), quickwebp_allowed_tags_for_svg_files() ); ?>
613 </span>
614 <?php esc_html_e( 'Upgrade to QuickWebP Pro', 'quickwebp' ); ?>
615 </a>
616 </div>
617
618 <div class="quickwebp__pro-popup__content__body__bottom__license">
619 <a href="<?php echo esc_url( admin_url( 'admin.php?page=quickwebp-manage-license' ) ); ?>" class="quickwebp__pro-popup__content__body__bottom__license__link">
620 <span class="quickwebp__pro-popup__content__body__bottom__license__link__icon">
621 <?php echo wp_kses( file_get_contents( QUICKWEBP_PLUGIN_PATH . 'public/assets/svg/shield-check.svg' ), quickwebp_allowed_tags_for_svg_files() ); ?>
622 </span>
623 <?php esc_html_e( 'I already have a license', 'quickwebp' ); ?>
624 </a>
625 </div>
626 </div>
627 </div>
628 </div>
629 </div>
630 <?php endif; ?>
631
632 <script>
633 document.addEventListener('DOMContentLoaded', function () {
634 const conversionToggles = document.querySelectorAll('input[type="radio"][name="quickwebp_settings_conversion"]');
635 const saveOriginalCheckbox = document.querySelector('input[type="checkbox"][name="quickwebp_settings_conversion_save_original[]"]');
636 const displayModeInputs = document.querySelectorAll('input[type="radio"][name="quickwebp_settings_conversion_display_webp_mode"]');
637 const disabledDisplayModeInput = document.querySelector('input[type="radio"][name="quickwebp_settings_conversion_display_webp_mode"][value="disabled"]');
638 const pictureDisplayModeInput = document.querySelector('input[type="radio"][name="quickwebp_settings_conversion_display_webp_mode"][value="picture"]');
639 const rewriteDisplayModeInput = document.querySelector('input[type="radio"][name="quickwebp_settings_conversion_display_webp_mode"][value="rewrite"]');
640 const bulkRow = document.querySelector('.quickwebp-row-bulk-optimization');
641 const guidanceMessage = document.querySelector('.quickwebp-guidance-message');
642 const displayWarningRow = document.querySelector('.quickwebp-display-warning-row');
643 const displayWarningText = document.querySelector('.quickwebp-display-warning');
644 const onboardingButtons = document.querySelectorAll('.quickwebp-onboarding-apply');
645 const onboardingFeedback = document.querySelector('.quickwebp-onboarding-feedback');
646 const seoExampleInput = document.querySelector('.quickwebp-seo-example-input');
647 const seoPreviewTitle = document.querySelector('.quickwebp-seo-preview-title');
648 const seoPreviewCaption = document.querySelector('.quickwebp-seo-preview-caption');
649 const seoPreviewAlt = document.querySelector('.quickwebp-seo-preview-alt');
650 const seoPreviewDescription = document.querySelector('.quickwebp-seo-preview-description');
651 const completionToggle = document.querySelector('input[type="checkbox"][name="quickwebp_settings_completion"]');
652 const completionOptionInputs = document.querySelectorAll('input[type="checkbox"][name="quickwebp_settings_completion_options[]"]');
653 const cleanupToggle = document.querySelector('input[type="checkbox"][name="quickwebp_settings_cleanup"]');
654 const cleanupExampleInput = document.querySelector('.quickwebp-cleanup-example-input');
655 const cleanupPreviewOriginal = document.querySelector('.quickwebp-cleanup-preview-original');
656 const cleanupPreviewCleaned = document.querySelector('.quickwebp-cleanup-preview-cleaned');
657
658 const displayModeRow = displayModeInputs.length ? displayModeInputs[0].closest('tr') : null;
659 const disabledDisplayModeLabel = disabledDisplayModeInput ? disabledDisplayModeInput.closest('label') : null;
660 const conversionCard = document.querySelector('#quickwebp-conversion');
661
662 const summary = {
663 sideConversion: document.querySelector('.quickwebp-summary-conversion-side'),
664 sideOriginals: document.querySelector('.quickwebp-summary-originals-side'),
665 sideDisplay: document.querySelector('.quickwebp-summary-display-side'),
666 sideBulk: document.querySelector('.quickwebp-summary-bulk-side')
667 };
668
669 const strings = {
670 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' ) ); ?>,
671 withOriginals: <?php echo wp_json_encode( __( 'Current mode: originals are preserved. Choose a frontend display strategy and run bulk optimization for existing media.', 'quickwebp' ) ); ?>,
672 conversionOff: <?php echo wp_json_encode( __( 'Conversion is disabled. Frontend display mode is forced to Deactivate.', 'quickwebp' ) ); ?>,
673 warningNoOriginals: <?php echo wp_json_encode( __( 'Display mode is locked to Deactivate because original images are not preserved.', 'quickwebp' ) ); ?>,
674 warningConversionOff: <?php echo wp_json_encode( __( 'Display mode is locked to Deactivate because image conversion is disabled.', 'quickwebp' ) ); ?>,
675 appliedNewSite: <?php echo wp_json_encode( __( 'Preset applied: New site profile. Originals are replaced and display mode is set to Deactivate.', 'quickwebp' ) ); ?>,
676 appliedExistingSite: <?php echo wp_json_encode( __( 'Preset applied: Existing site profile. Originals are preserved and rewrite mode is selected.', 'quickwebp' ) ); ?>,
677 profileNew: <?php echo wp_json_encode( __( 'New site profile', 'quickwebp' ) ); ?>,
678 profileExisting: <?php echo wp_json_encode( __( 'Existing site profile', 'quickwebp' ) ); ?>,
679 profileCustom: <?php echo wp_json_encode( __( 'Custom profile', 'quickwebp' ) ); ?>,
680 enabled: <?php echo wp_json_encode( __( 'Enabled', 'quickwebp' ) ); ?>,
681 disabled: <?php echo wp_json_encode( __( 'Disabled', 'quickwebp' ) ); ?>,
682 preserved: <?php echo wp_json_encode( __( 'Preserved', 'quickwebp' ) ); ?>,
683 replaced: <?php echo wp_json_encode( __( 'Replaced', 'quickwebp' ) ); ?>,
684 available: <?php echo wp_json_encode( __( 'Available', 'quickwebp' ) ); ?>,
685 unavailable: <?php echo wp_json_encode( __( 'Unavailable', 'quickwebp' ) ); ?>,
686 disabledPreview: <?php echo wp_json_encode( __( 'Disabled in current settings', 'quickwebp' ) ); ?>,
687 cleanupDisabledPreview: <?php echo wp_json_encode( __( 'Cleanup disabled in current settings', 'quickwebp' ) ); ?>,
688 };
689
690 function setDisplayMode(value) {
691 displayModeInputs.forEach((input) => {
692 input.checked = input.value === value;
693 });
694 }
695
696 function getSelectedDisplayMode() {
697 const selected = Array.from(displayModeInputs).find((input) => input.checked);
698 return selected ? selected.value : 'disabled';
699 }
700
701 function isSaveOriginalEnabled() {
702 return !!saveOriginalCheckbox && saveOriginalCheckbox.checked;
703 }
704
705 function isConversionEnabled() {
706 let conversionToggle = document.querySelector('input[type="radio"][name="quickwebp_settings_conversion"]:checked');
707
708 return !!conversionToggle && conversionToggle.value !== '0';
709 }
710
711 function getProfile(hasOriginals, conversionEnabled) {
712 if (!conversionEnabled) {
713 return strings.profileCustom;
714 }
715
716 return hasOriginals ? strings.profileExisting : strings.profileNew;
717 }
718
719 function updateSummary() {
720 const hasOriginals = isSaveOriginalEnabled();
721 const conversionEnabled = isConversionEnabled();
722 const displayMode = getSelectedDisplayMode();
723 const profile = getProfile(hasOriginals, conversionEnabled);
724
725 if (summary.sideConversion) {
726 summary.sideConversion.textContent = conversionEnabled ? strings.enabled : strings.disabled;
727 }
728
729 if (summary.sideOriginals) {
730 summary.sideOriginals.textContent = hasOriginals ? strings.preserved : strings.replaced;
731 }
732
733 if (summary.sideDisplay) {
734 summary.sideDisplay.textContent = displayMode;
735 }
736
737 if (summary.sideBulk) {
738 summary.sideBulk.textContent = hasOriginals && conversionEnabled ? strings.available : strings.unavailable;
739 }
740 }
741
742 function updateUiConsistency() {
743 const hasOriginals = isSaveOriginalEnabled();
744 const conversionEnabled = isConversionEnabled();
745 const forceDisabled = !hasOriginals || !conversionEnabled;
746
747 if (displayModeRow) {
748 displayModeRow.style.display = hasOriginals && conversionEnabled ? '' : 'none';
749 }
750
751 if (bulkRow) {
752 bulkRow.style.display = hasOriginals && conversionEnabled ? '' : 'none';
753 }
754
755 if (guidanceMessage) {
756 if (!conversionEnabled) {
757 guidanceMessage.textContent = strings.conversionOff;
758 } else {
759 guidanceMessage.textContent = hasOriginals ? strings.withOriginals : strings.noOriginals;
760 }
761 }
762
763 if (displayWarningRow && displayWarningText) {
764 displayWarningRow.style.display = forceDisabled ? '' : 'none';
765
766 if (!conversionEnabled) {
767 displayWarningText.textContent = strings.warningConversionOff;
768 } else {
769 displayWarningText.textContent = strings.warningNoOriginals;
770 }
771 }
772
773 if (disabledDisplayModeLabel) {
774 disabledDisplayModeLabel.style.display = hasOriginals && conversionEnabled ? 'none' : '';
775 }
776
777 if (disabledDisplayModeInput) {
778 disabledDisplayModeInput.disabled = hasOriginals && conversionEnabled;
779 }
780
781 if (forceDisabled) {
782 setDisplayMode('disabled');
783 updateSummary();
784 return;
785 }
786
787 if (disabledDisplayModeInput && disabledDisplayModeInput.checked) {
788 if (pictureDisplayModeInput) {
789 pictureDisplayModeInput.checked = true;
790 } else if (rewriteDisplayModeInput) {
791 rewriteDisplayModeInput.checked = true;
792 }
793 }
794
795 updateSummary();
796 }
797
798 function extractBaseFilename(value) {
799 if (!value) {
800 return 'example image';
801 }
802
803 const base = value.replace(/\.[^/.]+$/, '');
804 const normalized = base
805 .replace(/\s+/g, ' ')
806 .trim();
807
808 return normalized || 'example image';
809 }
810
811 function updateSeoLiveExample() {
812 if (!seoExampleInput || !seoPreviewTitle || !seoPreviewCaption || !seoPreviewAlt || !seoPreviewDescription) {
813 return;
814 }
815
816 const optionsMap = {
817 title: {
818 checked: !!document.querySelector('input[type="checkbox"][name="quickwebp_settings_completion_options[]"][value="title"]:checked'),
819 preview: seoPreviewTitle
820 },
821 caption: {
822 checked: !!document.querySelector('input[type="checkbox"][name="quickwebp_settings_completion_options[]"][value="caption"]:checked'),
823 preview: seoPreviewCaption
824 },
825 alt: {
826 checked: !!document.querySelector('input[type="checkbox"][name="quickwebp_settings_completion_options[]"][value="alt"]:checked'),
827 preview: seoPreviewAlt
828 },
829 description: {
830 checked: !!document.querySelector('input[type="checkbox"][name="quickwebp_settings_completion_options[]"][value="description"]:checked'),
831 preview: seoPreviewDescription
832 }
833 };
834
835 const completionEnabled = !!completionToggle && completionToggle.checked;
836 const baseFilename = extractBaseFilename(seoExampleInput.value);
837
838 optionsMap.title.preview.textContent = baseFilename;
839 optionsMap.caption.preview.textContent = baseFilename;
840 optionsMap.alt.preview.textContent = baseFilename;
841 optionsMap.description.preview.textContent = baseFilename;
842
843 Object.keys(optionsMap).forEach((key) => {
844 const item = optionsMap[key];
845 const container = item.preview.closest('.quickwebp-seo-example-item');
846 const isEnabled = completionEnabled && item.checked;
847
848 if (!isEnabled) {
849 item.preview.textContent = strings.disabledPreview;
850 }
851
852 if (container) {
853 container.classList.toggle('is-disabled', !isEnabled);
854 }
855 });
856 }
857
858 function sanitizeFilenamePreview(value) {
859 const inputValue = (value || '').trim();
860 if (!inputValue) {
861 return 'example-image.jpg';
862 }
863
864 const lastDot = inputValue.lastIndexOf('.');
865 const hasExtension = lastDot > 0 && lastDot < inputValue.length - 1;
866 const extension = hasExtension ? inputValue.slice(lastDot + 1).toLowerCase() : '';
867 const basename = hasExtension ? inputValue.slice(0, lastDot) : inputValue;
868
869 let normalized = basename;
870 if (normalized.normalize) {
871 normalized = normalized.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
872 }
873
874 normalized = normalized
875 .replace(/[']/g, '-')
876 .replace(/[^A-Za-z0-9\s-]/g, '')
877 .toLowerCase()
878 .trim()
879 .replace(/\s+/g, '-')
880 .replace(/-+/g, '-')
881 .replace(/^-+|-+$/g, '');
882
883 if (!normalized) {
884 normalized = 'image';
885 }
886
887 return extension ? normalized + '.' + extension : normalized;
888 }
889
890 function updateCleanupLiveExample() {
891 if (!cleanupExampleInput || !cleanupPreviewOriginal || !cleanupPreviewCleaned) {
892 return;
893 }
894
895 const original = cleanupExampleInput.value || '';
896 const cleaned = sanitizeFilenamePreview(original);
897 const isCleanupEnabled = !!cleanupToggle && cleanupToggle.checked;
898
899 cleanupPreviewOriginal.textContent = original || 'example image.jpg';
900
901 const cleanedContainer = cleanupPreviewCleaned.closest('.quickwebp-cleanup-example-item');
902 if (!isCleanupEnabled) {
903 cleanupPreviewCleaned.textContent = strings.cleanupDisabledPreview;
904 if (cleanedContainer) {
905 cleanedContainer.classList.add('is-disabled');
906 }
907 return;
908 }
909
910 cleanupPreviewCleaned.textContent = cleaned;
911 if (cleanedContainer) {
912 cleanedContainer.classList.remove('is-disabled');
913 }
914 }
915
916 onboardingButtons.forEach((button) => {
917 button.addEventListener('click', function () {
918 const profile = this.getAttribute('data-profile');
919
920 let conversionToggle = document.querySelector('input[type="radio"][name="quickwebp_settings_conversion"][value="1"]');
921 if (conversionToggle) {
922 conversionToggle.checked = true;
923 conversionToggle.dispatchEvent(new Event('change', { bubbles: true }));
924 }
925
926 if (!saveOriginalCheckbox) {
927 return;
928 }
929
930 if (profile === 'new-site') {
931 saveOriginalCheckbox.checked = false;
932 setDisplayMode('disabled');
933
934 if (onboardingFeedback) {
935 onboardingFeedback.textContent = strings.appliedNewSite;
936 }
937 }
938
939 if (profile === 'existing-site') {
940 saveOriginalCheckbox.checked = true;
941 if (rewriteDisplayModeInput) {
942 rewriteDisplayModeInput.checked = true;
943 } else {
944 setDisplayMode('picture');
945 }
946
947 if (onboardingFeedback) {
948 onboardingFeedback.textContent = strings.appliedExistingSite;
949 }
950 }
951
952 updateUiConsistency();
953
954 if (conversionCard) {
955 conversionCard.scrollIntoView({ behavior: 'smooth', block: 'start' });
956 }
957 });
958 });
959
960 if (saveOriginalCheckbox) {
961 saveOriginalCheckbox.addEventListener('change', updateUiConsistency);
962 }
963
964 conversionToggles.forEach((toggle) => {
965 toggle.addEventListener('change', updateUiConsistency);
966 });
967
968 displayModeInputs.forEach((input) => {
969 input.addEventListener('change', updateSummary);
970 });
971
972 if (seoExampleInput) {
973 seoExampleInput.addEventListener('input', updateSeoLiveExample);
974 updateSeoLiveExample();
975 }
976
977 if (cleanupExampleInput) {
978 cleanupExampleInput.addEventListener('input', updateCleanupLiveExample);
979 updateCleanupLiveExample();
980 }
981
982 if (completionToggle) {
983 completionToggle.addEventListener('change', updateSeoLiveExample);
984 }
985
986 if (cleanupToggle) {
987 cleanupToggle.addEventListener('change', updateCleanupLiveExample);
988 }
989
990 completionOptionInputs.forEach((input) => {
991 input.addEventListener('change', updateSeoLiveExample);
992 });
993
994 document.querySelectorAll('.quickwebp-quick-links a[href^="#"]').forEach((anchor) => {
995 anchor.addEventListener('click', function (event) {
996 const target = document.querySelector(this.getAttribute('href'));
997 if (!target) {
998 return;
999 }
1000
1001 event.preventDefault();
1002 target.scrollIntoView({ behavior: 'smooth', block: 'start' });
1003 });
1004 });
1005
1006 updateUiConsistency();
1007 });
1008 </script>
1009 </div>
1010