[SOLVED] Theme can't locate REST API endpoints when using with Bedrock

Hello,

I’m in the process of building a listing site using a paid theme (“citadela” by ait-themes.club/). It comes with a few plugins which are necessary to extend the theme to become a listing site.

To test the theme, I installed it on a normal fresh WordPress installation locally using Valet and PHP 8. Everything worked fine.

However, once I’ve decided to stick with the theme and put together a more professional environment with Bedrock, the theme can’t reach certain API endpoints. In this case, it was the endpoint to fetch items.

This fails and throws the following error message in Chrome’s console:

Uncaught (in promise) SyntaxError: Unexpected token '<', "<br />
<b>"... is not valid JSON

This was created by Valet’s error message, which is:

<br />
<b>Warning</b>:  chdir(): No such file or directory (errno 2) in <b>/Users/kolja/.composer/vendor/laravel/valet/server.php</b> on line <b>232</b><br />
<br />
<b>Warning</b>:  require(/Users/kolja/Sites/mysite.com/web/wp/wp-json/citadela-directory/map-data/points/citadela-item): Failed to open stream: No such file or directory in <b>/Users/kolja/.composer/vendor/laravel/valet/server.php</b> on line <b>234</b><br />
<br />
<b>Fatal error</b>:  Uncaught Error: Failed opening required '/Users/kolja/Sites/mysite.com/web/wp/wp-json/citadela-directory/map-data/points/citadela-item' (include_path='.:/opt/homebrew/Cellar/php@8.0/8.0.20/share/php@8.0/pear') in /Users/kolja/.composer/vendor/laravel/valet/server.php:234
Stack trace:
#0 {main}
  thrown in <b>/Users/kolja/.composer/vendor/laravel/valet/server.php</b> on line <b>234</b><br />

As you can see, the fatal error is caused by the request of the URL /web/wp/wp-json/citadela-directory/map-data/points/citadela-item.

Requesting this URL via the browser simply leads back to the front page with no error but still doesn’t access the endpoint.

Changing it to /wp-json/wp/v2/citadela-directory/ finally gives me a JSON object, but of course this custom route is not registered:

{
  "code": "rest_no_route",
  "message": "No route was found matching the URL and request method.",
  "data": {
  "status": 404
  }
}

I’m quite certain that this has something to do with Bedrock being located in a subdirectory but I have no idea how to solve this. For reference, here is the code that handles the call (it’s inside one of the plugin extensions):

register_rest_route( 'citadela-directory', 'wp-json/map-data/points/citadela-item(?:/(?P<id>\d+))?', [
            'methods' => 'GET',
            'callback' =>  array(__CLASS__, 'restGetItemPoints'),
            'permission_callback' => "__return_true",
            'args' => ['id' => [
                    'validate_callback' => function($param, $request, $key) {
                    return is_numeric( $param );
                    }
                ],
            ]
        ] );

Does anyone have an idea how I can fix this without editing the plugin itself and use Bedrock?

Many thanks!

  1. Are you registering (invoking register_rest_route) inside a rest_api_init action handler?
add_action('rest_api_init', function () {
  register_rest_route([...]
  [...]
});
  1. From what I know from docs and previous usage of custom routes in WordPress, the wp-json part is not passed with the custom route URL:
register_rest_route( 'citadela-directory', '/map-data/points/citadela-item(?:/(?P<id>\d+))?',
2 Likes

I know this in not the best answer, but please try to restart Valet. I’ve got the same error yesterday:

  • restart Valet
  • wp acorn optimize:clear

Give it a shot

2 Likes

Thanks for your reply. Yes, the plugin calls it in the static function init() of the CitadelaDirectorySearch class:

add_action( 'rest_api_init', array(__CLASS__, 'registerRestRoutes') );

Thanks, but I’ve already tried that. Many problems have been fixed with a simple valet restart, but not this one…

Have you cleared all views and config cache through Acorn?

Yes, I repeated it after you suggested it.

1 Like

Have you omitted the wp-join part in the custom URL (/map-data/points/citadela-item(?:/(?P<id>\d+))?)?

1 Like

No, it’s there. But your suggestion made me look into the source code of the plugin a bit more and I managed to get it loaded. In another function where the theme “guesses” the endpoint, the used the following code:

return site_url() . "/wp-json/citadela-directory/map-data/points/{$post->post_type}/{$post->ID}?{$queryString}";
return home_url() . "/wp-json/citadela-directory/map-data/points/{$postType}?{$queryString}";

Changing site_url() to home_url() did the trick.

However, now the console fills up with multiple lines of

google.maps.event.addDomListener() is deprecated, use the standard addEventListener() method instead

But I guess this is something for the theme author(s), I don’t feel comfortable hacking plugins, and there’s no hook anywhere.

Thanks so much for your help, guys!

P.S.: I’ve heard that the roots community is awesome, and now after giving it a try and actually having meaningful ideas, I agree. You guys rock!

2 Likes

There’s also rest_url().

return rest_url("citadela-directory/map-data/points/{$post->post_type}/{$post->ID}?{$queryString}");