设置API-基于不同的字段生成字段值?

时间:2013-08-22 作者:Wordpressor

我使用存储主题设置Settings API.

如果使用创建新设置add_settings_field() 是否可以基于第一个设置创建另一个设置?

为什么?假设我有三种设置:

main_color
lighter_color
darker_color
用户打开主题选项页并设置main_color 至#444。现在我想要lighter_colordarker_color 要根据main\\u color value(#444)自动更改值,请执行以下操作:

main_color = #444
lighter_color = #777
darker_color = #111
当然,我可以做3种不同的设置,让用户选择所有的颜色,但如果他将较浅的\\u颜色设置为比主\\u颜色更深的颜色,则不会对用户友好,整个主题看起来会很混乱。等

有什么想法吗?:)也许使用回调?

UPDATE

开始悬赏。简言之,我在settings API中存储了一些设置,我想将其稍微修改的版本存储在其他地方,我需要完全方便地访问这些修改后的值,并且他们应该在每次设置API“parents”更新时进行更新。

1 个回复
最合适的回答,由SO网友:gmazzap 整理而成

首先,您需要函数来计算较浅和较深的颜色。

一旦有十六进制格式的值,快速方法是:

将十六进制转换为rgb将rgb转换为hsl(这很容易)

  • 将更亮和更暗的hsl还原为十六进制(hsl>rgb>十六进制)
  • 设置API使用update_option 存储数据update_option_{$option} 保存后触发。

    假设您正在将主颜色保存到名为“main\\u color”的选项中,我创建了一个类来实现以下步骤:

    吊钩update_option_{$option}add_option_{$option} 并运行以下功能:

  • 获取主颜色的当前保存选项创建较亮和较暗(以上步骤)
  • 也为这些颜色保存选项

    class MyColorSettingsClass {
    
      var $default_main_color;
    
      var $lighther_perc;
    
      var $darker_perc;
    
      function __construct( $default_main_color = \'#444444\', $lighther_perc = 33, $darker_perc = 33 ) {
          $this->default_main_color = $default_main_color;
          $this->lighther_perc = $lighther_perc;
          $this->darker_perc = $darker_perc;
          add_action(\'add_option_main_color\', array($this, \'set_conversion\'), 20, 2 );
          add_action(\'update_option_main_color\', array($this, \'set_conversion\'), 20, 2 );
          // if not exists the main color option, set colors to default
          if ( ! get_option(\'main_color\') ) update_option(\'main_color\', $default_main_color );
      }
    
      function set_conversion($option_name_or_old_value = \'\', $newvalue = null ) {
          $main = $newvalue ? : $this->default_main_color;
          $this->lighther_and_darker( $main );
      }
    
      function lighther_and_darker( $color = null ) {
          $main_hls = self::rgbToHsl( self::hexToRgb($color) );
          if ( is_array($main_hls) && count($main_hls) == 3 ) {
              $main_hls = array_values($main_hls);
              $l = floor( $main_hls[2] * 100 );
              $lighther_l = $l + round( $l * ( $this->lighther_perc / 100 ) );
              if ( $lighther_l > 100 ) $lighther_l = 100;
              $darker_l = $l - round( $l * ( $this->darker_perc / 100) ) ? : 0;
              $lighther_hls = array(\'h\' => $main_hls[0], \'s\' => $main_hls[1], \'l\' => round($lighther_l/100, 2) );
              $darker_hls = array(\'h\' => $main_hls[0], \'s\' => $main_hls[1], \'l\' => round($darker_l/100, 2) );
              $lighther = self::rgbToHex( self::hslToRgb( $lighther_hls ) );
              $darker = self::rgbToHex( self::hslToRgb( $darker_hls ) );
              update_option(\'lighter_color\', $lighther);
              update_option(\'darker_color\', $darker);
          }
      }
    
      static function hexToRgb( $hex = \'000000\') {
        if ( empty($hex) || ! is_string($hex) ) return;
        // strip \'#\' if present
        $hex = str_replace(\'#\', \'\', $hex);  
        // accept only hexadecimal strings in 3 and 6 digit format
        if ( ( strlen($hex) != 3 && strlen($hex) != 6 ) || ! ctype_xdigit ( $hex ) ) return;    
        if ( strlen($hex) == 3) {
          $r = $hex{0} . $hex{0};
          $g = $hex{1} . $hex{1};
          $b = $hex{2} . $hex{2};
        } else {
          $r = substr($hex, 0, 2);
          $g = substr($hex, 2, 2);
          $b = substr($hex, 4, 2);
        }
        $rgb = array_map(\'hexdec\', compact(\'r\', \'g\', \'b\'));
        return $rgb;
      }
    
    
      static function rgbToHex( $rgb = array(0, 0, 0) ) {
        if ( ! is_array($rgb) || count($rgb) != 3 ) return;
        $rgb = array_map(\'intval\', $rgb);
        $hex = implode(\'\', array_map(\'dechex\', $rgb) );
        if ( ! ctype_xdigit ( $hex ) ) $hex = $this->default_main_color;
        return \'#\' . $hex;
      }
    
    
      // coming from http://www.brandonheyer.com/2013/03/27/convert-hsl-to-rgb-and-rgb-to-hsl-via-php/
      static function rgbToHsl( $rgb = array(0, 0, 0) ) {
        if ( ! is_array($rgb) || count($rgb) != 3 ) return;
        $rgb = array_values( array_map(\'intval\', $rgb) );
        $oldR = $r = $rgb[0];
        $oldG = $g = $rgb[1];
        $oldB = $b = $rgb[2];
        $r /= 255;
        $g /= 255;
        $b /= 255;
        $max = max( $r, $g, $b );
        $min = min( $r, $g, $b );
        $h = $s = 0;
        $l = ( $max + $min ) / 2;
        $d = $max - $min;
        if( $d != 0 ) {
            $s = $d / ( 1 - abs( 2 * $l - 1 ) );
            switch( $max ){
              case $r :
                $h = 60 * fmod( ( ( $g - $b ) / $d ), 6 );
                break;
    
              case $g:
                $h = 60 * ( ( $b - $r ) / $d + 2 );
                break;
    
              case $b:
                $h = 60 * ( ( $r - $g ) / $d + 4 );
                break;
            }
        }
        $hsl = array();
        foreach ( compact(\'h\', \'s\', \'l\') as $i => $var ) $hsl[$i] = round($var, 2);
        return $hsl;
      }
    
    
      // coming from http://www.brandonheyer.com/2013/03/27/convert-hsl-to-rgb-and-rgb-to-hsl-via-php/
      static function hslToRgb( $hsl = array(0, 0, 0) ) {
        if ( ! is_array($hsl) || count($hsl) != 3 ) return;
        $hsl = array_values($hsl);
        $h = (float)$hsl[0];
        $s = (float)$hsl[1];
        $l = (float)$hsl[2];
        $r = null;
        $g = null;
        $b = null;
        $c = ( 1 - abs( 2 * $l - 1 ) ) * $s;
        $x = $c * ( 1 - abs( fmod( ( $h / 60 ), 2 ) - 1 ) );
        $m = $l - ( $c / 2 );
        if ( $h < 60 ) {
          $r = $c;
          $g = $x;
          $b = 0;
        } else if ( $h < 120 ) {
          $r = $x;
          $g = $c;
          $b = 0;            
        } else if ( $h < 180 ) {
          $r = 0;
          $g = $c;
          $b = $x;                    
        } else if ( $h < 240 ) {
          $r = 0;
          $g = $x;
          $b = $c;
        } else if ( $h < 300 ) {
          $r = $x;
          $g = 0;
          $b = $c;
        } else {
          $r = $c;
          $g = 0;
          $b = $x;
        }
        $r = ( $r + $m ) * 255;
        $g = ( $g + $m ) * 255;
        $b = ( $b + $m  ) * 255;
        $rgb =  array();
        foreach ( compact(\'r\', \'g\', \'b\') as $i => $var ) $rgb[$i] = floor($var);
        return $rgb;
      }
    
    }
    
    一旦你在主题或插件中包含了这个类,就可以这样使用它:

    new MyColorSettingsClass(\'#444444\', 30, 30);
    
    其中,第一个参数是默认主颜色,第二个是较浅的百分比,第三个是较深的百分比。

    第一个参数接受3位和6位形式的十六进制颜色,并带有或不带有“#”。

    额外的功能是,当用户尚未设置任何内容时,此代码基于第一个参数为所有3种颜色创建默认选项。

    将功能从rgb转换为hsl,并从here 只是有点适应。

    在stackoverflow上,我找到了一个可以直接转换较浅和较深十六进制颜色的函数。我认为这比我的解决方案慢了一点(可能),但更容易实现。

    代码在这里https://stackoverflow.com/questions/3512311/how-to-generate-lighter-darker-color-with-php#11951022 如果需要,可以使用该函数编辑我的类以生成较浅和较深的颜色。

    请注意,stackoverflow函数接受从-255到255(负=暗/正=亮)的亮度增加/减少。我的类接受可能更直观的百分比值。

  • 结束

    相关推荐