如何从 API 调用附加到 WordPress 定制器中的选择框?

Posted

技术标签:

【中文标题】如何从 API 调用附加到 WordPress 定制器中的选择框?【英文标题】:How to append to a select box in the WordPress customiser from an API call? 【发布时间】:2020-01-26 15:01:12 【问题描述】:

我正在开发一个 WordPress 主题,并添加了一个选择框以允许用户为他们的网站选择一种字体。我想我会使用 Google Fonts API 来获取字体列表,而不是手动添加所有 900 种字体,但是当我调用 API 时,我无法将返回的数据作为选项附加到选择框中。

这是我的选择框类的 php 代码:

    class Customize_Select_Control extends WP_Customize_Control 
        public $type = 'select';

        public function render_content() 
            ?>
            <label>
                <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
                <select <?php $this->link(); ?> id="<?php echo str_replace(' ','-',strtolower(esc_html( $this->label ))); ?>-select">
                    <option value="<?php echo $this->value(); ?>" selected><?php echo $this->value(); ?></option>
                </select>
            </label>
            <?php
        
    

然后,我使用以下代码向定制器添加了一个部分、设置和控制:

    // Add Font Section
    $wp_customize->add_section( 'fonts' , array(
        'title' => __( 'Font', 'wordpress' ),
        'priority' => 100,
        'description' => __( 'Pick a font for your website.', 'wordpress' )
    ) );

    // Add the setting & control for the font
    $wp_customize->add_setting( 'font-select' , array(
        'default'   => 'Open Sans',
        'transport' => 'postMessage',
    ) );
    $wp_customize->add_control( new Customize_Select_Control( $wp_customize, 'font-select', array(
        'label'      => __( 'Font', 'wordpress' ),
        'section'    => 'fonts',
        'settings'   => 'font-select',
    ) ) );

以下代码应该将选项附加到选择框:

     $.ajax(
        type: "GET",
        url: "https://www.googleapis.com/webfonts/v1/webfonts?key=[REDACTED]&sort=popularity&fields=items",
        dataType: "json",
        success: function (result, status, xhr)
          console.log(result.items);
          for (var i = 0; i<result.items.length; i++)
            var family = result.items[i].family;
            console.log(family);
            $('#font-select').append(`<option value="$family">$family</option>`);
          
        ,
        error: function (xhr, status, error) 
          alert("There was an error loading the Google fonts API: " + status + " " + error + " " + xhr.status + " " + xhr.statusText + "\n\nPlease save your changes and refresh the page to try again.")
        
      );

如果我将 #font-select 更改为 body,它会很好地附加选项,但是我尝试将它们附加到选择框,它只是没有不工作。知道为什么以及如何使这项工作发挥作用吗?

【问题讨论】:

【参考方案1】:

您可以通过以下代码在定制器管理面板的选择框中添加选项值:

您的要求的完整代码

您只需在脚本中添加您的 google 字体 api 密钥 在我使用“twentynineteen”主题 slug 名称的地方,您可以使用您的主题 slug 名称

有3个部分:

1)  function mytheme_customize_register( $wp_customize ) 
        //All our sections, settings, and controls will be added here


        $wp_customize->add_section( 'fonts' , array(
            'title' => __( 'Font', 'twentynineteen' ),
            'priority' => 100,
            'description' => __( 'Pick a font for your website.', 'twentynineteen' )
        ) );

        // Add the setting & control for the font
        $wp_customize->add_setting( 'font-select' , array(
            'type' => 'select',
            'default' => 'Roboto',
            'transport' => 'postMessage',
        ) );

        $wp_customize->add_control(  'font-select', array(
            'type' => 'select',
            'priority' => 10, // Within the section.
            'section' => 'core', // Required, core or custom.
            'description' => __( 'This is a date control with a red border.' ),
            'choices' => array( // Optional.
            'wordpress' => __( 'Roboto' ),
            'hamsters' => __( 'Lato' ),
            'jet-fuel' => __( 'Muli' ),

        ),
            'label'      => __( 'Font', 'twentynineteen' ),
            'section'    => 'fonts',
            'settings'   => 'font-select',
        )  );

     
     add_action( 'customize_register', 'mytheme_customize_register' );

现在添加脚本文件

2) function add_font_scripts()

  wp_enqueue_script('custom_js_script', get_bloginfo('template_url').'/js/custom-scripts.js', array('jquery'));

add_action( 'admin_enqueue_scripts', 'add_font_scripts' );

现在最后一步,请在这个文件 custom-scripts.js 中添加下面的脚本,我们刚刚在上面排队

3)  var $= jQuery;
$(document).ready(function()


    $.ajax(
        type: "GET",

        url: "https://www.googleapis.com/webfonts/v1/webfonts?key=apikey&sort=popularity&fields=items",
        dataType: "json",

        success: function (result, status, xhr)
            var outputstate = [];
          console.log(result.items);
          for (var i = 0; i<result.items.length; i++)
            var family = result.items[i].family;
            console.log(family);

           outputstate.push('<option value="'+ family +'">'+ family +'</option>');
           $('#_customize-input-font-select').html(outputstate.join(''));
          
        ,
        error: function (xhr, status, error) 
          alert("There was an error loading the Google fonts API: " + status + " " + error + " " + xhr.status + " " + xhr.statusText + "\n\nPlease save your changes and refresh the page to try again.")
        


        );
    );

我已经尝试过这段代码,它运行良好!

希望这篇文章能帮到你!

【讨论】:

感谢您的回答@KrishnaSavani。我试图实现您的代码,但它似乎不适用于我的主题。看起来您将它与二十九岁主题一起使用,所以我想知道这是否是原因。我正在使用underscores 从头开始​​制作我的主题。您的代码仍在将字体记录到控制台,并将选项附加到 body html,但不会将选项附加到字体选择框,即使我已经仔细检查了 ID 并且它们都匹配。 我已经尝试过从 (underscores.me) 获取主题的方式,并且它在那里也可以正常工作..现在你可以仔细检查定制器中的选择框 ID (prnt.sc/pfs2bn) 它会与在 jquery 脚本中添加相同。我在定制器中添加控件时使用了“font-select”,但是当我附加到 jquery 时,我使用的是这个 id ('#_customize-input-font-select"') 所以请你可以这样检查吗?【参考方案2】:

您的 AJAX 成功回调正在寻找 idfont-select 的下拉列表。但是,Dropdown 的 id 是基于 Label(恰好是 font)。

下拉列表的 ID 由 render_content 方法中的以下代码行创建。

<?php echo str_replace(' ','-',strtolower(esc_html( $this->label ))); ?>

$this-&gt;label 这里指的是Fonts。由于您使用的是 strtolower,它将是fonts。我建议您为 id 传递另一个变量并使用该变量填充它。

【讨论】:

谢谢你回答@ascsoftw,但是选择框的id被渲染为#font-select(注意你提到的代码后面的-select)。 Screenshot here。最初我没有使用额外的-select 位,但我补充说,因为我认为它可能与某个地方的另一个 ID 发生冲突。 好的,我现在看到了。您能否确认没有其他 id 为“font-select”的元素 在元素检查器中搜索 font-select 除了相关的选择框之外不会产生任何结果。我唯一的猜测是,这与定制器设置面板是动态生成的事实有关。我也无法在定制器面板中的任何位置呈现来自 API 调用的数据,但在页面预览的 html 中呈现它们效果很好。我试过使用setTimeoutajaxComplete 来解决这个问题,但这也不起作用。 动态生成font-select 不应阻止其填充。你能不能把console.log( $('#font-select').length); 作为AJAX成功回调的第一行来确保选择框存在。 好电话,我没想到这样做。响应为“0”。但是,如果我直接在开发工具控制台中输入相同的命令,它会返回“1”。

以上是关于如何从 API 调用附加到 WordPress 定制器中的选择框?的主要内容,如果未能解决你的问题,请参考以下文章

禁用 WordPress 定制器上的 WordPress 自定义 css 部分

如何将带有附加数据的 FormData 文件发送到 asp.net web api ajax 调用

php 如何链接到WordPress定制器

php 如何链接到WordPress定制器

php 如何链接到WordPress定制器

PHP wordpress - 从附加到帖子的图像自动创建Greybox图像集