scribe icon indicating copy to clipboard operation
scribe copied to clipboard

Double curly brackets in API response break scribe blade template

Open alexweb opened this issue 2 years ago • 2 comments

Hi I have json response from my API containing string like "This field must be {{value}} or less" and looks like this breaks scribe's blade, because I get an error:

"Error PHP 8.2.0. 9.45.1 Undefined constant "value""

Looks like scribe inserts response from API right into blade without escaping double curly brackets {{ ? And laravel then tries to parse {{value}} in blade and can't find such constant? Maybe I can make scribe encode {{ in output from my API?

Thanks

alexweb avatar Jan 05 '23 14:01 alexweb

Since Blade uses @ for escaping, I guess the fix would be something like preg_replace("/(?<!{){{(?!{)/g", "@{{", $content) (escape all double braces). I'll try to get to this when I'm free, but you can send a PR.

shalvah avatar Jan 06 '23 12:01 shalvah

Hi,

I've also experienced this problem while creating docs for an API for our company's code guideliness project. The data in our database includes blade code examples and therefor, the scribe docs (type: laravel) break because of the blade syntax in these example responses.

I just found the solution for this problem (I think it covers everything, but I'm not a 100% sure).

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Support\Str;

class PageResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
     */
    public function toArray($request)
    {
        // Check if running scribe:generate
        if (app()->runningInConsole() && Str::contains(request()->userAgent(), 'Symfony')) {
            $body = Str::of($this->html_content)
                ->replaceMatches('/@(?!(end))\w+/', '@@')
                ->replace('{{', '@{{')
                ->replace('{!!', '@{!!');
        }

        return [
            'id' => $this->id,
            'title' => $this->title,
            'slug' => $this->slug,
            'body' => $body,
            'online' => $this->online,
            'category_id' => $this->category_id,
            'category' => new CategoryResource($this->whenLoaded('category')),
            'created_at' => $this->created_at,
            'updated_at' => $this->updated_at,
        ];
    }
}

So maybe these lines could be implemented in the blade file that is used to generate the content? Or a mapping in the controller to parse all the attributes of the example responses?

The ->replaceMatches('/@(?!(end))\w+/', '@@') is used to escape blade directives like @if, @foreach, @forelse, ... while not escaping the closing tags for these directives. so @if becomes @@if while @endif remains @endif

SimonBroekaert avatar Feb 03 '23 07:02 SimonBroekaert