Roots Discourse

Adding extend api file to sage 10

Sage 10.0.0, tailwind
Hello, I am trying to add a new file to the app directory called extend-api.php, but I am getting Cannot modify header information errors. I was getting the same errors when trying to register a custom post type until I moved it to a plugin, don’t know if that is related or not.

This is the extend-api.php file

 * Functions to extend the WP Rest API
 *
 * @package WordPress
 */
/**
 * Register custom fields for GET requests.
 *
 * Ref: https://developer.wordpress.org/reference/functions/register_rest_field/
 */
add_action( 'rest_api_init', 'msoto_extend_api_response' );
function msoto_extend_api_response() {
    register_rest_field(
        array( 'post' ), // post types.
        'vue_meta', // name of the new key.
        array(
            'get_callback' => 'vue_get_post_meta_fields',
            'update_callback' => null,
            'schema' => null,
        )
    );
}
/**
 * GET callback for the "vue_meta" field defined above.
 *
 * @param array $post_object Details of the current post.
 * @param string $field_name Field Name set in register_rest_field().
 * @param WP_REST_Request $request Current request.
 *
 * @return mixed
 */
function vue_get_post_meta_fields( $post_object, $field_name, $request ) {
    // make additional fields available in the response using an associative array.
    $additional_post_data = array();
    $terms = array();
    $term_links = array();
    $post_id = $post_object['id']; // get the post id.
    foreach ( $post_object['categories'] as $category_id ) {
        $term_data = get_category( $category_id );
        $term_name = $term_data->category_nicename;
        $term_url = get_term_link( $term_data->name, $term_data->taxonomy );
        $term_link = "<a href=\"$term_url\">$term_name</a>";
        array_push( $terms, $term_name );
        array_push( $term_links, $term_link );
    }
    // add categories, custom excerpt, featured image to the api response.
    $img_id  = get_post_thumbnail_id( $post_id );
    $img_alt = get_post_meta( $img_id,'_wp_attachment_image_alt', true );
    $additional_post_data = array(
        'custom_excerpt' => wp_trim_words(
            $post_object['excerpt']['rendered'],
            25,
            ' &hellip;'
        ),
        'terms' => $terms,
        'term_links' => $term_links,
        'featuredmedia_alt' => get_post_meta(
            $img_id,
            '_wp_attachment_image_alt',
            true
        ),
        'featuredmedia_url' => get_the_post_thumbnail_url(
            $post_id,
            'full'
        ),
    );
    // return data to the get_callback.
    // this data will be made available in the key "vue_meta".
    return $additional_post_data;
}

In my functions.php file

array_map(function ($file) use ($sage_error) {
$file = “app/{$file}.php”;
if (! locate_template($file, true, true)) {
$sage_error(
sprintf(__(‘Error locating %s for inclusion.’, ‘sage’), $file),
__(‘File not found’, ‘sage’)
);
}
}, [‘helpers’, ‘setup’, ‘filters’, ‘admin’, ‘extend-api’]);

Not sure if this part is needed here but:
In my setup.php I added this localize script part. This part of the code works when removing the extend-api file, however I get the same error when removing the code from extend-api file and just doing a simple ‘hello’ echo.

In setup.php

add_action(‘wp_enqueue_scripts’, function () {
wp_enqueue_script(‘sage/vendor’, asset(‘scripts/vendor.js’)->uri(), [‘jquery’], null, true);
wp_enqueue_script(‘sage/app’, asset(‘scripts/app.js’)->uri(), [‘sage/vendor’, ‘jquery’], null, true);
wp_add_inline_script(‘sage/vendor’, asset(‘scripts/manifest.js’)->contents(), ‘before’);
if (is_single() && comments_open() && get_option(‘thread_comments’)) {
wp_enqueue_script(‘comment-reply’);
}
$styles = [‘styles/app.css’];
foreach ($styles as $stylesheet) {
if (asset($stylesheet)->exists()) {
wp_enqueue_style(‘sage/’ . basename($stylesheet, ‘.css’), asset($stylesheet)->uri(), false, null);
}
}
//msoto localize script
global $post;
wp_localize_script(
‘sage/app’, // vue script handle defined in wp_register_script.
‘wpData’, // javascript object that will made availabe to Vue.
array( // wordpress data to be made available to the Vue app in ‘wpData’
‘template_directory_uri’ => get_template_directory_uri(), // theme directory path.
‘home_url’ => get_home_url(),
‘rest_url’ => untrailingslashit( esc_url_raw( rest_url() ) ), // URL to the REST endpoint.
‘app_path’ => $post->post_name, // page where the custom page template is loaded.
‘post_categories’ => get_terms( array(
‘taxonomy’ => ‘category’, // default post categories.
‘hide_empty’ => true,
‘fields’ => ‘names’,
) ),
) );
}, 100);

In the console I get this error

localhost/:1 Uncaught (in promise) SyntaxError: Unexpected token a in JSON at position 0
And the top of the file after clicking has this
a<!doctype html>

I also get this warning

DevTools failed to load SourceMap: Could not parse content for http://localhost:3000/manifest.js.map: Unexpected token a in JSON at position 0

Clicking it has this notice at the top

Notice: Trying to get property ‘post_name’ of non-object in /srv/www/test.test/current/web/app/themes/sage-vue-tailwind/app/setup.php on line 39

So it looks like $post is no longer recognized :frowning:

These are the modify header errors:

Warning: Cannot modify header information - headers already sent by (output started at /srv/www/test.test/current/web/app/themes/sage-vue-tailwind/app/extend-api.php:1) in /srv/www/test.test/current/web/wp/wp-includes/functions.php on line 6221

Warning: Cannot modify header information - headers already sent by (output started at /srv/www/test.test/current/web/app/themes/sage-vue-tailwind/app/extend-api.php:1) in /srv/www/test.test/current/web/wp/wp-admin/includes/misc.php on line 1259

Warning: Cannot modify header information - headers already sent by (output started at /srv/www/test.test/current/web/app/themes/sage-vue-tailwind/app/extend-api.php:1) in /srv/www/test.test/current/web/wp/wp-admin/admin-header.php on line 9

Warning: Cannot modify header information - headers already sent by (output started at /srv/www/test.test/current/web/app/themes/sage-vue-tailwind/app/extend-api.php:1) in /srv/www/test.test/current/web/wp/wp-includes/option.php on line 961

Warning: Cannot modify header information - headers already sent by (output started at /srv/www/test.test/current/web/app/themes/sage-vue-tailwind/app/extend-api.php:1) in /srv/www/test.test/current/web/wp/wp-includes/option.php on line 962

I’m not sure if it’s a bug, a configuration file issue, or if I am missing a step in adding new files to Sage, any help would be appreciated.

So the output already started at line 1 of your extend-api.php script.
Have you checked the traditional candidates like UTF-8 BOM and line endings,
maybe hidden characters that cause PHP to send these to the client?

I’ll be honest, not sure what I would look for as far as utf-8 bom, but I get the same error when I delete everything in the file and replace it with something like <?php echo 'hello'; ?> or even just delete everything in the file and leave it blank.

I also get the same error when reverting back and adding the same echo to the bottom of setup.php.

The error goes away when I delete echo hello from setup.php and it goes away when I remove the file from the array map and go back to default of helpers, setup, filters, admin. Basically it seems to be happening whenever I add any custom code to the bottom of setup.php or try to map a new file outside of a plugin.

Open that file in an editor like Notepad++. Check the encoding menu, what encoding is used for that file? UTF-8? Also check Edit > EOL Conversion, what line endings are used? You can also use a *nix CLI tool like dos2unix. Also try View > Show Symbol > Show all characters to check for hidden characters in that text file.

How are you uploading/editing/syncing that file onto the server? SFTP? RSYNC? GIT? Terminal text editor over SSH seesion?

Default webpack, virtualbox on dev using wsl and windows 10.

Using Notepad++ and searching for hidden characters and saving as unix worked though.
Adding a function to the bottom of setup.php still gives errors, I don’t know whether I’m supposed to edit that file unless I’m extending my function in the already included hooks. Outside of the existing hooks is what causes me issues. As long as I create a new file for my customizations I don’t get any errors so I have created a new file called app-main.php and added it to the map in functions.php and everything is now working as expected.

Thank you so much for all your help, I really appreciate it!

The root cause could be git line ending config and the combination of WSL/normal file system.
Case sensitivity in file/folder names and different line endings often cause issues.