JSON API to show Advanced Custom Fields - WordPress

后端 未结 6 2009
被撕碎了的回忆
被撕碎了的回忆 2021-01-30 15:14

I am developing a magazine WordPress site that will have a json feed for a Mobile App. I set the backend up using Advanced Custom Fields with a Repeater Field for Multiple Artic

相关标签:
6条回答
  • 2021-01-30 15:44

    Current version of ACF prints out a custom_fields object on a call to the JSON API, containing all the fields relative to the Post or Page. I edited @Myke version to add specific custom fields from the ACF Option page to each Post or Page. Unfortunately there is not get_fields() function for the whole Option Page so you'll have to edit it depending on your fields structure.

    add_filter('json_api_encode', 'json_api_encode_acf');
    
    function json_api_encode_acf($response) {
        if (isset($response['posts'])) {
            foreach ($response['posts'] as $post) {
                json_api_add_acf($post); // Add specs to each post
            }
        }
        else if (isset($response['post'])) {
            json_api_add_acf($response['post']); // Add a specs property
        }
        else if (isset($response['page'])) {
            json_api_add_acf($response['page']); // Add a specs to a page
        }
    
        return $response;
    }
    
    function json_api_add_acf(&$post) {
        $post->custom_fields->NAME_OF_YOUR_CUSTOM_FIELD = get_field( 'NAME_OF_YOUR_CUSTOM_FIELD', 'option' );
    }
    
    0 讨论(0)
  • 2021-01-30 15:47

    Came here by searching with the same question. This isn't totally vetted yet but I think this is getting on the right path. Check it out.

    I have one less nested level than you do so this might need altered a bit. But the JSON API plugin has a filter called json_api_encode. I have a repeater called specifications that looks like this.

    http://d.pr/i/YMvv

    In my functions file I have this.

    add_filter('json_api_encode', 'my_encode_specs');
    
    function my_encode_specs($response) {
      if (isset($response['posts'])) {
        foreach ($response['posts'] as $post) {
          my_add_specs($post); // Add specs to each post
        }
      } else if (isset($response['post'])) {
        my_add_specs($response['post']); // Add a specs property
      }
      return $response;
    }
    
    function my_add_specs(&$post) {
      $post->specs = get_field('specifications', $post->id);
    }
    

    Which appends a custom value to the JSON API output. Notice the get_field function from ACF works perfectly here for bringing back the array of the repeater values.

    Hope this helps!

    0 讨论(0)
  • 2021-01-30 15:49

    There is now a small plugin which adds the filter for you.

    https://github.com/PanManAms/WP-JSON-API-ACF

    0 讨论(0)
  • 2021-01-30 15:50

    I'm not sure if you're still interested in a solution, but I was able to modify the json-api plugin models/post.php file to display the repeater data as an array. This is a modification of a modification made by http://wordpress-problem.com/marioario-on-plugin-json-api-fixed-get-all-custom-fields-the-right-way/

    replace the set_custom_fields_value() function with the following:

    function set_custom_fields_value() {
    
        global $json_api;
    
        if ($json_api->include_value('custom_fields') && $json_api->query->custom_fields) {
    
            // Query string params for this query var
            $params = trim($json_api->query->custom_fields);
    
            // Get all custom fields if true|all|* is passed
            if ($params === "*" || $params === "true" || $params === "all") {
    
                $wp_custom_fields = get_post_custom($this->id);
                $this->custom_fields = new stdClass();
    
                // Loop through our custom fields and place on property
                foreach($wp_custom_fields as $key => $val) {
                    if (get_field($key)) {
                        $this->custom_fields->$key = get_field($key);
                    } else if ($val) {
                        // Some fields are stored as serialized arrays.
                        // This method does not support multidimensionals... 
                        // but didn't see anything wrong with this approach
                        $current_custom_field = @unserialize($wp_custom_fields[$key][0]);
    
                        if (is_array($current_custom_field)) {
    
                            // Loop through the unserialized array
                            foreach($current_custom_field as $sub_key => $sub_val) {
    
                                // Lets append these for correct JSON output
                                $this->custom_fields->$key->$sub_key = $sub_val;
                            }
    
                        } else {
    
                            // Break this value of this custom field out of its array
                            // and place it on the stack like usual
                            $this->custom_fields->$key = $wp_custom_fields[$key][0];
    
                        }
                    }
                }
            } else {
    
                // Well this is the old way but with the unserialized array fix
                $params = explode(',', $params);
                $wp_custom_fields = get_post_custom($this->id);
                $this->custom_fields = new stdClass();
    
                foreach ($params as $key) {
    
                    if (isset($wp_custom_fields[$key]) && $wp_custom_fields[$key][0] ) {
                        $current_custom_field = @unserialize($wp_custom_fields[$key][0]);
    
                        if (is_array($current_custom_field)) {
                            foreach($current_custom_field as $sub_key => $sub_val) {
                                $this->custom_fields->$key->$sub_key = $sub_val;
                            }
    
                        } else {
                            $this->custom_fields->$key = $wp_custom_fields[$key][0];
    
                        }
    
                    }
                }
            }
    
        } else {
            unset($this->custom_fields);
    
        }
    }
    
    0 讨论(0)
  • 2021-01-30 15:54

    @Myke: you helped me tremendously. Here's my humble addition:

    add_filter('json_api_encode', 'json_api_encode_acf');
    
    
    function json_api_encode_acf($response) 
    {
        if (isset($response['posts'])) {
            foreach ($response['posts'] as $post) {
                json_api_add_acf($post); // Add specs to each post
            }
        } 
        else if (isset($response['post'])) {
            json_api_add_acf($response['post']); // Add a specs property
        }
    
        return $response;
    }
    
    function json_api_add_acf(&$post) 
    {
        $post->acf = get_fields($post->id);
    }
    
    0 讨论(0)
  • 2021-01-30 15:57

    Update for Wordpress 4.7

    With the release of Wordpress 4.7 the REST functionality is no longer provided as a distinct plugin, rather its rolled in (no plugin required).

    The previous filters don't appear to work. However the following snippet does (can be in your functions.php):

    >= PHP 5.3

    add_filter('rest_prepare_post', function($response) {
        $response->data['acf'] = get_fields($response->data['id']);
        return $response;
    });
    

    < PHP 5.3

    add_filter('rest_prepare_post', 'append_acf');
    
    function append_acf($response) {
        $response->data['acf'] = get_fields($response->data['id']);
        return $response;
    };
    

    Note the filter is a wild card filter, applied like

    apply_filters("rest_prepare_$type", ...
    

    so if you have multiple content types (custom), you will need to do:

    add_filter('rest_prepare_multiple_choice', 'append_acf');
    add_filter('rest_prepare_vocabularies', 'append_acf');
    
    function append_acf($response) {
        $response->data['acf'] = get_fields($response->data['id']);
        return $response;
    };
    

    Note It appears that rest_prepare_x is called per record. So if you are pinging the index endpoint, it will be called multiple times (so you don't need to check if its posts or post)

    0 讨论(0)
提交回复
热议问题