PluginProbe
WP Attachments – Smarter File Management & Download Lists / 6.1
WP Attachments – Smarter File Management & Download Lists v6.1
6.1 6.0.2 6.0.3 trunk 2.0 3 3.0.1 3.0.2 3.0.3 3.1 3.1.1 3.1.2 3.1.3 3.1.4 3.2 3.2.1 3.2.2 3.2.3 3.2.4 3.3 3.4 3.5 3.5.1 3.5.2 3.5.3 All 53 releases
← All changes | inc/settings.php +244 -58 6.0.2 → 6.1 View file →
@@ -13,8 +13,11 @@
13 13 check_admin_referer('wpatt_general_settings');
14 14
15 15 update_option('wpatt_option_localization', sanitize_text_field($_POST["wpatt_option_localization_n"] ?? ''));
16 16 update_option('wpatt_option_date_localization', sanitize_text_field($_POST["wpatt_option_date_localization_n"] ?? ''));
17 +
18 + $heading_tag = sanitize_key($_POST['wpatt_option_heading_tag_n'] ?? 'h3');
19 + update_option('wpatt_option_heading_tag', in_array($heading_tag, array('h1', 'h2', 'h3', 'h4', 'h5', 'h6'), true) ? $heading_tag : 'h3');
17 20
18 21 update_option('wpatt_show_orderby', !empty($_POST['wpatt_show_orderby_n']) ? '1' : '0');
19 22 update_option('wpatt_option_includeimages', !empty($_POST['wpatt_option_includeimages_n']) ? '1' : '0');
20 23 update_option('wpatt_option_targetblank', !empty($_POST['wpatt_option_targetblank_n']) ? '1' : '0');
@@ -21,9 +24,9 @@
21 24 update_option('wpatt_option_restrictload', !empty($_POST['wpatt_option_restrictload_n']) ? '1' : '0');
22 25 update_option('wpatt_counter', !empty($_POST['wpatt_counter_n']) ? '1' : '0');
23 26 update_option('wpatt_excludelogged_counter', !empty($_POST['wpatt_excludelogged_counter_n']) ? '1' : '0');
24 27
25 - // Save per-post-type metabox and default display settings
28 + // Save per-post-type metabox and frontend settings
26 29 $post_types = get_post_types(['public' => true], 'objects');
27 30 foreach ($post_types as $post_type) {
28 31 if ($post_type->name === 'attachment') continue;
29 32
@@ -30,11 +33,14 @@
30 33 // Save metabox enabled/disabled
31 34 $metabox_enabled = !empty($_POST['wpatt_enable_' . $post_type->name]) ? '1' : '0';
32 35 update_option('wpatt_enable_metabox_' . $post_type->name, $metabox_enabled);
33 36
34 - // Save default display enabled/disabled
35 - $display_enabled = !empty($_POST['wpatt_defaulton_' . $post_type->name]) ? '1' : '0';
36 - update_option('wpatt_enable_display_' . $post_type->name, $display_enabled);
37 + // Save frontend list enabled/disabled
38 + $frontend_enabled = !empty($_POST['wpatt_frontend_' . $post_type->name]) ? '1' : '0';
39 + update_option('wpatt_enable_frontend_' . $post_type->name, $frontend_enabled);
40 +
41 + // Replaced by the frontend switch above.
42 + delete_option('wpatt_enable_display_' . $post_type->name);
37 43 }
38 44 $updated = true;
39 45 }
40 46
@@ -41,10 +47,29 @@
41 47 // Handle appearance settings submission securely
42 48 if (isset($_POST['submit-appearance'])) {
43 49 check_admin_referer('wpatt_appearance_settings');
44 50
45 - update_option('wpa_ict', sanitize_text_field($_POST['style'] ?? ''));
46 - update_option('wpa_template', sanitize_text_field($_POST['template'] ?? ''));
51 + $pack = (int) ($_POST['style'] ?? 0);
52 + update_option('wpa_ict', (string) (($pack >= 0 && $pack <= WPATT_PACK_MODERN) ? $pack : 0));
53 + $template = (int) ($_POST['template'] ?? 0);
54 + update_option('wpa_template', (string) (($template >= 0 && $template <= WPATT_TEMPLATE_CARD) ? $template : 0));
55 + $color_mode = sanitize_key($_POST['wpatt_icons_color'] ?? 'type');
56 + update_option('wpatt_icons_color', in_array($color_mode, array('type', 'theme', 'custom'), true) ? $color_mode : 'type');
57 + // Modern Card: unticked checkboxes are not posted, so start from all off;
58 + // wpatt_get_card_options() validates layout and width.
59 + $card_post = isset($_POST['wpatt_card']) && is_array($_POST['wpatt_card']) ? wp_unslash($_POST['wpatt_card']) : array();
60 + $card_save = array();
61 + foreach (array('ext', 'size', 'date', 'downloads', 'caption') as $flag) {
62 + $card_save[$flag] = empty($card_post[$flag]) ? 0 : 1;
63 + }
64 + $card_save['layout'] = sanitize_key($card_post['layout'] ?? 'grid');
65 + $card_save['width'] = sanitize_key($card_post['width'] ?? 'normal');
66 + update_option('wpatt_card', wpatt_get_card_options($card_save));
67 +
68 + $custom_color = sanitize_hex_color(wp_unslash($_POST['wpatt_icons_custom_color'] ?? ''));
69 + if ($custom_color) {
70 + update_option('wpatt_icons_custom_color', $custom_color);
71 + }
47 72 update_option('wpa_template_custom', wp_kses_post($_POST['wpa_template_custom'] ?? ''));
48 73 $updated = true;
49 74 }
50 75
@@ -71,15 +96,46 @@
71 96 .wpatt-settings-wrap .form-table td { padding-top: 12px; }
72 97 .wpatt-settings-wrap input[type="text"] { width: 100%; max-width: 400px; }
73 98 .wpatt-settings-wrap .wpatt-desc { color: #666; font-size: 0.9em; margin-top: 4px; display: block; }
74 99 .wpatt-settings-wrap .wpatt-checkbox-group label { display: block; margin-top: 8px; }
75 - .wpatt-settings-wrap .wpatt-template-radio { margin-bottom: 20px; display: block; padding: 12px; background: #fff; border: 1px solid #ccd0d4; border-radius: 4px; }
76 - .wpatt-settings-wrap .wpatt-template-radio:hover { background: #f6f7f7; }
77 - .wpatt-settings-wrap .wpatt-template-radio input[type="radio"] { margin-right: 10px; }
100 + .wpatt-settings-wrap .wpatt-heading-tag { margin: 10px 0 0; }
101 + .wpatt-settings-wrap .wpatt-heading-tag label { margin-right: 8px; }
78 102 .wpatt-settings-wrap textarea { font-family: monospace; width: 100%; max-width: 600px; }
103 + /* Appearance: one bordered row per option, title and description aligned. */
104 + .wpatt-settings-wrap .wpatt-intro { margin: 0 0 10px; }
105 + .wpatt-settings-wrap .wpatt-options { display: flex; flex-direction: column; gap: 8px; max-width: 760px; }
106 + .wpatt-settings-wrap .wpatt-option { padding: 12px 14px; background: #fff; border: 1px solid #dcdcde; border-radius: 4px; }
107 + .wpatt-settings-wrap .wpatt-option:has(> .wpatt-option-head input:checked) { border-color: #2271b1; box-shadow: 0 0 0 1px #2271b1; }
108 + .wpatt-settings-wrap .wpatt-option-head { display: flex; align-items: center; gap: 10px; cursor: pointer; }
109 + .wpatt-settings-wrap .wpatt-option-head input[type="radio"] { margin: 0; }
110 + .wpatt-settings-wrap .wpatt-option-title { font-weight: 600; }
111 + .wpatt-settings-wrap .wpatt-option-icons { display: inline-flex; gap: 6px; align-items: center; margin-left: auto; }
112 + .wpatt-settings-wrap .wpatt-option-icons img, .wpatt-settings-wrap .wpatt-option-icons .wpa-icon { display: block; width: 16px; height: 16px; margin: 0; }
113 + .wpatt-settings-wrap .wpatt-option-desc { margin: 4px 0 0 26px; color: #646970; font-size: 12px; }
114 + .wpatt-settings-wrap .wpatt-suboptions { margin: 12px 0 0 26px; padding-top: 12px; border-top: 1px solid #f0f0f1; }
115 + .wpatt-settings-wrap .wpatt-suboptions .wpatt-option-desc { margin-left: 0; }
116 + .wpatt-settings-wrap .wpatt-field { display: grid; grid-template-columns: 96px minmax(0, 1fr); align-items: start; gap: 8px; min-height: 30px; }
117 + .wpatt-settings-wrap .wpatt-field-name { line-height: 30px; }
118 + .wpatt-settings-wrap .wpatt-field-controls { min-height: 30px; }
119 + .wpatt-settings-wrap .wpatt-field + .wpatt-field { margin-top: 6px; }
120 + .wpatt-settings-wrap .wpatt-field-name { font-weight: 600; }
121 + .wpatt-settings-wrap .wpatt-field-controls { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 18px; }
122 + .wpatt-settings-wrap .wpatt-field-controls label { display: inline-flex; align-items: center; gap: 6px; margin: 0; }
123 + .wpatt-settings-wrap .wpatt-field-controls input[type="radio"], .wpatt-settings-wrap .wpatt-field-controls input[type="checkbox"] { margin: 0; }
124 + .wpatt-settings-wrap .wpatt-color { width: 40px; height: 28px; padding: 2px; margin-left: -10px; border: 1px solid #8c8f94; border-radius: 4px; background: #fff; cursor: pointer; }
125 + .wpatt-settings-wrap .wpatt-hint { color: #646970; font-size: 12px; }
126 + .wpatt-settings-wrap .wpatt-preview { margin: 12px 0 0 26px; padding: 12px 14px; background: #f6f7f7; border-radius: 4px; font-size: 14px; }
127 + .wpatt-settings-wrap .wpatt-preview .wpa-attachments-block { margin: 0; }
128 + .wpatt-settings-wrap .wpatt-preview ul.wpa-cards li.post-attachment { background: #fff; }
129 + .wpatt-settings-wrap .wpatt-preview li { margin-bottom: 4px; }
130 + .wpatt-settings-wrap .wpatt-code { margin: 10px 0 0 26px; }
131 + .wpatt-settings-wrap .wpatt-code summary { cursor: pointer; color: #2271b1; font-size: 12px; }
132 + .wpatt-settings-wrap .wpatt-code code { display: block; margin: 8px 0; padding: 8px 10px; background: #f6f7f7; font-size: 12px; word-break: break-all; }
133 + .wpatt-settings-wrap .wpatt-suboptions textarea { display: block; max-width: none; }
79 134 .wpatt-cpt-table { border-collapse: collapse; width: 100%; max-width: 600px; margin-top: 10px; background: #fff; border: 1px solid #ccd0d4; }
80 135 .wpatt-cpt-table th, .wpatt-cpt-table td { text-align: left; padding: 10px; border-bottom: 1px solid #ccd0d4; }
81 136 .wpatt-cpt-table th { background: #f6f7f7; font-weight: 600; }
137 + .wpatt-cpt-table th + th { text-align: center; }
82 138 .wpatt-cpt-table tr:last-child td { border-bottom: none; }
83 139 </style>';
84 140
85 141 $current = isset($_GET['tab']) ? sanitize_key($_GET['tab']) : 'general';
@@ -105,9 +161,17 @@
105 161 echo '<tr valign="top">
106 162 <th scope="row">' . esc_html__('List Header', 'wp-attachments') . '</th>
107 163 <td>
108 164 <input type="text" name="wpatt_option_localization_n" value="' . esc_attr(get_option('wpatt_option_localization')) . '" />
109 - <span class="wpatt-desc">' . esc_html__('Text displayed above the attachments list (e.g., "Downloads" or "Attachments").', 'wp-attachments') . '</span>
165 + <span class="wpatt-desc">' . esc_html__('Text displayed above the attachments list (e.g., "Downloads" or "Attachments"). Leave empty to hide the heading.', 'wp-attachments') . '</span>
166 + <p class="wpatt-heading-tag">
167 + <label for="wpatt_heading_tag">' . esc_html__('Heading level', 'wp-attachments') . '</label>
168 + <select id="wpatt_heading_tag" name="wpatt_option_heading_tag_n">';
169 + foreach (array('h1', 'h2', 'h3', 'h4', 'h5', 'h6') as $tag) {
170 + echo '<option value="' . esc_attr($tag) . '" ' . selected(wpatt_heading_tag(), $tag, false) . '>' . esc_html(strtoupper($tag)) . '</option>';
171 + }
172 + echo ' </select>
173 + </p>
110 174 </td>
111 175 </tr>';
112 176
113 177 echo '<tr valign="top">
@@ -138,10 +202,11 @@
138 202 <th scope="row">' . esc_html__('Date Format', 'wp-attachments') . '</th>
139 203 <td>
140 204 <input type="text" name="wpatt_option_date_localization_n" value="' . esc_attr(get_option('wpatt_option_date_localization')) . '" />
141 205 <span class="wpatt-desc">' . sprintf(
142 - esc_html__('Format for the %%DATE%% tag, following PHP date standards. Leave empty to use the WordPress setting. Default: %s', 'wp-attachments'),
143 - '<code>d.m.Y</code>'
206 + /* translators: %s: the WordPress date format, e.g. F j, Y */
207 + esc_html__('Format for the %%DATE%% tag, following PHP date standards (e.g. d.m.Y). Leave empty to use the WordPress date format: %s', 'wp-attachments'),
208 + '<code>' . esc_html(get_option('date_format')) . '</code>'
144 209 ) . '</span>
145 210 </td>
146 211 </tr>';
147 212
@@ -163,15 +228,15 @@
163 228
164 229 echo '<tr valign="top">
165 230 <th scope="row">' . esc_html__('Post Type Permissions', 'wp-attachments') . '</th>
166 231 <td>
167 - <p class="description">' . esc_html__('Configure where WP Attachments should be available and if they should show by default.', 'wp-attachments') . '</p>
232 + <p class="description">' . esc_html__('Configure where WP Attachments should be available.', 'wp-attachments') . '<br>' . esc_html__('"Enable Frontend" shows the list after the content. Each post can still hide it from the Media Attachments box of the editor.', 'wp-attachments') . '</p>
168 233 <table class="wpatt-cpt-table">
169 234 <thead>
170 235 <tr>
171 236 <th>' . esc_html__('Post Type', 'wp-attachments') . '</th>
172 237 <th>' . esc_html__('Enable Metabox', 'wp-attachments') . '</th>
173 - <th>' . esc_html__('Display Default', 'wp-attachments') . '</th>
238 + <th>' . esc_html__('Enable Frontend', 'wp-attachments') . '</th>
174 239 </tr>
175 240 </thead>
176 241 <tbody>';
177 242 $post_types = get_post_types(['public' => true], 'objects');
@@ -177,9 +242,9 @@
177 242 $post_types = get_post_types(['public' => true], 'objects');
178 243 foreach ($post_types as $post_type) {
179 244 if ($post_type->name === 'attachment') continue;
180 245 $mb_enabled = get_option('wpatt_enable_metabox_' . $post_type->name, '1');
181 - $disp_enabled = get_option('wpatt_enable_display_' . $post_type->name, '1');
246 + $fe_enabled = wpatt_is_frontend_enabled($post_type->name) ? '1' : '0';
182 247 echo '<tr>
183 248 <td><strong>' . esc_html($post_type->labels->singular_name) . '</strong></td>
184 249 <td style="text-align:center;">
185 250 <input type="checkbox" name="wpatt_enable_' . esc_attr($post_type->name) . '" value="1" ' . checked($mb_enabled, '1', false) . ' />
@@ -184,9 +249,9 @@
184 249 <td style="text-align:center;">
185 250 <input type="checkbox" name="wpatt_enable_' . esc_attr($post_type->name) . '" value="1" ' . checked($mb_enabled, '1', false) . ' />
186 251 </td>
187 252 <td style="text-align:center;">
188 - <input type="checkbox" name="wpatt_defaulton_' . esc_attr($post_type->name) . '" value="1" ' . checked($disp_enabled, '1', false) . ' />
253 + <input type="checkbox" name="wpatt_frontend_' . esc_attr($post_type->name) . '" value="1" ' . checked($fe_enabled, '1', false) . ' />
189 254 </td>
190 255 </tr>';
191 256 }
192 257 echo '</tbody></table>
@@ -197,66 +262,187 @@
197 262 break;
198 263
199 264 case 'appearance':
200 265 wp_nonce_field('wpatt_appearance_settings');
201 - echo '<table class="form-table">';
202 - echo '<tr valign="top">
203 - <th scope="row">' . esc_html__('Icon Pack', 'wp-attachments') . '</th>
266 + echo '<table class="form-table" role="presentation">';
267 +
268 + /* ---------- Icon pack ---------- */
269 + echo '<tr>
270 + <th scope="row" id="wpatt-pack-heading">' . esc_html__('Icon Pack', 'wp-attachments') . '</th>
204 271 <td>
205 - <fieldset>';
272 + <div class="wpatt-options" role="radiogroup" aria-labelledby="wpatt-pack-heading">';
273 +
206 274 $icon_packs = [
275 + WPATT_PACK_MODERN => ['label' => 'Modern SVG', 'desc' => __('Sharp vector icons for every file type. Used by the Modern Card template too.', 'wp-attachments')],
207 276 0 => ['label' => 'Fugue Icons', 'author' => 'Yusuke Kamiyamane'],
208 277 1 => ['label' => 'Crystal Clear', 'author' => 'Everaldo Coelho', 'url' => 'https://www.everaldo.com/'],
209 278 2 => ['label' => 'Diagona Icons', 'author' => 'Asher Abbasi'],
210 279 3 => ['label' => 'Page Icons', 'author' => 'Matthew Skiles', 'url' => 'https://iconblock.com/'],
280 + // Dropped from this list in 5.0.12 by mistake: sites that had
281 + // picked it kept using it but saw no option selected here.
282 + 4 => ['label' => 'Matrilineare'],
211 283 ];
212 284 foreach ($icon_packs as $val => $pack) {
213 - $checked = (intval(get_option('wpa_ict')) === $val) ? 'checked' : '';
214 - echo '<label class="wpatt-template-radio">
215 - <input type="radio" value="' . esc_attr($val) . '" name="style" ' . $checked . '>
216 - <strong>' . esc_html($pack['label']) . '</strong>
217 - <span style="float:right;">
218 - <img src="' . esc_url(plugins_url('wp-attachments/styles/' . $val . '/document.png')) . '" style="vertical-align:middle;"/>
219 - <img src="' . esc_url(plugins_url('wp-attachments/styles/' . $val . '/document-word.png')) . '" style="vertical-align:middle;"/>
220 - <img src="' . esc_url(plugins_url('wp-attachments/styles/' . $val . '/document-pdf.png')) . '" style="vertical-align:middle;"/>
221 - </span>
222 - <br><small class="wpatt-desc">' . esc_html__('Author', 'wp-attachments') . ': ' . (isset($pack['url']) ? '<a href="' . esc_url($pack['url']) . '" target="_blank">' . esc_html($pack['author']) . '</a>' : esc_html($pack['author'])) . '</small>
223 - </label>';
285 + if (WPATT_PACK_MODERN === $val) {
286 + // Same markup as the site, so the colour option shows here too.
287 + $colors = wpatt_icons_color_attrs();
288 + $icons = '<span class="wpatt-option-icons' . $colors['class'] . '"'
289 + . ($colors['style'] ? ' style="' . esc_attr($colors['style']) . '"' : '') . '>';
290 + foreach (array('pdf', 'doc', 'sheet', 'archive') as $type) {
291 + $icons .= '<span class="wpa-type-' . $type . '">' . wpatt_get_file_icon_svg($type, 'wpa-icon') . '</span>';
292 + }
293 + $icons .= '</span>';
294 + } else {
295 + $icons = '<span class="wpatt-option-icons">';
296 + foreach (array('document', 'document-word', 'document-pdf') as $png) {
297 + $icons .= '<img src="' . esc_url(plugins_url('styles/' . $val . '/' . $png . '.png', dirname(__FILE__))) . '" alt="" width="16" height="16" />';
298 + }
299 + $icons .= '</span>';
300 + }
301 +
302 + if (isset($pack['desc'])) {
303 + $meta = esc_html($pack['desc']);
304 + } elseif (isset($pack['author'])) {
305 + $meta = esc_html__('Author', 'wp-attachments') . ': ' . (isset($pack['url']) ? '<a href="' . esc_url($pack['url']) . '" target="_blank" rel="noopener noreferrer">' . esc_html($pack['author']) . '</a>' : esc_html($pack['author']));
306 + } else {
307 + $meta = '';
308 + }
309 +
310 + echo '<div class="wpatt-option">
311 + <label class="wpatt-option-head">
312 + <input type="radio" value="' . esc_attr($val) . '" name="style" ' . checked(wpatt_icon_pack(), $val, false) . ' />
313 + <span class="wpatt-option-title">' . esc_html($pack['label']) . '</span>' . $icons . '
314 + </label>'
315 + . ($meta ? '<p class="wpatt-option-desc">' . $meta . '</p>' : '');
316 +
317 + if (WPATT_PACK_MODERN === $val) {
318 + // Outside the <label>: a label holding other controls would
319 + // also tick the pack radio on every click.
320 + $color_mode = wpatt_icons_color_mode();
321 + echo '<div class="wpatt-suboptions">
322 + <div class="wpatt-field" role="radiogroup" aria-labelledby="wpatt-color-heading">
323 + <span class="wpatt-field-name" id="wpatt-color-heading">' . esc_html__('Icon colour', 'wp-attachments') . '</span>
324 + <span class="wpatt-field-controls">
325 + <label><input type="radio" name="wpatt_icons_color" value="type" ' . checked($color_mode, 'type', false) . ' /> ' . esc_html__('By file type', 'wp-attachments') . '</label>
326 + <label><input type="radio" name="wpatt_icons_color" value="theme" ' . checked($color_mode, 'theme', false) . ' /> ' . esc_html__('Theme text colour', 'wp-attachments') . '</label>
327 + <label><input type="radio" name="wpatt_icons_color" value="custom" ' . checked($color_mode, 'custom', false) . ' /> ' . esc_html__('Custom', 'wp-attachments') . '</label>
328 + <input type="color" class="wpatt-color" name="wpatt_icons_custom_color" value="' . esc_attr(wpatt_icons_custom_color()) . '" aria-label="' . esc_attr__('Custom colour', 'wp-attachments') . '" />
329 + </span>
330 + </div>
331 + <p class="wpatt-option-desc">' . esc_html__('Also applies to the Modern Card template, whatever the icon pack. Choose a custom colour dark enough to stand out against the page.', 'wp-attachments') . '</p>
332 + </div>';
333 + }
334 +
335 + echo '</div>';
224 336 }
225 - echo '</fieldset></td></tr>';
337 + echo '</div></td></tr>';
226 338
227 - echo '<tr valign="top">
228 - <th scope="row">' . esc_html__('Display Template', 'wp-attachments') . '</th>
339 + /* ---------- Display template ---------- */
340 + echo '<tr>
341 + <th scope="row" id="wpatt-template-heading">' . esc_html__('Display Template', 'wp-attachments') . '</th>
229 342 <td>
230 - <fieldset>';
343 + <p class="description wpatt-intro">' . esc_html__('Previews use sample files and the saved settings.', 'wp-attachments') . '</p>
344 + <div class="wpatt-options" role="radiogroup" aria-labelledby="wpatt-template-heading">';
345 +
346 + $card = wpatt_get_card_options();
231 347 $templates = [
232 - 0 => [
233 - 'label' => 'Simple List',
234 - 'code' => '<a href="%URL%">%TITLE%</a> <small>(%SIZE%)</small>',
235 - ],
236 - 1 => [
237 - 'label' => 'List with date',
238 - 'code' => '<a href="%URL%">%TITLE%</a> <small>(%SIZE%)</small> <span class="wpa-attachment-date">%DATE%</span>',
239 - ],
240 - 2 => [
241 - 'label' => 'Detailed List',
242 - 'code' => '<a href="%URL%">%TITLE%</a> <small>&bull; %SIZE% &bull; %DOWNLOADS% clicks</small> <span class="wpa-attachment-date">%DATE%</span><br><small>%CAPTION%</small>',
243 - ],
348 + WPATT_TEMPLATE_CARD => [__('Modern Card', 'wp-attachments'), __('Always uses the Modern SVG icons.', 'wp-attachments')],
349 + 0 => [__('Simple List', 'wp-attachments'), ''],
350 + 1 => [__('List with date', 'wp-attachments'), ''],
351 + 2 => [__('Detailed List', 'wp-attachments'), ''],
244 352 ];
245 353 foreach ($templates as $val => $tpl) {
246 - $checked = (intval(get_option('wpa_template')) === $val) ? 'checked' : '';
247 - echo '<label class="wpatt-template-radio">
248 - <input type="radio" value="' . esc_attr($val) . '" name="template" ' . $checked . '> <strong>' . esc_html($tpl['label']) . '</strong>
249 - <br><code style="background:transparent; padding:0;">' . esc_html($tpl['code']) . '</code>
250 - </label>';
354 + $code = wpatt_get_template_string($val, $card);
355 +
356 + echo '<div class="wpatt-option">
357 + <label class="wpatt-option-head">
358 + <input type="radio" value="' . esc_attr($val) . '" name="template" ' . checked(wpatt_template_id(), $val, false) . ' />
359 + <span class="wpatt-option-title">' . esc_html($tpl[0]) . '</span>
360 + </label>'
361 + . ($tpl[1] ? '<p class="wpatt-option-desc">' . esc_html($tpl[1]) . '</p>' : '');
362 +
363 + if (WPATT_TEMPLATE_CARD === $val) {
364 + $flags = array(
365 + 'ext' => __('Extension', 'wp-attachments'),
366 + 'size' => __('Size', 'wp-attachments'),
367 + 'date' => __('Date', 'wp-attachments'),
368 + 'downloads' => __('Downloads', 'wp-attachments'),
369 + 'caption' => __('Caption', 'wp-attachments'),
370 + );
371 + echo '<div class="wpatt-suboptions">
372 + <div class="wpatt-field" role="group" aria-labelledby="wpatt-card-show">
373 + <span class="wpatt-field-name" id="wpatt-card-show">' . esc_html__('Show', 'wp-attachments') . '</span>
374 + <span class="wpatt-field-controls">';
375 + foreach ($flags as $key => $flag_label) {
376 + echo '<label><input type="checkbox" name="wpatt_card[' . esc_attr($key) . ']" value="1" ' . checked($card[$key], 1, false) . ' /> ' . esc_html($flag_label) . '</label>';
377 + }
378 + echo '</span>
379 + </div>
380 + <div class="wpatt-field" role="radiogroup" aria-labelledby="wpatt-card-layout">
381 + <span class="wpatt-field-name" id="wpatt-card-layout">' . esc_html__('Layout', 'wp-attachments') . '</span>
382 + <span class="wpatt-field-controls">
383 + <label><input type="radio" name="wpatt_card[layout]" value="grid" ' . checked($card['layout'], 'grid', false) . ' /> ' . esc_html__('Grid', 'wp-attachments') . '</label>
384 + <label><input type="radio" name="wpatt_card[layout]" value="rows" ' . checked($card['layout'], 'rows', false) . ' /> ' . esc_html__('One per row', 'wp-attachments') . '</label>
385 + </span>
386 + </div>
387 + <div class="wpatt-field">
388 + <label class="wpatt-field-name" for="wpatt-card-width">' . esc_html__('Card width', 'wp-attachments') . '</label>
389 + <span class="wpatt-field-controls">
390 + <select id="wpatt-card-width" name="wpatt_card[width]">
391 + <option value="compact" ' . selected($card['width'], 'compact', false) . '>' . esc_html__('Compact', 'wp-attachments') . '</option>
392 + <option value="normal" ' . selected($card['width'], 'normal', false) . '>' . esc_html__('Normal', 'wp-attachments') . '</option>
393 + <option value="wide" ' . selected($card['width'], 'wide', false) . '>' . esc_html__('Wide', 'wp-attachments') . '</option>
394 + </select>
395 + <span class="wpatt-hint">' . esc_html__('Grid only. Downloads appear when the download counter is on.', 'wp-attachments') . '</span>
396 + </span>
397 + </div>
398 + </div>';
399 + }
400 +
401 + // inert: the sample links must not be focusable or clickable.
402 + echo '<div class="wpatt-preview" inert aria-hidden="true">' . wpatt_render_template_preview($val) . '</div>
403 + <details class="wpatt-code">
404 + <summary>' . esc_html__('Template code', 'wp-attachments') . '</summary>
405 + <code>' . esc_html($code) . '</code>
406 + <button type="button" class="button button-small wpatt-use-template hide-if-no-js" data-code="' . esc_attr($code) . '">' . esc_html__('Use as custom template', 'wp-attachments') . '</button>
407 + </details>
408 + </div>';
251 409 }
252 - echo '<label class="wpatt-template-radio">
253 - <input type="radio" value="3" name="template" ' . (intval(get_option('wpa_template')) === 3 ? 'checked' : '') . '> <strong>' . esc_html__('Custom Template', 'wp-attachments') . '</strong>
254 - <textarea name="wpa_template_custom" rows="4">' . esc_textarea(get_option('wpa_template_custom')) . '</textarea>
255 - <br><span class="wpatt-desc">' . esc_html__('Tags:', 'wp-attachments') . ' <code>%URL%</code>, <code>%TITLE%</code>, <code>%SIZE%</code>, <code>%DATE%</code>, <code>%DOWNLOADS%</code>, <code>%CAPTION%</code></span>
256 - </label>';
257 - echo '</fieldset></td></tr>';
410 +
411 + $custom = (string) get_option('wpa_template_custom');
412 + echo '<div class="wpatt-option">
413 + <label class="wpatt-option-head">
414 + <input type="radio" value="3" name="template" ' . checked(wpatt_template_id(), 3, false) . ' />
415 + <span class="wpatt-option-title">' . esc_html__('Custom Template', 'wp-attachments') . '</span>
416 + </label>
417 + <div class="wpatt-suboptions">
418 + <textarea id="wpa_template_custom" name="wpa_template_custom" rows="4" aria-label="' . esc_attr__('Custom Template', 'wp-attachments') . '">' . esc_textarea($custom) . '</textarea>
419 + <p class="wpatt-option-desc">' . esc_html__('Tags:', 'wp-attachments') . ' <code>%URL%</code> <code>%TITLE%</code> <code>%SIZE%</code> <code>%DATE%</code> <code>%DOWNLOADS%</code> <code>%CAPTION%</code> <code>%DESCRIPTION%</code> <code>%AUTHOR%</code> <code>%EXT%</code> <code>%MIME%</code> <code>%ICON%</code></p>
420 + </div>'
421 + . ('' !== trim($custom) ? '<div class="wpatt-preview" inert aria-hidden="true">' . wpatt_render_template_preview(3) . '</div>' : '') . '
422 + </div>';
423 +
424 + echo '</div></td></tr>';
258 425 echo '</table>';
426 +
427 + // Admin only: copy a template into the custom one; picking a colour
428 + // selects the Custom colour option.
429 + echo '<script>
430 +document.addEventListener("click", function (e) {
431 + var button = e.target.closest(".wpatt-use-template");
432 + if (!button) { return; }
433 + var field = document.getElementById("wpa_template_custom");
434 + if (field.value.trim() !== "" && !window.confirm(' . wp_json_encode(__('Replace the current custom template?', 'wp-attachments')) . ')) { return; }
435 + field.value = button.getAttribute("data-code");
436 + document.querySelector("input[name=template][value=\'3\']").checked = true;
437 + field.focus();
438 +});
439 +document.addEventListener("input", function (e) {
440 + if (e.target.classList && e.target.classList.contains("wpatt-color")) {
441 + document.querySelector("input[name=wpatt_icons_color][value=custom]").checked = true;
442 + }
443 +});
444 +</script>';
259 445 submit_button(__('Save Appearance Settings', 'wp-attachments'), 'primary', 'submit-appearance');
260 446 break;
261 447 }
262 448