torchlight-api / torchlight-laravel

A Laravel client for Torchlight - the syntax highlighting API.
https://torchlight.dev
MIT License
113 stars 17 forks source link

Extra docs for Statamic static site generation #22

Open stevebauman opened 2 years ago

stevebauman commented 2 years ago

There were issues I ran into and had to resolve when using Statamic with their Static Site Generation plugin. This isn't an issue with Torchlight exactly but with how SSG is performed in the plugin.

When generating the pages via php please ssg:generate, views are generated with the raw Torchlight placeholders:

Screen Shot 2022-01-06 at 11 19 52 AM

After creating a Statamic custom page generator and forcing the page to be rendered in full by manually calling the RenderTorchlight middleware, we get the full HTML code snippets:

Screen Shot 2022-01-06 at 11 20 00 AM

Results can be seen here: https://stevebauman.ca/create-api-responses-with-eloquent-factories/

Here's the code for forcing code generation:

// app/Providers/AppServiceProvider.php

use App\CustomGenerator;
use Statamic\StaticSite\Tasks;
use Statamic\Facades\Markdown;
use Statamic\StaticSite\Generator;
use Torchlight\Commonmark\V2\TorchlightExtension;

/**
 * Bootstrap any application services.
 *
 * @return void
 */
public function boot()
{
    Markdown::addExtension(function () {
        return new TorchlightExtension;
    });

    $this->app->singleton(Generator::class, function ($app) {
        return new CustomGenerator($app, $app['files'], $app['router'], $app[Tasks::class]);
    });
}
// app/CustomGenerator.php

namespace App;

use Statamic\StaticSite\Generator;

class CustomGenerator extends Generator
{
    protected function createPage($content)
    {
        return new CustomPage($this->files, $this->config, $content);
    }
}
// app/CustomPage.php

namespace App;

use Illuminate\Http\Exceptions\HttpResponseException;
use Illuminate\Http\RedirectResponse;
use Statamic\StaticSite\GeneratedPage;
use Statamic\StaticSite\Page;
use Torchlight\Middleware\RenderTorchlight;

class CustomPage extends Page
{
    protected function write($request)
    {
        $response = (new RenderTorchlight())->handle($request, function ($request) {
            try {
                $response = $this->content->toResponse($request);
            } catch (HttpResponseException $e) {
                $response = $e->getResponse();
                throw_unless($response instanceof RedirectResponse, $e);
            }

            // This has to be set/overridden, as additional pages being generated
            // by Statamic SSG will have a `null` content type and Torchlight
            // relies on this to return the full response instead of Blade.
            $response->headers->set('content-type', 'html');

            return $response;
        });

        $html = $response->getContent();

        if (! $this->files->exists($this->directory())) {
            $this->files->makeDirectory($this->directory(), 0755, true);
        }

        $this->files->put($this->path(), $html);

        return new GeneratedPage($this, $response);
    }
}

I hope this helps someone who is looking to do the same thing! 😄

aarondfrancis commented 2 years ago

Steve this is amazing, thank you for taking the time to write this up. I'll add it to the docs, I really really appreciate it!

mbootsman commented 1 year ago

Thanks for the tip to look at this issue for a solution @joshuablum. I have a pair of red underlines in my code that prevents this from working.

Markdown::addExtension(function () {
   return new TorchlightExtension;
});

Undefined type 'App\Providers\Markdown' And Undefined type 'Torchlight\Commonmark\V2\TorchlightExtension'`

Hope you can point me in the right way.

joshuablum commented 1 year ago

Looks like you might have forgotten to import Statamic's Markdown facade, @mbootsman?

Try to add use Statamic\Facades\Markdown;, like mentioned here and here.

stevebauman commented 1 year ago

Thanks @joshuablum -- I missed that import in the example, I've added it in 👍

joshuablum commented 1 year ago

Don't worry, it's nothing more than a Facade, @stevebauman. Thanks for the great work, really appreciated!

simonhamp commented 1 year ago

I am shocked... SHOOK! ... to see that these classes are not final @stevebauman

😏

stevebauman commented 1 year ago

lmao I would rather DIE @simonhamp