Plugin Directory

Changeset 3437920


Ignore:
Timestamp:
01/12/2026 04:05:21 PM (6 weeks ago)
Author:
spelhubben
Message:

Update to version 1.9.3 from GitHub

Location:
spelhubben-weather
Files:
4 added
24 edited
1 copied

Legend:

Unmodified
Added
Removed
  • spelhubben-weather/tags/1.9.3/admin/admin.js

    r3435748 r3437920  
    313313      var layout = document.querySelector('.svv-b-layout').value;
    314314      var theme = (document.querySelector('.svv-b-theme') && document.querySelector('.svv-b-theme').value) || 'auto';
     315      var windunit = (document.querySelector('.svv-b-windunit') && document.querySelector('.svv-b-windunit').value) || '';
    315316      var map = document.querySelector('.svv-b-map').checked ? '1' : '0';
    316317      var animate = document.querySelector('.svv-b-animate').checked ? '1' : '0';
     
    324325      if (animate === '0') sc += ' animate="0"';
    325326      if (provs && provs !== 'openmeteo,smhi,yr') sc += ' providers="' + provs + '"';
     327      if (windunit) sc += ' wind_unit="' + windunit + '"';
    326328      sc += ']';
    327329
  • spelhubben-weather/tags/1.9.3/admin/admin.php

    r3435228 r3437920  
    525525        'metric'     => __( 'Metric (°C, m/s, mm)', 'spelhubben-weather' ),
    526526        'metric_kmh' => __( 'Metric (°C, km/h, mm)', 'spelhubben-weather' ),
     527        'metric_knt' => __( 'Metric (°C, knt, mm)', 'spelhubben-weather' ),
    527528        'imperial'   => __( 'Imperial (°F, mph, in)', 'spelhubben-weather' ),
    528529    );
     
    547548    );
    548549    printf(
    549         '<label>%s <input type="text" name="sv_vader_options[wind_unit]" value="%s" class="small-text" placeholder="ms|kmh|mph" /></label> ',
     550        '<label>%s <input type="text" name="sv_vader_options[wind_unit]" value="%s" class="small-text" placeholder="ms|kmh|mph|knt" /></label> ',
    550551        esc_html__( 'Wind unit', 'spelhubben-weather' ),
    551552        esc_attr( $o['wind_unit'] ?? '' )
  • spelhubben-weather/tags/1.9.3/admin/page-shortcodes.php

    r3435748 r3437920  
    99    function sv_vader_render_shortcodes_page() {
    1010        if ( ! current_user_can( 'manage_options' ) ) return;
     11
     12            // Load current options so Quick Builder can default to site settings
     13            $opts = sv_vader_get_options();
    1114
    1215        // Examples (new aliases)
     
    8689                                </div>
    8790                            <?php endforeach; ?>
     91
     92                                <!-- Wind unit examples (compact, translatable) -->
     93                                <div class="svv-codeblock svv-codeblock--light" data-svv-visible="1" data-label="<?php echo esc_attr__( 'Wind unit examples', 'spelhubben-weather' ); ?>">
     94                                    <div class="svv-codeblock-head">
     95                                        <span><?php echo esc_html__( 'Wind unit examples', 'spelhubben-weather' ); ?></span>
     96                                        <button type="button" class="button button-secondary svv-copy-btn" data-copy="[spelhubben_weather layout=\"compact\" map=\"0\" theme=\"light\" show=\"temp,wind,wind_dir,icon\" wind_unit=\"knt\"]">
     97                                            <?php esc_html_e( 'Copy', 'spelhubben-weather' ); ?>
     98                                        </button>
     99                                    </div>
     100                                    <pre class="svv-pre"><code tabindex="0"><?php echo esc_html( '[spelhubben_weather layout="compact" map="0" theme="light" show="temp,wind,wind_dir,icon" wind_unit="kmh"]' ); ?>
     101
     102        <?php echo esc_html( '[spelhubben_weather layout="compact" map="0" theme="light" show="temp,wind,wind_dir,icon" wind_unit="knt"]' ); ?></code></pre>
     103                                </div>
    88104                        </div>
    89105
    90106                    </div>
    91107                </div>
     108
     109
    92110
    93111                <!-- RIGHT: Preview + Attributes -->
     
    158176                                    <label><input type="checkbox" class="svv-b-prov" value="openweathermap"> OpenWeather</label>
    159177                                    <label><input type="checkbox" class="svv-b-prov" value="weatherapi"> WeatherAPI</label>
     178                                </div>
     179                                <div>
     180                                    <strong><?php esc_html_e( 'Wind unit (override):', 'spelhubben-weather' ); ?></strong><br>
     181                                    <select class="svv-b-windunit">
     182                                        <option value=""<?php echo selected( $opts['wind_unit'] ?? '', '', false ); ?>><?php esc_html_e('(use site default)', 'spelhubben-weather'); ?></option>
     183                                        <option value="ms"<?php echo selected( $opts['wind_unit'] ?? '', 'ms', false ); ?>>m/s</option>
     184                                        <option value="kmh"<?php echo selected( $opts['wind_unit'] ?? '', 'kmh', false ); ?>>km/h</option>
     185                                        <option value="mph"<?php echo selected( $opts['wind_unit'] ?? '', 'mph', false ); ?>>mph</option>
     186                                        <option value="knt"<?php echo selected( $opts['wind_unit'] ?? '', 'knt', false ); ?>>knt (knots)</option>
     187                                    </select>
    160188                                </div>
    161189                            </div>
     
    212240                                    <tr data-group="uf"><td><code>units</code></td><td><?php esc_html_e( 'Preset: metric | metric_kmh | imperial', 'spelhubben-weather' ); ?></td><td><code>units="metric_kmh"</code></td></tr>
    213241                                    <tr data-group="uf"><td><code>temp_unit</code></td><td><?php esc_html_e( 'Override temperature unit', 'spelhubben-weather' ); ?></td><td><code>temp_unit="F"</code></td></tr>
    214                                     <tr data-group="uf"><td><code>wind_unit</code></td><td><?php esc_html_e( 'Override wind unit', 'spelhubben-weather' ); ?></td><td><code>wind_unit="kmh"</code></td></tr>
     242                                    <tr data-group="uf"><td><code>wind_unit</code></td><td><?php esc_html_e( 'Override wind unit', 'spelhubben-weather' ); ?></td><td><code>wind_unit="kmh"</code> (or <code>wind_unit="knt"</code> for knots)</td></tr>
    215243                                    <tr data-group="uf"><td><code>precip_unit</code></td><td><?php esc_html_e( 'Override precipitation unit', 'spelhubben-weather' ); ?></td><td><code>precip_unit="in"</code></td></tr>
    216244                                    <tr data-group="uf"><td><code>date_format</code></td><td><?php esc_html_e( 'Forecast date label (PHP date)', 'spelhubben-weather' ); ?></td><td><code>date_format="D j/n"</code></td></tr>
     
    233261    }
    234262}
     263
  • spelhubben-weather/tags/1.9.3/assets/style.css

    r3435748 r3437920  
    3333/* Dark Mode Support */
    3434@media (prefers-color-scheme: dark) {
    35   .sv-vader:not(.svv-force-light) {
     35  /* Do not apply automatic dark-vars when user/site explicitly forces light or dark */
     36  .sv-vader:not(.svv-force-light):not(.svv-force-dark) {
    3637    --svv-bg: #1e1e1e;
    3738    --svv-text: #f0f0f0;
     
    4142    --svv-muted: #aaaaaa;
    4243  }
    43   .sv-vader:not(.svv-force-light) .svv-map {
     44  .sv-vader:not(.svv-force-light):not(.svv-force-dark) .svv-map {
    4445    filter: brightness(0.8) contrast(1.2) invert(100%) hue-rotate(180deg);
    4546  }
  • spelhubben-weather/tags/1.9.3/blocks/spelhubben-weather/block.json

    r3435228 r3437920  
    2323    "showAlerts": { "type": "boolean", "default": true },
    2424    "units":      { "type": "string",  "default": "metric" },
    25     "date_format":{ "type": "string",  "default": "D j/n" }
     25    "date_format":{ "type": "string",  "default": "D j/n" },
     26    "wind_unit":  { "type": "string",  "default": "" }
    2627  },
    2728  "editorScript": "file:./index.js",
  • spelhubben-weather/tags/1.9.3/blocks/spelhubben-weather/index.js

    r3435228 r3437920  
    1717    { label: __( 'Metric (°C, m/s, mm)', 'spelhubben-weather' ), value: 'metric' },
    1818    { label: __( 'Metric (°C, km/h, mm)', 'spelhubben-weather' ), value: 'metric_kmh' },
     19    { label: __( 'Metric (°C, knt, mm)', 'spelhubben-weather' ), value: 'metric_knt' },
    1920    { label: __( 'Imperial (°F, mph, in)', 'spelhubben-weather' ), value: 'imperial' },
     21  ];
     22
     23  const WIND_UNITS = [
     24    { label: __( 'm/s', 'spelhubben-weather' ), value: 'ms' },
     25    { label: __( 'km/h', 'spelhubben-weather' ), value: 'kmh' },
     26    { label: __( 'mph', 'spelhubben-weather' ), value: 'mph' },
     27    { label: __( 'knt (knots)', 'spelhubben-weather' ), value: 'knt' },
    2028  ];
    2129
     
    121129              onChange: ( v ) => setAttributes( { units: v } ),
    122130            } ),
     131            el( SelectControl, {
     132              label: __( 'Wind unit override', 'spelhubben-weather' ),
     133              value: attributes.wind_unit || '',
     134              options: [
     135                { label: __( '(use preset)', 'spelhubben-weather' ), value: '' },
     136                ...WIND_UNITS
     137              ],
     138              onChange: ( v ) => setAttributes( { wind_unit: v } ),
     139            } ),
    123140            el( TextControl, {
    124141              label: __( 'Date format (PHP date)', 'spelhubben-weather' ),
     
    154171          bp,
    155172          ServerSideRender
    156             ? el( ServerSideRender, { block: 'spelhubben/weather', attributes } )
     173            ? el( ServerSideRender, { block: 'spelhubben-weather/spelhubben-weather', attributes } )
    157174            : el( 'p', null, __( 'Spelhubben Weather preview (ServerSideRender unavailable). Save/update to view.', 'spelhubben-weather' ) )
    158175        )
  • spelhubben-weather/tags/1.9.3/includes/Widget/class-widget.php

    r3435748 r3437920  
    3838            'theme'     => 'auto',
    3939            'class'     => 'is-widget',
     40            'wind_unit' => '',
    4041        ];
    4142        $instance = wp_parse_args((array) $instance, $defaults);
     
    9192                'show_alerts' => $show_alerts ? '1' : '0',
    9293                    'theme'       => $theme,
     94                    'wind_unit'   => $instance['wind_unit'] ?? $opts['wind_unit'],
    9395            ]);
    9496
     
    118120            'theme'     => 'auto',
    119121            'class'     => '',
     122            'wind_unit' => '',
    120123        ];
    121124        $instance   = wp_parse_args((array) $instance, $defaults);
     
    259262        </p>
    260263        <p>
     264            <label for="<?php echo esc_attr($this->get_field_id('wind_unit')); ?>"><?php esc_html_e('Wind unit:', 'spelhubben-weather'); ?></label>
     265            <select id="<?php echo esc_attr($this->get_field_id('wind_unit')); ?>"
     266                    name="<?php echo esc_attr($this->get_field_name('wind_unit')); ?>"
     267                    class="widefat">
     268                <option value="" <?php selected($instance['wind_unit'] ?? '', ''); ?>><?php esc_html_e('(use site default)', 'spelhubben-weather'); ?></option>
     269                <option value="ms" <?php selected($instance['wind_unit'] ?? '', 'ms'); ?>>m/s</option>
     270                <option value="kmh" <?php selected($instance['wind_unit'] ?? '', 'kmh'); ?>>km/h</option>
     271                <option value="mph" <?php selected($instance['wind_unit'] ?? '', 'mph'); ?>>mph</option>
     272                <option value="knt" <?php selected($instance['wind_unit'] ?? '', 'knt'); ?>>knt (knots)</option>
     273            </select>
     274        </p>
     275        <p>
    261276            <label for="<?php echo esc_attr($this->get_field_id('class')); ?>"><?php esc_html_e('Extra CSS class:', 'spelhubben-weather'); ?></label>
    262277            <input class="widefat"
     
    294309        $instance['theme']       = in_array(strtolower($new_instance['theme'] ?? 'auto'), ['auto','light','dark'], true) ? sanitize_text_field(strtolower($new_instance['theme'])) : 'auto';
    295310        $instance['class']       = sanitize_html_class($new_instance['class'] ?? '', '');
     311        $wu = strtolower(trim((string)($new_instance['wind_unit'] ?? '')));
     312        $instance['wind_unit'] = in_array($wu, ['ms','kmh','mph','knt','kn'], true) ? $wu : '';
    296313
    297314        return $instance;
  • spelhubben-weather/tags/1.9.3/includes/class-renderer.php

    r3435748 r3437920  
    6363        ]);
    6464
     65        // Safety: if shortcode explicitly sets wind_unit, ensure it is applied.
     66        // Accept both 'knt' and 'kn' and canonicalize to 'knt'.
     67        $allowed_winds = ['ms','kmh','mph','knt','kn'];
     68        $wu_attr = strtolower(trim((string)($a['wind_unit'] ?? '')));
     69        if ($wu_attr !== '' && in_array($wu_attr, $allowed_winds, true)) {
     70            if ($wu_attr === 'kn') $wu_attr = 'knt';
     71            $units['wind'] = $wu_attr;
     72        }
     73
    6574        $api = new SV_Vader_API(intval($opts['cache_minutes']));
    6675       
     
    105114
    106115        if ($theme !== 'auto') {
    107             $classes .= ' svv-theme-' . $theme;
     116            // Add both theme class and a force-class to override OS/browser prefers-color-scheme
     117            $classes .= ' svv-theme-' . $theme . ' svv-force-' . $theme;
    108118        }
    109119
    110120        ob_start(); ?>
    111         <div class="<?php echo esc_attr($classes); ?>" data-svv-ro="1" data-svv-theme="<?php echo esc_attr($theme); ?>">
     121        <div class="<?php echo esc_attr($classes); ?>" data-svv-ro="1" data-svv-theme="<?php echo esc_attr($theme); ?>" data-svv-wind-unit="<?php echo esc_attr($units['wind']); ?>">
    112122            <?php if (!empty($name) && $layout !== 'inline'): ?>
    113123                <div class="svv-ort"><?php echo esc_html($name); ?></div>
     
    151161                            <span class="svv-wind svv-badge">
    152162                                <?php echo esc_html( $wind_compact ); ?>
    153                                 <?php if (in_array('wind_dir', $show, true)) echo wp_kses_post( sv_vader_wind_dir_icon($w_dir) ); ?>
     163                            <?php if (in_array('wind_dir', $show, true) && $w_dir !== null) echo wp_kses_post( sv_vader_wind_dir_icon($w_dir) ); ?>
     164                            </span>
     165                        <?php elseif (in_array('wind_dir', $show, true) && $w_dir !== null): ?>
     166                            <span class="svv-wind svv-badge">
     167                                <?php echo wp_kses_post( sv_vader_wind_dir_icon($w_dir) ); ?>
    154168                            </span>
    155169                        <?php endif; ?>
     
    177191                                    <span class="svv-wind">
    178192                                        <?php echo esc_html( $wind_detailed ); ?>
    179                                         <?php if (in_array('wind_dir', $show, true)) echo wp_kses_post( sv_vader_wind_dir_icon($w_dir) ); ?>
     193                                    <?php if (in_array('wind_dir', $show, true) && $w_dir !== null) echo wp_kses_post( sv_vader_wind_dir_icon($w_dir) ); ?>
     194                                    </span>
     195                                <?php endif; ?>
     196                                <?php if (!(in_array('wind', $show, true) && $w_val !== null) && in_array('wind_dir', $show, true) && $w_dir !== null): ?>
     197                                    <span class="svv-wind">
     198                                        <?php echo wp_kses_post( sv_vader_wind_dir_icon($w_dir) ); ?>
    180199                                    </span>
    181200                                <?php endif; ?>
     
    223242                            <span class="svv-wind">
    224243                                <?php echo esc_html( $wind_card ); ?>
    225                                 <?php if (in_array('wind_dir', $show, true)) echo wp_kses_post( sv_vader_wind_dir_icon($w_dir) ); ?>
     244                            <?php if (in_array('wind_dir', $show, true) && $w_dir !== null) echo wp_kses_post( sv_vader_wind_dir_icon($w_dir) ); ?>
     245                            </span>
     246                        <?php endif; ?>
     247                        <?php if (!(in_array('wind', $show, true) && $w_val !== null) && in_array('wind_dir', $show, true) && $w_dir !== null): ?>
     248                            <span class="svv-wind">
     249                                <?php echo wp_kses_post( sv_vader_wind_dir_icon($w_dir) ); ?>
    226250                            </span>
    227251                        <?php endif; ?>
  • spelhubben-weather/tags/1.9.3/includes/format.php

    r3435228 r3437920  
    1515        $map = [
    1616            'metric'     => ['temp'=>'C',  'wind'=>'ms',  'precip'=>'mm'],
     17            'metric_knt' => ['temp'=>'C',  'wind'=>'knt', 'precip'=>'mm'],
    1718            'metric_kmh' => ['temp'=>'C',  'wind'=>'kmh', 'precip'=>'mm'],
    1819            'imperial'   => ['temp'=>'F',  'wind'=>'mph', 'precip'=>'in'],
     
    2627
    2728        if (in_array($tu, ['C','F'], true))     $u['temp']   = $tu;
    28         if (in_array($wu, ['ms','kmh','mph'], true)) $u['wind']   = $wu;
     29        // Accept both 'knt' and 'kn' as aliases for knots.
     30        if (in_array($wu, ['ms','kmh','mph','knt','kn'], true)) $u['wind']   = $wu;
    2931        if (in_array($pu, ['mm','in'], true))   $u['precip'] = $pu;
    3032
     
    5052        switch ($unit) {
    5153            case 'kmh': $val = $ms * 3.6; break;
     54            case 'knt':
     55            case 'kn': $val = $ms * 1.94384449; $unit = 'kn'; break;
    5256            case 'mph': $val = $ms * 2.23693629; break;
    5357            default:    $val = $ms; $unit = 'm/s';
     
    7983        if ($deg === null) return '';
    8084        return sprintf(
    81             '<span class="svv-wind-dir" style="display:inline-block;transform:rotate(%ddeg);line-height:1;font-style:normal;vertical-align:middle;" title="%s">➤</span>',
    82             intval($deg),
     85                '<span class="svv-wind-dir" style="display:inline-block;transform:rotate(%ddeg);line-height:1;font-style:normal;vertical-align:middle;" title="%s">➤</span>',
     86                intval($deg) - 90,
    8387            esc_attr(sv_vader_wind_dir($deg))
    8488        );
     
    120124        list($precip) = sv_vader_precip($weather['precip'] ?? null, $units['precip'], 1);
    121125
     126        // Convert configured alert thresholds (stored in plugin options, metric base)
     127        // into the resolved units so comparisons are meaningful regardless of unit prefs.
     128        $th_cold_extreme = sv_vader_temp(floatval($opts['alert_cold_extreme'] ?? 0), $units['temp'], 1)[0];
     129        $th_cold_freezing = sv_vader_temp(floatval($opts['alert_cold_freezing'] ?? 0), $units['temp'], 1)[0];
     130        $th_heat_extreme = sv_vader_temp(floatval($opts['alert_heat_extreme'] ?? 0), $units['temp'], 1)[0];
     131        $th_heat_warm = sv_vader_temp(floatval($opts['alert_heat_warm'] ?? 0), $units['temp'], 1)[0];
     132
     133        $th_wind_storm = sv_vader_wind(floatval($opts['alert_wind_storm'] ?? 0), $units['wind'], 1)[0];
     134        $th_wind_strong = sv_vader_wind(floatval($opts['alert_wind_strong'] ?? 0), $units['wind'], 1)[0];
     135
     136        $th_precip_heavy = sv_vader_precip(floatval($opts['alert_precip_heavy'] ?? 0), $units['precip'], 1)[0];
     137
    122138        if ($temp !== null) {
    123             if ($temp < $opts['alert_cold_extreme']) {
     139            if ($temp < $th_cold_extreme) {
    124140                $alerts[] = [
    125141                    'level' => 'danger',
     
    128144                    'icon'  => 'thermometer-minus'
    129145                ];
    130             } elseif ($temp < $opts['alert_cold_freezing']) {
     146            } elseif ($temp < $th_cold_freezing) {
    131147                $alerts[] = [
    132148                    'level' => 'warning',
     
    135151                    'icon'  => 'snow'
    136152                ];
    137             } elseif ($temp > $opts['alert_heat_extreme']) {
     153            } elseif ($temp > $th_heat_extreme) {
    138154                $alerts[] = [
    139155                    'level' => 'danger',
     
    142158                    'icon'  => 'thermometer-plus'
    143159                ];
    144             } elseif ($temp > $opts['alert_heat_warm']) {
     160            } elseif ($temp > $th_heat_warm) {
    145161                $alerts[] = [
    146162                    'level' => 'info',
     
    153169
    154170        if ($wind !== null) {
    155             if ($wind > $opts['alert_wind_storm']) {
     171            if ($wind > $th_wind_storm) {
    156172                $alerts[] = [
    157173                    'level' => 'danger',
     
    160176                    'icon'  => 'wind'
    161177                ];
    162             } elseif ($wind > $opts['alert_wind_strong']) {
     178            } elseif ($wind > $th_wind_strong) {
    163179                $alerts[] = [
    164180                    'level' => 'warning',
  • spelhubben-weather/tags/1.9.3/includes/options.php

    r3435228 r3437920  
    2626        'prov_weatherapi'     => 1,
    2727            'temp_unit'    => '',       // optional override: C|F
    28             'wind_unit'    => '',       // optional override: ms|kmh|mph
     28            'wind_unit'    => '',       // optional override: ms|kmh|mph|knt
    2929            'precip_unit'  => '',       // optional override: mm|in
    3030            'date_format'  => 'D j/n',  // used in forecast labels
     
    9292
    9393        // NEW: Units & format
    94         $units_allowed = ['metric','metric_kmh','imperial'];
     94        $units_allowed = ['metric','metric_kmh','metric_knt','imperial'];
    9595        $units_in = strtolower((string)($in['units'] ?? $def['units']));
    9696        $out['units'] = in_array($units_in, $units_allowed, true) ? $units_in : 'metric';
     
    100100        $pu = strtolower((string)($in['precip_unit'] ?? ''));
    101101        $out['temp_unit']   = in_array($tu, ['C','F'], true) ? $tu : '';
    102         $out['wind_unit']   = in_array($wu, ['ms','kmh','mph'], true) ? $wu : '';
     102        // Accept both 'knt' and 'kn' as valid aliases for knots.
     103        $out['wind_unit']   = in_array($wu, ['ms','kmh','mph','knt','kn'], true) ? $wu : '';
    103104        $out['precip_unit'] = in_array($pu, ['mm','in'], true) ? $pu : '';
    104105        $out['date_format'] = sanitize_text_field($in['date_format'] ?? $def['date_format']);
  • spelhubben-weather/tags/1.9.3/readme.txt

    r3435848 r3437920  
    55Tested up to: 6.9
    66Requires PHP: 7.4
    7 Stable tag: 1.9.2
     7Stable tag: 1.9.3
    88Donate link: https://www.paypal.com/donate/?hosted_button_id=CV74CEXY5XEAU
    99
     
    7777All three render the same UI. Use the **block** in the block editor, the **shortcode** in classic content areas, and the **widget** in sidebars (Appearance → Widgets). Each lets you override global defaults.
    7878
    79 = Where is the Shortcodes page? (new in 1.7.0) =
    80 Go to **Settings → Spelhubben Weather → Shortcodes**. You’ll find searchable examples, one-click copy (and “copy all”), a **Quick Builder** with selectable options, and a **live preview** that renders the shortcode inside WP-admin.
    81 
    8279= How do place and coordinates work? =
    8380If `lat` and `lon` are provided they take precedence. Otherwise the plugin geocodes the `place` string (e.g. `place="Umeå"`). Set a global default place in settings.
     
    200197
    201198== Changelog ==
    202  - = 1.9.2 =
    203  - **New:** Shortcode/Block/Widget `theme` attribute — `theme="auto|light|dark"` to force UI theme per instance (default `auto`).
    204  - **New:** Quick Builder theme selector in admin Shortcodes page; example shortcode added.
    205  - **Improved:** Renderer emits `data-svv-theme` and `svv-theme-<value>` class for easier CSS targeting.
    206  - **Improved:** Frontend CSS and map styling — darker Leaflet tiles in dark theme and darker alert box styles for better contrast.
    207  - **Changed:** Admin JS updated to include `theme` when generating shortcodes; docs updated across readmes.
     199- = 1.9.3 =
     200- **New:** Support for wind in knots (`knt`, alias `kn`) across Shortcodes, Block, Widget and WPBakery/VC.
     201- **New:** `wind_unit` override in Block inspector, Widget settings and Shortcodes Quick Builder.
     202- **Improved:** `metric_knt` preset for metric display with knots.
     203- **Fixed:** Wind direction arrow rotation corrected to match compass degrees.
     204- **Fixed:** Shortcode `wind_unit` reliably overrides resolved units and renderer emits `data-svv-wind-unit` for debugging.
     205- **Fixed:** Alert threshold comparisons now converted into display units to avoid false alerts.
     206- **Fixed:** PHP parse error in admin page resolved.
     207- **Changed:** Plugin version bumped to 1.9.3; readme stable tag updated.
     208- = 1.9.2 =
     209- **New:** Shortcode/Block/Widget `theme` attribute — `theme="auto|light|dark"` to force UI theme per instance (default `auto`).
     210- **New:** Quick Builder theme selector in admin Shortcodes page; example shortcode added.
     211- **Improved:** Renderer emits `data-svv-theme` and `svv-theme-<value>` class for easier CSS targeting.
     212- **Improved:** Frontend CSS and map styling — darker Leaflet tiles in dark theme and darker alert box styles for better contrast.
     213- **Changed:** Admin JS updated to include `theme` when generating shortcodes; docs updated across readmes.
    208214
    209215- = 1.9.0 =
  • spelhubben-weather/tags/1.9.3/spelhubben-weather.php

    r3435848 r3437920  
    33 * Plugin Name: Spelhubben Weather
    44 * Description: Displays current weather and an optional forecast with a simple consensus across providers (Open-Meteo, SMHI, Yr/MET Norway). Supports shortcode + Gutenberg block + classic widget. Optional Leaflet map, subtle animations, daily forecast, and multiple layouts.
    5  * Version: 1.9.2
     5 * Version: 1.9.3
    66 * Author: Spelhubben
    77 * Text Domain: spelhubben-weather
     
    2424// ── Constants (kept for backward compatibility).
    2525if ( ! defined( 'SV_VADER_VER' ) ) {
    26     define( 'SV_VADER_VER', '1.9.2' );
     26    define( 'SV_VADER_VER', '1.9.3' );
    2727}
    2828if ( ! defined( 'SV_VADER_DIR' ) ) {
     
    6969require_once SV_VADER_DIR . 'includes/class-sv-vader.php'; // API/service layer.
    7070
     71// Optional integrations
     72$sv_vader_vc = SV_VADER_DIR . 'includes/integrations/vc.php';
     73if ( file_exists( $sv_vader_vc ) ) {
     74    require_once $sv_vader_vc;
     75}
     76
    7177if ( is_admin() ) {
    7278    $sv_vader_admin = SV_VADER_DIR . 'admin/admin.php';
  • spelhubben-weather/trunk/admin/admin.js

    r3435748 r3437920  
    313313      var layout = document.querySelector('.svv-b-layout').value;
    314314      var theme = (document.querySelector('.svv-b-theme') && document.querySelector('.svv-b-theme').value) || 'auto';
     315      var windunit = (document.querySelector('.svv-b-windunit') && document.querySelector('.svv-b-windunit').value) || '';
    315316      var map = document.querySelector('.svv-b-map').checked ? '1' : '0';
    316317      var animate = document.querySelector('.svv-b-animate').checked ? '1' : '0';
     
    324325      if (animate === '0') sc += ' animate="0"';
    325326      if (provs && provs !== 'openmeteo,smhi,yr') sc += ' providers="' + provs + '"';
     327      if (windunit) sc += ' wind_unit="' + windunit + '"';
    326328      sc += ']';
    327329
  • spelhubben-weather/trunk/admin/admin.php

    r3435228 r3437920  
    525525        'metric'     => __( 'Metric (°C, m/s, mm)', 'spelhubben-weather' ),
    526526        'metric_kmh' => __( 'Metric (°C, km/h, mm)', 'spelhubben-weather' ),
     527        'metric_knt' => __( 'Metric (°C, knt, mm)', 'spelhubben-weather' ),
    527528        'imperial'   => __( 'Imperial (°F, mph, in)', 'spelhubben-weather' ),
    528529    );
     
    547548    );
    548549    printf(
    549         '<label>%s <input type="text" name="sv_vader_options[wind_unit]" value="%s" class="small-text" placeholder="ms|kmh|mph" /></label> ',
     550        '<label>%s <input type="text" name="sv_vader_options[wind_unit]" value="%s" class="small-text" placeholder="ms|kmh|mph|knt" /></label> ',
    550551        esc_html__( 'Wind unit', 'spelhubben-weather' ),
    551552        esc_attr( $o['wind_unit'] ?? '' )
  • spelhubben-weather/trunk/admin/page-shortcodes.php

    r3435748 r3437920  
    99    function sv_vader_render_shortcodes_page() {
    1010        if ( ! current_user_can( 'manage_options' ) ) return;
     11
     12            // Load current options so Quick Builder can default to site settings
     13            $opts = sv_vader_get_options();
    1114
    1215        // Examples (new aliases)
     
    8689                                </div>
    8790                            <?php endforeach; ?>
     91
     92                                <!-- Wind unit examples (compact, translatable) -->
     93                                <div class="svv-codeblock svv-codeblock--light" data-svv-visible="1" data-label="<?php echo esc_attr__( 'Wind unit examples', 'spelhubben-weather' ); ?>">
     94                                    <div class="svv-codeblock-head">
     95                                        <span><?php echo esc_html__( 'Wind unit examples', 'spelhubben-weather' ); ?></span>
     96                                        <button type="button" class="button button-secondary svv-copy-btn" data-copy="[spelhubben_weather layout=\"compact\" map=\"0\" theme=\"light\" show=\"temp,wind,wind_dir,icon\" wind_unit=\"knt\"]">
     97                                            <?php esc_html_e( 'Copy', 'spelhubben-weather' ); ?>
     98                                        </button>
     99                                    </div>
     100                                    <pre class="svv-pre"><code tabindex="0"><?php echo esc_html( '[spelhubben_weather layout="compact" map="0" theme="light" show="temp,wind,wind_dir,icon" wind_unit="kmh"]' ); ?>
     101
     102        <?php echo esc_html( '[spelhubben_weather layout="compact" map="0" theme="light" show="temp,wind,wind_dir,icon" wind_unit="knt"]' ); ?></code></pre>
     103                                </div>
    88104                        </div>
    89105
    90106                    </div>
    91107                </div>
     108
     109
    92110
    93111                <!-- RIGHT: Preview + Attributes -->
     
    158176                                    <label><input type="checkbox" class="svv-b-prov" value="openweathermap"> OpenWeather</label>
    159177                                    <label><input type="checkbox" class="svv-b-prov" value="weatherapi"> WeatherAPI</label>
     178                                </div>
     179                                <div>
     180                                    <strong><?php esc_html_e( 'Wind unit (override):', 'spelhubben-weather' ); ?></strong><br>
     181                                    <select class="svv-b-windunit">
     182                                        <option value=""<?php echo selected( $opts['wind_unit'] ?? '', '', false ); ?>><?php esc_html_e('(use site default)', 'spelhubben-weather'); ?></option>
     183                                        <option value="ms"<?php echo selected( $opts['wind_unit'] ?? '', 'ms', false ); ?>>m/s</option>
     184                                        <option value="kmh"<?php echo selected( $opts['wind_unit'] ?? '', 'kmh', false ); ?>>km/h</option>
     185                                        <option value="mph"<?php echo selected( $opts['wind_unit'] ?? '', 'mph', false ); ?>>mph</option>
     186                                        <option value="knt"<?php echo selected( $opts['wind_unit'] ?? '', 'knt', false ); ?>>knt (knots)</option>
     187                                    </select>
    160188                                </div>
    161189                            </div>
     
    212240                                    <tr data-group="uf"><td><code>units</code></td><td><?php esc_html_e( 'Preset: metric | metric_kmh | imperial', 'spelhubben-weather' ); ?></td><td><code>units="metric_kmh"</code></td></tr>
    213241                                    <tr data-group="uf"><td><code>temp_unit</code></td><td><?php esc_html_e( 'Override temperature unit', 'spelhubben-weather' ); ?></td><td><code>temp_unit="F"</code></td></tr>
    214                                     <tr data-group="uf"><td><code>wind_unit</code></td><td><?php esc_html_e( 'Override wind unit', 'spelhubben-weather' ); ?></td><td><code>wind_unit="kmh"</code></td></tr>
     242                                    <tr data-group="uf"><td><code>wind_unit</code></td><td><?php esc_html_e( 'Override wind unit', 'spelhubben-weather' ); ?></td><td><code>wind_unit="kmh"</code> (or <code>wind_unit="knt"</code> for knots)</td></tr>
    215243                                    <tr data-group="uf"><td><code>precip_unit</code></td><td><?php esc_html_e( 'Override precipitation unit', 'spelhubben-weather' ); ?></td><td><code>precip_unit="in"</code></td></tr>
    216244                                    <tr data-group="uf"><td><code>date_format</code></td><td><?php esc_html_e( 'Forecast date label (PHP date)', 'spelhubben-weather' ); ?></td><td><code>date_format="D j/n"</code></td></tr>
     
    233261    }
    234262}
     263
  • spelhubben-weather/trunk/assets/style.css

    r3435748 r3437920  
    3333/* Dark Mode Support */
    3434@media (prefers-color-scheme: dark) {
    35   .sv-vader:not(.svv-force-light) {
     35  /* Do not apply automatic dark-vars when user/site explicitly forces light or dark */
     36  .sv-vader:not(.svv-force-light):not(.svv-force-dark) {
    3637    --svv-bg: #1e1e1e;
    3738    --svv-text: #f0f0f0;
     
    4142    --svv-muted: #aaaaaa;
    4243  }
    43   .sv-vader:not(.svv-force-light) .svv-map {
     44  .sv-vader:not(.svv-force-light):not(.svv-force-dark) .svv-map {
    4445    filter: brightness(0.8) contrast(1.2) invert(100%) hue-rotate(180deg);
    4546  }
  • spelhubben-weather/trunk/blocks/spelhubben-weather/block.json

    r3435228 r3437920  
    2323    "showAlerts": { "type": "boolean", "default": true },
    2424    "units":      { "type": "string",  "default": "metric" },
    25     "date_format":{ "type": "string",  "default": "D j/n" }
     25    "date_format":{ "type": "string",  "default": "D j/n" },
     26    "wind_unit":  { "type": "string",  "default": "" }
    2627  },
    2728  "editorScript": "file:./index.js",
  • spelhubben-weather/trunk/blocks/spelhubben-weather/index.js

    r3435228 r3437920  
    1717    { label: __( 'Metric (°C, m/s, mm)', 'spelhubben-weather' ), value: 'metric' },
    1818    { label: __( 'Metric (°C, km/h, mm)', 'spelhubben-weather' ), value: 'metric_kmh' },
     19    { label: __( 'Metric (°C, knt, mm)', 'spelhubben-weather' ), value: 'metric_knt' },
    1920    { label: __( 'Imperial (°F, mph, in)', 'spelhubben-weather' ), value: 'imperial' },
     21  ];
     22
     23  const WIND_UNITS = [
     24    { label: __( 'm/s', 'spelhubben-weather' ), value: 'ms' },
     25    { label: __( 'km/h', 'spelhubben-weather' ), value: 'kmh' },
     26    { label: __( 'mph', 'spelhubben-weather' ), value: 'mph' },
     27    { label: __( 'knt (knots)', 'spelhubben-weather' ), value: 'knt' },
    2028  ];
    2129
     
    121129              onChange: ( v ) => setAttributes( { units: v } ),
    122130            } ),
     131            el( SelectControl, {
     132              label: __( 'Wind unit override', 'spelhubben-weather' ),
     133              value: attributes.wind_unit || '',
     134              options: [
     135                { label: __( '(use preset)', 'spelhubben-weather' ), value: '' },
     136                ...WIND_UNITS
     137              ],
     138              onChange: ( v ) => setAttributes( { wind_unit: v } ),
     139            } ),
    123140            el( TextControl, {
    124141              label: __( 'Date format (PHP date)', 'spelhubben-weather' ),
     
    154171          bp,
    155172          ServerSideRender
    156             ? el( ServerSideRender, { block: 'spelhubben/weather', attributes } )
     173            ? el( ServerSideRender, { block: 'spelhubben-weather/spelhubben-weather', attributes } )
    157174            : el( 'p', null, __( 'Spelhubben Weather preview (ServerSideRender unavailable). Save/update to view.', 'spelhubben-weather' ) )
    158175        )
  • spelhubben-weather/trunk/includes/Widget/class-widget.php

    r3435748 r3437920  
    3838            'theme'     => 'auto',
    3939            'class'     => 'is-widget',
     40            'wind_unit' => '',
    4041        ];
    4142        $instance = wp_parse_args((array) $instance, $defaults);
     
    9192                'show_alerts' => $show_alerts ? '1' : '0',
    9293                    'theme'       => $theme,
     94                    'wind_unit'   => $instance['wind_unit'] ?? $opts['wind_unit'],
    9395            ]);
    9496
     
    118120            'theme'     => 'auto',
    119121            'class'     => '',
     122            'wind_unit' => '',
    120123        ];
    121124        $instance   = wp_parse_args((array) $instance, $defaults);
     
    259262        </p>
    260263        <p>
     264            <label for="<?php echo esc_attr($this->get_field_id('wind_unit')); ?>"><?php esc_html_e('Wind unit:', 'spelhubben-weather'); ?></label>
     265            <select id="<?php echo esc_attr($this->get_field_id('wind_unit')); ?>"
     266                    name="<?php echo esc_attr($this->get_field_name('wind_unit')); ?>"
     267                    class="widefat">
     268                <option value="" <?php selected($instance['wind_unit'] ?? '', ''); ?>><?php esc_html_e('(use site default)', 'spelhubben-weather'); ?></option>
     269                <option value="ms" <?php selected($instance['wind_unit'] ?? '', 'ms'); ?>>m/s</option>
     270                <option value="kmh" <?php selected($instance['wind_unit'] ?? '', 'kmh'); ?>>km/h</option>
     271                <option value="mph" <?php selected($instance['wind_unit'] ?? '', 'mph'); ?>>mph</option>
     272                <option value="knt" <?php selected($instance['wind_unit'] ?? '', 'knt'); ?>>knt (knots)</option>
     273            </select>
     274        </p>
     275        <p>
    261276            <label for="<?php echo esc_attr($this->get_field_id('class')); ?>"><?php esc_html_e('Extra CSS class:', 'spelhubben-weather'); ?></label>
    262277            <input class="widefat"
     
    294309        $instance['theme']       = in_array(strtolower($new_instance['theme'] ?? 'auto'), ['auto','light','dark'], true) ? sanitize_text_field(strtolower($new_instance['theme'])) : 'auto';
    295310        $instance['class']       = sanitize_html_class($new_instance['class'] ?? '', '');
     311        $wu = strtolower(trim((string)($new_instance['wind_unit'] ?? '')));
     312        $instance['wind_unit'] = in_array($wu, ['ms','kmh','mph','knt','kn'], true) ? $wu : '';
    296313
    297314        return $instance;
  • spelhubben-weather/trunk/includes/class-renderer.php

    r3435748 r3437920  
    6363        ]);
    6464
     65        // Safety: if shortcode explicitly sets wind_unit, ensure it is applied.
     66        // Accept both 'knt' and 'kn' and canonicalize to 'knt'.
     67        $allowed_winds = ['ms','kmh','mph','knt','kn'];
     68        $wu_attr = strtolower(trim((string)($a['wind_unit'] ?? '')));
     69        if ($wu_attr !== '' && in_array($wu_attr, $allowed_winds, true)) {
     70            if ($wu_attr === 'kn') $wu_attr = 'knt';
     71            $units['wind'] = $wu_attr;
     72        }
     73
    6574        $api = new SV_Vader_API(intval($opts['cache_minutes']));
    6675       
     
    105114
    106115        if ($theme !== 'auto') {
    107             $classes .= ' svv-theme-' . $theme;
     116            // Add both theme class and a force-class to override OS/browser prefers-color-scheme
     117            $classes .= ' svv-theme-' . $theme . ' svv-force-' . $theme;
    108118        }
    109119
    110120        ob_start(); ?>
    111         <div class="<?php echo esc_attr($classes); ?>" data-svv-ro="1" data-svv-theme="<?php echo esc_attr($theme); ?>">
     121        <div class="<?php echo esc_attr($classes); ?>" data-svv-ro="1" data-svv-theme="<?php echo esc_attr($theme); ?>" data-svv-wind-unit="<?php echo esc_attr($units['wind']); ?>">
    112122            <?php if (!empty($name) && $layout !== 'inline'): ?>
    113123                <div class="svv-ort"><?php echo esc_html($name); ?></div>
     
    151161                            <span class="svv-wind svv-badge">
    152162                                <?php echo esc_html( $wind_compact ); ?>
    153                                 <?php if (in_array('wind_dir', $show, true)) echo wp_kses_post( sv_vader_wind_dir_icon($w_dir) ); ?>
     163                            <?php if (in_array('wind_dir', $show, true) && $w_dir !== null) echo wp_kses_post( sv_vader_wind_dir_icon($w_dir) ); ?>
     164                            </span>
     165                        <?php elseif (in_array('wind_dir', $show, true) && $w_dir !== null): ?>
     166                            <span class="svv-wind svv-badge">
     167                                <?php echo wp_kses_post( sv_vader_wind_dir_icon($w_dir) ); ?>
    154168                            </span>
    155169                        <?php endif; ?>
     
    177191                                    <span class="svv-wind">
    178192                                        <?php echo esc_html( $wind_detailed ); ?>
    179                                         <?php if (in_array('wind_dir', $show, true)) echo wp_kses_post( sv_vader_wind_dir_icon($w_dir) ); ?>
     193                                    <?php if (in_array('wind_dir', $show, true) && $w_dir !== null) echo wp_kses_post( sv_vader_wind_dir_icon($w_dir) ); ?>
     194                                    </span>
     195                                <?php endif; ?>
     196                                <?php if (!(in_array('wind', $show, true) && $w_val !== null) && in_array('wind_dir', $show, true) && $w_dir !== null): ?>
     197                                    <span class="svv-wind">
     198                                        <?php echo wp_kses_post( sv_vader_wind_dir_icon($w_dir) ); ?>
    180199                                    </span>
    181200                                <?php endif; ?>
     
    223242                            <span class="svv-wind">
    224243                                <?php echo esc_html( $wind_card ); ?>
    225                                 <?php if (in_array('wind_dir', $show, true)) echo wp_kses_post( sv_vader_wind_dir_icon($w_dir) ); ?>
     244                            <?php if (in_array('wind_dir', $show, true) && $w_dir !== null) echo wp_kses_post( sv_vader_wind_dir_icon($w_dir) ); ?>
     245                            </span>
     246                        <?php endif; ?>
     247                        <?php if (!(in_array('wind', $show, true) && $w_val !== null) && in_array('wind_dir', $show, true) && $w_dir !== null): ?>
     248                            <span class="svv-wind">
     249                                <?php echo wp_kses_post( sv_vader_wind_dir_icon($w_dir) ); ?>
    226250                            </span>
    227251                        <?php endif; ?>
  • spelhubben-weather/trunk/includes/format.php

    r3435228 r3437920  
    1515        $map = [
    1616            'metric'     => ['temp'=>'C',  'wind'=>'ms',  'precip'=>'mm'],
     17            'metric_knt' => ['temp'=>'C',  'wind'=>'knt', 'precip'=>'mm'],
    1718            'metric_kmh' => ['temp'=>'C',  'wind'=>'kmh', 'precip'=>'mm'],
    1819            'imperial'   => ['temp'=>'F',  'wind'=>'mph', 'precip'=>'in'],
     
    2627
    2728        if (in_array($tu, ['C','F'], true))     $u['temp']   = $tu;
    28         if (in_array($wu, ['ms','kmh','mph'], true)) $u['wind']   = $wu;
     29        // Accept both 'knt' and 'kn' as aliases for knots.
     30        if (in_array($wu, ['ms','kmh','mph','knt','kn'], true)) $u['wind']   = $wu;
    2931        if (in_array($pu, ['mm','in'], true))   $u['precip'] = $pu;
    3032
     
    5052        switch ($unit) {
    5153            case 'kmh': $val = $ms * 3.6; break;
     54            case 'knt':
     55            case 'kn': $val = $ms * 1.94384449; $unit = 'kn'; break;
    5256            case 'mph': $val = $ms * 2.23693629; break;
    5357            default:    $val = $ms; $unit = 'm/s';
     
    7983        if ($deg === null) return '';
    8084        return sprintf(
    81             '<span class="svv-wind-dir" style="display:inline-block;transform:rotate(%ddeg);line-height:1;font-style:normal;vertical-align:middle;" title="%s">➤</span>',
    82             intval($deg),
     85                '<span class="svv-wind-dir" style="display:inline-block;transform:rotate(%ddeg);line-height:1;font-style:normal;vertical-align:middle;" title="%s">➤</span>',
     86                intval($deg) - 90,
    8387            esc_attr(sv_vader_wind_dir($deg))
    8488        );
     
    120124        list($precip) = sv_vader_precip($weather['precip'] ?? null, $units['precip'], 1);
    121125
     126        // Convert configured alert thresholds (stored in plugin options, metric base)
     127        // into the resolved units so comparisons are meaningful regardless of unit prefs.
     128        $th_cold_extreme = sv_vader_temp(floatval($opts['alert_cold_extreme'] ?? 0), $units['temp'], 1)[0];
     129        $th_cold_freezing = sv_vader_temp(floatval($opts['alert_cold_freezing'] ?? 0), $units['temp'], 1)[0];
     130        $th_heat_extreme = sv_vader_temp(floatval($opts['alert_heat_extreme'] ?? 0), $units['temp'], 1)[0];
     131        $th_heat_warm = sv_vader_temp(floatval($opts['alert_heat_warm'] ?? 0), $units['temp'], 1)[0];
     132
     133        $th_wind_storm = sv_vader_wind(floatval($opts['alert_wind_storm'] ?? 0), $units['wind'], 1)[0];
     134        $th_wind_strong = sv_vader_wind(floatval($opts['alert_wind_strong'] ?? 0), $units['wind'], 1)[0];
     135
     136        $th_precip_heavy = sv_vader_precip(floatval($opts['alert_precip_heavy'] ?? 0), $units['precip'], 1)[0];
     137
    122138        if ($temp !== null) {
    123             if ($temp < $opts['alert_cold_extreme']) {
     139            if ($temp < $th_cold_extreme) {
    124140                $alerts[] = [
    125141                    'level' => 'danger',
     
    128144                    'icon'  => 'thermometer-minus'
    129145                ];
    130             } elseif ($temp < $opts['alert_cold_freezing']) {
     146            } elseif ($temp < $th_cold_freezing) {
    131147                $alerts[] = [
    132148                    'level' => 'warning',
     
    135151                    'icon'  => 'snow'
    136152                ];
    137             } elseif ($temp > $opts['alert_heat_extreme']) {
     153            } elseif ($temp > $th_heat_extreme) {
    138154                $alerts[] = [
    139155                    'level' => 'danger',
     
    142158                    'icon'  => 'thermometer-plus'
    143159                ];
    144             } elseif ($temp > $opts['alert_heat_warm']) {
     160            } elseif ($temp > $th_heat_warm) {
    145161                $alerts[] = [
    146162                    'level' => 'info',
     
    153169
    154170        if ($wind !== null) {
    155             if ($wind > $opts['alert_wind_storm']) {
     171            if ($wind > $th_wind_storm) {
    156172                $alerts[] = [
    157173                    'level' => 'danger',
     
    160176                    'icon'  => 'wind'
    161177                ];
    162             } elseif ($wind > $opts['alert_wind_strong']) {
     178            } elseif ($wind > $th_wind_strong) {
    163179                $alerts[] = [
    164180                    'level' => 'warning',
  • spelhubben-weather/trunk/includes/options.php

    r3435228 r3437920  
    2626        'prov_weatherapi'     => 1,
    2727            'temp_unit'    => '',       // optional override: C|F
    28             'wind_unit'    => '',       // optional override: ms|kmh|mph
     28            'wind_unit'    => '',       // optional override: ms|kmh|mph|knt
    2929            'precip_unit'  => '',       // optional override: mm|in
    3030            'date_format'  => 'D j/n',  // used in forecast labels
     
    9292
    9393        // NEW: Units & format
    94         $units_allowed = ['metric','metric_kmh','imperial'];
     94        $units_allowed = ['metric','metric_kmh','metric_knt','imperial'];
    9595        $units_in = strtolower((string)($in['units'] ?? $def['units']));
    9696        $out['units'] = in_array($units_in, $units_allowed, true) ? $units_in : 'metric';
     
    100100        $pu = strtolower((string)($in['precip_unit'] ?? ''));
    101101        $out['temp_unit']   = in_array($tu, ['C','F'], true) ? $tu : '';
    102         $out['wind_unit']   = in_array($wu, ['ms','kmh','mph'], true) ? $wu : '';
     102        // Accept both 'knt' and 'kn' as valid aliases for knots.
     103        $out['wind_unit']   = in_array($wu, ['ms','kmh','mph','knt','kn'], true) ? $wu : '';
    103104        $out['precip_unit'] = in_array($pu, ['mm','in'], true) ? $pu : '';
    104105        $out['date_format'] = sanitize_text_field($in['date_format'] ?? $def['date_format']);
  • spelhubben-weather/trunk/readme.txt

    r3435848 r3437920  
    55Tested up to: 6.9
    66Requires PHP: 7.4
    7 Stable tag: 1.9.2
     7Stable tag: 1.9.3
    88Donate link: https://www.paypal.com/donate/?hosted_button_id=CV74CEXY5XEAU
    99
     
    7777All three render the same UI. Use the **block** in the block editor, the **shortcode** in classic content areas, and the **widget** in sidebars (Appearance → Widgets). Each lets you override global defaults.
    7878
    79 = Where is the Shortcodes page? (new in 1.7.0) =
    80 Go to **Settings → Spelhubben Weather → Shortcodes**. You’ll find searchable examples, one-click copy (and “copy all”), a **Quick Builder** with selectable options, and a **live preview** that renders the shortcode inside WP-admin.
    81 
    8279= How do place and coordinates work? =
    8380If `lat` and `lon` are provided they take precedence. Otherwise the plugin geocodes the `place` string (e.g. `place="Umeå"`). Set a global default place in settings.
     
    200197
    201198== Changelog ==
    202  - = 1.9.2 =
    203  - **New:** Shortcode/Block/Widget `theme` attribute — `theme="auto|light|dark"` to force UI theme per instance (default `auto`).
    204  - **New:** Quick Builder theme selector in admin Shortcodes page; example shortcode added.
    205  - **Improved:** Renderer emits `data-svv-theme` and `svv-theme-<value>` class for easier CSS targeting.
    206  - **Improved:** Frontend CSS and map styling — darker Leaflet tiles in dark theme and darker alert box styles for better contrast.
    207  - **Changed:** Admin JS updated to include `theme` when generating shortcodes; docs updated across readmes.
     199- = 1.9.3 =
     200- **New:** Support for wind in knots (`knt`, alias `kn`) across Shortcodes, Block, Widget and WPBakery/VC.
     201- **New:** `wind_unit` override in Block inspector, Widget settings and Shortcodes Quick Builder.
     202- **Improved:** `metric_knt` preset for metric display with knots.
     203- **Fixed:** Wind direction arrow rotation corrected to match compass degrees.
     204- **Fixed:** Shortcode `wind_unit` reliably overrides resolved units and renderer emits `data-svv-wind-unit` for debugging.
     205- **Fixed:** Alert threshold comparisons now converted into display units to avoid false alerts.
     206- **Fixed:** PHP parse error in admin page resolved.
     207- **Changed:** Plugin version bumped to 1.9.3; readme stable tag updated.
     208- = 1.9.2 =
     209- **New:** Shortcode/Block/Widget `theme` attribute — `theme="auto|light|dark"` to force UI theme per instance (default `auto`).
     210- **New:** Quick Builder theme selector in admin Shortcodes page; example shortcode added.
     211- **Improved:** Renderer emits `data-svv-theme` and `svv-theme-<value>` class for easier CSS targeting.
     212- **Improved:** Frontend CSS and map styling — darker Leaflet tiles in dark theme and darker alert box styles for better contrast.
     213- **Changed:** Admin JS updated to include `theme` when generating shortcodes; docs updated across readmes.
    208214
    209215- = 1.9.0 =
  • spelhubben-weather/trunk/spelhubben-weather.php

    r3435848 r3437920  
    33 * Plugin Name: Spelhubben Weather
    44 * Description: Displays current weather and an optional forecast with a simple consensus across providers (Open-Meteo, SMHI, Yr/MET Norway). Supports shortcode + Gutenberg block + classic widget. Optional Leaflet map, subtle animations, daily forecast, and multiple layouts.
    5  * Version: 1.9.2
     5 * Version: 1.9.3
    66 * Author: Spelhubben
    77 * Text Domain: spelhubben-weather
     
    2424// ── Constants (kept for backward compatibility).
    2525if ( ! defined( 'SV_VADER_VER' ) ) {
    26     define( 'SV_VADER_VER', '1.9.2' );
     26    define( 'SV_VADER_VER', '1.9.3' );
    2727}
    2828if ( ! defined( 'SV_VADER_DIR' ) ) {
     
    6969require_once SV_VADER_DIR . 'includes/class-sv-vader.php'; // API/service layer.
    7070
     71// Optional integrations
     72$sv_vader_vc = SV_VADER_DIR . 'includes/integrations/vc.php';
     73if ( file_exists( $sv_vader_vc ) ) {
     74    require_once $sv_vader_vc;
     75}
     76
    7177if ( is_admin() ) {
    7278    $sv_vader_admin = SV_VADER_DIR . 'admin/admin.php';
Note: See TracChangeset for help on using the changeset viewer.